├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── accessibility.spec.js ├── budget ├── assert-metrics.spec.js ├── budget.json └── helpers.js ├── cert-expiration.js ├── code-coverage.js ├── dark-mode.js ├── dom-snapshot.spec.js ├── element-to-pdf.js ├── fps.jpeg ├── fps.js ├── memory-leak-heap.spec.js ├── memory-leak-proto.spec.js ├── package-lock.json ├── package.json ├── pptrgram.js ├── pptrjourney.js ├── sample.jpg ├── security.js ├── side-by-side-pageload.js ├── speech.js ├── tensor-sample.jpg ├── tensorflow.html ├── tensorflow.js ├── timeline-trace.js ├── visual-regression.spec.js └── whatsapp ├── .firebaserc ├── .gitignore ├── firebase.json ├── functions ├── .eslintrc.json ├── .gitignore ├── helpers.js ├── index.js ├── package-lock.json └── package.json ├── storage.rules └── whatsapp-demo.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __snapshots__ 3 | node_modules 4 | .idea 5 | coverage 6 | .nyc_output 7 | .screenshots 8 | pptgram/* 9 | whatsapp/.tmp 10 | dark.jpg 11 | light.jpg 12 | fps.jpg 13 | trace.json 14 | tweet.pdf 15 | tweet.png 16 | discord 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2018 Google Inc. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Puppeteer Demos 2 | 3 | This repo contains various demos of the concepts, ideas and experiments over puppeteer that were demonstrated as part of the talks of mine. You can also find references of the links which are shown during the talk. 4 | 5 | 🎥 Video of the talk : https://www.youtube.com/watch?v=d2WSO3w5E94 6 | 7 | **Puppeteer can automate that! @HolyJS:** https://www.slideshare.net/nderCeylan/puppeteer-can-automate-that-holyjs-piter-2020 8 | 9 | **Puppeteer can automate that! @AmsterdamJS:** https://www.slideshare.net/nderCeylan/puppeteer-can-automate-that-amsterdamjs 10 | 11 | **Puppeteer can automate that! @Frontmania:** https://www.slideshare.net/nderCeylan/puppeteer-can-automate-that 12 | 13 | **Introducing perf budgets on CI with puppeteer @perf.now():** https://www.slideshare.net/nderCeylan/introducing-perf-budgets-on-ci-with-puppeteer 14 | 15 | > If you attended my talk, would you help me make my next one better? Please share your feedback with this form https://onderceylan.typeform.com/to/Z4SbFn. It'll only take a minute, promise :) 16 | 17 | The scripts in this repo are built for training and demonstration purposes, feel free to use them at your own risk. 18 | 19 | ## How to run scripts? 20 | 21 | Install dependencies 22 | ``` 23 | npm i 24 | ``` 25 | 26 | Execute scripts with 27 | ``` 28 | node fps.js 29 | cd whatsapp && node whatsapp.js 30 | ``` 31 | 32 | Run tests with 33 | ``` 34 | npx jest dom-snapshot.spec.js 35 | cd budget && npx jest assert-metrics.spec.js 36 | ``` 37 | 38 | ## References in talk 39 | 40 | * https://pptr.dev 41 | * https://try-puppeteer.appspot.com 42 | * https://github.com/transitive-bullshit/awesome-puppeteer 43 | * https://chrome.google.com/webstore/detail/puppeteer-recorder/djeegiggegleadkkbgopoonhjimgehda 44 | * https://github.com/ChromeDevTools/devtools-frontend 45 | * chrome://flags/#enable-devtools-experiments 46 | * chrome —-remote-debugging-port=9222 47 | * http://127.0.0.1:9222/devtools 48 | * http://127.0.0.1:9222/json/version 49 | * https://chromedevtools.github.io/devtools-protocol 50 | * https://github.com/ChromeDevTools/awesome-chrome-devtools 51 | * https://github.com/onderceylan/pwa-asset-generator 52 | * https://www.tensorflow.org/js/models 53 | * https://chromedevtools.github.io/timeline-viewer/ 54 | * https://github.com/mapbox/pixelmatch#nodejs 55 | * https://github.com/serverless/examples/tree/master/aws-node-puppeteer 56 | * https://browserless.io 57 | * https://checklyhq.com 58 | 59 | ## Script references for some of the concepts 60 | * https://github.com/GoogleChromeLabs/puppeteer-examples 61 | * https://github.com/trentmwillis/devtools-protocol-demos 62 | -------------------------------------------------------------------------------- /accessibility.spec.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | // Inspiration: https://github.com/trentmwillis/devtools-protocol-demos/blob/master/testing-demos/accessibility.js 4 | 5 | beforeAll(async () => { 6 | this.browser = await puppeteer.launch(); 7 | }); 8 | 9 | afterAll(async () => { 10 | await this.browser.close(); 11 | }); 12 | 13 | test('app is accessible and has no accessibility violations', async() => { 14 | const page = await this.browser.newPage(); 15 | await page.goto('https://frontmania.com'); 16 | 17 | await page.addScriptTag({ url: 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/3.3.2/axe.min.js' }); 18 | const results = await page.evaluate(() => axe.run(document)); 19 | 20 | if (results.violations.length > 0) { 21 | console.log(`Found ${results.violations.length} accessibility violations`); 22 | console.log(results.violations); 23 | } 24 | expect(results.violations.length).toBe(0); 25 | 26 | await page.close(); 27 | }); 28 | -------------------------------------------------------------------------------- /budget/assert-metrics.spec.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | const { getBudgetMetricsOfPage, getMatchedPageMetrics, getBudgetMetricByPageMetricName } = require('./helpers'); 3 | 4 | // Example page metrics 5 | // [ 6 | // { name: 'Timestamp', value: 66567.150449 }, 7 | // { name: 'AudioHandlers', value: 0 }, 8 | // { name: 'Documents', value: 8 }, 9 | // { name: 'Frames', value: 3 }, 10 | // { name: 'JSEventListeners', value: 34 }, 11 | // { name: 'LayoutObjects', value: 455 }, 12 | // { name: 'MediaKeySessions', value: 0 }, 13 | // { name: 'MediaKeys', value: 0 }, 14 | // { name: 'Nodes', value: 970 }, 15 | // { name: 'Resources', value: 74 }, 16 | // { name: 'ContextLifecycleStateObservers', value: 0 }, 17 | // { name: 'V8PerContextDatas', value: 4 }, 18 | // { name: 'WorkerGlobalScopes', value: 0 }, 19 | // { name: 'UACSSResources', value: 0 }, 20 | // { name: 'RTCPeerConnections', value: 0 }, 21 | // { name: 'ResourceFetchers', value: 8 }, 22 | // { name: 'AdSubframes', value: 0 }, 23 | // { name: 'DetachedScriptStates', value: 2 }, 24 | // { name: 'LayoutCount', value: 13 }, 25 | // { name: 'RecalcStyleCount', value: 22 }, 26 | // { name: 'LayoutDuration', value: 0.067929 }, 27 | // { name: 'RecalcStyleDuration', value: 0.029508 }, 28 | // { name: 'ScriptDuration', value: 0.122922 }, 29 | // { name: 'V8CompileDuration', value: 0.003031 }, 30 | // { name: 'TaskDuration', value: 0.336774 }, 31 | // { name: 'TaskOtherDuration', value: 0.116415 }, 32 | // { name: 'ThreadTime', value: 0.275266 }, 33 | // { name: 'JSHeapUsedSize', value: 7816504 }, 34 | // { name: 'JSHeapTotalSize', value: 11096064 }, 35 | // { name: 'FirstMeaningfulPaint', value: 66565.452541 }, 36 | // { name: 'DomContentLoaded', value: 66565.386449 }, 37 | // { name: 'NavigationStart', value: 66564.624457 } 38 | // ] 39 | 40 | const assertMetricsOnUrl = async (siteUrl) => { 41 | const page = await this.browser.newPage(); 42 | const protocol = await page.target().createCDPSession(); 43 | await protocol.send('Performance.enable'); 44 | 45 | await page.goto(siteUrl, { waitUntil: 'networkidle0' }); 46 | const budgetMetrics = await getBudgetMetricsOfPage(page); 47 | const { metrics: pageMetrics } = await protocol.send('Performance.getMetrics'); 48 | 49 | const matchedMetrics = getMatchedPageMetrics(pageMetrics, budgetMetrics); 50 | 51 | matchedMetrics.forEach(pageMetric => { 52 | expect(pageMetric.value).toBeLessThan(getBudgetMetricByPageMetricName(budgetMetrics, pageMetric)); 53 | }); 54 | 55 | await page.close(); 56 | }; 57 | 58 | beforeAll(async () => { 59 | this.browser = await puppeteer.launch(); 60 | }); 61 | 62 | afterAll(async () => { 63 | await this.browser.close(); 64 | }); 65 | 66 | test('asserts budget performance metrics on the main page', async() => { 67 | await assertMetricsOnUrl('https://pptr.dev'); 68 | }, 30000); 69 | 70 | test('asserts budget performance metrics on api page', async() => { 71 | await assertMetricsOnUrl('https://pptr.dev/api'); 72 | }, 30000); 73 | -------------------------------------------------------------------------------- /budget/budget.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "/", 4 | "perfMetrics": [ 5 | { 6 | "metric": "JSEventListeners", 7 | "budget": 100 8 | }, 9 | { 10 | "metric": "Nodes", 11 | "budget": 2000 12 | }, 13 | { 14 | "metric": "JSHeapUsedSize", 15 | "budget": 20000000 16 | } 17 | ] 18 | }, 19 | { 20 | "path": "/vacatures", 21 | "perfMetrics": [ 22 | { 23 | "metric": "Resources", 24 | "budget": 80 25 | } 26 | ] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /budget/helpers.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const { promisify } = require('util'); 3 | const readFileAsync = promisify(fs.readFile); 4 | 5 | const bytesToMb = (bytes) => { 6 | return bytes/1e+6; 7 | }; 8 | 9 | const getTimeFromPerformanceMetrics = (metrics, name) => 10 | metrics.metrics.find(x => x.name === name).value * 1000; 11 | 12 | const parsePerformanceMetrics = (metrics, ...metricNames) => { 13 | const parsedData = {}; 14 | const navigationStart = getTimeFromPerformanceMetrics( 15 | metrics, 16 | 'NavigationStart' 17 | ); 18 | 19 | metricNames.forEach(metricName => { 20 | parsedData[metricName] = 21 | getTimeFromPerformanceMetrics(metrics, metricName) - navigationStart; 22 | }); 23 | 24 | return parsedData; 25 | }; 26 | 27 | const getCustomMetric = (page, metricName) => 28 | new Promise(resolve => 29 | page.on('metrics', ({ title, metrics }) => { 30 | if (title === metricName) { 31 | resolve(metrics.Timestamp * 1000); 32 | } 33 | }) 34 | ); 35 | 36 | const getPath = (page) => { 37 | return page.evaluate(() => document.location.pathname); 38 | }; 39 | 40 | const getBudgetMetrics = async () => { 41 | const budgetMetrics = await readFileAsync('./budget.json', { encoding: 'utf8' }); 42 | return JSON.parse(budgetMetrics); 43 | }; 44 | 45 | const getBudgetMetricsForPath = async (path) => { 46 | const metrics = await getBudgetMetrics(); 47 | const metricForPath = metrics.find(metric => metric.path === path); 48 | 49 | if (metricForPath) { 50 | return metricForPath.perfMetrics; 51 | } 52 | 53 | return null; 54 | }; 55 | 56 | const getBudgetMetricsOfPage = async (page) => { 57 | const path = await getPath(page); 58 | return getBudgetMetricsForPath(path); 59 | }; 60 | 61 | const getMatchedPageMetrics = (pageMetrics, budgetMetrics) => { 62 | return pageMetrics.filter((pageMetric) => 63 | budgetMetrics.some(budgetMetric => budgetMetric.metric === pageMetric.name)); 64 | }; 65 | 66 | const getBudgetMetricByPageMetricName = (budgetMetrics, pageMetric) => { 67 | return budgetMetrics.find(budgetMetric => budgetMetric.metric === pageMetric.name).budget 68 | }; 69 | 70 | module.exports = { 71 | getBudgetMetricByPageMetricName, 72 | getTimeFromPerformanceMetrics, 73 | parsePerformanceMetrics, 74 | getBudgetMetricsOfPage, 75 | getBudgetMetricsForPath, 76 | getMatchedPageMetrics, 77 | getBudgetMetrics, 78 | getCustomMetric, 79 | bytesToMb, 80 | getPath 81 | }; 82 | -------------------------------------------------------------------------------- /cert-expiration.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | (async () => { 4 | const siteUrl = 'https://pptr.dev'; 5 | const browser = await puppeteer.launch(); 6 | const page = await browser.newPage(); 7 | 8 | page.on('response', (resp) => { 9 | const url = resp.url(); 10 | if (url === siteUrl) { 11 | const secDetails = resp.securityDetails(); 12 | const ts = Math.floor((new Date()).getTime() / 1000); 13 | console.log((Math.floor((secDetails.validTo() - ts) / 86400)), 'days to expire'); 14 | } 15 | }); 16 | 17 | await page.goto(siteUrl, { waitUntil: 'networkidle0' }); 18 | await page.close(); 19 | await browser.close(); 20 | })(); 21 | -------------------------------------------------------------------------------- /code-coverage.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | const pti = require('puppeteer-to-istanbul'); 3 | 4 | // Inspiration: https://github.com/trentmwillis/devtools-protocol-demos/blob/master/testing-demos/code-coverage.js 5 | 6 | (async () => { 7 | const browser = await puppeteer.launch(); 8 | 9 | const page = await browser.newPage(); 10 | 11 | await page.coverage.startJSCoverage(); 12 | 13 | await page.goto('https://pptr.dev'); 14 | 15 | const jsCoverage = await page.coverage.stopJSCoverage(); 16 | pti.write(jsCoverage); 17 | 18 | await page.close(); 19 | 20 | await browser.close(); 21 | })(); 22 | -------------------------------------------------------------------------------- /dark-mode.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | (async () => { 4 | const browser = await puppeteer.launch(); 5 | 6 | const page = await browser.newPage(); 7 | 8 | await page.goto('https://googlechromelabs.github.io/dark-mode-toggle/demo/index.html'); 9 | await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'light' }]); 10 | await page.waitForTimeout(200); 11 | await page.screenshot({ path: 'light.jpg', type: 'jpeg', omitBackground: true }); 12 | await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]); 13 | await page.waitForTimeout(200); 14 | await page.screenshot({ path: 'dark.jpg', type: 'jpeg', omitBackground: true }); 15 | await browser.close(); 16 | })(); 17 | -------------------------------------------------------------------------------- /dom-snapshot.spec.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | test('regression testing page dom snapshot', async() => { 4 | const browser = await puppeteer.launch(); 5 | 6 | const page = await browser.newPage(); 7 | 8 | await page.goto('https://pptr.dev'); 9 | 10 | expect(await page.content()).toMatchSnapshot(); 11 | 12 | await page.close(); 13 | 14 | await browser.close(); 15 | }); 16 | -------------------------------------------------------------------------------- /element-to-pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @author ebidel@ (Eric Bidelman) 17 | */ 18 | 19 | /** 20 | * Takes a screenshot of the latest tweet in a user's timeline and creates a 21 | * PDF of it. Shows how to use Puppeteer to: 22 | * 23 | * 1. screenshot a DOM element 24 | * 2. craft an HTML page on-the-fly 25 | * 3. produce an image of the element and PDF of the page with the image embedded 26 | * 27 | * Usage: 28 | * node element-to-pdf.js 29 | * USERNAME=ChromiumDev node element-to-pdf.js 30 | * 31 | * --searchable makes "find in page" work: 32 | * node element-to-pdf.js --searchable 33 | * 34 | * Output: 35 | * tweet.png and tweet.pdf 36 | */ 37 | 38 | // Inspiration: https://github.com/GoogleChromeLabs/puppeteer-examples/blob/master/element-to-pdf.js 39 | 40 | const puppeteer = require('puppeteer'); 41 | 42 | const username = process.env.USERNAME || 'onderceylan'; 43 | const searchable = process.argv.includes('--searchable'); 44 | 45 | (async() => { 46 | 47 | const browser = await puppeteer.launch({headless: false}); 48 | 49 | const page = await browser.newPage(); 50 | await page.setViewport({width: 1200, height: 1000, deviceScaleFactor: 2}); 51 | await page.goto(`https://twitter.com/${username}/status/1648736108304297985`); 52 | 53 | await page.waitForSelector('[data-testid="tweet"]', {visible: true}); 54 | 55 | await page.$eval('#layers', el => el.remove()); 56 | 57 | const overlay = await page.$('[data-testid="tweet"]'); 58 | const screenshot = await overlay.screenshot({path: 'tweet.png'}); 59 | 60 | await page.setContent(` 61 | 62 | 63 | 64 | 79 | 80 | 81 | 82 | 83 | 84 | `); 85 | 86 | await page.pdf({path: 'tweet.pdf', printBackground: true}); 87 | await browser.close(); 88 | })(); 89 | -------------------------------------------------------------------------------- /fps.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onderceylan/puppeteer-demos/bdffbe3b9a14f00f07c29614eea90310051a2eed/fps.jpeg -------------------------------------------------------------------------------- /fps.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | (async () => { 4 | const browser = await puppeteer.launch({ 5 | headless: false, 6 | }); 7 | const page = await browser.newPage(); 8 | const protocol = await page.target().createCDPSession(); 9 | await protocol.send('Overlay.setShowFPSCounter', { show: true }); 10 | await page.goto('https://pptr.dev'); 11 | 12 | // Do graphical regressions here by interacting with the page 13 | await protocol.send('Input.synthesizeScrollGesture', { 14 | x: 100, 15 | y: 100, 16 | yDistance: -400, 17 | repeatCount: 3 18 | }); 19 | 20 | await page.screenshot({ 21 | path: 'fps.jpeg', 22 | type: 'jpeg', 23 | clip: { 24 | x:0, 25 | y:0, 26 | width: 370, 27 | height: 370 28 | } 29 | }); 30 | await page.close(); 31 | await browser.close(); 32 | })(); 33 | -------------------------------------------------------------------------------- /memory-leak-heap.spec.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | // Inspiration: https://github.com/trentmwillis/devtools-protocol-demos/blob/master/testing-demos/memory-leak-by-heap.js 4 | 5 | beforeAll(async () => { 6 | this.browser = await puppeteer.launch(); 7 | }); 8 | 9 | afterAll(async () => { 10 | await this.browser.close(); 11 | }); 12 | 13 | test('asserts memory leak by heap on the main page', async() => { 14 | const page = await this.browser.newPage(); 15 | await page.goto('https://pptr.dev'); 16 | 17 | 18 | const protocol = await page.target().createCDPSession(); 19 | await protocol.send('HeapProfiler.enable'); 20 | await protocol.send('HeapProfiler.collectGarbage'); 21 | 22 | const startMetrics = await page.metrics(); 23 | 24 | // Do memory regressions here by interacting with the page 25 | await protocol.send('Input.synthesizeScrollGesture', { 26 | x: 100, 27 | y: 100, 28 | yDistance: -400, 29 | repeatCount: 3 30 | }); 31 | 32 | // Or just keep your app open for a certain amoun of time 33 | await page.waitForTimeout(5000); 34 | 35 | await protocol.send('HeapProfiler.collectGarbage'); 36 | 37 | const endMetrics = await page.metrics(); 38 | 39 | expect(endMetrics.JSHeapUsedSize < startMetrics.JSHeapUsedSize * 1.1).toBeTruthy(); 40 | 41 | await page.close(); 42 | }, 30000); 43 | -------------------------------------------------------------------------------- /memory-leak-proto.spec.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | // Inspiration: https://github.com/trentmwillis/devtools-protocol-demos/blob/master/testing-demos/memory-leak-by-prototype.js 4 | 5 | beforeAll(async () => { 6 | this.browser = await puppeteer.launch(); 7 | }); 8 | 9 | afterAll(async () => { 10 | await this.browser.close(); 11 | }); 12 | 13 | test('asserts memory leak by prototype on the main page', async() => { 14 | const page = await this.browser.newPage(); 15 | await page.goto('https://pptr.dev'); 16 | 17 | // Get a handle to the Map object prototype 18 | const mapPrototype = await page.evaluateHandle(() => Map.prototype); 19 | 20 | // Query all map instances into an array 21 | const mapInstances = await page.queryObjects(mapPrototype); 22 | 23 | // Count amount of map objects in heap 24 | const count = await page.evaluate(maps => maps.length, mapInstances); 25 | 26 | // Idea here is to test object instances on the page 27 | // where it's expected to be invalidated 28 | expect(count).toBe(0); 29 | 30 | await page.close(); 31 | }, 30000); 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppeteer-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@d-lab/discord-puppet": "^0.6.4", 14 | "chrome-launcher": "^0.13.1", 15 | "jest": "^25.5.4", 16 | "looks-same": "^7.2.1", 17 | "node-notifier": "^9.0.0", 18 | "nyc": "^15.0.0", 19 | "puppeteer": "^20.1.2", 20 | "puppeteer-to-istanbul": "^1.4.0", 21 | "superstatic": "^6.0.4", 22 | "yargs": "^16.0.3" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pptrgram.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const puppeteer = require('puppeteer'); 3 | 4 | (async () => { 5 | // All available filters from cssgram 6 | const filters = [ 7 | '1977', 8 | 'aden', 9 | 'amaro', 10 | 'brannan', 11 | 'brooklyn', 12 | 'clarendon', 13 | 'gingham', 14 | 'hudson', 15 | 'inkwell', 16 | 'kelvin', 17 | 'lark', 18 | 'lofi', 19 | 'mayfair', 20 | 'moon', 21 | 'nashville', 22 | 'perpetua', 23 | 'reyes', 24 | 'rise', 25 | 'slumber', 26 | 'stinson', 27 | 'toaster', 28 | 'valencia', 29 | 'walden', 30 | 'willow', 31 | 'xpro2' 32 | ]; 33 | 34 | const browser = await puppeteer.launch({ 35 | headless: true, 36 | }); 37 | 38 | const getImageBase64Url = (imagePath) => { 39 | return `data:image/jpeg;base64,${fs.readFileSync(imagePath, { 40 | encoding: 'base64', 41 | })}`; 42 | }; 43 | 44 | await Promise.all(filters.map(async (filter) => { 45 | const page = await browser.newPage(); 46 | await page.setContent(` 47 | 68 |
69 | 70 | @onderceylan 71 |
72 | `, { waitUntil: 'networkidle2' }); 73 | 74 | await page.addStyleTag({ 75 | url: 'https://cdnjs.cloudflare.com/ajax/libs/cssgram/0.1.10/cssgram.min.css' 76 | }); 77 | 78 | // Get original image dimensions 79 | const { width, height } = await page.evaluate(() => { 80 | return (({naturalWidth: width, naturalHeight: height}) => ({width, height}))(document.querySelector('img')); 81 | }); 82 | 83 | await page.setViewport({ width, height }); 84 | 85 | await page.screenshot({ 86 | path: `pptgram/pptrgram-${filter}.jpeg`, 87 | type: 'jpeg', 88 | quality: 70, 89 | fullPage: true, 90 | }); 91 | 92 | await page.close(); 93 | })); 94 | 95 | await browser.close(); 96 | })(); 97 | -------------------------------------------------------------------------------- /pptrjourney.js: -------------------------------------------------------------------------------- 1 | const {MidjourneyPuppet, options} = require("@d-lab/discord-puppet"); 2 | 3 | // See prerequisites at https://github.com/Draym/discord-puppet#prerequisite 4 | 5 | (async () => { 6 | const config = options( 7 | process.env.DISCORD_USERNAME, 8 | process.env.DISCORD_PASSWORD, 9 | [], 10 | process.env.DISCORD_USER_DATA_DIR 11 | ) 12 | const puppet = new MidjourneyPuppet(config) 13 | await puppet.start() 14 | await puppet.clickServer("PptrJourney") 15 | await puppet.clickChannel("art") 16 | 17 | const msg2 = await puppet.imagine(`Your awesome prompt here!`) 18 | console.log("MJY image: ", msg2) 19 | })(); 20 | 21 | -------------------------------------------------------------------------------- /sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onderceylan/puppeteer-demos/bdffbe3b9a14f00f07c29614eea90310051a2eed/sample.jpg -------------------------------------------------------------------------------- /security.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | (async () => { 4 | const siteUrl = 'https://pptr.dev'; 5 | const browser = await puppeteer.launch(); 6 | const page = await browser.newPage(); 7 | 8 | const protocol = await page.target().createCDPSession(); 9 | await protocol.send('Security.enable'); 10 | 11 | protocol.on('Security.securityStateChanged', (state) => { 12 | console.log(state); 13 | }); 14 | 15 | await page.goto(siteUrl, { waitUntil: 'networkidle0' }); 16 | await page.close(); 17 | await browser.close(); 18 | })(); 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /side-by-side-pageload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @author ebidel@ (Eric Bidelman) 17 | */ 18 | 19 | /** 20 | * Launches one or more URLs in different browser windows to visually compare 21 | * the page loads side-by-side. Options to center the windows on screen, 22 | * emulate mobile devices, and toggle CPU/Network throttling. 23 | * 24 | * Usage: 25 | * 26 | * node side-by-side-pageload.js -h 27 | */ 28 | 29 | // Inspiration: https://github.com/GoogleChromeLabs/puppeteer-examples/blob/master/side-by-side-pageload.js 30 | 31 | const puppeteer = require('puppeteer'); 32 | const devices = require('puppeteer/DeviceDescriptors'); 33 | const iphone6 = puppeteer.KnownDevices['iPhone 6']; 34 | 35 | const argv = require('yargs') 36 | .options({ 37 | 'mobile': { 38 | alias: 'm', 39 | describe: 'Emulate a mobile viewport', 40 | default: true, 41 | }, 42 | 'throttle': { 43 | describe: 'Throttles CPU by 4x and network to "Slow 3G"', 44 | default: true, 45 | }, 46 | 'center': { 47 | alias: 'c', 48 | describe: 'Centers the the windows on screen', 49 | default: true, 50 | }, 51 | 'url': { 52 | alias: 'u', 53 | describe: 'URL to load', 54 | demandOption: true, 55 | }, 56 | 'space': { 57 | alias: 's', 58 | describe: 'Spaces between windows (when emulating mobile)', 59 | default: 20, 60 | }, 61 | 'timeout': { 62 | alias: 't', 63 | describe: 'Timeout after page finish loading before closing the browers', 64 | default: 3000, 65 | }, 66 | }) 67 | .array('url') 68 | .help() 69 | .example('$0 --url https://devwebfeed.appspot.com https://devwebfeed.appspot.com/ssr') 70 | .example('$0 --no-throttle --no-mobile -u https://devwebfeed.appspot.com https://devwebfeed.appspot.com/ssr') 71 | .example('$0 -u https://www.bing.com/ https://www.google.com/ https://www.yahoo.com/') 72 | .wrap(null) 73 | .argv; 74 | 75 | const urls = argv.url.length ? argv.url : [ 76 | 'https://devwebfeed.appspot.com/', 77 | 'https://devwebfeed.appspot.com/ssr', 78 | ]; 79 | 80 | const CENTER_WINDOWS_ON_SCREEN = argv.center; 81 | const SPACE_BETWEEN_WINDOWS = argv.space; 82 | const MOBILE = argv.mobile; 83 | const THROTTLE = argv.throttle; 84 | const TIMEOUT_AFTER_LOAD = argv.timeout; 85 | const DEFAULT_VIEWPORT = {width: 1000, height: 800, deviceScaleFactor: 2}; 86 | 87 | const sleep = (timeout) => new Promise(r => setTimeout(r, timeout)); 88 | 89 | async function launch(position, screen) { 90 | const totalSpacerWidthAddition = SPACE_BETWEEN_WINDOWS * (urls.length - 1); 91 | const totalWidthOfWindows = urls.length * DEFAULT_VIEWPORT.width; 92 | const totalWidthOfWindowsWithSpacers = totalWidthOfWindows + totalSpacerWidthAddition; 93 | 94 | const centerScreenX = screen.width / 2; 95 | const centerScreenY = screen.height / 2; 96 | 97 | let dx = DEFAULT_VIEWPORT.width * position; 98 | dx += SPACE_BETWEEN_WINDOWS * position; 99 | 100 | const x = Math.floor(centerScreenX - (totalWidthOfWindowsWithSpacers / 2) + dx); 101 | const y = Math.floor(centerScreenY - (DEFAULT_VIEWPORT.height / 2)); 102 | 103 | const browser = await puppeteer.launch({ 104 | headless: false, 105 | args: [ 106 | `--window-size=${DEFAULT_VIEWPORT.width},${DEFAULT_VIEWPORT.height}`, 107 | CENTER_WINDOWS_ON_SCREEN ? `--window-position=${x},${y}` : `--window-position=${dx},0`, 108 | ], 109 | }); 110 | 111 | const page = await browser.newPage(); 112 | if (MOBILE) { 113 | await page.emulate(iphone6); 114 | } else { 115 | await page.setViewport(DEFAULT_VIEWPORT); 116 | } 117 | 118 | if (THROTTLE) { 119 | const client = await page.target().createCDPSession(); 120 | // Emulate "Slow 3G" according to WebPageTest. 121 | await client.send('Network.emulateNetworkConditions', { 122 | offline: false, 123 | latency: 400, 124 | downloadThroughput: Math.floor(400 * 1024 / 8), // 400 Kbps 125 | uploadThroughput: Math.floor(400 * 1024 / 8) // 400 Kbps 126 | }); 127 | await client.send('Emulation.setCPUThrottlingRate', {rate: 4}); 128 | } 129 | 130 | return page; 131 | } 132 | 133 | (async () => { 134 | 135 | const browser = await puppeteer.launch(); 136 | const page = await browser.newPage(); 137 | 138 | const screen = await page.evaluate(() => { 139 | return {width: window.screen.availWidth, height: window.screen.availHeight}; 140 | }); 141 | await browser.close(); 142 | 143 | // Take up full desktop space or emulate mobile. 144 | DEFAULT_VIEWPORT.width = MOBILE ? iphone6.viewport.width : Math.floor(screen.width / urls.length); 145 | DEFAULT_VIEWPORT.height = MOBILE ? iphone6.viewport.height : screen.height; 146 | 147 | const pages = await Promise.all(urls.map((url, i) => launch(i, screen))); 148 | 149 | const start = Date.now(); 150 | 151 | const waitForPage = async pos => { 152 | const page = pages[pos]; 153 | const url = urls[pos]; 154 | return page.goto(url, {waitUntil: 'networkidle2'}) 155 | .then(() => Date.now()); 156 | }; 157 | 158 | const stopTimes = await Promise.all(urls.map((url, i) => waitForPage(i))); 159 | stopTimes.forEach((stopTime, i) => console.log(`Page ${i + 1} took ${stopTime - start} ms to reach network idle`)); 160 | 161 | await sleep(TIMEOUT_AFTER_LOAD); 162 | 163 | await Promise.all(pages.map(page => page.browser().close())); 164 | 165 | })(); 166 | -------------------------------------------------------------------------------- /speech.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @author ebidel@ (Eric Bidelman) 17 | */ 18 | 19 | /** 20 | * Uses the web speech synth API to make the browser talk. 21 | * 22 | * Run it: 23 | * node speech.js -t Hello there, my name is Jarvis. 24 | * node speech.js -t Read anything good lately? 25 | * CHROME_PATH=/path/to/chrome node speech.js -t hi and bye! 26 | */ 27 | 28 | // Inspiration: https://github.com/GoogleChromeLabs/puppeteer-examples/blob/master/speech.js 29 | 30 | const argv = require('yargs').argv; 31 | const puppeteer = require('puppeteer'); 32 | 33 | const DEFAULT_TXT = 'Hello there, my name is Puppeteer. I am controlling your browser.'; 34 | const DEFAULT_VOICE = 'Milena'; 35 | 36 | const executablePath = process.env.CHROME_PATH || 37 | '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'; 38 | 39 | const html = (voiceName) => ` 40 | 41 | 42 | `; 70 | 71 | (async() => { 72 | 73 | const browser = await puppeteer.launch({ 74 | executablePath, // Note: need Chrome (not Chromium) to use non-default voices. 75 | headless: false, // Speech synth API doesn't work in headless. crbug.com/815388 76 | args: [ 77 | '--window-size=0,0', // Launch baby window for fun. 78 | '--window-position=0,0', 79 | '--enable-speech-dispatcher', // Needed for Linux? 80 | ], 81 | }); 82 | 83 | const page = await browser.newPage(); 84 | 85 | // Clever way to "communicate with page". Know when speech is done. 86 | page.on('console', async msg => { 87 | if (msg.text() === 'SPEECH_DONE') { 88 | await browser.close(); 89 | } 90 | }); 91 | 92 | const text = argv.text || DEFAULT_TXT; 93 | const voiceName = argv.voice || DEFAULT_VOICE; 94 | 95 | await page.evaluateOnNewDocument(text => window.TEXT2SPEECH = text, text); 96 | 97 | // Cause a navigation so the evaluateOnNewDocument kicks in. 98 | await page.goto(`data:text/html,${html(voiceName)}`); 99 | 100 | const button = await page.$('button'); 101 | button.click(); 102 | 103 | })(); 104 | -------------------------------------------------------------------------------- /tensor-sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onderceylan/puppeteer-demos/bdffbe3b9a14f00f07c29614eea90310051a2eed/tensor-sample.jpg -------------------------------------------------------------------------------- /tensorflow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tensorflow.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | (async () => { 4 | 5 | const browser = await puppeteer.launch({ 6 | headless: true, 7 | }); 8 | 9 | const page = await browser.newPage(); 10 | 11 | await page.goto(`http://localhost:8002/tensorflow.html`); 12 | 13 | const result = await page.evaluate(() => { 14 | const img = document.getElementById('img'); 15 | 16 | // Load the model. 17 | return cocoSsd.load().then(model => model.detect(img)) 18 | }); 19 | 20 | console.log(result); 21 | 22 | await page.close(); 23 | 24 | await browser.close(); 25 | })(); 26 | -------------------------------------------------------------------------------- /timeline-trace.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | 3 | // Example on how to use this data: https://michaljanaszek.com/blog/test-website-performance-with-puppeteer 4 | // Timeline viewer: https://chromedevtools.github.io/timeline-viewer/ 5 | 6 | (async () => { 7 | const browser = await puppeteer.launch(({ 8 | headless: true, 9 | })); 10 | 11 | const page = await browser.newPage(); 12 | 13 | await page.tracing.start({ path: 'trace.json' }); 14 | await page.goto('https://www.google.com'); 15 | await page.waitForTimeout(2000); 16 | await page.tracing.stop(); 17 | 18 | await page.close(); 19 | 20 | await browser.close(); 21 | })(); 22 | -------------------------------------------------------------------------------- /visual-regression.spec.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | const fs = require('fs'); 3 | const looksSame = require('looks-same'); 4 | // You can switch to using https://github.com/mapbox/pixelmatch#nodejs 5 | // If you prefer to keep a diff image in your reports 6 | 7 | // Inspiration: https://github.com/trentmwillis/devtools-protocol-demos/blob/master/testing-demos/visual-regression.js 8 | 9 | const takeScreenshot = async (page, title) => { 10 | if (!fs.existsSync('./.screenshots')) { 11 | fs.mkdirSync('./.screenshots'); 12 | } 13 | const filePath = `./.screenshots/${title}.png`; 14 | if (fs.existsSync(filePath)) { 15 | const newFilePath = `./.screenshots/${title}-new.png`; 16 | await page.screenshot({ 17 | path: newFilePath, 18 | fullPage: true 19 | }); 20 | const result = await new Promise(resolve => looksSame(filePath, newFilePath, (err, equal) => resolve(equal))); 21 | fs.unlinkSync(newFilePath); 22 | return result; 23 | } else { 24 | await page.screenshot({ 25 | path: filePath, 26 | fullPage: true 27 | }); 28 | return true; 29 | } 30 | }; 31 | 32 | beforeAll(async () => { 33 | this.browser = await puppeteer.launch(); 34 | }); 35 | 36 | afterAll(async () => { 37 | await this.browser.close(); 38 | }); 39 | 40 | test('asserts visual regression on the main page', async() => { 41 | const page = await this.browser.newPage(); 42 | await page.goto('https://pptr.dev'); 43 | 44 | expect(await takeScreenshot(page, 'main-page.1')).toBeTruthy(); 45 | 46 | await page.close(); 47 | }, 20000); 48 | -------------------------------------------------------------------------------- /whatsapp/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "morning-hail" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /whatsapp/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | firebase-debug.log* 8 | 9 | # Firebase cache 10 | .firebase/ 11 | 12 | # Firebase config 13 | 14 | # Uncomment this if you'd like others to create their own Firebase project. 15 | # For a team working on the same Firebase project(s), it is recommended to leave 16 | # it commented so all members can deploy to the same project(s) in .firebaserc. 17 | # .firebaserc 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (http://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | 49 | # Optional npm cache directory 50 | .npm 51 | 52 | # Optional eslint cache 53 | .eslintcache 54 | 55 | # Optional REPL history 56 | .node_repl_history 57 | 58 | # Output of 'npm pack' 59 | *.tgz 60 | 61 | # Yarn Integrity file 62 | .yarn-integrity 63 | 64 | # dotenv environment variables file 65 | .env 66 | 67 | qr.png 68 | chrome-user.zip 69 | -------------------------------------------------------------------------------- /whatsapp/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "predeploy": [ 4 | "npm --prefix \"$RESOURCE_DIR\" run lint" 5 | ] 6 | }, 7 | "storage": { 8 | "rules": "storage.rules" 9 | }, 10 | "emulators": { 11 | "functions": { 12 | "port": 5001 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /whatsapp/functions/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | // Required for certain syntax usages 4 | "ecmaVersion": 2017 5 | }, 6 | "plugins": [ 7 | "promise" 8 | ], 9 | "extends": "eslint:recommended", 10 | "rules": { 11 | // Removed rule "disallow the use of console" from recommended eslint rules 12 | "no-console": "off", 13 | 14 | // Removed rule "disallow multiple spaces in regular expressions" from recommended eslint rules 15 | "no-regex-spaces": "off", 16 | 17 | // Removed rule "disallow the use of debugger" from recommended eslint rules 18 | "no-debugger": "off", 19 | 20 | // Removed rule "disallow unused variables" from recommended eslint rules 21 | "no-unused-vars": "off", 22 | 23 | // Removed rule "disallow mixed spaces and tabs for indentation" from recommended eslint rules 24 | "no-mixed-spaces-and-tabs": "off", 25 | 26 | // Removed rule "disallow the use of undeclared variables unless mentioned in /*global */ comments" from recommended eslint rules 27 | "no-undef": "off", 28 | 29 | // Warn against template literal placeholder syntax in regular strings 30 | "no-template-curly-in-string": 1, 31 | 32 | // Warn if return statements do not either always or never specify values 33 | "consistent-return": 1, 34 | 35 | // Warn if no return statements in callbacks of array methods 36 | "array-callback-return": 1, 37 | 38 | // Require the use of === and !== 39 | "eqeqeq": 2, 40 | 41 | // Disallow the use of alert, confirm, and prompt 42 | "no-alert": 2, 43 | 44 | // Disallow the use of arguments.caller or arguments.callee 45 | "no-caller": 2, 46 | 47 | // Disallow null comparisons without type-checking operators 48 | "no-eq-null": 2, 49 | 50 | // Disallow the use of eval() 51 | "no-eval": 2, 52 | 53 | // Warn against extending native types 54 | "no-extend-native": 1, 55 | 56 | // Warn against unnecessary calls to .bind() 57 | "no-extra-bind": 1, 58 | 59 | // Warn against unnecessary labels 60 | "no-extra-label": 1, 61 | 62 | // Disallow leading or trailing decimal points in numeric literals 63 | "no-floating-decimal": 2, 64 | 65 | // Warn against shorthand type conversions 66 | "no-implicit-coercion": 1, 67 | 68 | // Warn against function declarations and expressions inside loop statements 69 | "no-loop-func": 1, 70 | 71 | // Disallow new operators with the Function object 72 | "no-new-func": 2, 73 | 74 | // Warn against new operators with the String, Number, and Boolean objects 75 | "no-new-wrappers": 1, 76 | 77 | // Disallow throwing literals as exceptions 78 | "no-throw-literal": 2, 79 | 80 | // Require using Error objects as Promise rejection reasons 81 | "prefer-promise-reject-errors": 2, 82 | 83 | // Enforce “for” loop update clause moving the counter in the right direction 84 | "for-direction": 2, 85 | 86 | // Enforce return statements in getters 87 | "getter-return": 2, 88 | 89 | // Disallow await inside of loops 90 | "no-await-in-loop": 2, 91 | 92 | // Disallow comparing against -0 93 | "no-compare-neg-zero": 2, 94 | 95 | // Warn against catch clause parameters from shadowing variables in the outer scope 96 | "no-catch-shadow": 1, 97 | 98 | // Disallow identifiers from shadowing restricted names 99 | "no-shadow-restricted-names": 2, 100 | 101 | // Enforce return statements in callbacks of array methods 102 | "callback-return": 2, 103 | 104 | // Require error handling in callbacks 105 | "handle-callback-err": 2, 106 | 107 | // Warn against string concatenation with __dirname and __filename 108 | "no-path-concat": 1, 109 | 110 | // Prefer using arrow functions for callbacks 111 | "prefer-arrow-callback": 1, 112 | 113 | // Return inside each then() to create readable and reusable Promise chains. 114 | // Forces developers to return console logs and http calls in promises. 115 | "promise/always-return": 2, 116 | 117 | //Enforces the use of catch() on un-returned promises 118 | "promise/catch-or-return": 2, 119 | 120 | // Warn against nested then() or catch() statements 121 | "promise/no-nesting": 1 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /whatsapp/functions/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | secret/ -------------------------------------------------------------------------------- /whatsapp/functions/helpers.js: -------------------------------------------------------------------------------- 1 | const admin = require('firebase-admin'); 2 | const unzipper = require('unzipper'); 3 | const fs = require('fs'); 4 | const os = require('os'); 5 | const path = require('path'); 6 | const USER_FOLDER_NAME = 'chrome-user'; 7 | const TEMP_USER_FOLDER_PATH = path.resolve(os.tmpdir(), USER_FOLDER_NAME); 8 | 9 | admin.initializeApp(); 10 | 11 | const listStorageFiles = () => { 12 | return admin.storage().bucket().getFiles(); 13 | }; 14 | 15 | const downloadUserFile = async (filePath) => { 16 | const tempFilePath = path.join(os.tmpdir(), filePath); 17 | const bucket = admin.storage().bucket(); 18 | await bucket.file(filePath).download({ destination: tempFilePath }); 19 | return tempFilePath; 20 | }; 21 | 22 | const saveFileToStorage = (filePath, data, options = null) => { 23 | // const tempFilePath = path.join(os.tmpdir(), filePath); 24 | const bucket = admin.storage().bucket(); 25 | return bucket.file(filePath).save(data, options); 26 | }; 27 | 28 | const unzipUserData = async (filePath) => { 29 | return new Promise((resolve, reject) => { 30 | fs.createReadStream(filePath).pipe(unzipper.Extract({ path: TEMP_USER_FOLDER_PATH })).on('close', resolve).on('error', reject); 31 | }); 32 | }; 33 | 34 | const getRandomElem = (array) => array[Math.floor(Math.random() * array.length)]; 35 | 36 | const getRandomEmoji = () => { 37 | const emojis = ['😘', '😙', '👋', '🤗', '🥰', '🤓', '🤩']; 38 | return getRandomElem(emojis); 39 | }; 40 | 41 | const getTodaysMessage = () => { 42 | const awesomeWishes = ['güzel', 'şahane', 'keyifli', 'huzurlu', 'harika']; 43 | const weekendWishes = [ ...awesomeWishes, 'eğlenceli', 'bol dinlenmeli', 'bol gezmeli']; 44 | const weekDayWishes = [ ...awesomeWishes, 'bereketli', 'başarılı', 'verimli', 'sağlıklı']; 45 | const kisses = ['öpüyorum', 'öpüldünüz', 'öpüyore', 'öptüm']; 46 | const hails = ['Gunaydın', 'Gününüz aydın', 'Günaydınlar']; 47 | const address = ['sevgili ailem', 'canım ailem', 'ceylanos', 'canlar']; 48 | const who = ['', ' herkese']; 49 | const comma = ['', ',']; 50 | 51 | let date = new Date(); 52 | let day = date.getDay(); 53 | 54 | // Randomizing the message a bit so my mom doesn't suspect automation 55 | const randomMessage = `${getRandomElem(hails)} ${getRandomElem(address)}${getRandomElem(comma)}${getRandomElem(who)} :wish: bir gün olsun ${getRandomElem(kisses)} ${getRandomEmoji()}`; 56 | 57 | switch (day) { 58 | case 5: 59 | // Because Friday is a sacred day for my parents, message changes a bit 60 | return randomMessage.replace(':wish: bir gün olsun', 'hayırlı cumalar'); 61 | case 6: 62 | // Because we like to hail the weekend on saturday mornings, yay! 63 | return randomMessage.replace(':wish:', getRandomElem(weekendWishes)).replace('gün', 'haftasonu'); 64 | case 0: 65 | // Because we enjoy stressing it's Sunday :) 66 | return randomMessage.replace(':wish:', getRandomElem(weekendWishes)).replace('gün', 'pazar'); 67 | case 1: 68 | // Because we enjoy stressing it's the week start 69 | return randomMessage.replace(':wish:', getRandomElem(weekDayWishes)).replace('gün', 'hafta'); 70 | default: 71 | return randomMessage.replace(':wish:', getRandomElem(weekDayWishes)); 72 | } 73 | }; 74 | 75 | // Checks if session is expired and qr code is shown 76 | // Saves qr code as qr.png image and logs it to console as base64 encoded string 77 | const checkSessionValidityAndSaveQR = async (page) => { 78 | const qrImgEl = await page.$x('//canvas[@aria-label="Scan me!"]'); 79 | 80 | if (qrImgEl.length > 0) { 81 | const img = qrImgEl[0]; 82 | try { 83 | await img.screenshot({ path: 'qr.png' }); 84 | console.log('Saved QR code as qr.png'); 85 | } catch (e) { 86 | console.log(`Won't save the QR code, authenticate again`); 87 | } 88 | throw new Error('Session is expired, need to authenticate again'); 89 | } 90 | }; 91 | 92 | // Forcefully capture the session when there's a session conflict, aka 'Use Here' prompt 93 | const forcefullyCaptureSession = async (page) => { 94 | await page.exposeFunction('onDomUpdate', async (innerText) => { 95 | if (innerText.toLowerCase().includes('use here')) { 96 | console.log(`"Use here" button is shown`); 97 | const useHereBtn = await page.$x('//div[@role="button"][text()="Use Here"]'); 98 | if (useHereBtn.length > 0) { 99 | console.log(`Clicking`); 100 | await useHereBtn[0].click(); 101 | } 102 | } 103 | }); 104 | 105 | await page.evaluate(() => { 106 | const observer = new MutationObserver((mutations) => { 107 | for(let mutation of mutations) { 108 | if(mutation.addedNodes.length) { 109 | onDomUpdate(mutation.addedNodes[0].innerText); 110 | } 111 | } 112 | }); 113 | observer.observe(document.querySelector("body"), { attributes: false, childList: true, subtree: true }); 114 | }); 115 | }; 116 | 117 | const waitForAppLoad = async (page) => { 118 | // WhatsApp has it's own loading mechanism detached from native page load events 119 | await page.waitForSelector('#startup', { hidden: true }); 120 | await page.waitForTimeout(1000); 121 | }; 122 | 123 | const sendMessageToGroup = async (page, message, groupName, dryRun = false) => { 124 | const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3641.0 Safari/537.36'; 125 | try { 126 | // WhatsApp web tries to detect headless chrome so faking the user agent is necessary 127 | await page.setUserAgent(USER_AGENT); 128 | await page.goto('https://web.whatsapp.com/', { waitUntil: 'networkidle0', timeout: 0 }); 129 | 130 | await forcefullyCaptureSession(page); 131 | await waitForAppLoad(page); 132 | await checkSessionValidityAndSaveQR(page); 133 | 134 | await page.waitForSelector('#side div[contenteditable="true"]'); 135 | await page.type('#side div[contenteditable="true"]', groupName); 136 | await page.waitForSelector(`#pane-side span[title="${groupName}"]`, { visible: true }); 137 | await page.click(`span[title="${groupName}"`); 138 | await page.waitForSelector('footer .copyable-text', { visible: true }); 139 | await page.type('footer .copyable-text', message); 140 | if (dryRun === false) { 141 | await page.keyboard.press('Enter'); 142 | } 143 | await page.waitForTimeout(1000); 144 | console.log(`Message "${message}" sent to group "${groupName}"`); 145 | } catch (e) { 146 | console.error(`There was an error on automated flow`); 147 | const screen = await page.screenshot({ fullPage: true }); 148 | const dom = await page.content(); 149 | await saveFileToStorage('screen.png', screen, { contentType: 'image/png' }); 150 | await saveFileToStorage('dom.html', dom, { contentType: 'text/html' }); 151 | console.log('Saved screenshot to the storage'); 152 | console.log('Saved DOM to the storage'); 153 | throw e; 154 | } 155 | }; 156 | 157 | module.exports = { 158 | getTodaysMessage, 159 | sendMessageToGroup, 160 | listStorageFiles, 161 | downloadUserFile, 162 | saveFileToStorage, 163 | unzipUserData, 164 | USER_FOLDER_NAME, 165 | TEMP_USER_FOLDER_PATH 166 | }; 167 | -------------------------------------------------------------------------------- /whatsapp/functions/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * WhatsApp Morning Hail! 3 | * Firebase/Google Cloud function to hail parents on WhatsApp automatically in the morning that is executed daily via scheduler! 4 | * 5 | * It keeps your WhatsApp session in Cloud Storage over Chrome's user data directory 6 | * And sends a message to a WhatsApp group every morning with headless chrome instance using Puppeteer on a cloud function 7 | * 8 | * Although I use it personally on my personal cloud environment, I need to warn you to use it at your own risk! 9 | * 10 | * Setup 11 | * 1. Execute whatsapp-demo.js with `node whatsapp-demo` in parent dir and manually authenticate yourself via your mobile app, qr.png image will be saved 12 | * 2. After authentication, your credentials will be saved to .tmp folder. Get into the folder and zip all the contents to a file named chrome-user.zip 13 | * !! If you are not able to see .tmp folder, you need to reveal hidden files and folders 14 | * 3. Upload your chrome-user.zip file to the default bucket on your Cloud Storage 15 | * !! Be careful if you decide to change storage.rules, make sure this file is securely stored 16 | * 4. Enable Cloud Scheduler and Pub/Sub APIs on your project 17 | * !! https://cloud.google.com/scheduler/docs/quickstart 18 | * 5. Configure crontab for scheduler by using an online generator, like https://crontab.guru/ on L:141-145 19 | * 6. Emulate and deploy your functions with npm scripts emulate & deploy 20 | * !! When emulating, set up admin credentials for local emulation https://firebase.google.com/docs/functions/local-emulator#set_up_admin_credentials_optional and modify path on preemulate script 21 | * !! To enable emulator and run functions locally https: //firebase.google.com/docs/functions/local-emulator 22 | * Tweet me @onderceylan if you've any questions! 23 | */ 24 | 25 | const functions = require('firebase-functions'); 26 | const puppeteer = require('puppeteer'); 27 | const { 28 | getTodaysMessage, 29 | sendMessageToGroup, 30 | listStorageFiles, 31 | downloadUserFile, 32 | unzipUserData, 33 | TEMP_USER_FOLDER_PATH, 34 | USER_FOLDER_NAME } = require('./helpers'); 35 | 36 | const GROUP_NAME = 'Bizimkiler'; 37 | 38 | sendMessage = async () => { 39 | const todaysMessage = getTodaysMessage(); 40 | 41 | // --user-data-dir not as option but as launch arg because https://github.com/puppeteer/puppeteer/issues/921#issuecomment-561054884 42 | // --no-sandbox because fails otherwise with "Running as root without —-no-sandbox is not supported." 43 | const browser = await puppeteer.launch({ headless: true, args: [`--user-data-dir=${TEMP_USER_FOLDER_PATH}`, '--no-sandbox'] }); 44 | const page = await browser.newPage(); 45 | 46 | try { 47 | await sendMessageToGroup(page, todaysMessage, GROUP_NAME); 48 | } finally { 49 | await page.close(); 50 | await browser.close(); 51 | } 52 | 53 | return todaysMessage; 54 | }; 55 | 56 | executeFunction = async () => { 57 | 58 | const [filesInStorage] = await listStorageFiles(); 59 | const userProfileFile = filesInStorage.find(file => file.name.includes(USER_FOLDER_NAME)); 60 | const tempFilePath = await downloadUserFile(userProfileFile.name); 61 | 62 | await unzipUserData(tempFilePath); 63 | 64 | return sendMessage(); 65 | }; 66 | 67 | const scheduleFnAt = (crontab) => functions 68 | // Because function exceeds memory limits when memory is lower than 1GB 69 | .runWith({ timeoutSeconds: 500, memory: '1GB' }) 70 | .region('europe-west1') 71 | .pubsub 72 | .schedule(crontab) 73 | .timeZone('Europe/Amsterdam') 74 | .onRun(executeFunction); 75 | 76 | // TODO: find a way to programmatically randomize crontab on Google Cloud scheduler 77 | exports.morningHailOnWeekdays1 = scheduleFnAt('44 7 * * 1'); 78 | exports.morningHailOnWeekdays2 = scheduleFnAt('10 8 * * 2'); 79 | exports.morningHailOnWeekdays3 = scheduleFnAt('52 7 * * 3'); 80 | exports.morningHailOnWeekdays4 = scheduleFnAt('15 8 * * 4'); 81 | exports.morningHailOnWeekdays5 = scheduleFnAt('38 8 * * 5'); 82 | exports.morningHailOnWeekends1 = scheduleFnAt('44 10 * * 6'); 83 | exports.morningHailOnWeekends2 = scheduleFnAt('27 11 * * 0'); 84 | -------------------------------------------------------------------------------- /whatsapp/functions/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whatsapp-morning-hail", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@babel/code-frame": { 7 | "version": "7.5.5", 8 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", 9 | "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", 10 | "dev": true, 11 | "requires": { 12 | "@babel/highlight": "^7.0.0" 13 | } 14 | }, 15 | "@babel/highlight": { 16 | "version": "7.5.0", 17 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", 18 | "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", 19 | "dev": true, 20 | "requires": { 21 | "chalk": "^2.0.0", 22 | "esutils": "^2.0.2", 23 | "js-tokens": "^4.0.0" 24 | } 25 | }, 26 | "@firebase/app-types": { 27 | "version": "0.6.1", 28 | "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz", 29 | "integrity": "sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==" 30 | }, 31 | "@firebase/auth-interop-types": { 32 | "version": "0.1.5", 33 | "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz", 34 | "integrity": "sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==" 35 | }, 36 | "@firebase/component": { 37 | "version": "0.1.19", 38 | "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.19.tgz", 39 | "integrity": "sha512-L0S3g8eqaerg8y0zox3oOHSTwn/FE8RbcRHiurnbESvDViZtP5S5WnhuAPd7FnFxa8ElWK0z1Tr3ikzWDv1xdQ==", 40 | "requires": { 41 | "@firebase/util": "0.3.2", 42 | "tslib": "^1.11.1" 43 | }, 44 | "dependencies": { 45 | "tslib": { 46 | "version": "1.14.0", 47 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", 48 | "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" 49 | } 50 | } 51 | }, 52 | "@firebase/database": { 53 | "version": "0.6.13", 54 | "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.6.13.tgz", 55 | "integrity": "sha512-NommVkAPzU7CKd1gyehmi3lz0K78q0KOfiex7Nfy7MBMwknLm7oNqKovXSgQV1PCLvKXvvAplDSFhDhzIf9obA==", 56 | "requires": { 57 | "@firebase/auth-interop-types": "0.1.5", 58 | "@firebase/component": "0.1.19", 59 | "@firebase/database-types": "0.5.2", 60 | "@firebase/logger": "0.2.6", 61 | "@firebase/util": "0.3.2", 62 | "faye-websocket": "0.11.3", 63 | "tslib": "^1.11.1" 64 | }, 65 | "dependencies": { 66 | "tslib": { 67 | "version": "1.14.0", 68 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", 69 | "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" 70 | } 71 | } 72 | }, 73 | "@firebase/database-types": { 74 | "version": "0.5.2", 75 | "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.5.2.tgz", 76 | "integrity": "sha512-ap2WQOS3LKmGuVFKUghFft7RxXTyZTDr0Xd8y2aqmWsbJVjgozi0huL/EUMgTjGFrATAjcf2A7aNs8AKKZ2a8g==", 77 | "requires": { 78 | "@firebase/app-types": "0.6.1" 79 | } 80 | }, 81 | "@firebase/logger": { 82 | "version": "0.2.6", 83 | "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", 84 | "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" 85 | }, 86 | "@firebase/util": { 87 | "version": "0.3.2", 88 | "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.3.2.tgz", 89 | "integrity": "sha512-Dqs00++c8rwKky6KCKLLY2T1qYO4Q+X5t+lF7DInXDNF4ae1Oau35bkD+OpJ9u7l1pEv7KHowP6CUKuySCOc8g==", 90 | "requires": { 91 | "tslib": "^1.11.1" 92 | }, 93 | "dependencies": { 94 | "tslib": { 95 | "version": "1.14.0", 96 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", 97 | "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" 98 | } 99 | } 100 | }, 101 | "@google-cloud/common": { 102 | "version": "3.4.1", 103 | "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.4.1.tgz", 104 | "integrity": "sha512-e5z0CwsM0RXky+PnyPtQ3QK46ksqm+kE7kX8pm8X+ddBwZJipHchKeazMM5fLlGCS+AALalzXb+uYmH72TRnpQ==", 105 | "requires": { 106 | "@google-cloud/projectify": "^2.0.0", 107 | "@google-cloud/promisify": "^2.0.0", 108 | "arrify": "^2.0.1", 109 | "duplexify": "^4.1.1", 110 | "ent": "^2.2.0", 111 | "extend": "^3.0.2", 112 | "google-auth-library": "^6.1.1", 113 | "retry-request": "^4.1.1", 114 | "teeny-request": "^7.0.0" 115 | }, 116 | "dependencies": { 117 | "duplexify": { 118 | "version": "4.1.1", 119 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", 120 | "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", 121 | "requires": { 122 | "end-of-stream": "^1.4.1", 123 | "inherits": "^2.0.3", 124 | "readable-stream": "^3.1.1", 125 | "stream-shift": "^1.0.0" 126 | } 127 | } 128 | } 129 | }, 130 | "@google-cloud/firestore": { 131 | "version": "4.4.0", 132 | "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.4.0.tgz", 133 | "integrity": "sha512-nixsumd4C7eL+hHEgyihspzhBBNe3agsvNFRX0xfqO3uR/6ro4CUj9XdcCvdnSSd3yTyqKfdBSRK2fEj1jIbYg==", 134 | "optional": true, 135 | "requires": { 136 | "fast-deep-equal": "^3.1.1", 137 | "functional-red-black-tree": "^1.0.1", 138 | "google-gax": "^2.2.0" 139 | }, 140 | "dependencies": { 141 | "fast-deep-equal": { 142 | "version": "3.1.3", 143 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 144 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 145 | "optional": true 146 | } 147 | } 148 | }, 149 | "@google-cloud/paginator": { 150 | "version": "3.0.5", 151 | "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", 152 | "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", 153 | "requires": { 154 | "arrify": "^2.0.0", 155 | "extend": "^3.0.2" 156 | } 157 | }, 158 | "@google-cloud/projectify": { 159 | "version": "2.0.1", 160 | "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", 161 | "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" 162 | }, 163 | "@google-cloud/promisify": { 164 | "version": "2.0.3", 165 | "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", 166 | "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" 167 | }, 168 | "@google-cloud/storage": { 169 | "version": "5.3.0", 170 | "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.3.0.tgz", 171 | "integrity": "sha512-3t5UF3SZ14Bw2kcBHubCai6EIugU2GnQOstYWVSFuoO8IJ94RAaIOPq/dtexvQbUTpBTAGpd5smVR9WPL1mJVw==", 172 | "requires": { 173 | "@google-cloud/common": "^3.3.0", 174 | "@google-cloud/paginator": "^3.0.0", 175 | "@google-cloud/promisify": "^2.0.0", 176 | "arrify": "^2.0.0", 177 | "compressible": "^2.0.12", 178 | "concat-stream": "^2.0.0", 179 | "date-and-time": "^0.14.0", 180 | "duplexify": "^3.5.0", 181 | "extend": "^3.0.2", 182 | "gaxios": "^3.0.0", 183 | "gcs-resumable-upload": "^3.1.0", 184 | "hash-stream-validation": "^0.2.2", 185 | "mime": "^2.2.0", 186 | "mime-types": "^2.0.8", 187 | "onetime": "^5.1.0", 188 | "p-limit": "^3.0.1", 189 | "pumpify": "^2.0.0", 190 | "snakeize": "^0.1.0", 191 | "stream-events": "^1.0.1", 192 | "xdg-basedir": "^4.0.0" 193 | } 194 | }, 195 | "@grpc/grpc-js": { 196 | "version": "1.1.8", 197 | "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.1.8.tgz", 198 | "integrity": "sha512-64hg5rmEm6F/NvlWERhHmmgxbWU8nD2TMWE+9TvG7/WcOrFT3fzg/Uu631pXRFwmJ4aWO/kp9vVSlr8FUjBDLA==", 199 | "optional": true, 200 | "requires": { 201 | "@grpc/proto-loader": "^0.6.0-pre14", 202 | "@types/node": "^12.12.47", 203 | "google-auth-library": "^6.0.0", 204 | "semver": "^6.2.0" 205 | }, 206 | "dependencies": { 207 | "@grpc/proto-loader": { 208 | "version": "0.6.2", 209 | "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", 210 | "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", 211 | "optional": true, 212 | "requires": { 213 | "@types/long": "^4.0.1", 214 | "lodash.camelcase": "^4.3.0", 215 | "long": "^4.0.0", 216 | "protobufjs": "^6.10.0", 217 | "yargs": "^16.1.1" 218 | } 219 | }, 220 | "@types/node": { 221 | "version": "12.20.13", 222 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", 223 | "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", 224 | "optional": true 225 | }, 226 | "ansi-regex": { 227 | "version": "5.0.0", 228 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 229 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 230 | "optional": true 231 | }, 232 | "ansi-styles": { 233 | "version": "4.3.0", 234 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 235 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 236 | "optional": true, 237 | "requires": { 238 | "color-convert": "^2.0.1" 239 | } 240 | }, 241 | "cliui": { 242 | "version": "7.0.4", 243 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 244 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 245 | "optional": true, 246 | "requires": { 247 | "string-width": "^4.2.0", 248 | "strip-ansi": "^6.0.0", 249 | "wrap-ansi": "^7.0.0" 250 | } 251 | }, 252 | "color-convert": { 253 | "version": "2.0.1", 254 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 255 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 256 | "optional": true, 257 | "requires": { 258 | "color-name": "~1.1.4" 259 | } 260 | }, 261 | "color-name": { 262 | "version": "1.1.4", 263 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 264 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 265 | "optional": true 266 | }, 267 | "emoji-regex": { 268 | "version": "8.0.0", 269 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 270 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 271 | "optional": true 272 | }, 273 | "is-fullwidth-code-point": { 274 | "version": "3.0.0", 275 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 276 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 277 | "optional": true 278 | }, 279 | "string-width": { 280 | "version": "4.2.2", 281 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 282 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 283 | "optional": true, 284 | "requires": { 285 | "emoji-regex": "^8.0.0", 286 | "is-fullwidth-code-point": "^3.0.0", 287 | "strip-ansi": "^6.0.0" 288 | } 289 | }, 290 | "strip-ansi": { 291 | "version": "6.0.0", 292 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 293 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 294 | "optional": true, 295 | "requires": { 296 | "ansi-regex": "^5.0.0" 297 | } 298 | }, 299 | "wrap-ansi": { 300 | "version": "7.0.0", 301 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 302 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 303 | "optional": true, 304 | "requires": { 305 | "ansi-styles": "^4.0.0", 306 | "string-width": "^4.1.0", 307 | "strip-ansi": "^6.0.0" 308 | } 309 | }, 310 | "y18n": { 311 | "version": "5.0.8", 312 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 313 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 314 | "optional": true 315 | }, 316 | "yargs": { 317 | "version": "16.2.0", 318 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 319 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 320 | "optional": true, 321 | "requires": { 322 | "cliui": "^7.0.2", 323 | "escalade": "^3.1.1", 324 | "get-caller-file": "^2.0.5", 325 | "require-directory": "^2.1.1", 326 | "string-width": "^4.2.0", 327 | "y18n": "^5.0.5", 328 | "yargs-parser": "^20.2.2" 329 | } 330 | }, 331 | "yargs-parser": { 332 | "version": "20.2.7", 333 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", 334 | "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", 335 | "optional": true 336 | } 337 | } 338 | }, 339 | "@grpc/proto-loader": { 340 | "version": "0.5.5", 341 | "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.5.tgz", 342 | "integrity": "sha512-WwN9jVNdHRQoOBo9FDH7qU+mgfjPc8GygPYms3M+y3fbQLfnCe/Kv/E01t7JRgnrsOHH8euvSbed3mIalXhwqQ==", 343 | "optional": true, 344 | "requires": { 345 | "lodash.camelcase": "^4.3.0", 346 | "protobufjs": "^6.8.6" 347 | } 348 | }, 349 | "@protobufjs/aspromise": { 350 | "version": "1.1.2", 351 | "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", 352 | "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", 353 | "optional": true 354 | }, 355 | "@protobufjs/base64": { 356 | "version": "1.1.2", 357 | "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", 358 | "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", 359 | "optional": true 360 | }, 361 | "@protobufjs/codegen": { 362 | "version": "2.0.4", 363 | "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", 364 | "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", 365 | "optional": true 366 | }, 367 | "@protobufjs/eventemitter": { 368 | "version": "1.1.0", 369 | "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", 370 | "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", 371 | "optional": true 372 | }, 373 | "@protobufjs/fetch": { 374 | "version": "1.1.0", 375 | "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", 376 | "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", 377 | "optional": true, 378 | "requires": { 379 | "@protobufjs/aspromise": "^1.1.1", 380 | "@protobufjs/inquire": "^1.1.0" 381 | } 382 | }, 383 | "@protobufjs/float": { 384 | "version": "1.0.2", 385 | "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", 386 | "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", 387 | "optional": true 388 | }, 389 | "@protobufjs/inquire": { 390 | "version": "1.1.0", 391 | "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", 392 | "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", 393 | "optional": true 394 | }, 395 | "@protobufjs/path": { 396 | "version": "1.1.2", 397 | "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", 398 | "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", 399 | "optional": true 400 | }, 401 | "@protobufjs/pool": { 402 | "version": "1.1.0", 403 | "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", 404 | "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", 405 | "optional": true 406 | }, 407 | "@protobufjs/utf8": { 408 | "version": "1.1.0", 409 | "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", 410 | "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", 411 | "optional": true 412 | }, 413 | "@tootallnate/once": { 414 | "version": "1.1.2", 415 | "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", 416 | "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" 417 | }, 418 | "@types/body-parser": { 419 | "version": "1.17.1", 420 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", 421 | "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", 422 | "requires": { 423 | "@types/connect": "*", 424 | "@types/node": "*" 425 | } 426 | }, 427 | "@types/connect": { 428 | "version": "3.4.32", 429 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", 430 | "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", 431 | "requires": { 432 | "@types/node": "*" 433 | } 434 | }, 435 | "@types/express": { 436 | "version": "4.17.2", 437 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz", 438 | "integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==", 439 | "requires": { 440 | "@types/body-parser": "*", 441 | "@types/express-serve-static-core": "*", 442 | "@types/serve-static": "*" 443 | } 444 | }, 445 | "@types/express-serve-static-core": { 446 | "version": "4.17.0", 447 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.0.tgz", 448 | "integrity": "sha512-Xnub7w57uvcBqFdIGoRg1KhNOeEj0vB6ykUM7uFWyxvbdE89GFyqgmUcanAriMr4YOxNFZBAWkfcWIb4WBPt3g==", 449 | "requires": { 450 | "@types/node": "*", 451 | "@types/range-parser": "*" 452 | } 453 | }, 454 | "@types/lodash": { 455 | "version": "4.14.149", 456 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", 457 | "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==", 458 | "dev": true 459 | }, 460 | "@types/long": { 461 | "version": "4.0.1", 462 | "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", 463 | "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", 464 | "optional": true 465 | }, 466 | "@types/mime": { 467 | "version": "2.0.1", 468 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", 469 | "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" 470 | }, 471 | "@types/node": { 472 | "version": "8.10.59", 473 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz", 474 | "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==" 475 | }, 476 | "@types/range-parser": { 477 | "version": "1.2.3", 478 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 479 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" 480 | }, 481 | "@types/serve-static": { 482 | "version": "1.13.3", 483 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", 484 | "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", 485 | "requires": { 486 | "@types/express-serve-static-core": "*", 487 | "@types/mime": "*" 488 | } 489 | }, 490 | "abort-controller": { 491 | "version": "3.0.0", 492 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 493 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 494 | "requires": { 495 | "event-target-shim": "^5.0.0" 496 | } 497 | }, 498 | "accepts": { 499 | "version": "1.3.7", 500 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 501 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 502 | "requires": { 503 | "mime-types": "~2.1.24", 504 | "negotiator": "0.6.2" 505 | } 506 | }, 507 | "acorn": { 508 | "version": "6.4.1", 509 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", 510 | "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", 511 | "dev": true 512 | }, 513 | "acorn-jsx": { 514 | "version": "5.1.0", 515 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", 516 | "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", 517 | "dev": true 518 | }, 519 | "agent-base": { 520 | "version": "4.3.0", 521 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", 522 | "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", 523 | "requires": { 524 | "es6-promisify": "^5.0.0" 525 | } 526 | }, 527 | "ajv": { 528 | "version": "6.10.2", 529 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", 530 | "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", 531 | "dev": true, 532 | "requires": { 533 | "fast-deep-equal": "^2.0.1", 534 | "fast-json-stable-stringify": "^2.0.0", 535 | "json-schema-traverse": "^0.4.1", 536 | "uri-js": "^4.2.2" 537 | } 538 | }, 539 | "ansi-escapes": { 540 | "version": "3.2.0", 541 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 542 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", 543 | "dev": true 544 | }, 545 | "ansi-regex": { 546 | "version": "3.0.0", 547 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 548 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 549 | "dev": true 550 | }, 551 | "ansi-styles": { 552 | "version": "3.2.1", 553 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 554 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 555 | "dev": true, 556 | "requires": { 557 | "color-convert": "^1.9.0" 558 | } 559 | }, 560 | "argparse": { 561 | "version": "1.0.10", 562 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 563 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 564 | "dev": true, 565 | "requires": { 566 | "sprintf-js": "~1.0.2" 567 | } 568 | }, 569 | "array-flatten": { 570 | "version": "1.1.1", 571 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 572 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 573 | }, 574 | "arrify": { 575 | "version": "2.0.1", 576 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", 577 | "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" 578 | }, 579 | "astral-regex": { 580 | "version": "1.0.0", 581 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 582 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 583 | "dev": true 584 | }, 585 | "async-limiter": { 586 | "version": "1.0.1", 587 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 588 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" 589 | }, 590 | "balanced-match": { 591 | "version": "1.0.0", 592 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 593 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 594 | }, 595 | "base64-js": { 596 | "version": "1.3.1", 597 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", 598 | "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" 599 | }, 600 | "big-integer": { 601 | "version": "1.6.48", 602 | "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", 603 | "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" 604 | }, 605 | "bignumber.js": { 606 | "version": "9.0.1", 607 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", 608 | "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" 609 | }, 610 | "binary": { 611 | "version": "0.3.0", 612 | "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", 613 | "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", 614 | "requires": { 615 | "buffers": "~0.1.1", 616 | "chainsaw": "~0.1.0" 617 | } 618 | }, 619 | "bluebird": { 620 | "version": "3.4.7", 621 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", 622 | "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" 623 | }, 624 | "body-parser": { 625 | "version": "1.19.0", 626 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 627 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 628 | "requires": { 629 | "bytes": "3.1.0", 630 | "content-type": "~1.0.4", 631 | "debug": "2.6.9", 632 | "depd": "~1.1.2", 633 | "http-errors": "1.7.2", 634 | "iconv-lite": "0.4.24", 635 | "on-finished": "~2.3.0", 636 | "qs": "6.7.0", 637 | "raw-body": "2.4.0", 638 | "type-is": "~1.6.17" 639 | }, 640 | "dependencies": { 641 | "debug": { 642 | "version": "2.6.9", 643 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 644 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 645 | "requires": { 646 | "ms": "2.0.0" 647 | } 648 | }, 649 | "ms": { 650 | "version": "2.0.0", 651 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 652 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 653 | } 654 | } 655 | }, 656 | "brace-expansion": { 657 | "version": "1.1.11", 658 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 659 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 660 | "requires": { 661 | "balanced-match": "^1.0.0", 662 | "concat-map": "0.0.1" 663 | } 664 | }, 665 | "buffer-crc32": { 666 | "version": "0.2.13", 667 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 668 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" 669 | }, 670 | "buffer-equal-constant-time": { 671 | "version": "1.0.1", 672 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 673 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" 674 | }, 675 | "buffer-from": { 676 | "version": "1.1.1", 677 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 678 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 679 | }, 680 | "buffer-indexof-polyfill": { 681 | "version": "1.0.1", 682 | "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz", 683 | "integrity": "sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8=" 684 | }, 685 | "buffers": { 686 | "version": "0.1.1", 687 | "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", 688 | "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" 689 | }, 690 | "bytes": { 691 | "version": "3.1.0", 692 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 693 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 694 | }, 695 | "callsites": { 696 | "version": "3.1.0", 697 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 698 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 699 | "dev": true 700 | }, 701 | "chainsaw": { 702 | "version": "0.1.0", 703 | "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", 704 | "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", 705 | "requires": { 706 | "traverse": ">=0.3.0 <0.4" 707 | } 708 | }, 709 | "chalk": { 710 | "version": "2.4.2", 711 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 712 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 713 | "dev": true, 714 | "requires": { 715 | "ansi-styles": "^3.2.1", 716 | "escape-string-regexp": "^1.0.5", 717 | "supports-color": "^5.3.0" 718 | } 719 | }, 720 | "chardet": { 721 | "version": "0.7.0", 722 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 723 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 724 | "dev": true 725 | }, 726 | "cli-cursor": { 727 | "version": "2.1.0", 728 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 729 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 730 | "dev": true, 731 | "requires": { 732 | "restore-cursor": "^2.0.0" 733 | } 734 | }, 735 | "cli-width": { 736 | "version": "2.2.0", 737 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 738 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 739 | "dev": true 740 | }, 741 | "color-convert": { 742 | "version": "1.9.3", 743 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 744 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 745 | "dev": true, 746 | "requires": { 747 | "color-name": "1.1.3" 748 | } 749 | }, 750 | "color-name": { 751 | "version": "1.1.3", 752 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 753 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 754 | "dev": true 755 | }, 756 | "compressible": { 757 | "version": "2.0.18", 758 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", 759 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", 760 | "requires": { 761 | "mime-db": ">= 1.43.0 < 2" 762 | }, 763 | "dependencies": { 764 | "mime-db": { 765 | "version": "1.45.0", 766 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", 767 | "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" 768 | } 769 | } 770 | }, 771 | "concat-map": { 772 | "version": "0.0.1", 773 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 774 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 775 | }, 776 | "concat-stream": { 777 | "version": "2.0.0", 778 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", 779 | "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", 780 | "requires": { 781 | "buffer-from": "^1.0.0", 782 | "inherits": "^2.0.3", 783 | "readable-stream": "^3.0.2", 784 | "typedarray": "^0.0.6" 785 | } 786 | }, 787 | "configstore": { 788 | "version": "5.0.1", 789 | "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", 790 | "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", 791 | "requires": { 792 | "dot-prop": "^5.2.0", 793 | "graceful-fs": "^4.1.2", 794 | "make-dir": "^3.0.0", 795 | "unique-string": "^2.0.0", 796 | "write-file-atomic": "^3.0.0", 797 | "xdg-basedir": "^4.0.0" 798 | } 799 | }, 800 | "content-disposition": { 801 | "version": "0.5.3", 802 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 803 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 804 | "requires": { 805 | "safe-buffer": "5.1.2" 806 | } 807 | }, 808 | "content-type": { 809 | "version": "1.0.4", 810 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 811 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 812 | }, 813 | "cookie": { 814 | "version": "0.4.0", 815 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 816 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 817 | }, 818 | "cookie-signature": { 819 | "version": "1.0.6", 820 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 821 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 822 | }, 823 | "core-util-is": { 824 | "version": "1.0.2", 825 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 826 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 827 | }, 828 | "cors": { 829 | "version": "2.8.5", 830 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 831 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 832 | "requires": { 833 | "object-assign": "^4", 834 | "vary": "^1" 835 | } 836 | }, 837 | "cross-spawn": { 838 | "version": "6.0.5", 839 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 840 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 841 | "dev": true, 842 | "requires": { 843 | "nice-try": "^1.0.4", 844 | "path-key": "^2.0.1", 845 | "semver": "^5.5.0", 846 | "shebang-command": "^1.2.0", 847 | "which": "^1.2.9" 848 | }, 849 | "dependencies": { 850 | "semver": { 851 | "version": "5.7.1", 852 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 853 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 854 | "dev": true 855 | } 856 | } 857 | }, 858 | "crypto-random-string": { 859 | "version": "2.0.0", 860 | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", 861 | "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" 862 | }, 863 | "date-and-time": { 864 | "version": "0.14.2", 865 | "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-0.14.2.tgz", 866 | "integrity": "sha512-EFTCh9zRSEpGPmJaexg7HTuzZHh6cnJj1ui7IGCFNXzd2QdpsNh05Db5TF3xzJm30YN+A8/6xHSuRcQqoc3kFA==" 867 | }, 868 | "debug": { 869 | "version": "3.2.6", 870 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 871 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 872 | "requires": { 873 | "ms": "^2.1.1" 874 | } 875 | }, 876 | "deep-is": { 877 | "version": "0.1.3", 878 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 879 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 880 | "dev": true 881 | }, 882 | "depd": { 883 | "version": "1.1.2", 884 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 885 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 886 | }, 887 | "destroy": { 888 | "version": "1.0.4", 889 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 890 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 891 | }, 892 | "dicer": { 893 | "version": "0.3.0", 894 | "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", 895 | "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", 896 | "requires": { 897 | "streamsearch": "0.1.2" 898 | } 899 | }, 900 | "doctrine": { 901 | "version": "3.0.0", 902 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 903 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 904 | "dev": true, 905 | "requires": { 906 | "esutils": "^2.0.2" 907 | } 908 | }, 909 | "dot-prop": { 910 | "version": "5.3.0", 911 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", 912 | "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", 913 | "requires": { 914 | "is-obj": "^2.0.0" 915 | } 916 | }, 917 | "duplexer2": { 918 | "version": "0.1.4", 919 | "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", 920 | "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", 921 | "requires": { 922 | "readable-stream": "^2.0.2" 923 | }, 924 | "dependencies": { 925 | "readable-stream": { 926 | "version": "2.3.7", 927 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 928 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 929 | "requires": { 930 | "core-util-is": "~1.0.0", 931 | "inherits": "~2.0.3", 932 | "isarray": "~1.0.0", 933 | "process-nextick-args": "~2.0.0", 934 | "safe-buffer": "~5.1.1", 935 | "string_decoder": "~1.1.1", 936 | "util-deprecate": "~1.0.1" 937 | } 938 | } 939 | } 940 | }, 941 | "duplexify": { 942 | "version": "3.7.1", 943 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", 944 | "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", 945 | "requires": { 946 | "end-of-stream": "^1.0.0", 947 | "inherits": "^2.0.1", 948 | "readable-stream": "^2.0.0", 949 | "stream-shift": "^1.0.0" 950 | }, 951 | "dependencies": { 952 | "readable-stream": { 953 | "version": "2.3.7", 954 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 955 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 956 | "requires": { 957 | "core-util-is": "~1.0.0", 958 | "inherits": "~2.0.3", 959 | "isarray": "~1.0.0", 960 | "process-nextick-args": "~2.0.0", 961 | "safe-buffer": "~5.1.1", 962 | "string_decoder": "~1.1.1", 963 | "util-deprecate": "~1.0.1" 964 | } 965 | } 966 | } 967 | }, 968 | "ecdsa-sig-formatter": { 969 | "version": "1.0.11", 970 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 971 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 972 | "requires": { 973 | "safe-buffer": "^5.0.1" 974 | } 975 | }, 976 | "ee-first": { 977 | "version": "1.1.1", 978 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 979 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 980 | }, 981 | "emoji-regex": { 982 | "version": "7.0.3", 983 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 984 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 985 | "dev": true 986 | }, 987 | "encodeurl": { 988 | "version": "1.0.2", 989 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 990 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 991 | }, 992 | "end-of-stream": { 993 | "version": "1.4.4", 994 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 995 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 996 | "requires": { 997 | "once": "^1.4.0" 998 | } 999 | }, 1000 | "ent": { 1001 | "version": "2.2.0", 1002 | "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", 1003 | "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" 1004 | }, 1005 | "es6-promise": { 1006 | "version": "4.2.8", 1007 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", 1008 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" 1009 | }, 1010 | "es6-promisify": { 1011 | "version": "5.0.0", 1012 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 1013 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 1014 | "requires": { 1015 | "es6-promise": "^4.0.3" 1016 | } 1017 | }, 1018 | "escalade": { 1019 | "version": "3.1.1", 1020 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1021 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1022 | "optional": true 1023 | }, 1024 | "escape-html": { 1025 | "version": "1.0.3", 1026 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1027 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 1028 | }, 1029 | "escape-string-regexp": { 1030 | "version": "1.0.5", 1031 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1032 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 1033 | "dev": true 1034 | }, 1035 | "eslint": { 1036 | "version": "5.16.0", 1037 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", 1038 | "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", 1039 | "dev": true, 1040 | "requires": { 1041 | "@babel/code-frame": "^7.0.0", 1042 | "ajv": "^6.9.1", 1043 | "chalk": "^2.1.0", 1044 | "cross-spawn": "^6.0.5", 1045 | "debug": "^4.0.1", 1046 | "doctrine": "^3.0.0", 1047 | "eslint-scope": "^4.0.3", 1048 | "eslint-utils": "^1.3.1", 1049 | "eslint-visitor-keys": "^1.0.0", 1050 | "espree": "^5.0.1", 1051 | "esquery": "^1.0.1", 1052 | "esutils": "^2.0.2", 1053 | "file-entry-cache": "^5.0.1", 1054 | "functional-red-black-tree": "^1.0.1", 1055 | "glob": "^7.1.2", 1056 | "globals": "^11.7.0", 1057 | "ignore": "^4.0.6", 1058 | "import-fresh": "^3.0.0", 1059 | "imurmurhash": "^0.1.4", 1060 | "inquirer": "^6.2.2", 1061 | "js-yaml": "^3.13.0", 1062 | "json-stable-stringify-without-jsonify": "^1.0.1", 1063 | "levn": "^0.3.0", 1064 | "lodash": "^4.17.11", 1065 | "minimatch": "^3.0.4", 1066 | "mkdirp": "^0.5.1", 1067 | "natural-compare": "^1.4.0", 1068 | "optionator": "^0.8.2", 1069 | "path-is-inside": "^1.0.2", 1070 | "progress": "^2.0.0", 1071 | "regexpp": "^2.0.1", 1072 | "semver": "^5.5.1", 1073 | "strip-ansi": "^4.0.0", 1074 | "strip-json-comments": "^2.0.1", 1075 | "table": "^5.2.3", 1076 | "text-table": "^0.2.0" 1077 | }, 1078 | "dependencies": { 1079 | "debug": { 1080 | "version": "4.1.1", 1081 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 1082 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 1083 | "dev": true, 1084 | "requires": { 1085 | "ms": "^2.1.1" 1086 | } 1087 | }, 1088 | "semver": { 1089 | "version": "5.7.1", 1090 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1091 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1092 | "dev": true 1093 | } 1094 | } 1095 | }, 1096 | "eslint-plugin-promise": { 1097 | "version": "4.2.1", 1098 | "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", 1099 | "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", 1100 | "dev": true 1101 | }, 1102 | "eslint-scope": { 1103 | "version": "4.0.3", 1104 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", 1105 | "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", 1106 | "dev": true, 1107 | "requires": { 1108 | "esrecurse": "^4.1.0", 1109 | "estraverse": "^4.1.1" 1110 | } 1111 | }, 1112 | "eslint-utils": { 1113 | "version": "1.4.3", 1114 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 1115 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 1116 | "dev": true, 1117 | "requires": { 1118 | "eslint-visitor-keys": "^1.1.0" 1119 | } 1120 | }, 1121 | "eslint-visitor-keys": { 1122 | "version": "1.1.0", 1123 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 1124 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", 1125 | "dev": true 1126 | }, 1127 | "espree": { 1128 | "version": "5.0.1", 1129 | "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", 1130 | "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", 1131 | "dev": true, 1132 | "requires": { 1133 | "acorn": "^6.0.7", 1134 | "acorn-jsx": "^5.0.0", 1135 | "eslint-visitor-keys": "^1.0.0" 1136 | } 1137 | }, 1138 | "esprima": { 1139 | "version": "4.0.1", 1140 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1141 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 1142 | "dev": true 1143 | }, 1144 | "esquery": { 1145 | "version": "1.0.1", 1146 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 1147 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 1148 | "dev": true, 1149 | "requires": { 1150 | "estraverse": "^4.0.0" 1151 | } 1152 | }, 1153 | "esrecurse": { 1154 | "version": "4.2.1", 1155 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 1156 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 1157 | "dev": true, 1158 | "requires": { 1159 | "estraverse": "^4.1.0" 1160 | } 1161 | }, 1162 | "estraverse": { 1163 | "version": "4.3.0", 1164 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 1165 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 1166 | "dev": true 1167 | }, 1168 | "esutils": { 1169 | "version": "2.0.3", 1170 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1171 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1172 | "dev": true 1173 | }, 1174 | "etag": { 1175 | "version": "1.8.1", 1176 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1177 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 1178 | }, 1179 | "event-target-shim": { 1180 | "version": "5.0.1", 1181 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 1182 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" 1183 | }, 1184 | "express": { 1185 | "version": "4.17.1", 1186 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 1187 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 1188 | "requires": { 1189 | "accepts": "~1.3.7", 1190 | "array-flatten": "1.1.1", 1191 | "body-parser": "1.19.0", 1192 | "content-disposition": "0.5.3", 1193 | "content-type": "~1.0.4", 1194 | "cookie": "0.4.0", 1195 | "cookie-signature": "1.0.6", 1196 | "debug": "2.6.9", 1197 | "depd": "~1.1.2", 1198 | "encodeurl": "~1.0.2", 1199 | "escape-html": "~1.0.3", 1200 | "etag": "~1.8.1", 1201 | "finalhandler": "~1.1.2", 1202 | "fresh": "0.5.2", 1203 | "merge-descriptors": "1.0.1", 1204 | "methods": "~1.1.2", 1205 | "on-finished": "~2.3.0", 1206 | "parseurl": "~1.3.3", 1207 | "path-to-regexp": "0.1.7", 1208 | "proxy-addr": "~2.0.5", 1209 | "qs": "6.7.0", 1210 | "range-parser": "~1.2.1", 1211 | "safe-buffer": "5.1.2", 1212 | "send": "0.17.1", 1213 | "serve-static": "1.14.1", 1214 | "setprototypeof": "1.1.1", 1215 | "statuses": "~1.5.0", 1216 | "type-is": "~1.6.18", 1217 | "utils-merge": "1.0.1", 1218 | "vary": "~1.1.2" 1219 | }, 1220 | "dependencies": { 1221 | "debug": { 1222 | "version": "2.6.9", 1223 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1224 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1225 | "requires": { 1226 | "ms": "2.0.0" 1227 | } 1228 | }, 1229 | "ms": { 1230 | "version": "2.0.0", 1231 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1232 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1233 | } 1234 | } 1235 | }, 1236 | "extend": { 1237 | "version": "3.0.2", 1238 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 1239 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 1240 | }, 1241 | "external-editor": { 1242 | "version": "3.1.0", 1243 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 1244 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 1245 | "dev": true, 1246 | "requires": { 1247 | "chardet": "^0.7.0", 1248 | "iconv-lite": "^0.4.24", 1249 | "tmp": "^0.0.33" 1250 | } 1251 | }, 1252 | "extract-zip": { 1253 | "version": "1.7.0", 1254 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", 1255 | "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", 1256 | "requires": { 1257 | "concat-stream": "^1.6.2", 1258 | "debug": "^2.6.9", 1259 | "mkdirp": "^0.5.4", 1260 | "yauzl": "^2.10.0" 1261 | }, 1262 | "dependencies": { 1263 | "concat-stream": { 1264 | "version": "1.6.2", 1265 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 1266 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 1267 | "requires": { 1268 | "buffer-from": "^1.0.0", 1269 | "inherits": "^2.0.3", 1270 | "readable-stream": "^2.2.2", 1271 | "typedarray": "^0.0.6" 1272 | } 1273 | }, 1274 | "debug": { 1275 | "version": "2.6.9", 1276 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1277 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1278 | "requires": { 1279 | "ms": "2.0.0" 1280 | } 1281 | }, 1282 | "ms": { 1283 | "version": "2.0.0", 1284 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1285 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1286 | }, 1287 | "readable-stream": { 1288 | "version": "2.3.7", 1289 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 1290 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 1291 | "requires": { 1292 | "core-util-is": "~1.0.0", 1293 | "inherits": "~2.0.3", 1294 | "isarray": "~1.0.0", 1295 | "process-nextick-args": "~2.0.0", 1296 | "safe-buffer": "~5.1.1", 1297 | "string_decoder": "~1.1.1", 1298 | "util-deprecate": "~1.0.1" 1299 | } 1300 | } 1301 | } 1302 | }, 1303 | "fast-deep-equal": { 1304 | "version": "2.0.1", 1305 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 1306 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", 1307 | "dev": true 1308 | }, 1309 | "fast-json-stable-stringify": { 1310 | "version": "2.0.0", 1311 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 1312 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 1313 | "dev": true 1314 | }, 1315 | "fast-levenshtein": { 1316 | "version": "2.0.6", 1317 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1318 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 1319 | "dev": true 1320 | }, 1321 | "fast-text-encoding": { 1322 | "version": "1.0.3", 1323 | "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", 1324 | "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" 1325 | }, 1326 | "faye-websocket": { 1327 | "version": "0.11.3", 1328 | "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", 1329 | "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", 1330 | "requires": { 1331 | "websocket-driver": ">=0.5.1" 1332 | } 1333 | }, 1334 | "fd-slicer": { 1335 | "version": "1.1.0", 1336 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 1337 | "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", 1338 | "requires": { 1339 | "pend": "~1.2.0" 1340 | } 1341 | }, 1342 | "figures": { 1343 | "version": "2.0.0", 1344 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 1345 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 1346 | "dev": true, 1347 | "requires": { 1348 | "escape-string-regexp": "^1.0.5" 1349 | } 1350 | }, 1351 | "file-entry-cache": { 1352 | "version": "5.0.1", 1353 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 1354 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 1355 | "dev": true, 1356 | "requires": { 1357 | "flat-cache": "^2.0.1" 1358 | } 1359 | }, 1360 | "finalhandler": { 1361 | "version": "1.1.2", 1362 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 1363 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 1364 | "requires": { 1365 | "debug": "2.6.9", 1366 | "encodeurl": "~1.0.2", 1367 | "escape-html": "~1.0.3", 1368 | "on-finished": "~2.3.0", 1369 | "parseurl": "~1.3.3", 1370 | "statuses": "~1.5.0", 1371 | "unpipe": "~1.0.0" 1372 | }, 1373 | "dependencies": { 1374 | "debug": { 1375 | "version": "2.6.9", 1376 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1377 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1378 | "requires": { 1379 | "ms": "2.0.0" 1380 | } 1381 | }, 1382 | "ms": { 1383 | "version": "2.0.0", 1384 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1385 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1386 | } 1387 | } 1388 | }, 1389 | "firebase-admin": { 1390 | "version": "9.2.0", 1391 | "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.2.0.tgz", 1392 | "integrity": "sha512-LhnMYl71B4gP1FlTLfwaYlOWhBCAcNF+byb2CPTfaW/T4hkp4qlXOgo2bws/zbAv5X9GTFqGir3KexMslVGsIA==", 1393 | "requires": { 1394 | "@firebase/database": "^0.6.10", 1395 | "@firebase/database-types": "^0.5.2", 1396 | "@google-cloud/firestore": "^4.0.0", 1397 | "@google-cloud/storage": "^5.3.0", 1398 | "@types/node": "^10.10.0", 1399 | "dicer": "^0.3.0", 1400 | "jsonwebtoken": "^8.5.1", 1401 | "node-forge": "^0.10.0" 1402 | }, 1403 | "dependencies": { 1404 | "@types/node": { 1405 | "version": "10.17.37", 1406 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.37.tgz", 1407 | "integrity": "sha512-4c38N7p9k9yqdcANh/WExTahkBgOTmggCyrTvVcbE8ByqO3g8evt/407v/I4X/gdfUkIyZBSQh/Rc3tvuwlVGw==" 1408 | } 1409 | } 1410 | }, 1411 | "firebase-functions": { 1412 | "version": "3.3.0", 1413 | "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.3.0.tgz", 1414 | "integrity": "sha512-dP6PCG+OwR6RtFpOqwPsLnfiCr3CwXAm/SVGMbO53vDAk0nhUQ1WGAyHDYmIyMAkaLJkIKGwDnX7XmZ5+yAg7g==", 1415 | "requires": { 1416 | "@types/express": "^4.17.0", 1417 | "cors": "^2.8.5", 1418 | "express": "^4.17.1", 1419 | "jsonwebtoken": "^8.5.1", 1420 | "lodash": "^4.17.14" 1421 | }, 1422 | "dependencies": { 1423 | "jsonwebtoken": { 1424 | "version": "8.5.1", 1425 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", 1426 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", 1427 | "requires": { 1428 | "jws": "^3.2.2", 1429 | "lodash.includes": "^4.3.0", 1430 | "lodash.isboolean": "^3.0.3", 1431 | "lodash.isinteger": "^4.0.4", 1432 | "lodash.isnumber": "^3.0.3", 1433 | "lodash.isplainobject": "^4.0.6", 1434 | "lodash.isstring": "^4.0.1", 1435 | "lodash.once": "^4.0.0", 1436 | "ms": "^2.1.1", 1437 | "semver": "^5.6.0" 1438 | } 1439 | }, 1440 | "semver": { 1441 | "version": "5.7.1", 1442 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1443 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1444 | } 1445 | } 1446 | }, 1447 | "firebase-functions-test": { 1448 | "version": "0.1.7", 1449 | "resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.1.7.tgz", 1450 | "integrity": "sha512-/zVQhaUZ+M7z25aUaZSIah0MIDZIfnRfQxtHYTE8hgUgODmKdaMX20vh5Gv23hnCPauIHuYb7XFTUOZiWU1udA==", 1451 | "dev": true, 1452 | "requires": { 1453 | "@types/lodash": "^4.14.104", 1454 | "lodash": "^4.17.5" 1455 | } 1456 | }, 1457 | "flat-cache": { 1458 | "version": "2.0.1", 1459 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 1460 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 1461 | "dev": true, 1462 | "requires": { 1463 | "flatted": "^2.0.0", 1464 | "rimraf": "2.6.3", 1465 | "write": "1.0.3" 1466 | }, 1467 | "dependencies": { 1468 | "rimraf": { 1469 | "version": "2.6.3", 1470 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1471 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1472 | "dev": true, 1473 | "requires": { 1474 | "glob": "^7.1.3" 1475 | } 1476 | } 1477 | } 1478 | }, 1479 | "flatted": { 1480 | "version": "2.0.1", 1481 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 1482 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 1483 | "dev": true 1484 | }, 1485 | "forwarded": { 1486 | "version": "0.1.2", 1487 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 1488 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 1489 | }, 1490 | "fresh": { 1491 | "version": "0.5.2", 1492 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1493 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1494 | }, 1495 | "fs.realpath": { 1496 | "version": "1.0.0", 1497 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1498 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 1499 | }, 1500 | "fstream": { 1501 | "version": "1.0.12", 1502 | "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", 1503 | "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", 1504 | "requires": { 1505 | "graceful-fs": "^4.1.2", 1506 | "inherits": "~2.0.0", 1507 | "mkdirp": ">=0.5 0", 1508 | "rimraf": "2" 1509 | } 1510 | }, 1511 | "functional-red-black-tree": { 1512 | "version": "1.0.1", 1513 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1514 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" 1515 | }, 1516 | "gaxios": { 1517 | "version": "3.2.0", 1518 | "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz", 1519 | "integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==", 1520 | "requires": { 1521 | "abort-controller": "^3.0.0", 1522 | "extend": "^3.0.2", 1523 | "https-proxy-agent": "^5.0.0", 1524 | "is-stream": "^2.0.0", 1525 | "node-fetch": "^2.3.0" 1526 | }, 1527 | "dependencies": { 1528 | "agent-base": { 1529 | "version": "6.0.1", 1530 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", 1531 | "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", 1532 | "requires": { 1533 | "debug": "4" 1534 | } 1535 | }, 1536 | "debug": { 1537 | "version": "4.2.0", 1538 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 1539 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 1540 | "requires": { 1541 | "ms": "2.1.2" 1542 | } 1543 | }, 1544 | "https-proxy-agent": { 1545 | "version": "5.0.0", 1546 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 1547 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 1548 | "requires": { 1549 | "agent-base": "6", 1550 | "debug": "4" 1551 | } 1552 | } 1553 | } 1554 | }, 1555 | "gcp-metadata": { 1556 | "version": "4.2.0", 1557 | "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.0.tgz", 1558 | "integrity": "sha512-vQZD57cQkqIA6YPGXM/zc+PIZfNRFdukWGsGZ5+LcJzesi5xp6Gn7a02wRJi4eXPyArNMIYpPET4QMxGqtlk6Q==", 1559 | "requires": { 1560 | "gaxios": "^3.0.0", 1561 | "json-bigint": "^1.0.0" 1562 | } 1563 | }, 1564 | "gcs-resumable-upload": { 1565 | "version": "3.1.1", 1566 | "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.1.1.tgz", 1567 | "integrity": "sha512-RS1osvAicj9+MjCc6jAcVL1Pt3tg7NK2C2gXM5nqD1Gs0klF2kj5nnAFSBy97JrtslMIQzpb7iSuxaG8rFWd2A==", 1568 | "requires": { 1569 | "abort-controller": "^3.0.0", 1570 | "configstore": "^5.0.0", 1571 | "extend": "^3.0.2", 1572 | "gaxios": "^3.0.0", 1573 | "google-auth-library": "^6.0.0", 1574 | "pumpify": "^2.0.0", 1575 | "stream-events": "^1.0.4" 1576 | } 1577 | }, 1578 | "get-caller-file": { 1579 | "version": "2.0.5", 1580 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1581 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1582 | "optional": true 1583 | }, 1584 | "glob": { 1585 | "version": "7.1.6", 1586 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1587 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1588 | "requires": { 1589 | "fs.realpath": "^1.0.0", 1590 | "inflight": "^1.0.4", 1591 | "inherits": "2", 1592 | "minimatch": "^3.0.4", 1593 | "once": "^1.3.0", 1594 | "path-is-absolute": "^1.0.0" 1595 | } 1596 | }, 1597 | "globals": { 1598 | "version": "11.12.0", 1599 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1600 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1601 | "dev": true 1602 | }, 1603 | "google-auth-library": { 1604 | "version": "6.1.1", 1605 | "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.1.tgz", 1606 | "integrity": "sha512-0WfExOx3FrLYnY88RICQxvpaNzdwjz44OsHqHkIoAJfjY6Jck6CZRl1ASWadk+wbJ0LhkQ8rNY4zZebKml4Ghg==", 1607 | "requires": { 1608 | "arrify": "^2.0.0", 1609 | "base64-js": "^1.3.0", 1610 | "ecdsa-sig-formatter": "^1.0.11", 1611 | "fast-text-encoding": "^1.0.0", 1612 | "gaxios": "^3.0.0", 1613 | "gcp-metadata": "^4.1.0", 1614 | "gtoken": "^5.0.4", 1615 | "jws": "^4.0.0", 1616 | "lru-cache": "^6.0.0" 1617 | }, 1618 | "dependencies": { 1619 | "jwa": { 1620 | "version": "2.0.0", 1621 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", 1622 | "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", 1623 | "requires": { 1624 | "buffer-equal-constant-time": "1.0.1", 1625 | "ecdsa-sig-formatter": "1.0.11", 1626 | "safe-buffer": "^5.0.1" 1627 | } 1628 | }, 1629 | "jws": { 1630 | "version": "4.0.0", 1631 | "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", 1632 | "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", 1633 | "requires": { 1634 | "jwa": "^2.0.0", 1635 | "safe-buffer": "^5.0.1" 1636 | } 1637 | } 1638 | } 1639 | }, 1640 | "google-gax": { 1641 | "version": "2.9.0", 1642 | "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.9.0.tgz", 1643 | "integrity": "sha512-MFMwA7Fb8PEwjnYwfGXjZMidCNyMl3gSnvS/+kS8TQioJZQDpzK+W3dmwyNyig/U13+kbABqDnbkkAXJ5NiUkw==", 1644 | "optional": true, 1645 | "requires": { 1646 | "@grpc/grpc-js": "~1.1.1", 1647 | "@grpc/proto-loader": "^0.5.1", 1648 | "@types/long": "^4.0.0", 1649 | "abort-controller": "^3.0.0", 1650 | "duplexify": "^4.0.0", 1651 | "google-auth-library": "^6.0.0", 1652 | "is-stream-ended": "^0.1.4", 1653 | "node-fetch": "^2.6.1", 1654 | "protobufjs": "^6.9.0", 1655 | "retry-request": "^4.0.0" 1656 | }, 1657 | "dependencies": { 1658 | "duplexify": { 1659 | "version": "4.1.1", 1660 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", 1661 | "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", 1662 | "optional": true, 1663 | "requires": { 1664 | "end-of-stream": "^1.4.1", 1665 | "inherits": "^2.0.3", 1666 | "readable-stream": "^3.1.1", 1667 | "stream-shift": "^1.0.0" 1668 | } 1669 | } 1670 | } 1671 | }, 1672 | "google-p12-pem": { 1673 | "version": "3.0.3", 1674 | "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", 1675 | "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", 1676 | "requires": { 1677 | "node-forge": "^0.10.0" 1678 | } 1679 | }, 1680 | "graceful-fs": { 1681 | "version": "4.2.3", 1682 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", 1683 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" 1684 | }, 1685 | "gtoken": { 1686 | "version": "5.0.4", 1687 | "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.4.tgz", 1688 | "integrity": "sha512-U9wnSp4GZ7ov6zRdPuRHG4TuqEWqRRgT1gfXGNArhzBUn9byrPeH8uTmBWU/ZiWJJvTEmkjhDIC3mqHWdVi3xQ==", 1689 | "requires": { 1690 | "gaxios": "^3.0.0", 1691 | "google-p12-pem": "^3.0.3", 1692 | "jws": "^4.0.0", 1693 | "mime": "^2.2.0" 1694 | }, 1695 | "dependencies": { 1696 | "jwa": { 1697 | "version": "2.0.0", 1698 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", 1699 | "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", 1700 | "requires": { 1701 | "buffer-equal-constant-time": "1.0.1", 1702 | "ecdsa-sig-formatter": "1.0.11", 1703 | "safe-buffer": "^5.0.1" 1704 | } 1705 | }, 1706 | "jws": { 1707 | "version": "4.0.0", 1708 | "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", 1709 | "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", 1710 | "requires": { 1711 | "jwa": "^2.0.0", 1712 | "safe-buffer": "^5.0.1" 1713 | } 1714 | } 1715 | } 1716 | }, 1717 | "has-flag": { 1718 | "version": "3.0.0", 1719 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1720 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1721 | "dev": true 1722 | }, 1723 | "hash-stream-validation": { 1724 | "version": "0.2.4", 1725 | "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", 1726 | "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==" 1727 | }, 1728 | "http-errors": { 1729 | "version": "1.7.2", 1730 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 1731 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 1732 | "requires": { 1733 | "depd": "~1.1.2", 1734 | "inherits": "2.0.3", 1735 | "setprototypeof": "1.1.1", 1736 | "statuses": ">= 1.5.0 < 2", 1737 | "toidentifier": "1.0.0" 1738 | }, 1739 | "dependencies": { 1740 | "inherits": { 1741 | "version": "2.0.3", 1742 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1743 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1744 | } 1745 | } 1746 | }, 1747 | "http-parser-js": { 1748 | "version": "0.5.2", 1749 | "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", 1750 | "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==" 1751 | }, 1752 | "http-proxy-agent": { 1753 | "version": "4.0.1", 1754 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", 1755 | "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", 1756 | "requires": { 1757 | "@tootallnate/once": "1", 1758 | "agent-base": "6", 1759 | "debug": "4" 1760 | }, 1761 | "dependencies": { 1762 | "agent-base": { 1763 | "version": "6.0.1", 1764 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", 1765 | "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", 1766 | "requires": { 1767 | "debug": "4" 1768 | } 1769 | }, 1770 | "debug": { 1771 | "version": "4.2.0", 1772 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 1773 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 1774 | "requires": { 1775 | "ms": "2.1.2" 1776 | } 1777 | } 1778 | } 1779 | }, 1780 | "https-proxy-agent": { 1781 | "version": "3.0.1", 1782 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", 1783 | "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", 1784 | "requires": { 1785 | "agent-base": "^4.3.0", 1786 | "debug": "^3.1.0" 1787 | } 1788 | }, 1789 | "iconv-lite": { 1790 | "version": "0.4.24", 1791 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1792 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1793 | "requires": { 1794 | "safer-buffer": ">= 2.1.2 < 3" 1795 | } 1796 | }, 1797 | "ignore": { 1798 | "version": "4.0.6", 1799 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 1800 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 1801 | "dev": true 1802 | }, 1803 | "import-fresh": { 1804 | "version": "3.2.1", 1805 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 1806 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 1807 | "dev": true, 1808 | "requires": { 1809 | "parent-module": "^1.0.0", 1810 | "resolve-from": "^4.0.0" 1811 | } 1812 | }, 1813 | "imurmurhash": { 1814 | "version": "0.1.4", 1815 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1816 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 1817 | }, 1818 | "inflight": { 1819 | "version": "1.0.6", 1820 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1821 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1822 | "requires": { 1823 | "once": "^1.3.0", 1824 | "wrappy": "1" 1825 | } 1826 | }, 1827 | "inherits": { 1828 | "version": "2.0.4", 1829 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1830 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1831 | }, 1832 | "inquirer": { 1833 | "version": "6.5.2", 1834 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", 1835 | "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", 1836 | "dev": true, 1837 | "requires": { 1838 | "ansi-escapes": "^3.2.0", 1839 | "chalk": "^2.4.2", 1840 | "cli-cursor": "^2.1.0", 1841 | "cli-width": "^2.0.0", 1842 | "external-editor": "^3.0.3", 1843 | "figures": "^2.0.0", 1844 | "lodash": "^4.17.12", 1845 | "mute-stream": "0.0.7", 1846 | "run-async": "^2.2.0", 1847 | "rxjs": "^6.4.0", 1848 | "string-width": "^2.1.0", 1849 | "strip-ansi": "^5.1.0", 1850 | "through": "^2.3.6" 1851 | }, 1852 | "dependencies": { 1853 | "ansi-regex": { 1854 | "version": "4.1.0", 1855 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1856 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1857 | "dev": true 1858 | }, 1859 | "strip-ansi": { 1860 | "version": "5.2.0", 1861 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1862 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1863 | "dev": true, 1864 | "requires": { 1865 | "ansi-regex": "^4.1.0" 1866 | } 1867 | } 1868 | } 1869 | }, 1870 | "ipaddr.js": { 1871 | "version": "1.9.0", 1872 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", 1873 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" 1874 | }, 1875 | "is-fullwidth-code-point": { 1876 | "version": "2.0.0", 1877 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1878 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1879 | "dev": true 1880 | }, 1881 | "is-obj": { 1882 | "version": "2.0.0", 1883 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", 1884 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" 1885 | }, 1886 | "is-promise": { 1887 | "version": "2.1.0", 1888 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 1889 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 1890 | "dev": true 1891 | }, 1892 | "is-stream": { 1893 | "version": "2.0.0", 1894 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", 1895 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" 1896 | }, 1897 | "is-stream-ended": { 1898 | "version": "0.1.4", 1899 | "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", 1900 | "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", 1901 | "optional": true 1902 | }, 1903 | "is-typedarray": { 1904 | "version": "1.0.0", 1905 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1906 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 1907 | }, 1908 | "isarray": { 1909 | "version": "1.0.0", 1910 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1911 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 1912 | }, 1913 | "isexe": { 1914 | "version": "2.0.0", 1915 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1916 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1917 | "dev": true 1918 | }, 1919 | "js-tokens": { 1920 | "version": "4.0.0", 1921 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1922 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1923 | "dev": true 1924 | }, 1925 | "js-yaml": { 1926 | "version": "3.13.1", 1927 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1928 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1929 | "dev": true, 1930 | "requires": { 1931 | "argparse": "^1.0.7", 1932 | "esprima": "^4.0.0" 1933 | } 1934 | }, 1935 | "json-bigint": { 1936 | "version": "1.0.0", 1937 | "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", 1938 | "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", 1939 | "requires": { 1940 | "bignumber.js": "^9.0.0" 1941 | } 1942 | }, 1943 | "json-schema-traverse": { 1944 | "version": "0.4.1", 1945 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1946 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1947 | "dev": true 1948 | }, 1949 | "json-stable-stringify-without-jsonify": { 1950 | "version": "1.0.1", 1951 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1952 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1953 | "dev": true 1954 | }, 1955 | "jsonwebtoken": { 1956 | "version": "8.5.1", 1957 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", 1958 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", 1959 | "requires": { 1960 | "jws": "^3.2.2", 1961 | "lodash.includes": "^4.3.0", 1962 | "lodash.isboolean": "^3.0.3", 1963 | "lodash.isinteger": "^4.0.4", 1964 | "lodash.isnumber": "^3.0.3", 1965 | "lodash.isplainobject": "^4.0.6", 1966 | "lodash.isstring": "^4.0.1", 1967 | "lodash.once": "^4.0.0", 1968 | "ms": "^2.1.1", 1969 | "semver": "^5.6.0" 1970 | }, 1971 | "dependencies": { 1972 | "semver": { 1973 | "version": "5.7.1", 1974 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1975 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1976 | } 1977 | } 1978 | }, 1979 | "jwa": { 1980 | "version": "1.4.1", 1981 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 1982 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 1983 | "requires": { 1984 | "buffer-equal-constant-time": "1.0.1", 1985 | "ecdsa-sig-formatter": "1.0.11", 1986 | "safe-buffer": "^5.0.1" 1987 | } 1988 | }, 1989 | "jws": { 1990 | "version": "3.2.2", 1991 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 1992 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 1993 | "requires": { 1994 | "jwa": "^1.4.1", 1995 | "safe-buffer": "^5.0.1" 1996 | } 1997 | }, 1998 | "levn": { 1999 | "version": "0.3.0", 2000 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 2001 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 2002 | "dev": true, 2003 | "requires": { 2004 | "prelude-ls": "~1.1.2", 2005 | "type-check": "~0.3.2" 2006 | } 2007 | }, 2008 | "listenercount": { 2009 | "version": "1.0.1", 2010 | "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", 2011 | "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" 2012 | }, 2013 | "lodash": { 2014 | "version": "4.17.21", 2015 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 2016 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 2017 | }, 2018 | "lodash.camelcase": { 2019 | "version": "4.3.0", 2020 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 2021 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", 2022 | "optional": true 2023 | }, 2024 | "lodash.includes": { 2025 | "version": "4.3.0", 2026 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 2027 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" 2028 | }, 2029 | "lodash.isboolean": { 2030 | "version": "3.0.3", 2031 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 2032 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" 2033 | }, 2034 | "lodash.isinteger": { 2035 | "version": "4.0.4", 2036 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 2037 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" 2038 | }, 2039 | "lodash.isnumber": { 2040 | "version": "3.0.3", 2041 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 2042 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" 2043 | }, 2044 | "lodash.isplainobject": { 2045 | "version": "4.0.6", 2046 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 2047 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 2048 | }, 2049 | "lodash.isstring": { 2050 | "version": "4.0.1", 2051 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 2052 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" 2053 | }, 2054 | "lodash.once": { 2055 | "version": "4.1.1", 2056 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 2057 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" 2058 | }, 2059 | "long": { 2060 | "version": "4.0.0", 2061 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", 2062 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", 2063 | "optional": true 2064 | }, 2065 | "lru-cache": { 2066 | "version": "6.0.0", 2067 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 2068 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 2069 | "requires": { 2070 | "yallist": "^4.0.0" 2071 | } 2072 | }, 2073 | "make-dir": { 2074 | "version": "3.1.0", 2075 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 2076 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 2077 | "requires": { 2078 | "semver": "^6.0.0" 2079 | } 2080 | }, 2081 | "media-typer": { 2082 | "version": "0.3.0", 2083 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 2084 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 2085 | }, 2086 | "merge-descriptors": { 2087 | "version": "1.0.1", 2088 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 2089 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 2090 | }, 2091 | "methods": { 2092 | "version": "1.1.2", 2093 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 2094 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 2095 | }, 2096 | "mime": { 2097 | "version": "2.4.4", 2098 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", 2099 | "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" 2100 | }, 2101 | "mime-db": { 2102 | "version": "1.42.0", 2103 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", 2104 | "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" 2105 | }, 2106 | "mime-types": { 2107 | "version": "2.1.25", 2108 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", 2109 | "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", 2110 | "requires": { 2111 | "mime-db": "1.42.0" 2112 | } 2113 | }, 2114 | "mimic-fn": { 2115 | "version": "2.1.0", 2116 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 2117 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" 2118 | }, 2119 | "minimatch": { 2120 | "version": "3.0.4", 2121 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2122 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2123 | "requires": { 2124 | "brace-expansion": "^1.1.7" 2125 | } 2126 | }, 2127 | "minimist": { 2128 | "version": "1.2.5", 2129 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 2130 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 2131 | }, 2132 | "mkdirp": { 2133 | "version": "0.5.5", 2134 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 2135 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 2136 | "requires": { 2137 | "minimist": "^1.2.5" 2138 | } 2139 | }, 2140 | "ms": { 2141 | "version": "2.1.2", 2142 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2143 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2144 | }, 2145 | "mute-stream": { 2146 | "version": "0.0.7", 2147 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 2148 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 2149 | "dev": true 2150 | }, 2151 | "natural-compare": { 2152 | "version": "1.4.0", 2153 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2154 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 2155 | "dev": true 2156 | }, 2157 | "negotiator": { 2158 | "version": "0.6.2", 2159 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 2160 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 2161 | }, 2162 | "nice-try": { 2163 | "version": "1.0.5", 2164 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 2165 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 2166 | "dev": true 2167 | }, 2168 | "node-fetch": { 2169 | "version": "2.6.1", 2170 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 2171 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 2172 | }, 2173 | "node-forge": { 2174 | "version": "0.10.0", 2175 | "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", 2176 | "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" 2177 | }, 2178 | "object-assign": { 2179 | "version": "4.1.1", 2180 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 2181 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 2182 | }, 2183 | "on-finished": { 2184 | "version": "2.3.0", 2185 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 2186 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 2187 | "requires": { 2188 | "ee-first": "1.1.1" 2189 | } 2190 | }, 2191 | "once": { 2192 | "version": "1.4.0", 2193 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2194 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2195 | "requires": { 2196 | "wrappy": "1" 2197 | } 2198 | }, 2199 | "onetime": { 2200 | "version": "5.1.2", 2201 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", 2202 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", 2203 | "requires": { 2204 | "mimic-fn": "^2.1.0" 2205 | } 2206 | }, 2207 | "optionator": { 2208 | "version": "0.8.3", 2209 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 2210 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 2211 | "dev": true, 2212 | "requires": { 2213 | "deep-is": "~0.1.3", 2214 | "fast-levenshtein": "~2.0.6", 2215 | "levn": "~0.3.0", 2216 | "prelude-ls": "~1.1.2", 2217 | "type-check": "~0.3.2", 2218 | "word-wrap": "~1.2.3" 2219 | } 2220 | }, 2221 | "os-tmpdir": { 2222 | "version": "1.0.2", 2223 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 2224 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 2225 | "dev": true 2226 | }, 2227 | "p-limit": { 2228 | "version": "3.0.2", 2229 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", 2230 | "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", 2231 | "requires": { 2232 | "p-try": "^2.0.0" 2233 | } 2234 | }, 2235 | "p-try": { 2236 | "version": "2.2.0", 2237 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 2238 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" 2239 | }, 2240 | "parent-module": { 2241 | "version": "1.0.1", 2242 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2243 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2244 | "dev": true, 2245 | "requires": { 2246 | "callsites": "^3.0.0" 2247 | } 2248 | }, 2249 | "parseurl": { 2250 | "version": "1.3.3", 2251 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 2252 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 2253 | }, 2254 | "path-is-absolute": { 2255 | "version": "1.0.1", 2256 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2257 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 2258 | }, 2259 | "path-is-inside": { 2260 | "version": "1.0.2", 2261 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 2262 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 2263 | "dev": true 2264 | }, 2265 | "path-key": { 2266 | "version": "2.0.1", 2267 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 2268 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 2269 | "dev": true 2270 | }, 2271 | "path-to-regexp": { 2272 | "version": "0.1.7", 2273 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 2274 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 2275 | }, 2276 | "pend": { 2277 | "version": "1.2.0", 2278 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 2279 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 2280 | }, 2281 | "prelude-ls": { 2282 | "version": "1.1.2", 2283 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 2284 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 2285 | "dev": true 2286 | }, 2287 | "process-nextick-args": { 2288 | "version": "2.0.1", 2289 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 2290 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 2291 | }, 2292 | "progress": { 2293 | "version": "2.0.3", 2294 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 2295 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" 2296 | }, 2297 | "protobufjs": { 2298 | "version": "6.10.1", 2299 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz", 2300 | "integrity": "sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ==", 2301 | "optional": true, 2302 | "requires": { 2303 | "@protobufjs/aspromise": "^1.1.2", 2304 | "@protobufjs/base64": "^1.1.2", 2305 | "@protobufjs/codegen": "^2.0.4", 2306 | "@protobufjs/eventemitter": "^1.1.0", 2307 | "@protobufjs/fetch": "^1.1.0", 2308 | "@protobufjs/float": "^1.0.2", 2309 | "@protobufjs/inquire": "^1.1.0", 2310 | "@protobufjs/path": "^1.1.2", 2311 | "@protobufjs/pool": "^1.1.0", 2312 | "@protobufjs/utf8": "^1.1.0", 2313 | "@types/long": "^4.0.1", 2314 | "@types/node": "^13.7.0", 2315 | "long": "^4.0.0" 2316 | }, 2317 | "dependencies": { 2318 | "@types/node": { 2319 | "version": "13.13.23", 2320 | "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.23.tgz", 2321 | "integrity": "sha512-L31WmMJYKb15PDqFWutn8HNwrNK6CE6bkWgSB0dO1XpNoHrszVKV1Clcnfgd6c/oG54TVF8XQEvY2gQrW8K6Mw==", 2322 | "optional": true 2323 | } 2324 | } 2325 | }, 2326 | "proxy-addr": { 2327 | "version": "2.0.5", 2328 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", 2329 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", 2330 | "requires": { 2331 | "forwarded": "~0.1.2", 2332 | "ipaddr.js": "1.9.0" 2333 | } 2334 | }, 2335 | "proxy-from-env": { 2336 | "version": "1.0.0", 2337 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", 2338 | "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" 2339 | }, 2340 | "pump": { 2341 | "version": "3.0.0", 2342 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 2343 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 2344 | "requires": { 2345 | "end-of-stream": "^1.1.0", 2346 | "once": "^1.3.1" 2347 | } 2348 | }, 2349 | "pumpify": { 2350 | "version": "2.0.1", 2351 | "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", 2352 | "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", 2353 | "requires": { 2354 | "duplexify": "^4.1.1", 2355 | "inherits": "^2.0.3", 2356 | "pump": "^3.0.0" 2357 | }, 2358 | "dependencies": { 2359 | "duplexify": { 2360 | "version": "4.1.1", 2361 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", 2362 | "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", 2363 | "requires": { 2364 | "end-of-stream": "^1.4.1", 2365 | "inherits": "^2.0.3", 2366 | "readable-stream": "^3.1.1", 2367 | "stream-shift": "^1.0.0" 2368 | } 2369 | } 2370 | } 2371 | }, 2372 | "punycode": { 2373 | "version": "2.1.1", 2374 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 2375 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 2376 | "dev": true 2377 | }, 2378 | "puppeteer": { 2379 | "version": "2.0.0", 2380 | "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.0.0.tgz", 2381 | "integrity": "sha512-t3MmTWzQxPRP71teU6l0jX47PHXlc4Z52sQv4LJQSZLq1ttkKS2yGM3gaI57uQwZkNaoGd0+HPPMELZkcyhlqA==", 2382 | "requires": { 2383 | "debug": "^4.1.0", 2384 | "extract-zip": "^1.6.6", 2385 | "https-proxy-agent": "^3.0.0", 2386 | "mime": "^2.0.3", 2387 | "progress": "^2.0.1", 2388 | "proxy-from-env": "^1.0.0", 2389 | "rimraf": "^2.6.1", 2390 | "ws": "^6.1.0" 2391 | }, 2392 | "dependencies": { 2393 | "debug": { 2394 | "version": "4.1.1", 2395 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 2396 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 2397 | "requires": { 2398 | "ms": "^2.1.1" 2399 | } 2400 | } 2401 | } 2402 | }, 2403 | "qs": { 2404 | "version": "6.7.0", 2405 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 2406 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 2407 | }, 2408 | "range-parser": { 2409 | "version": "1.2.1", 2410 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 2411 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 2412 | }, 2413 | "raw-body": { 2414 | "version": "2.4.0", 2415 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 2416 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 2417 | "requires": { 2418 | "bytes": "3.1.0", 2419 | "http-errors": "1.7.2", 2420 | "iconv-lite": "0.4.24", 2421 | "unpipe": "1.0.0" 2422 | } 2423 | }, 2424 | "readable-stream": { 2425 | "version": "3.6.0", 2426 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 2427 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 2428 | "requires": { 2429 | "inherits": "^2.0.3", 2430 | "string_decoder": "^1.1.1", 2431 | "util-deprecate": "^1.0.1" 2432 | } 2433 | }, 2434 | "regexpp": { 2435 | "version": "2.0.1", 2436 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 2437 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 2438 | "dev": true 2439 | }, 2440 | "require-directory": { 2441 | "version": "2.1.1", 2442 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2443 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 2444 | "optional": true 2445 | }, 2446 | "resolve-from": { 2447 | "version": "4.0.0", 2448 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2449 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2450 | "dev": true 2451 | }, 2452 | "restore-cursor": { 2453 | "version": "2.0.0", 2454 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 2455 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 2456 | "dev": true, 2457 | "requires": { 2458 | "onetime": "^2.0.0", 2459 | "signal-exit": "^3.0.2" 2460 | }, 2461 | "dependencies": { 2462 | "mimic-fn": { 2463 | "version": "1.2.0", 2464 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 2465 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 2466 | "dev": true 2467 | }, 2468 | "onetime": { 2469 | "version": "2.0.1", 2470 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 2471 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 2472 | "dev": true, 2473 | "requires": { 2474 | "mimic-fn": "^1.0.0" 2475 | } 2476 | } 2477 | } 2478 | }, 2479 | "retry-request": { 2480 | "version": "4.1.3", 2481 | "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.3.tgz", 2482 | "integrity": "sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ==", 2483 | "requires": { 2484 | "debug": "^4.1.1" 2485 | }, 2486 | "dependencies": { 2487 | "debug": { 2488 | "version": "4.2.0", 2489 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 2490 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 2491 | "requires": { 2492 | "ms": "2.1.2" 2493 | } 2494 | } 2495 | } 2496 | }, 2497 | "rimraf": { 2498 | "version": "2.7.1", 2499 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 2500 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 2501 | "requires": { 2502 | "glob": "^7.1.3" 2503 | } 2504 | }, 2505 | "run-async": { 2506 | "version": "2.3.0", 2507 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 2508 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 2509 | "dev": true, 2510 | "requires": { 2511 | "is-promise": "^2.1.0" 2512 | } 2513 | }, 2514 | "rxjs": { 2515 | "version": "6.5.3", 2516 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", 2517 | "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", 2518 | "dev": true, 2519 | "requires": { 2520 | "tslib": "^1.9.0" 2521 | } 2522 | }, 2523 | "safe-buffer": { 2524 | "version": "5.1.2", 2525 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2526 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2527 | }, 2528 | "safer-buffer": { 2529 | "version": "2.1.2", 2530 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2531 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2532 | }, 2533 | "semver": { 2534 | "version": "6.3.0", 2535 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2536 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 2537 | }, 2538 | "send": { 2539 | "version": "0.17.1", 2540 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 2541 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 2542 | "requires": { 2543 | "debug": "2.6.9", 2544 | "depd": "~1.1.2", 2545 | "destroy": "~1.0.4", 2546 | "encodeurl": "~1.0.2", 2547 | "escape-html": "~1.0.3", 2548 | "etag": "~1.8.1", 2549 | "fresh": "0.5.2", 2550 | "http-errors": "~1.7.2", 2551 | "mime": "1.6.0", 2552 | "ms": "2.1.1", 2553 | "on-finished": "~2.3.0", 2554 | "range-parser": "~1.2.1", 2555 | "statuses": "~1.5.0" 2556 | }, 2557 | "dependencies": { 2558 | "debug": { 2559 | "version": "2.6.9", 2560 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 2561 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 2562 | "requires": { 2563 | "ms": "2.0.0" 2564 | }, 2565 | "dependencies": { 2566 | "ms": { 2567 | "version": "2.0.0", 2568 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2569 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 2570 | } 2571 | } 2572 | }, 2573 | "mime": { 2574 | "version": "1.6.0", 2575 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 2576 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 2577 | }, 2578 | "ms": { 2579 | "version": "2.1.1", 2580 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 2581 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 2582 | } 2583 | } 2584 | }, 2585 | "serve-static": { 2586 | "version": "1.14.1", 2587 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 2588 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 2589 | "requires": { 2590 | "encodeurl": "~1.0.2", 2591 | "escape-html": "~1.0.3", 2592 | "parseurl": "~1.3.3", 2593 | "send": "0.17.1" 2594 | } 2595 | }, 2596 | "setimmediate": { 2597 | "version": "1.0.5", 2598 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 2599 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" 2600 | }, 2601 | "setprototypeof": { 2602 | "version": "1.1.1", 2603 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 2604 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 2605 | }, 2606 | "shebang-command": { 2607 | "version": "1.2.0", 2608 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2609 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 2610 | "dev": true, 2611 | "requires": { 2612 | "shebang-regex": "^1.0.0" 2613 | } 2614 | }, 2615 | "shebang-regex": { 2616 | "version": "1.0.0", 2617 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2618 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 2619 | "dev": true 2620 | }, 2621 | "signal-exit": { 2622 | "version": "3.0.2", 2623 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 2624 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 2625 | }, 2626 | "slice-ansi": { 2627 | "version": "2.1.0", 2628 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 2629 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 2630 | "dev": true, 2631 | "requires": { 2632 | "ansi-styles": "^3.2.0", 2633 | "astral-regex": "^1.0.0", 2634 | "is-fullwidth-code-point": "^2.0.0" 2635 | } 2636 | }, 2637 | "snakeize": { 2638 | "version": "0.1.0", 2639 | "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", 2640 | "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=" 2641 | }, 2642 | "sprintf-js": { 2643 | "version": "1.0.3", 2644 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2645 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2646 | "dev": true 2647 | }, 2648 | "statuses": { 2649 | "version": "1.5.0", 2650 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 2651 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 2652 | }, 2653 | "stream-events": { 2654 | "version": "1.0.5", 2655 | "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", 2656 | "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", 2657 | "requires": { 2658 | "stubs": "^3.0.0" 2659 | } 2660 | }, 2661 | "stream-shift": { 2662 | "version": "1.0.1", 2663 | "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", 2664 | "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" 2665 | }, 2666 | "streamsearch": { 2667 | "version": "0.1.2", 2668 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 2669 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" 2670 | }, 2671 | "string-width": { 2672 | "version": "2.1.1", 2673 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 2674 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 2675 | "dev": true, 2676 | "requires": { 2677 | "is-fullwidth-code-point": "^2.0.0", 2678 | "strip-ansi": "^4.0.0" 2679 | } 2680 | }, 2681 | "string_decoder": { 2682 | "version": "1.1.1", 2683 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 2684 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2685 | "requires": { 2686 | "safe-buffer": "~5.1.0" 2687 | } 2688 | }, 2689 | "strip-ansi": { 2690 | "version": "4.0.0", 2691 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 2692 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 2693 | "dev": true, 2694 | "requires": { 2695 | "ansi-regex": "^3.0.0" 2696 | } 2697 | }, 2698 | "strip-json-comments": { 2699 | "version": "2.0.1", 2700 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 2701 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 2702 | "dev": true 2703 | }, 2704 | "stubs": { 2705 | "version": "3.0.0", 2706 | "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", 2707 | "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" 2708 | }, 2709 | "supports-color": { 2710 | "version": "5.5.0", 2711 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2712 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2713 | "dev": true, 2714 | "requires": { 2715 | "has-flag": "^3.0.0" 2716 | } 2717 | }, 2718 | "table": { 2719 | "version": "5.4.6", 2720 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 2721 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 2722 | "dev": true, 2723 | "requires": { 2724 | "ajv": "^6.10.2", 2725 | "lodash": "^4.17.14", 2726 | "slice-ansi": "^2.1.0", 2727 | "string-width": "^3.0.0" 2728 | }, 2729 | "dependencies": { 2730 | "ansi-regex": { 2731 | "version": "4.1.0", 2732 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 2733 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 2734 | "dev": true 2735 | }, 2736 | "string-width": { 2737 | "version": "3.1.0", 2738 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2739 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2740 | "dev": true, 2741 | "requires": { 2742 | "emoji-regex": "^7.0.1", 2743 | "is-fullwidth-code-point": "^2.0.0", 2744 | "strip-ansi": "^5.1.0" 2745 | } 2746 | }, 2747 | "strip-ansi": { 2748 | "version": "5.2.0", 2749 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 2750 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 2751 | "dev": true, 2752 | "requires": { 2753 | "ansi-regex": "^4.1.0" 2754 | } 2755 | } 2756 | } 2757 | }, 2758 | "teeny-request": { 2759 | "version": "7.0.1", 2760 | "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", 2761 | "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", 2762 | "requires": { 2763 | "http-proxy-agent": "^4.0.0", 2764 | "https-proxy-agent": "^5.0.0", 2765 | "node-fetch": "^2.6.1", 2766 | "stream-events": "^1.0.5", 2767 | "uuid": "^8.0.0" 2768 | }, 2769 | "dependencies": { 2770 | "agent-base": { 2771 | "version": "6.0.1", 2772 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", 2773 | "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", 2774 | "requires": { 2775 | "debug": "4" 2776 | } 2777 | }, 2778 | "debug": { 2779 | "version": "4.2.0", 2780 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 2781 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 2782 | "requires": { 2783 | "ms": "2.1.2" 2784 | } 2785 | }, 2786 | "https-proxy-agent": { 2787 | "version": "5.0.0", 2788 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 2789 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 2790 | "requires": { 2791 | "agent-base": "6", 2792 | "debug": "4" 2793 | } 2794 | } 2795 | } 2796 | }, 2797 | "text-table": { 2798 | "version": "0.2.0", 2799 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2800 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2801 | "dev": true 2802 | }, 2803 | "through": { 2804 | "version": "2.3.8", 2805 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2806 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2807 | "dev": true 2808 | }, 2809 | "tmp": { 2810 | "version": "0.0.33", 2811 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2812 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2813 | "dev": true, 2814 | "requires": { 2815 | "os-tmpdir": "~1.0.2" 2816 | } 2817 | }, 2818 | "toidentifier": { 2819 | "version": "1.0.0", 2820 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 2821 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 2822 | }, 2823 | "traverse": { 2824 | "version": "0.3.9", 2825 | "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", 2826 | "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" 2827 | }, 2828 | "tslib": { 2829 | "version": "1.10.0", 2830 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 2831 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", 2832 | "dev": true 2833 | }, 2834 | "type-check": { 2835 | "version": "0.3.2", 2836 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2837 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2838 | "dev": true, 2839 | "requires": { 2840 | "prelude-ls": "~1.1.2" 2841 | } 2842 | }, 2843 | "type-is": { 2844 | "version": "1.6.18", 2845 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2846 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2847 | "requires": { 2848 | "media-typer": "0.3.0", 2849 | "mime-types": "~2.1.24" 2850 | } 2851 | }, 2852 | "typedarray": { 2853 | "version": "0.0.6", 2854 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 2855 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 2856 | }, 2857 | "typedarray-to-buffer": { 2858 | "version": "3.1.5", 2859 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", 2860 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", 2861 | "requires": { 2862 | "is-typedarray": "^1.0.0" 2863 | } 2864 | }, 2865 | "unique-string": { 2866 | "version": "2.0.0", 2867 | "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", 2868 | "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", 2869 | "requires": { 2870 | "crypto-random-string": "^2.0.0" 2871 | } 2872 | }, 2873 | "unpipe": { 2874 | "version": "1.0.0", 2875 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2876 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 2877 | }, 2878 | "unzipper": { 2879 | "version": "0.10.10", 2880 | "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.10.tgz", 2881 | "integrity": "sha512-wEgtqtrnJ/9zIBsQb8UIxOhAH1eTHfi7D/xvmrUoMEePeI6u24nq1wigazbIFtHt6ANYXdEVTvc8XYNlTurs7A==", 2882 | "requires": { 2883 | "big-integer": "^1.6.17", 2884 | "binary": "~0.3.0", 2885 | "bluebird": "~3.4.1", 2886 | "buffer-indexof-polyfill": "~1.0.0", 2887 | "duplexer2": "~0.1.4", 2888 | "fstream": "^1.0.12", 2889 | "graceful-fs": "^4.2.2", 2890 | "listenercount": "~1.0.1", 2891 | "readable-stream": "~2.3.6", 2892 | "setimmediate": "~1.0.4" 2893 | }, 2894 | "dependencies": { 2895 | "readable-stream": { 2896 | "version": "2.3.7", 2897 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 2898 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 2899 | "requires": { 2900 | "core-util-is": "~1.0.0", 2901 | "inherits": "~2.0.3", 2902 | "isarray": "~1.0.0", 2903 | "process-nextick-args": "~2.0.0", 2904 | "safe-buffer": "~5.1.1", 2905 | "string_decoder": "~1.1.1", 2906 | "util-deprecate": "~1.0.1" 2907 | } 2908 | } 2909 | } 2910 | }, 2911 | "uri-js": { 2912 | "version": "4.2.2", 2913 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 2914 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 2915 | "dev": true, 2916 | "requires": { 2917 | "punycode": "^2.1.0" 2918 | } 2919 | }, 2920 | "util-deprecate": { 2921 | "version": "1.0.2", 2922 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2923 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 2924 | }, 2925 | "utils-merge": { 2926 | "version": "1.0.1", 2927 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2928 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 2929 | }, 2930 | "uuid": { 2931 | "version": "8.3.1", 2932 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", 2933 | "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" 2934 | }, 2935 | "vary": { 2936 | "version": "1.1.2", 2937 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2938 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 2939 | }, 2940 | "websocket-driver": { 2941 | "version": "0.7.4", 2942 | "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", 2943 | "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", 2944 | "requires": { 2945 | "http-parser-js": ">=0.5.1", 2946 | "safe-buffer": ">=5.1.0", 2947 | "websocket-extensions": ">=0.1.1" 2948 | } 2949 | }, 2950 | "websocket-extensions": { 2951 | "version": "0.1.4", 2952 | "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", 2953 | "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" 2954 | }, 2955 | "which": { 2956 | "version": "1.3.1", 2957 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2958 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2959 | "dev": true, 2960 | "requires": { 2961 | "isexe": "^2.0.0" 2962 | } 2963 | }, 2964 | "word-wrap": { 2965 | "version": "1.2.3", 2966 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2967 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2968 | "dev": true 2969 | }, 2970 | "wrappy": { 2971 | "version": "1.0.2", 2972 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2973 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 2974 | }, 2975 | "write": { 2976 | "version": "1.0.3", 2977 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 2978 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 2979 | "dev": true, 2980 | "requires": { 2981 | "mkdirp": "^0.5.1" 2982 | } 2983 | }, 2984 | "write-file-atomic": { 2985 | "version": "3.0.3", 2986 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", 2987 | "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", 2988 | "requires": { 2989 | "imurmurhash": "^0.1.4", 2990 | "is-typedarray": "^1.0.0", 2991 | "signal-exit": "^3.0.2", 2992 | "typedarray-to-buffer": "^3.1.5" 2993 | } 2994 | }, 2995 | "ws": { 2996 | "version": "6.2.1", 2997 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", 2998 | "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", 2999 | "requires": { 3000 | "async-limiter": "~1.0.0" 3001 | } 3002 | }, 3003 | "xdg-basedir": { 3004 | "version": "4.0.0", 3005 | "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", 3006 | "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" 3007 | }, 3008 | "yallist": { 3009 | "version": "4.0.0", 3010 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 3011 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 3012 | }, 3013 | "yauzl": { 3014 | "version": "2.10.0", 3015 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 3016 | "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", 3017 | "requires": { 3018 | "buffer-crc32": "~0.2.3", 3019 | "fd-slicer": "~1.1.0" 3020 | } 3021 | } 3022 | } 3023 | } 3024 | -------------------------------------------------------------------------------- /whatsapp/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whatsapp-morning-hail", 3 | "description": "Firebase/Google Cloud function to hail parents on WhatsApp automatically in the morning that is executed daily via scheduler! It keeps your WhatsApp session in Cloud Storage over Chrome's user data directory and sends a message to a WhatsApp group every morning with headless chrome instance using Puppeteer on a cloud function.", 4 | "scripts": { 5 | "lint": "eslint .", 6 | "serve": "firebase serve --only functions", 7 | "shell": "firebase functions:shell", 8 | "preemulate": "export GOOGLE_APPLICATION_CREDENTIALS=./secret/morning-hail-56d9123ccf2d.json", 9 | "emulate": "firebase emulators:start --only functions", 10 | "start": "npm run shell", 11 | "deploy": "firebase deploy --only functions", 12 | "logs": "firebase functions:log" 13 | }, 14 | "engines": { 15 | "node": "8" 16 | }, 17 | "dependencies": { 18 | "@google-cloud/storage": "^5.3.0", 19 | "firebase-admin": "^9.2.0", 20 | "firebase-functions": "^3.3.0", 21 | "puppeteer": "^2.0.0", 22 | "unzipper": "^0.10.10" 23 | }, 24 | "devDependencies": { 25 | "eslint": "5.16.0", 26 | "eslint-plugin-promise": "^4.0.1", 27 | "firebase-functions-test": "^0.1.6" 28 | }, 29 | "private": true 30 | } 31 | -------------------------------------------------------------------------------- /whatsapp/storage.rules: -------------------------------------------------------------------------------- 1 | service firebase.storage { 2 | match /b/{bucket}/o { 3 | match /{allPaths=**} { 4 | allow read, write: if false; 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /whatsapp/whatsapp-demo.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | const { getTodaysMessage, sendMessageToGroup } = require('./functions/helpers'); 3 | 4 | (async () => { 5 | 6 | try { 7 | const path = require('path'); 8 | const browser = await puppeteer.launch({ headless: false, args: [`--user-data-dir=${path.resolve(__dirname, '.tmp')}`] }); 9 | const page = await browser.newPage(); 10 | 11 | try { 12 | await sendMessageToGroup(page, getTodaysMessage(), 'Bizimkiler', true); 13 | } finally { 14 | await page.close(); 15 | await browser.close(); 16 | } 17 | } catch(e) { 18 | console.error(e); 19 | process.exit(1); 20 | } 21 | })(); 22 | --------------------------------------------------------------------------------