diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index b26357f..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "image": "mcr.microsoft.com/devcontainers/universal:2", - "features": { - "ghcr.io/devcontainers-contrib/features/deno:1": {} - }, - "postCreateCommand": "npm install" -} diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 6e87a00..0000000 --- a/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Editor configuration, see http://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -max_line_length = off -trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 3c3629e..0000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 0be733b..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "root": true, - "ignorePatterns": ["**/*"], - "plugins": ["@nx"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": { - "@nx/enforce-module-boundaries": [ - "error", - { - "enforceBuildableLibDependency": true, - "allow": [], - "depConstraints": [ - { - "sourceTag": "*", - "onlyDependOnLibsWithTags": ["*"] - } - ] - } - ] - } - }, - { - "files": ["*.ts", "*.tsx"], - "extends": ["plugin:@nx/typescript"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "extends": ["plugin:@nx/javascript"], - "rules": {} - }, - { - "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], - "env": { - "jest": true - }, - "rules": {} - } - ] -} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c832ba4..0000000 --- a/.gitignore +++ /dev/null @@ -1,55 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. - -# compiled output -# https://theapache64.github.io/git-do-not-ignore/ -!dist/ -dist/* -!dist/apps/ -dist/apps/* -!dist/apps/cf-page -!dist/apps/node-vless - -tmp -/out-tsc - -# dependencies -node_modules - -# IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# IDE - VSCode -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -# misc -/.sass-cache -/connect.lock -/coverage -/libpeerconnection.log -npm-debug.log -yarn-error.log -testem.log -/typings - -# System Files -.DS_Store -Thumbs.db - -## -**/config-local.json - -**/.env - -**/.dev.vars -wrangler.toml -.npmrc diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index d0b804d..0000000 --- a/.prettierignore +++ /dev/null @@ -1,4 +0,0 @@ -# Add files here to ignore them from prettier formatting - -/dist -/coverage diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 544138b..0000000 --- a/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "singleQuote": true -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 2f66f4a..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "recommendations": [ - "nrwl.angular-console", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - "firsttris.vscode-jest-runner", - "denoland.vscode-deno", - "GitHub.copilot", - "GitHub.copilot-labs", - "eamodio.gitlens" - ] -} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 8a8c05e..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Attach by Process ID", - "processId": "${command:PickProcess}", - "request": "attach", - "skipFiles": ["/**"], - "type": "node" - }, - { - "request": "launch", - "name": "Launch Program", - "type": "pwa-node", - "program": "C:\\github\\test-deno\\apps\\deno-vless\\src\\main.ts", - "cwd": "${workspaceFolder}", - "runtimeExecutable": "C:\\Users\\zizifn\\scoop\\shims\\deno.EXE", - "runtimeArgs": ["run", "--inspect", "--allow-all", "--unstable"], - "attachSimplePort": 9229, - "env": { - "UUID": "e0a102c8-51c8-436c-860b-ef279d8a6ada" - } - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index dc74292..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "deno.codeLens.implementations": true, - "deno.codeLens.references": true, - "deno.enablePaths": [ - "apps/deno-vless/src/deno", - "apps/deno-vless/src/main.ts", - "apps/deno-vless/src/deno-test.ts", - "apps/deno-vless2" - ], - "deno.unstable": true, - "deno.importMap": "./import_map.json" -} diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index a566f66..0000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM node:slim - -ENV NODE_ENV=production -ENV PORT=4100 - -WORKDIR /app - -COPY dist dist/ - -EXPOSE 4100 - -CMD [ "node", "./dist/apps/node-vless/main.js" ] \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d159169..0000000 --- a/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/README.md b/README.md index 37b14bc..2283a57 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,3 @@ -# Edge Tunnel(Beta) +Delete code, but keep the project for the sake of memories. I'm only create this project for fun, for try new things and for learn by doing. **I'm even not write any outside marketing post for this project. Just for my own fun...** But I feel emotional damage by the community. -Running **V2ray** in the edge/serverless runtime. - -# Documentation - -**!!If your find project can't use, please check the your deploy page and rescan the QRcode!!!!** - -https://edgetunnel.114567.xyz/ - -# Feedback - -If you have any questions, please open GitHub issue or use https://t.me/edgetunnel for communication. +删除代码。为了回忆保留项目。我只是出于娱乐、尝试新事物和学习的目的创建这个项目。我甚至没有为这个项目撰写任何外部营销文章。只是为了我自己的乐趣... 但是,我感到受到社区的情感伤害。 diff --git a/apps/cf-page-vless/.eslintrc.json b/apps/cf-page-vless/.eslintrc.json deleted file mode 100644 index a39ac5d..0000000 --- a/apps/cf-page-vless/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": ["plugin:@nx/react", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/apps/cf-page-vless/index.html b/apps/cf-page-vless/index.html deleted file mode 100644 index a44b803..0000000 --- a/apps/cf-page-vless/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Edge Tunnel VLESS CF - - - - - - - - -
- - - diff --git a/apps/cf-page-vless/postcss.config.js b/apps/cf-page-vless/postcss.config.js deleted file mode 100644 index c72626d..0000000 --- a/apps/cf-page-vless/postcss.config.js +++ /dev/null @@ -1,15 +0,0 @@ -const { join } = require('path'); - -// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build -// option from your application's configuration (i.e. project.json). -// -// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries - -module.exports = { - plugins: { - tailwindcss: { - config: join(__dirname, 'tailwind.config.js'), - }, - autoprefixer: {}, - }, -}; diff --git a/apps/cf-page-vless/project.json b/apps/cf-page-vless/project.json deleted file mode 100644 index 4938385..0000000 --- a/apps/cf-page-vless/project.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "cf-page-vless", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/cf-page-vless/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nx/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { - "outputPath": "dist/apps/cf-page-vless" - }, - "configurations": { - "development": { - "mode": "development" - }, - "production": { - "mode": "production" - } - } - }, - "serve": { - "executor": "@nx/vite:dev-server", - "defaultConfiguration": "development", - "options": { - "buildTarget": "cf-page-vless:build" - }, - "configurations": { - "development": { - "buildTarget": "cf-page-vless:build:development", - "hmr": true - }, - "production": { - "buildTarget": "cf-page-vless:build:production", - "hmr": false - } - } - }, - "serve-cf-page": { - "executor": "nx:run-commands", - "options": { - "command": "wrangler pages dev dist/apps/cf-page-vless" - }, - "dependsOn": ["^build"] - }, - "test": { - "executor": "@nx/vite:test", - "outputs": ["{projectRoot}/coverage"], - "options": { - "passWithNoTests": true - } - }, - "lint": { - "executor": "@nx/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/cf-page-vless/**/*.{ts,tsx,js,jsx}"] - } - } - }, - "tags": [] -} diff --git a/apps/cf-page-vless/public/401.html b/apps/cf-page-vless/public/401.html deleted file mode 100644 index 05471a6..0000000 --- a/apps/cf-page-vless/public/401.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - 401 - UUID Not Valid - - - -

Not set valid UUID in Environment Variables.

-

- Please use tool to generate and - remember UUID or use this one - -

-

- You must use same UUID for login this page after config valid UUID - Environment Variables -

-

- Please refer to - deno deploy guide -

- - - diff --git a/apps/cf-page-vless/public/favicon.ico b/apps/cf-page-vless/public/favicon.ico deleted file mode 100644 index 317ebcb..0000000 Binary files a/apps/cf-page-vless/public/favicon.ico and /dev/null differ diff --git a/apps/cf-page-vless/src/app/app.module.css b/apps/cf-page-vless/src/app/app.module.css deleted file mode 100644 index 7b88fba..0000000 --- a/apps/cf-page-vless/src/app/app.module.css +++ /dev/null @@ -1 +0,0 @@ -/* Your styles goes here. */ diff --git a/apps/cf-page-vless/src/app/app.spec.tsx b/apps/cf-page-vless/src/app/app.spec.tsx deleted file mode 100644 index 1fcd97b..0000000 --- a/apps/cf-page-vless/src/app/app.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { render } from '@testing-library/react'; - -import App from './app'; - -describe('App', () => { - it('should render successfully', () => { - const { baseElement } = render(); - - expect(baseElement).toBeTruthy(); - }); - - it('should have a greeting as the title', () => { - const { getByText } = render(); - - expect(getByText(/Welcome cf-page/gi)).toBeTruthy(); - }); -}); diff --git a/apps/cf-page-vless/src/app/app.tsx b/apps/cf-page-vless/src/app/app.tsx deleted file mode 100644 index 529195e..0000000 --- a/apps/cf-page-vless/src/app/app.tsx +++ /dev/null @@ -1,12 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import styles from './app.module.css'; - -export function App() { - return ( - <> -
- - ); -} - -export default App; diff --git a/apps/cf-page-vless/src/assets/.gitkeep b/apps/cf-page-vless/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/cf-page-vless/src/main.tsx b/apps/cf-page-vless/src/main.tsx deleted file mode 100644 index f0d9210..0000000 --- a/apps/cf-page-vless/src/main.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { StrictMode } from 'react'; -import * as ReactDOM from 'react-dom/client'; - -// import App from './app/app'; -import { EdgeApp } from 'edge-ui'; - -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -); -root.render( - - - -); diff --git a/apps/cf-page-vless/src/styles.css b/apps/cf-page-vless/src/styles.css deleted file mode 100644 index f477788..0000000 --- a/apps/cf-page-vless/src/styles.css +++ /dev/null @@ -1,4 +0,0 @@ -@tailwind components; -@tailwind base; -@tailwind utilities; -/* You can add global styles to this file, and also import other style files */ diff --git a/apps/cf-page-vless/tailwind.config.js b/apps/cf-page-vless/tailwind.config.js deleted file mode 100644 index ffa4bde..0000000 --- a/apps/cf-page-vless/tailwind.config.js +++ /dev/null @@ -1,18 +0,0 @@ -const { createGlobPatternsForDependencies } = require('@nx/react/tailwind'); -const { join } = require('path'); - -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: [ - join( - __dirname, - '{src,pages,components}/**/*!(*.stories|*.spec).{ts,tsx,html}' - ), - ...createGlobPatternsForDependencies(__dirname), - 'libs/edge-ui/src/lib/*.tsx', - ], - theme: { - extend: {}, - }, - plugins: [], -}; diff --git a/apps/cf-page-vless/tsconfig.app.json b/apps/cf-page-vless/tsconfig.app.json deleted file mode 100644 index 116fc93..0000000 --- a/apps/cf-page-vless/tsconfig.app.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": ["node"] - }, - "files": [ - "../../node_modules/@nx/react/typings/cssmodule.d.ts", - "../../node_modules/@nx/react/typings/image.d.ts" - ], - "exclude": [ - "src/**/*.spec.ts", - "src/**/*.test.ts", - "src/**/*.spec.tsx", - "src/**/*.test.tsx", - "src/**/*.spec.js", - "src/**/*.test.js", - "src/**/*.spec.jsx", - "src/**/*.test.jsx" - ], - "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] -} diff --git a/apps/cf-page-vless/tsconfig.json b/apps/cf-page-vless/tsconfig.json deleted file mode 100644 index b1de769..0000000 --- a/apps/cf-page-vless/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "jsx": "react-jsx", - "allowJs": false, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, - "strict": true, - "types": ["vite/client"] - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - } - ], - "extends": "../../tsconfig.base.json" -} diff --git a/apps/cf-page-vless/tsconfig.spec.json b/apps/cf-page-vless/tsconfig.spec.json deleted file mode 100644 index 776f451..0000000 --- a/apps/cf-page-vless/tsconfig.spec.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": ["vitest/globals", "node"] - }, - "include": [ - "vite.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.test.tsx", - "src/**/*.spec.tsx", - "src/**/*.test.js", - "src/**/*.spec.js", - "src/**/*.test.jsx", - "src/**/*.spec.jsx", - "src/**/*.d.ts" - ], - "files": [ - "../../node_modules/@nx/react/typings/cssmodule.d.ts", - "../../node_modules/@nx/react/typings/image.d.ts" - ] -} diff --git a/apps/cf-page-vless/vite.config.ts b/apps/cf-page-vless/vite.config.ts deleted file mode 100644 index afb7b3d..0000000 --- a/apps/cf-page-vless/vite.config.ts +++ /dev/null @@ -1,26 +0,0 @@ -/// -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import viteTsConfigPaths from 'vite-tsconfig-paths'; - -export default defineConfig({ - server: { - port: 4200, - host: 'localhost', - }, - plugins: [ - react(), - viteTsConfigPaths({ - root: '../../', - }), - ], - - test: { - globals: true, - cache: { - dir: '../../node_modules/.vitest', - }, - environment: 'jsdom', - include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], - }, -}); diff --git a/apps/deno-vless/deno-bunled.js b/apps/deno-vless/deno-bunled.js deleted file mode 100644 index 1c4a6a6..0000000 --- a/apps/deno-vless/deno-bunled.js +++ /dev/null @@ -1,975 +0,0 @@ -// deno-fmt-ignore-file -// deno-lint-ignore-file -// This code was bundled using `deno bundle` and it's not recommended to edit it manually - -function deferred() { - let methods; - let state = "pending"; - const promise = new Promise((resolve, reject)=>{ - methods = { - async resolve (value) { - await value; - state = "fulfilled"; - resolve(value); - }, - reject (reason) { - state = "rejected"; - reject(reason); - } - }; - }); - Object.defineProperty(promise, "state", { - get: ()=>state - }); - return Object.assign(promise, methods); -} -function delay(ms, options = {}) { - const { signal , persistent } = options; - if (signal?.aborted) { - return Promise.reject(new DOMException("Delay was aborted.", "AbortError")); - } - return new Promise((resolve, reject)=>{ - const abort = ()=>{ - clearTimeout(i); - reject(new DOMException("Delay was aborted.", "AbortError")); - }; - const done = ()=>{ - signal?.removeEventListener("abort", abort); - resolve(); - }; - const i = setTimeout(done, ms); - signal?.addEventListener("abort", abort, { - once: true - }); - if (persistent === false) { - try { - Deno.unrefTimer(i); - } catch (error) { - if (!(error instanceof ReferenceError)) { - throw error; - } - console.error("`persistent` option is only available in Deno"); - } - } - }); -} -class MuxAsyncIterator { - #iteratorCount = 0; - #yields = []; - #throws = []; - #signal = deferred(); - add(iterable) { - ++this.#iteratorCount; - this.#callIteratorNext(iterable[Symbol.asyncIterator]()); - } - async #callIteratorNext(iterator) { - try { - const { value , done } = await iterator.next(); - if (done) { - --this.#iteratorCount; - } else { - this.#yields.push({ - iterator, - value - }); - } - } catch (e) { - this.#throws.push(e); - } - this.#signal.resolve(); - } - async *iterate() { - while(this.#iteratorCount > 0){ - await this.#signal; - for(let i = 0; i < this.#yields.length; i++){ - const { iterator , value } = this.#yields[i]; - yield value; - this.#callIteratorNext(iterator); - } - if (this.#throws.length) { - for (const e of this.#throws){ - throw e; - } - this.#throws.length = 0; - } - this.#yields.length = 0; - this.#signal = deferred(); - } - } - [Symbol.asyncIterator]() { - return this.iterate(); - } -} -const ERROR_SERVER_CLOSED = "Server closed"; -const INITIAL_ACCEPT_BACKOFF_DELAY = 5; -const MAX_ACCEPT_BACKOFF_DELAY = 1000; -class Server { - #port; - #host; - #handler; - #closed = false; - #listeners = new Set(); - #acceptBackoffDelayAbortController = new AbortController(); - #httpConnections = new Set(); - #onError; - constructor(serverInit){ - this.#port = serverInit.port; - this.#host = serverInit.hostname; - this.#handler = serverInit.handler; - this.#onError = serverInit.onError ?? function(error) { - console.error(error); - return new Response("Internal Server Error", { - status: 500 - }); - }; - } - async serve(listener) { - if (this.#closed) { - throw new Deno.errors.Http(ERROR_SERVER_CLOSED); - } - this.#trackListener(listener); - try { - return await this.#accept(listener); - } finally{ - this.#untrackListener(listener); - try { - listener.close(); - } catch {} - } - } - async listenAndServe() { - if (this.#closed) { - throw new Deno.errors.Http(ERROR_SERVER_CLOSED); - } - const listener = Deno.listen({ - port: this.#port ?? 80, - hostname: this.#host ?? "0.0.0.0", - transport: "tcp" - }); - return await this.serve(listener); - } - async listenAndServeTls(certFile, keyFile) { - if (this.#closed) { - throw new Deno.errors.Http(ERROR_SERVER_CLOSED); - } - const listener = Deno.listenTls({ - port: this.#port ?? 443, - hostname: this.#host ?? "0.0.0.0", - certFile, - keyFile, - transport: "tcp" - }); - return await this.serve(listener); - } - close() { - if (this.#closed) { - throw new Deno.errors.Http(ERROR_SERVER_CLOSED); - } - this.#closed = true; - for (const listener of this.#listeners){ - try { - listener.close(); - } catch {} - } - this.#listeners.clear(); - this.#acceptBackoffDelayAbortController.abort(); - for (const httpConn of this.#httpConnections){ - this.#closeHttpConn(httpConn); - } - this.#httpConnections.clear(); - } - get closed() { - return this.#closed; - } - get addrs() { - return Array.from(this.#listeners).map((listener)=>listener.addr); - } - async #respond(requestEvent, connInfo) { - let response; - try { - response = await this.#handler(requestEvent.request, connInfo); - if (response.bodyUsed && response.body !== null) { - throw new TypeError("Response body already consumed."); - } - } catch (error) { - response = await this.#onError(error); - } - try { - await requestEvent.respondWith(response); - } catch {} - } - async #serveHttp(httpConn, connInfo1) { - while(!this.#closed){ - let requestEvent; - try { - requestEvent = await httpConn.nextRequest(); - } catch { - break; - } - if (requestEvent === null) { - break; - } - this.#respond(requestEvent, connInfo1); - } - this.#closeHttpConn(httpConn); - } - async #accept(listener) { - let acceptBackoffDelay; - while(!this.#closed){ - let conn; - try { - conn = await listener.accept(); - } catch (error) { - if (error instanceof Deno.errors.BadResource || error instanceof Deno.errors.InvalidData || error instanceof Deno.errors.UnexpectedEof || error instanceof Deno.errors.ConnectionReset || error instanceof Deno.errors.NotConnected) { - if (!acceptBackoffDelay) { - acceptBackoffDelay = INITIAL_ACCEPT_BACKOFF_DELAY; - } else { - acceptBackoffDelay *= 2; - } - if (acceptBackoffDelay >= 1000) { - acceptBackoffDelay = MAX_ACCEPT_BACKOFF_DELAY; - } - try { - await delay(acceptBackoffDelay, { - signal: this.#acceptBackoffDelayAbortController.signal - }); - } catch (err) { - if (!(err instanceof DOMException && err.name === "AbortError")) { - throw err; - } - } - continue; - } - throw error; - } - acceptBackoffDelay = undefined; - let httpConn; - try { - httpConn = Deno.serveHttp(conn); - } catch { - continue; - } - this.#trackHttpConnection(httpConn); - const connInfo = { - localAddr: conn.localAddr, - remoteAddr: conn.remoteAddr - }; - this.#serveHttp(httpConn, connInfo); - } - } - #closeHttpConn(httpConn1) { - this.#untrackHttpConnection(httpConn1); - try { - httpConn1.close(); - } catch {} - } - #trackListener(listener1) { - this.#listeners.add(listener1); - } - #untrackListener(listener2) { - this.#listeners.delete(listener2); - } - #trackHttpConnection(httpConn2) { - this.#httpConnections.add(httpConn2); - } - #untrackHttpConnection(httpConn3) { - this.#httpConnections.delete(httpConn3); - } -} -function hostnameForDisplay(hostname) { - return hostname === "0.0.0.0" ? "localhost" : hostname; -} -async function serve(handler, options = {}) { - let port = options.port ?? 8000; - const hostname = options.hostname ?? "0.0.0.0"; - const server = new Server({ - port, - hostname, - handler, - onError: options.onError - }); - options?.signal?.addEventListener("abort", ()=>server.close(), { - once: true - }); - const s = server.listenAndServe(); - port = server.addrs[0].port; - if ("onListen" in options) { - options.onListen?.({ - port, - hostname - }); - } else { - console.log(`Listening on http://${hostnameForDisplay(hostname)}:${port}/`); - } - return await s; -} -new Uint8Array(16); -var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; -function validate(uuid) { - return typeof uuid === 'string' && REGEX.test(uuid); -} -const byteToHex = []; -for(let i = 0; i < 256; ++i){ - byteToHex.push((i + 0x100).toString(16).slice(1)); -} -function unsafeStringify(arr, offset = 0) { - return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); -} -function stringify(arr, offset = 0) { - const uuid = unsafeStringify(arr, offset); - if (!validate(uuid)) { - throw TypeError('Stringified UUID is invalid'); - } - return uuid; -} -function parse(uuid) { - if (!validate(uuid)) { - throw TypeError('Invalid UUID'); - } - let v; - const arr = new Uint8Array(16); - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 0xff; - arr[2] = v >>> 8 & 0xff; - arr[3] = v & 0xff; - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 0xff; - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 0xff; - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 0xff; - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; - arr[11] = v / 0x100000000 & 0xff; - arr[12] = v >>> 24 & 0xff; - arr[13] = v >>> 16 & 0xff; - arr[14] = v >>> 8 & 0xff; - arr[15] = v & 0xff; - return arr; -} -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); - const bytes = []; - for(let i = 0; i < str.length; ++i){ - bytes.push(str.charCodeAt(i)); - } - return bytes; -} -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -const URL1 = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -function v35(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - var _namespace; - if (typeof value === 'string') { - value = stringToBytes(value); - } - if (typeof namespace === 'string') { - namespace = parse(namespace); - } - if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - if (buf) { - offset = offset || 0; - for(let i = 0; i < 16; ++i){ - buf[offset + i] = bytes[i]; - } - return buf; - } - return unsafeStringify(bytes); - } - try { - generateUUID.name = name; - } catch (err) {} - generateUUID.DNS = DNS; - generateUUID.URL = URL1; - return generateUUID; -} -function md5(bytes) { - if (typeof bytes === 'string') { - const msg = unescape(encodeURIComponent(bytes)); - bytes = new Uint8Array(msg.length); - for(let i = 0; i < msg.length; ++i){ - bytes[i] = msg.charCodeAt(i); - } - } - return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8)); -} -function md5ToHexEncodedArray(input) { - const output = []; - const length32 = input.length * 32; - const hexTab = '0123456789abcdef'; - for(let i = 0; i < length32; i += 8){ - const x = input[i >> 5] >>> i % 32 & 0xff; - const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16); - output.push(hex); - } - return output; -} -function getOutputLength(inputLength8) { - return (inputLength8 + 64 >>> 9 << 4) + 14 + 1; -} -function wordsToMd5(x, len) { - x[len >> 5] |= 0x80 << len % 32; - x[getOutputLength(len) - 1] = len; - let a = 1732584193; - let b = -271733879; - let c = -1732584194; - let d = 271733878; - for(let i = 0; i < x.length; i += 16){ - const olda = a; - const oldb = b; - const oldc = c; - const oldd = d; - a = md5ff(a, b, c, d, x[i], 7, -680876936); - d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); - c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); - b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); - a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); - d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); - c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); - b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); - a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); - d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); - c = md5ff(c, d, a, b, x[i + 10], 17, -42063); - b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); - a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); - d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); - c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); - b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); - a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); - d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); - c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); - b = md5gg(b, c, d, a, x[i], 20, -373897302); - a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); - d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); - c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); - b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); - a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); - d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); - c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); - b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); - a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); - d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); - c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); - b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); - a = md5hh(a, b, c, d, x[i + 5], 4, -378558); - d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); - c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); - b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); - a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); - d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); - c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); - b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); - a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); - d = md5hh(d, a, b, c, x[i], 11, -358537222); - c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); - b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); - a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); - d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); - c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); - b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); - a = md5ii(a, b, c, d, x[i], 6, -198630844); - d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); - c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); - b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); - a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); - d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); - c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); - b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); - a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); - d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); - c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); - b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); - a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); - d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); - c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); - b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); - a = safeAdd(a, olda); - b = safeAdd(b, oldb); - c = safeAdd(c, oldc); - d = safeAdd(d, oldd); - } - return [ - a, - b, - c, - d - ]; -} -function bytesToWords(input) { - if (input.length === 0) { - return []; - } - const length8 = input.length * 8; - const output = new Uint32Array(getOutputLength(length8)); - for(let i = 0; i < length8; i += 8){ - output[i >> 5] |= (input[i / 8] & 0xff) << i % 32; - } - return output; -} -function safeAdd(x, y) { - const lsw = (x & 0xffff) + (y & 0xffff); - const msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return msw << 16 | lsw & 0xffff; -} -function bitRotateLeft(num, cnt) { - return num << cnt | num >>> 32 - cnt; -} -function md5cmn(q, a, b, x, s, t) { - return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); -} -function md5ff(a, b, c, d, x, s, t) { - return md5cmn(b & c | ~b & d, a, b, x, s, t); -} -function md5gg(a, b, c, d, x, s, t) { - return md5cmn(b & d | c & ~d, a, b, x, s, t); -} -function md5hh(a, b, c, d, x, s, t) { - return md5cmn(b ^ c ^ d, a, b, x, s, t); -} -function md5ii(a, b, c, d, x, s, t) { - return md5cmn(c ^ (b | ~d), a, b, x, s, t); -} -v35('v3', 0x30, md5); -typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); -function f(s, x, y, z) { - switch(s){ - case 0: - return x & y ^ ~x & z; - case 1: - return x ^ y ^ z; - case 2: - return x & y ^ x & z ^ y & z; - case 3: - return x ^ y ^ z; - } -} -function ROTL(x, n) { - return x << n | x >>> 32 - n; -} -function sha1(bytes) { - const K = [ - 0x5a827999, - 0x6ed9eba1, - 0x8f1bbcdc, - 0xca62c1d6 - ]; - const H = [ - 0x67452301, - 0xefcdab89, - 0x98badcfe, - 0x10325476, - 0xc3d2e1f0 - ]; - if (typeof bytes === 'string') { - const msg = unescape(encodeURIComponent(bytes)); - bytes = []; - for(let i = 0; i < msg.length; ++i){ - bytes.push(msg.charCodeAt(i)); - } - } else if (!Array.isArray(bytes)) { - bytes = Array.prototype.slice.call(bytes); - } - bytes.push(0x80); - const l = bytes.length / 4 + 2; - const N = Math.ceil(l / 16); - const M = new Array(N); - for(let i = 0; i < N; ++i){ - const arr = new Uint32Array(16); - for(let j = 0; j < 16; ++j){ - arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3]; - } - M[i] = arr; - } - M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32); - M[N - 1][14] = Math.floor(M[N - 1][14]); - M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff; - for(let i = 0; i < N; ++i){ - const W = new Uint32Array(80); - for(let t = 0; t < 16; ++t){ - W[t] = M[i][t]; - } - for(let t = 16; t < 80; ++t){ - W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); - } - let a = H[0]; - let b = H[1]; - let c = H[2]; - let d = H[3]; - let e = H[4]; - for(let t = 0; t < 80; ++t){ - const s = Math.floor(t / 20); - const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0; - e = d; - d = c; - c = ROTL(b, 30) >>> 0; - b = a; - a = T; - } - H[0] = H[0] + a >>> 0; - H[1] = H[1] + b >>> 0; - H[2] = H[2] + c >>> 0; - H[3] = H[3] + d >>> 0; - H[4] = H[4] + e >>> 0; - } - return [ - H[0] >> 24 & 0xff, - H[0] >> 16 & 0xff, - H[0] >> 8 & 0xff, - H[0] & 0xff, - H[1] >> 24 & 0xff, - H[1] >> 16 & 0xff, - H[1] >> 8 & 0xff, - H[1] & 0xff, - H[2] >> 24 & 0xff, - H[2] >> 16 & 0xff, - H[2] >> 8 & 0xff, - H[2] & 0xff, - H[3] >> 24 & 0xff, - H[3] >> 16 & 0xff, - H[3] >> 8 & 0xff, - H[3] & 0xff, - H[4] >> 24 & 0xff, - H[4] >> 16 & 0xff, - H[4] >> 8 & 0xff, - H[4] & 0xff - ]; -} -v35('v5', 0x50, sha1); -async function serveClient(req, basePath) { - const url = new URL(req.url); - if (url.pathname.startsWith('/assets') || url.pathname.includes(basePath)) { - let targetUrl = `https://raw.githubusercontent.com/zizifn/edgetunnel/main/dist/apps/cf-page${url.pathname}`; - if (url.pathname.includes(basePath)) { - targetUrl = `https://raw.githubusercontent.com/zizifn/edgetunnel/main/dist/apps/cf-page/index.html`; - } - console.log(targetUrl); - const resp = await fetch(targetUrl); - const modifiedHeaders = new Headers(resp.headers); - modifiedHeaders.delete('content-security-policy'); - if (url.pathname.endsWith('.js')) { - modifiedHeaders.set('content-type', 'application/javascript'); - } else if (url.pathname.endsWith('.css')) { - modifiedHeaders.set('content-type', 'text/css'); - } else if (url.pathname.includes(basePath)) { - modifiedHeaders.set('content-type', 'text/html; charset=utf-8'); - } - return new Response(resp.body, { - status: resp.status, - headers: modifiedHeaders - }); - } - const basicAuth = req.headers.get('Authorization') || ''; - const authString = basicAuth.split(' ')?.[1] || ''; - if (atob(authString).includes(basePath)) { - console.log('302'); - return new Response(``, { - status: 302, - headers: { - 'content-type': 'text/html; charset=utf-8', - Location: `./${basePath}` - } - }); - } else { - return new Response(``, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic' - } - }); - } -} -function delay1(ms) { - return new Promise((resolve, rej)=>{ - setTimeout(resolve, ms); - }); -} -function makeReadableWebSocketStream(ws, earlyDataHeader, log) { - let readableStreamCancel = false; - return new ReadableStream({ - start (controller) { - ws.addEventListener('message', async (e)=>{ - if (readableStreamCancel) { - return; - } - const vlessBuffer = e.data; - controller.enqueue(vlessBuffer); - }); - ws.addEventListener('error', (e)=>{ - log('socket has error'); - readableStreamCancel = true; - controller.error(e); - }); - ws.addEventListener('close', ()=>{ - try { - log('webSocket is close'); - if (readableStreamCancel) { - return; - } - controller.close(); - } catch (error) { - log(`websocketStream can't close DUE to `, error); - } - }); - const { earlyData , error } = base64ToArrayBuffer(earlyDataHeader); - if (error) { - log(`earlyDataHeader has invaild base64`); - closeWebSocket(ws); - return; - } - if (earlyData) { - controller.enqueue(earlyData); - } - }, - pull (controller) {}, - cancel (reason) { - log(`websocketStream is cancel DUE to `, reason); - if (readableStreamCancel) { - return; - } - readableStreamCancel = true; - closeWebSocket(ws); - } - }); -} -function base64ToArrayBuffer(base64Str) { - if (!base64Str) { - return { - error: null - }; - } - try { - base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/'); - const decode = atob(base64Str); - const arryBuffer = Uint8Array.from(decode, (c)=>c.charCodeAt(0)); - return { - earlyData: arryBuffer.buffer, - error: null - }; - } catch (error) { - return { - error - }; - } -} -function closeWebSocket(socket) { - if (socket.readyState === socket.OPEN) { - socket.close(); - } -} -function processVlessHeader(vlessBuffer, userID) { - if (vlessBuffer.byteLength < 24) { - return { - hasError: true, - message: 'invalid data' - }; - } - const version = new Uint8Array(vlessBuffer.slice(0, 1)); - let isValidUser = false; - let isUDP = false; - if (stringify(new Uint8Array(vlessBuffer.slice(1, 17))) === userID) { - isValidUser = true; - } - if (!isValidUser) { - return { - hasError: true, - message: 'invalid user' - }; - } - const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0]; - const command = new Uint8Array(vlessBuffer.slice(18 + optLength, 18 + optLength + 1))[0]; - if (command === 1) {} else if (command === 2) { - isUDP = true; - } else { - return { - hasError: true, - message: `command ${command} is not support, command 01-tcp,02-udp,03-mux` - }; - } - const portIndex = 18 + optLength + 1; - const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2); - const portRemote = new DataView(portBuffer).getInt16(0); - let addressIndex = portIndex + 2; - const addressBuffer = new Uint8Array(vlessBuffer.slice(addressIndex, addressIndex + 1)); - const addressType = addressBuffer[0]; - let addressLength = 0; - let addressValueIndex = addressIndex + 1; - let addressValue = ''; - switch(addressType){ - case 1: - addressLength = 4; - addressValue = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)).join('.'); - break; - case 2: - addressLength = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + 1))[0]; - addressValueIndex += 1; - addressValue = new TextDecoder().decode(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); - break; - case 3: - addressLength = 16; - const dataView = new DataView(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); - const ipv6 = []; - for(let i = 0; i < 8; i++){ - ipv6.push(dataView.getUint16(i * 2).toString(16)); - } - addressValue = ipv6.join(':'); - break; - default: - console.log(`invild addressType is ${addressType}`); - } - if (!addressValue) { - return { - hasError: true, - message: `addressValue is empty, addressType is ${addressType}` - }; - } - return { - hasError: false, - addressRemote: addressValue, - portRemote, - rawDataIndex: addressValueIndex + addressLength, - vlessVersion: version, - isUDP - }; -} -const userID = Deno.env.get('UUID') || ''; -let isVaildUser = validate(userID); -if (!isVaildUser) { - console.log('not set valid UUID'); -} -const handler = async (req)=>{ - if (!isVaildUser) { - const index401 = await Deno.readFile(`${Deno.cwd()}/dist/apps/cf-page/401.html`); - return new Response(index401, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8' - } - }); - } - const upgrade = req.headers.get('upgrade') || ''; - if (upgrade.toLowerCase() != 'websocket') { - return await serveClient(req, userID); - } - const { socket , response } = Deno.upgradeWebSocket(req); - socket.addEventListener('open', ()=>{}); - const earlyDataHeader = req.headers.get('sec-websocket-protocol') || ''; - processWebSocket({ - userID, - webSocket: socket, - earlyDataHeader - }); - return response; -}; -async function processWebSocket({ userID , webSocket , earlyDataHeader }) { - let address = ''; - let portWithRandomLog = ''; - let remoteConnection = null; - let remoteConnectionReadyResolve; - try { - const log = (info, event)=>{ - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log); - let vlessResponseHeader = null; - readableWebSocketStream.pipeTo(new WritableStream({ - async write (chunk, controller) { - const vlessBuffer = chunk; - if (remoteConnection) { - await remoteConnection.write(new Uint8Array(vlessBuffer)); - return; - } - const { hasError , message , portRemote , addressRemote , rawDataIndex , vlessVersion , isUDP } = processVlessHeader(vlessBuffer, userID); - address = addressRemote || ''; - portWithRandomLog = `${portRemote}--${Math.random()}`; - if (isUDP) { - console.log('udp'); - controller.error(`[${address}:${portWithRandomLog}] command udp is not support `); - return; - } - if (hasError) { - controller.error(`[${address}:${portWithRandomLog}] ${message} `); - } - console.log(`[${address}:${portWithRandomLog}] connecting`); - remoteConnection = await Deno.connect({ - port: portRemote, - hostname: address - }); - vlessResponseHeader = new Uint8Array([ - vlessVersion[0], - 0 - ]); - const rawClientData = vlessBuffer.slice(rawDataIndex); - await remoteConnection.write(new Uint8Array(rawClientData)); - remoteConnectionReadyResolve(remoteConnection); - }, - close () { - console.log(`[${address}:${portWithRandomLog}] readableWebSocketStream is close`); - }, - abort (reason) { - console.log(`[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, JSON.stringify(reason)); - } - })).catch((error)=>{ - console.error(`[${address}:${portWithRandomLog}] readableWebSocketStream pipeto has exception`, error.stack || error); - }); - await new Promise((resolve)=>remoteConnectionReadyResolve = resolve); - let remoteChunkCount = 0; - await remoteConnection.readable.pipeTo(new WritableStream({ - start () { - if (webSocket.readyState === webSocket.OPEN) { - webSocket.send(vlessResponseHeader); - } - }, - async write (chunk, controller) { - function send2WebSocket() { - if (webSocket.readyState !== webSocket.OPEN) { - controller.error(`can't accept data from remoteConnection!.readable when client webSocket is close early`); - return; - } - webSocket.send(chunk); - } - remoteChunkCount++; - if (remoteChunkCount < 20) { - send2WebSocket(); - } else if (remoteChunkCount < 120) { - await delay1(10); - send2WebSocket(); - } else if (remoteChunkCount < 500) { - await delay1(20); - send2WebSocket(); - } else { - await delay1(50); - send2WebSocket(); - } - }, - close () { - console.log(`[${address}:${portWithRandomLog}] remoteConnection!.readable is close`); - }, - abort (reason) { - closeWebSocket(webSocket); - console.error(`[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, reason); - } - })); - } catch (error) { - console.error(`[${address}:${portWithRandomLog}] processWebSocket has exception `, error.stack || error); - closeWebSocket(webSocket); - } - return; -} -globalThis.addEventListener('beforeunload', (e)=>{ - console.log('About to exit...'); -}); -globalThis.addEventListener('unload', (e)=>{ - console.log('Exiting'); -}); -serve(handler, { - port: 8080, - hostname: '0.0.0.0' -}); diff --git a/apps/deno-vless/deno.json b/apps/deno-vless/deno.json deleted file mode 100644 index 315d5ac..0000000 --- a/apps/deno-vless/deno.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "importMap": "../../import_map.json" -} diff --git a/apps/deno-vless/deno.lock b/apps/deno-vless/deno.lock deleted file mode 100644 index 654523e..0000000 --- a/apps/deno-vless/deno.lock +++ /dev/null @@ -1,539 +0,0 @@ -{ - "version": "2", - "remote": { - "https://deno.land/std@0.157.0/async/abortable.ts": "87aa7230be8360c24ad437212311c9e8d4328854baec27b4c7abb26e85515c06", - "https://deno.land/std@0.157.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0", - "https://deno.land/std@0.157.0/async/debounce.ts": "de5433bff08a2bb61416fc53b3bd2d5867090c8a815465e5b4a10a77495b1051", - "https://deno.land/std@0.157.0/async/deferred.ts": "c01de44b9192359cebd3fe93273fcebf9e95110bf3360023917da9a2d1489fae", - "https://deno.land/std@0.157.0/async/delay.ts": "0419dfc993752849692d1f9647edf13407c7facc3509b099381be99ffbc9d699", - "https://deno.land/std@0.157.0/async/mod.ts": "dd0a8ed4f3984ffabe2fcca7c9f466b7932d57b1864ffee148a5d5388316db6b", - "https://deno.land/std@0.157.0/async/mux_async_iterator.ts": "3447b28a2a582224a3d4d3596bccbba6e85040da3b97ed64012f7decce98d093", - "https://deno.land/std@0.157.0/async/pool.ts": "ef9eb97b388543acbf0ac32647121e4dbe629236899586c4d4311a8770fbb239", - "https://deno.land/std@0.157.0/async/tee.ts": "d27680d911816fcb3d231e16d690e7588079e66a9b2e5ce8cc354db94fdce95f", - "https://deno.land/std@0.157.0/http/server.ts": "c1bce1cbf4060055f622d5c3f0e406fd553e5dca111ca836d28c6268f170ebeb", - "https://deno.land/std@0.167.0/_util/asserts.ts": "d0844e9b62510f89ce1f9878b046f6a57bf88f208a10304aab50efcb48365272", - "https://deno.land/std@0.167.0/_util/os.ts": "8a33345f74990e627b9dfe2de9b040004b08ea5146c7c9e8fe9a29070d193934", - "https://deno.land/std@0.167.0/async/abortable.ts": "80b2ac399f142cc528f95a037a7d0e653296352d95c681e284533765961de409", - "https://deno.land/std@0.167.0/async/deadline.ts": "2c2deb53c7c28ca1dda7a3ad81e70508b1ebc25db52559de6b8636c9278fd41f", - "https://deno.land/std@0.167.0/async/debounce.ts": "60301ffb37e730cd2d6f9dadfd0ecb2a38857681bd7aaf6b0a106b06e5210a98", - "https://deno.land/std@0.167.0/async/deferred.ts": "77d3f84255c3627f1cc88699d8472b664d7635990d5358c4351623e098e917d6", - "https://deno.land/std@0.167.0/async/delay.ts": "5a9bfba8de38840308a7a33786a0155a7f6c1f7a859558ddcec5fe06e16daf57", - "https://deno.land/std@0.167.0/async/mod.ts": "7809ad4bb223e40f5fdc043e5c7ca04e0e25eed35c32c3c32e28697c553fa6d9", - "https://deno.land/std@0.167.0/async/mux_async_iterator.ts": "770a0ff26c59f8bbbda6b703a2235f04e379f73238e8d66a087edc68c2a2c35f", - "https://deno.land/std@0.167.0/async/pool.ts": "6854d8cd675a74c73391c82005cbbe4cc58183bddcd1fbbd7c2bcda42b61cf69", - "https://deno.land/std@0.167.0/async/retry.ts": "e8e5173623915bbc0ddc537698fa418cf875456c347eda1ed453528645b42e67", - "https://deno.land/std@0.167.0/async/tee.ts": "3a47cc4e9a940904fd4341f0224907e199121c80b831faa5ec2b054c6d2eff5e", - "https://deno.land/std@0.167.0/collections/_utils.ts": "fd759867be7a0047a1fa89ec89f7b58ebe3f2f7f089a8f4e416eb30c5d764868", - "https://deno.land/std@0.167.0/collections/deep_merge.ts": "0303cca7697646c5464ecb3337d494602056babae4f09baf6619f1043ba7eb6d", - "https://deno.land/std@0.167.0/crypto/_fnv/fnv32.ts": "aa9bddead8c6345087d3abd4ef35fb9655622afc333fc41fff382b36e64280b5", - "https://deno.land/std@0.167.0/crypto/_fnv/fnv64.ts": "625d7e7505b6cb2e9801b5fd6ed0a89256bac12b2bbb3e4664b85a88b0ec5bef", - "https://deno.land/std@0.167.0/crypto/_fnv/index.ts": "a8f6a361b4c6d54e5e89c16098f99b6962a1dd6ad1307dbc97fa1ecac5d7060a", - "https://deno.land/std@0.167.0/crypto/_fnv/util.ts": "4848313bed7f00f55be3cb080aa0583fc007812ba965b03e4009665bde614ce3", - "https://deno.land/std@0.167.0/crypto/_util.ts": "4a8cb74e7273d2400aa6da582ec58078cf8d54bc66530592048cbd7cc4152621", - "https://deno.land/std@0.167.0/crypto/_wasm/lib/deno_std_wasm_crypto.generated.mjs": "71c1ac20f32fdbdc9b31a14917779c7fa392dbc8b050059cbb2c35b400b975b1", - "https://deno.land/std@0.167.0/crypto/_wasm/mod.ts": "b49ec171049bbbaaed3c5a5a71dfcb3d09f880607c8d9c517638d0443bd0f874", - "https://deno.land/std@0.167.0/crypto/keystack.ts": "ee8ee58ca876f619cef56f40127405f77f9738f50a459b6ba44234b3a2cb6cc8", - "https://deno.land/std@0.167.0/crypto/mod.ts": "f953406904aa4257a6c76c40eb74b47d8dad83af8a77f33a4639cbac6d311baf", - "https://deno.land/std@0.167.0/crypto/timing_safe_equal.ts": "3784958e40a5fe10429a68b75cc5f8d34356bf0bc2eb93c80c3033e2a6f17821", - "https://deno.land/std@0.167.0/crypto/util.ts": "93fc9dbaa62421538ad60ee65337cbf1d8a0298fac3c4f70b37e5627e7e129eb", - "https://deno.land/std@0.167.0/encoding/base64.ts": "8605e018e49211efc767686f6f687827d7f5fd5217163e981d8d693105640d7a", - "https://deno.land/std@0.167.0/encoding/base64url.ts": "0283b12fcd306c11e3cf26fc022fecc800c6acc19704ea8bdb3908898fcd06d6", - "https://deno.land/std@0.167.0/encoding/hex.ts": "b51e99b684486a3ad2406807a8be953f5ef8bac95af202774a759f9fcf0d87a6", - "https://deno.land/std@0.167.0/flags/mod.ts": "4f50ec6383c02684db35de38b3ffb2cd5b9fcfcc0b1147055d1980c49e82521c", - "https://deno.land/std@0.167.0/fmt/colors.ts": "03ad95e543d2808bc43c17a3dd29d25b43d0f16287fe562a0be89bf632454a12", - "https://deno.land/std@0.167.0/http/file_server.ts": "369b5e4bb418e3ad6aae6d53102de292521604937acb3bfa27b90bbc59b50396", - "https://deno.land/std@0.167.0/http/http_status.ts": "ed24048cc0d06066c944da59b0301da3ae2f990564bb4ad79bb52a09cf8e9b30", - "https://deno.land/std@0.167.0/http/server.ts": "e99c1bee8a3f6571ee4cdeb2966efad465b8f6fe62bec1bdb59c1f007cc4d155", - "https://deno.land/std@0.167.0/http/util.ts": "759a2b57b44b722d2033d0dfe077f7e9a257f431db6d0319b78dcfebed0adb1e", - "https://deno.land/std@0.167.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", - "https://deno.land/std@0.167.0/media_types/mod.ts": "8c0447e561dd74fb26c52ad0df92d9f2ab170329a11a3f78498e3ea94c0590fd", - "https://deno.land/std@0.167.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", - "https://deno.land/std@0.167.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", - "https://deno.land/std@0.167.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", - "https://deno.land/std@0.167.0/path/_util.ts": "d16be2a16e1204b65f9d0dfc54a9bc472cafe5f4a190b3c8471ec2016ccd1677", - "https://deno.land/std@0.167.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", - "https://deno.land/std@0.167.0/path/glob.ts": "81cc6c72be002cd546c7a22d1f263f82f63f37fe0035d9726aa96fc8f6e4afa1", - "https://deno.land/std@0.167.0/path/mod.ts": "cf7cec7ac11b7048bb66af8ae03513e66595c279c65cfa12bfc07d9599608b78", - "https://deno.land/std@0.167.0/path/posix.ts": "b859684bc4d80edfd4cad0a82371b50c716330bed51143d6dcdbe59e6278b30c", - "https://deno.land/std@0.167.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", - "https://deno.land/std@0.167.0/path/win32.ts": "7cebd2bda6657371adc00061a1d23fdd87bcdf64b4843bb148b0b24c11b40f69", - "https://deno.land/std@0.167.0/version.ts": "06714d4f648ff89b814ffe8ccd3a67f80517b078e0c9367496b8ef8b7d31fbfc", - "https://deno.land/std@0.170.0/async/abortable.ts": "80b2ac399f142cc528f95a037a7d0e653296352d95c681e284533765961de409", - "https://deno.land/std@0.170.0/async/deadline.ts": "2c2deb53c7c28ca1dda7a3ad81e70508b1ebc25db52559de6b8636c9278fd41f", - "https://deno.land/std@0.170.0/async/debounce.ts": "60301ffb37e730cd2d6f9dadfd0ecb2a38857681bd7aaf6b0a106b06e5210a98", - "https://deno.land/std@0.170.0/async/deferred.ts": "77d3f84255c3627f1cc88699d8472b664d7635990d5358c4351623e098e917d6", - "https://deno.land/std@0.170.0/async/delay.ts": "5a9bfba8de38840308a7a33786a0155a7f6c1f7a859558ddcec5fe06e16daf57", - "https://deno.land/std@0.170.0/async/mod.ts": "7809ad4bb223e40f5fdc043e5c7ca04e0e25eed35c32c3c32e28697c553fa6d9", - "https://deno.land/std@0.170.0/async/mux_async_iterator.ts": "770a0ff26c59f8bbbda6b703a2235f04e379f73238e8d66a087edc68c2a2c35f", - "https://deno.land/std@0.170.0/async/pool.ts": "6854d8cd675a74c73391c82005cbbe4cc58183bddcd1fbbd7c2bcda42b61cf69", - "https://deno.land/std@0.170.0/async/retry.ts": "e8e5173623915bbc0ddc537698fa418cf875456c347eda1ed453528645b42e67", - "https://deno.land/std@0.170.0/async/tee.ts": "3a47cc4e9a940904fd4341f0224907e199121c80b831faa5ec2b054c6d2eff5e", - "https://deno.land/std@0.170.0/http/server.ts": "1b93c76cd415d7b6ad0ae36c17ccb9149b23f4dff018f7d5aa1ab5c36637eb45", - "https://jspm.dev/lodash-es": "bd969abe143ae52e316a482de288c33f697a78f113ecddd0893d75a668ea7d62", - "https://jspm.dev/npm:lodash-es@4.17.21/_/00eee99c.js": "37070aa0478b631d73a493088920e39e809c4c8887c4a5ede242ad8cbfb95758", - "https://jspm.dev/npm:lodash-es@4.17.21/_/01736674.js": "2bedb78993d68efec3a9f12a882f71679a2a361b3d25d714e293f8b5b2de51bc", - "https://jspm.dev/npm:lodash-es@4.17.21/_/02d6c299.js": "6fe98cef98517a9381fa22636fd0557a8ee146d224e5821ebdbe0740ae475983", - "https://jspm.dev/npm:lodash-es@4.17.21/_/05d03ed7.js": "3f8b9275e36ce11dc34d8a355fea3a204ce200fdea42c1644c9566bfd531f542", - "https://jspm.dev/npm:lodash-es@4.17.21/_/0b311353.js": "416555d524b35bd3bcddcad23cb4f9400b18df197da272a0e34349b49c2da289", - "https://jspm.dev/npm:lodash-es@4.17.21/_/0b5bcb97.js": "f85857f8c923cd0dc96b8e077c724238b19d976c622675f693037c2fddda8c8b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/0bb20403.js": "13d1eec9a9ae4403fcfe97aa85d11f581a43b05a5f43a436b43f010b24a93522", - "https://jspm.dev/npm:lodash-es@4.17.21/_/0c0b1c46.js": "e06d62e267fd70698fc849dbee243bce22a4c67b27a95e229a709ae7927e9b4b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/10c2be66.js": "fef2a0411495287081dcdb487f8a19056d163988822f175a532303e45e26bdc4", - "https://jspm.dev/npm:lodash-es@4.17.21/_/130bf524.js": "1a3941e656304ee9247bfc10de18e8f15c530ebc326624a68b65ec596144c0a8", - "https://jspm.dev/npm:lodash-es@4.17.21/_/1383de04.js": "f11f6cf2b27b5ec70710e992415193550776673e2c2df05e2ee81a580239c9f5", - "https://jspm.dev/npm:lodash-es@4.17.21/_/1386403c.js": "2832b0a6d4a1a7d4050ed24a3576451a7fc9b923aad3cfa18aa78cbd8007a91b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/1545748e.js": "3770903adc448f2d3d6e6e03c9c34d33c913e224b87646082be11f11fc88d562", - "https://jspm.dev/npm:lodash-es@4.17.21/_/16393db3.js": "a5095c7aa6f2d717a5ecf4845e3ea9f30c093f5211cdd6928275b1983dbc5084", - "https://jspm.dev/npm:lodash-es@4.17.21/_/17fb905d.js": "00f0bc1a6cd1564dc7812bba6b82e432eafe079762b9a90c83f56d8cc32a8563", - "https://jspm.dev/npm:lodash-es@4.17.21/_/19315954.js": "0be2bac09cd0fd8df4fd7805b4674f9ffa534ba3a5ea98fddde2faefd436dcfc", - "https://jspm.dev/npm:lodash-es@4.17.21/_/1d34989e.js": "64cbd52b2880f70c665a9b41d74f72307d326fd90c34e429300c7221453f6436", - "https://jspm.dev/npm:lodash-es@4.17.21/_/1dfe23ae.js": "813088b806241074f3f000e435ff0e21864eb6df27127a32eedcbb868f4c788a", - "https://jspm.dev/npm:lodash-es@4.17.21/_/1e0e86cd.js": "980593e57c9215cfb61e6c34bbedbbe42c1507d175b2cd603ffc91aad2ad647c", - "https://jspm.dev/npm:lodash-es@4.17.21/_/203a09f2.js": "62eb56ac3aceb71788219ff1b2f56f3be858ab53f059b69585938b1691cde0bd", - "https://jspm.dev/npm:lodash-es@4.17.21/_/24eddd3d.js": "2dc23d60b9e3977a0db4aed01d2e584aa87d94a58750559db88e5ca4ad9d71a6", - "https://jspm.dev/npm:lodash-es@4.17.21/_/27733a90.js": "2d8afdb8dc0bdb492f088915bad9e87da92f7c962cca96df370d8c3f8767ca17", - "https://jspm.dev/npm:lodash-es@4.17.21/_/28e2aab9.js": "539cef76090d73da43e2506c72e6cc9d2c3644c85557d11698d6d6f0ad796832", - "https://jspm.dev/npm:lodash-es@4.17.21/_/2a83f3a2.js": "d82cba4f089f95e365b979287c7781a7791add7e1f3f5fff83a3c1658035c284", - "https://jspm.dev/npm:lodash-es@4.17.21/_/2b1d23fe.js": "8afce7d40a560985789df5242f1391d581e1168d943b2fde77c6bac7d6e8ce35", - "https://jspm.dev/npm:lodash-es@4.17.21/_/2d655bf5.js": "51782fa05b78d8df3b0eab334b9319a1d6d2c76c9f680522c3151ef8d8750db3", - "https://jspm.dev/npm:lodash-es@4.17.21/_/30141f0f.js": "b39b533cb1df9d177e94f19c599052646a3e6761a080ac3488bdbcd84ae9a163", - "https://jspm.dev/npm:lodash-es@4.17.21/_/3151fc5f.js": "dbf0065b61f72e0e9d73aa8df49cdf0004271e364dfbfe175c499b98b49a7bee", - "https://jspm.dev/npm:lodash-es@4.17.21/_/31bf9ac3.js": "7dbe1e52f19dc675be8c3addd35ea7a9c6b70c93c4d5821a310c0a629516c6e9", - "https://jspm.dev/npm:lodash-es@4.17.21/_/36c815fc.js": "80f3fd5c8e1c75d840d0b01dd6bc1125926ec1f61bd39d504a578464602a50e0", - "https://jspm.dev/npm:lodash-es@4.17.21/_/38394896.js": "c6ef95c557f1eba137d41a232ead46d7775d91d93f1640cbe9b072298baa3707", - "https://jspm.dev/npm:lodash-es@4.17.21/_/399d274a.js": "ca843f79d6c6f71e3b89d02e850417884f1296ad6300baee52804326a354920a", - "https://jspm.dev/npm:lodash-es@4.17.21/_/3a395ce1.js": "d658b0c52d7aad0e1e76920320a74fc36488f8fd8023208a69bf7fcb1327cd7b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/3cfb9cd3.js": "c8d0c25ca446ced635aa39de4b741031f3b0ef778669d69fe05c20dc49428188", - "https://jspm.dev/npm:lodash-es@4.17.21/_/3d95c57d.js": "bb9274bf53afea744b1138dddbb8e5ef8866229f661b4cba131d6158ad90cca4", - "https://jspm.dev/npm:lodash-es@4.17.21/_/402c5d7a.js": "8bf062d4423f6f6a7f9c50bd5e929f91f8df740591a5f254630ff559179c983f", - "https://jspm.dev/npm:lodash-es@4.17.21/_/407ebd0d.js": "a558f31bd1e749e84084f90a19a19df72b80e089ee16e69dd022ba34d8b553c8", - "https://jspm.dev/npm:lodash-es@4.17.21/_/43b5d56d.js": "af04041dd2dc11d0ee0967c002d12dfb09f16745e5575849a16d343c92c4c071", - "https://jspm.dev/npm:lodash-es@4.17.21/_/463e7889.js": "ac52074f7a4e4c47c3339e813bb2623f6c486b68f0f58cc9023b6fff0fa581a5", - "https://jspm.dev/npm:lodash-es@4.17.21/_/48027737.js": "5048145a8eec822e1c810854d50b5200eb9db397017b17ff6d9f00f69fa31672", - "https://jspm.dev/npm:lodash-es@4.17.21/_/484e8999.js": "58b03040e5caa0c0e2109c3846cc6bab5df92c4d27ec4224159ecce9406e2903", - "https://jspm.dev/npm:lodash-es@4.17.21/_/4d837337.js": "854450a64703426033bf70c2c8a6dca8fc88c6cef2e569f6ed38cd535874e84d", - "https://jspm.dev/npm:lodash-es@4.17.21/_/502197cf.js": "6fea2a2ca31fbc71a3727bde69ec982fb0e20eb0b75ca703960fd57b428f464f", - "https://jspm.dev/npm:lodash-es@4.17.21/_/51a9bdd4.js": "4de759414b19f610be5f380bf07ac2ae8da66b59249c9ea74a0061717ec281c4", - "https://jspm.dev/npm:lodash-es@4.17.21/_/53bd6314.js": "023303433119467c1a845e3594c9b21c2ef6b238b76edc196759fd31f6146da4", - "https://jspm.dev/npm:lodash-es@4.17.21/_/56765766.js": "ec493b01df613f602d488b2bb3caa13bdc3c522a86eaeec3dadb5de33b1890d6", - "https://jspm.dev/npm:lodash-es@4.17.21/_/5839515d.js": "ee0762bcb9a20e698eea69f971b9b91d172ec39f5a513a1cd36b8e0daeb81220", - "https://jspm.dev/npm:lodash-es@4.17.21/_/585c9edc.js": "c89d4b434be7deb2c1a7e1de856fbe69aa37125411c8fd6b6b05241b90883ff5", - "https://jspm.dev/npm:lodash-es@4.17.21/_/592507a7.js": "76b75d86efd915c46d53c07aa8d1f2c0083c043747afde898a96a9023f862b68", - "https://jspm.dev/npm:lodash-es@4.17.21/_/5c0e4804.js": "10bf72afaee300056346251d07c085f731b67f6725e0abf6f471c8c765ac719b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/5f448d66.js": "57f7ca9d4574963a160b9cc9e21a31b5e274b03f1f3d390a327ae05e6da3e313", - "https://jspm.dev/npm:lodash-es@4.17.21/_/5feb7f4d.js": "77a9344c0752364af435ed34ecfebc2eeedf1b8d5fff00a54d7eb29f33b48121", - "https://jspm.dev/npm:lodash-es@4.17.21/_/60f3bb4b.js": "d6e6f5a638db2cd61d9edc4eea06557158bfe4c36432f3f91b6f0613325fbb7d", - "https://jspm.dev/npm:lodash-es@4.17.21/_/635961f9.js": "71317f9cf5723be1bd660582dc67d14f3da9acd2b69a3c28b177a55ecd302215", - "https://jspm.dev/npm:lodash-es@4.17.21/_/65103b5d.js": "ee5510d5ebf566c883df89bd7942c579a3d8fb9dd279ad53bb71b48df22e1ea2", - "https://jspm.dev/npm:lodash-es@4.17.21/_/66f45db3.js": "b0e86aa06314c4129c6526a11fc088879750c2799938f5e5a13595a164a90f6a", - "https://jspm.dev/npm:lodash-es@4.17.21/_/6703045c.js": "6198501112257dd9e6ecb9b5c57a594cdaf37af777fce5ff83684b19e47f974c", - "https://jspm.dev/npm:lodash-es@4.17.21/_/67807643.js": "dfd3e7795b80ce39d52263067985032c4751eede9c6eeff503cf59995a6ab272", - "https://jspm.dev/npm:lodash-es@4.17.21/_/6fb96f49.js": "d933516b8a1a67bd0ff40fe3fd5ee3789d814125b4d787abe81a60eddd1271eb", - "https://jspm.dev/npm:lodash-es@4.17.21/_/703e5e28.js": "4dc6c69c7955c9260a874b1a06979c6f4923fae4197c86277f3453e8bd4d16cd", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7100b469.js": "4e2b3570f10e1bf90b687dd342b935b60ee6a180bbf3f377b4bfb41ac21b6d0f", - "https://jspm.dev/npm:lodash-es@4.17.21/_/73372287.js": "fb96dce6428c3fb5fec2317a08f86850f31367af5a18d73753ca40e140a7a5d2", - "https://jspm.dev/npm:lodash-es@4.17.21/_/75cff482.js": "182b02e552b20319f058a9f4c0c180718bb1bfaaf74aed67d5e6972a231dde8e", - "https://jspm.dev/npm:lodash-es@4.17.21/_/76ea3370.js": "8d1f899618e63ba94489bddd8d80a2c62dc07b3f69cacf48e9dc7ed16fe586e0", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7801f571.js": "a20305d64ee42a5bb7938e62dae0c806af207dd32125bf2e2c0d5021fe944523", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7953e050.js": "3db506ed2c3c531038244dce34cd5dbfdf83e3bb2bec81326b667c25fd00c4ce", - "https://jspm.dev/npm:lodash-es@4.17.21/_/796fa7c7.js": "13a4ae014d4e80db42128df3439935f47e9c80520998bc8b3179490631ebe776", - "https://jspm.dev/npm:lodash-es@4.17.21/_/79a1b287.js": "838dc4f43daf1247a7afdf17094936c5a75ae805404c6ea8e338c891d8c9a6ac", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7a7ec766.js": "dee0686a9fbde7f463698fe010d61287cb3afbbb65d746c44cbba7bda82c46b9", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7a86998d.js": "580be03b87915a1a7c58161bcc8ecf8622e4b667fa9d7f73eff04247638215b8", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7bbc195f.js": "4324b885bb1c31e1d839f9322e06643fbcbdc92c5fa67ff7a4e80ae5b94d4fdb", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7e70392a.js": "72a4cd7ee7882df13ccb8d9271171ea0117f1c3b16a9d60c1edd27b80153d63f", - "https://jspm.dev/npm:lodash-es@4.17.21/_/7fcaefab.js": "7022d8cffed88a437cac03dc06cb5dc4705d69b2ec97f46bed07c881a108f252", - "https://jspm.dev/npm:lodash-es@4.17.21/_/822773d9.js": "87f8b42251a27a2fe97e56dde36926308b3a594949af1b196decb881f0aae145", - "https://jspm.dev/npm:lodash-es@4.17.21/_/841bb6c0.js": "a18a19d08c179a17fc105d40e2627fc35244555c22aac2b3cb88d78a112cc63f", - "https://jspm.dev/npm:lodash-es@4.17.21/_/874eb754.js": "4a68b137ae16b855946f71115bc42122415aee29d3081e6663b12b57115c1c15", - "https://jspm.dev/npm:lodash-es@4.17.21/_/87e6bc8a.js": "62b7398cc1ff6a6dfe705c11fe4f8637d3d3b89d6d59fdd57b399dd2aa39e021", - "https://jspm.dev/npm:lodash-es@4.17.21/_/88d7c693.js": "eb6b1a07b8341a677684f2420019c6d1f0e7cf59389cc19570c1ac2599262aae", - "https://jspm.dev/npm:lodash-es@4.17.21/_/894288ab.js": "90ee762097c230c8d807d8e4f7d58be7efaa1c0d6fed92f011ba82770082bf4c", - "https://jspm.dev/npm:lodash-es@4.17.21/_/8babf61e.js": "7d3735645ad3d5f40d3ffe0e20ef5e4ec03d4873f02a211b300f79f16240c4fb", - "https://jspm.dev/npm:lodash-es@4.17.21/_/8bc5f7f3.js": "ac061a69c7cc70d4d8072ba9a10605188946dfc6662735232db513b3b9839b4e", - "https://jspm.dev/npm:lodash-es@4.17.21/_/8d4d122f.js": "ba1e9835b009e90fd3dd5cab7053c2ca7fe4aeb319812ec422692cb95582a83a", - "https://jspm.dev/npm:lodash-es@4.17.21/_/8d8705aa.js": "23b2c68207f3e3dd8b449b9d4f190e4620ac22d5d7a12ad69859cb0b9a51980c", - "https://jspm.dev/npm:lodash-es@4.17.21/_/8fb9d566.js": "68eefe77564498475dabafa07be0076eba21cd941966e33822915e2da5b35c37", - "https://jspm.dev/npm:lodash-es@4.17.21/_/9056e65a.js": "e00f21dc84616751a13b6590a81c1c52b3a70ec32c5223a0ee64e970d6326fda", - "https://jspm.dev/npm:lodash-es@4.17.21/_/98062778.js": "43e805ed06acc9d93aa6e7f7e9e3571c941a18d3bf4e12c6a3d36802d2eee6c3", - "https://jspm.dev/npm:lodash-es@4.17.21/_/986b7729.js": "921aaaa196ad899f72d955b0a84689f874826562132ec43797c7df1c8e2f8edc", - "https://jspm.dev/npm:lodash-es@4.17.21/_/98df1741.js": "ce999fd4ce4e2637497fb9a2b158b5286a6be9a397947201bc7da0dabf932456", - "https://jspm.dev/npm:lodash-es@4.17.21/_/9950791a.js": "fca503f242e2c1d2570db9cad24f0217724e8dad2e74fb96bde27da8fbbc5e10", - "https://jspm.dev/npm:lodash-es@4.17.21/_/9bf895a3.js": "8028ad9529cfcb56f5c0f23c89e1523680ad3caa6564660483863d2319c164ea", - "https://jspm.dev/npm:lodash-es@4.17.21/_/9c462ada.js": "9c097bedd311655ed640d3c6cf7c50bf17dccd0f2973176309e654ae8ed3b6db", - "https://jspm.dev/npm:lodash-es@4.17.21/_/9db0989d.js": "f79eb7b4fb71aec9f77ddd22be0fecf8058eac98dff324f68a6a1735c6f99df2", - "https://jspm.dev/npm:lodash-es@4.17.21/_/9f137e5b.js": "30996c0bf954eaef8e195011b13250947b2ece8cdb9f3a8416474b302e7a64c6", - "https://jspm.dev/npm:lodash-es@4.17.21/_/a4e96b24.js": "c8c8498aab385ea8c73c12c884e1ad6279c2adc116093a6cafa5795705620f6d", - "https://jspm.dev/npm:lodash-es@4.17.21/_/a8ebb5d4.js": "15282b92bbddc4040df4745a1045d28449e4919d3909b9b2f706b4a5f3683975", - "https://jspm.dev/npm:lodash-es@4.17.21/_/ad435a40.js": "01f97d1f669b867f15c228b7e53e66dd81ba7799202546ecc17d3c7245e64471", - "https://jspm.dev/npm:lodash-es@4.17.21/_/b0d71dac.js": "07a29f1ff46e4411f9b63f5082f63dbe45ce88c67688159c32088a95b8beaa75", - "https://jspm.dev/npm:lodash-es@4.17.21/_/b17df163.js": "219baa925ae221c086fc7bf7487091c02713ab541475818de7c7bb381fa6b1d0", - "https://jspm.dev/npm:lodash-es@4.17.21/_/b1d05723.js": "d4f60198c50c33679afd356b5391030982d11f187b39fac285ad4c9fa4d4f272", - "https://jspm.dev/npm:lodash-es@4.17.21/_/b225817a.js": "750214238a44dbb94665795080ccde95c44d52547e3dad248d50354c1a411b83", - "https://jspm.dev/npm:lodash-es@4.17.21/_/b731ddec.js": "392c581875c331eede5d0376fe9bb31977d3efc7de72217059ed81139478b08d", - "https://jspm.dev/npm:lodash-es@4.17.21/_/bda11cda.js": "c98c5df65d3d4662863207e02cec664de57f463b3c7c79383e8d015abf4e4f3e", - "https://jspm.dev/npm:lodash-es@4.17.21/_/be1f91e4.js": "3896ea6a62b3d3631a0a3141bbc5c60e91ebb1ce3da583124adf673dcc670182", - "https://jspm.dev/npm:lodash-es@4.17.21/_/c0862ccb.js": "2ce24f0af749237355cd91eaf5a4223e08d0e33391a625006cc82281fa0c706c", - "https://jspm.dev/npm:lodash-es@4.17.21/_/c5f390e5.js": "965a712b7146026be20665c514c00ec77c73ebab9302f06a278806f656e24d11", - "https://jspm.dev/npm:lodash-es@4.17.21/_/c7012d8a.js": "99719f1416495375967029974daa1944750a2046a65a3b48dbd1d36ff79c3f59", - "https://jspm.dev/npm:lodash-es@4.17.21/_/c952862c.js": "0226be118dc33fb52ced27a9639c18fa0347695dbdb6a1abc33eb34b5d4f4458", - "https://jspm.dev/npm:lodash-es@4.17.21/_/c96a0489.js": "d5d59f61eed1703618cc70376a473ec97c98e26c585d4000bf41a678c0dde1df", - "https://jspm.dev/npm:lodash-es@4.17.21/_/cc60ce64.js": "e7a59d1cc18e203fe15d32dce0ae80d5dc9c9173a68f3cc8536f906631c08b21", - "https://jspm.dev/npm:lodash-es@4.17.21/_/cf0de6d8.js": "7853c9c380abecaba7128bcd4c221c90486d2361c06dde43f5a695306abbce5d", - "https://jspm.dev/npm:lodash-es@4.17.21/_/d14d4efa.js": "ab48edb7a88caeffda97f9b0d4c581ebe220dce27b718f997977de88bbc512e7", - "https://jspm.dev/npm:lodash-es@4.17.21/_/d32deed4.js": "e7e959a4d28ba39cdb59ce7f002ead6adc7d7e62ab1496c4dc460452d6452b2e", - "https://jspm.dev/npm:lodash-es@4.17.21/_/d4a1ebe8.js": "1eaa0d642534855d16c1f13fa2a82051dd33bfe6608dfcd28aff94ed9c0bc2e9", - "https://jspm.dev/npm:lodash-es@4.17.21/_/d9fd2a7c.js": "6f2dfdcaf1678853ffa4b36faa392b2df50903c40522b85ad6e3135e5464f98b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/da987058.js": "a43aa826c50185b6cdf59831750b5deae4510d36a34dcbffaae842845740b13a", - "https://jspm.dev/npm:lodash-es@4.17.21/_/db85cb17.js": "be21f10d6372c7af85a7a4124768860c37c7a3e58b19a2d728cfdf7216218e55", - "https://jspm.dev/npm:lodash-es@4.17.21/_/dcfc3998.js": "663caa0605460b5ba360e84d3d435ea4ef4ec2573f9346fc36ca9f0d3f731566", - "https://jspm.dev/npm:lodash-es@4.17.21/_/def5a505.js": "f3224b338bad3da8fedeb47bfb4023888baf8d5387745911ee4dcb04f225d366", - "https://jspm.dev/npm:lodash-es@4.17.21/_/df9293ee.js": "73776a64dc12f1413646bfd2d250ad854c64b9ef172fd4c6d77b93fa332f91e2", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e10cd6f2.js": "c54b7034d8a82a2d63ca542eba8f17296c4a05beec312735a44dc17a2770a950", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e1d4e071.js": "8feb9df6185324d58ca1167d9c14873c53e7e7ed396238756da6c451189677e8", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e524acca.js": "f1bd4a54716f512f4a3249e37f6dcc3281d09ae0053f76758bcb27579dd6d6d7", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e52eecc0.js": "92531672d0331c7101f0dba92dcab787f5a55472cf965e9a94c7d0a4dfe2c600", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e6902cb9.js": "e075f9be90c0d1c57148a546b9d3e5e68c6537421163478168f07dced72d5aa6", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e6cabbd0.js": "2549cbe0827d2754abb5b45f64b7e96ae24fecfbb802859ecf8b0d5ad58d6898", - "https://jspm.dev/npm:lodash-es@4.17.21/_/e8626fab.js": "a0eb1aac0507355c359588ca71ec7d91d5c269542ce0a29242fe005b49378a3b", - "https://jspm.dev/npm:lodash-es@4.17.21/_/ebbec2c8.js": "2e4d7652a563e35d3213c54e00bdd8d2b6c8bd87f1734c3c38ddd27a9d062e01", - "https://jspm.dev/npm:lodash-es@4.17.21/_/f01ae9b5.js": "295cdcaa1029b51ee863fc0cf9e819bfeae55ee2a7df367483e63712e3cebfb8", - "https://jspm.dev/npm:lodash-es@4.17.21/_/f08a6ffe.js": "9109344bf0776b2c30de2dcc4b8d5f58dc32aee48e649f11811f9ec1177db9e1", - "https://jspm.dev/npm:lodash-es@4.17.21/_/f945550f.js": "cf04071a967ad944ea086be9822f09a9e52ca4d17c9c9db8cd65eb1f80ab53b1", - "https://jspm.dev/npm:lodash-es@4.17.21/_/fc09277a.js": "2706d821dd6e7f5ef880f6b9e631efd44949a0e081a723063d2fda09929fcdc0", - "https://jspm.dev/npm:lodash-es@4.17.21/_/fccdb4f4.js": "767bd249ef3089cb7da63149080211025236694919cc4b1007f1c7e4b9d3fffd", - "https://jspm.dev/npm:lodash-es@4.17.21/_/ff41ecfb.js": "7d63ff01dce794a12ac4415ef94d9d5f2bb476cb7adc97aabfc7b586bd1aa488", - "https://jspm.dev/npm:lodash-es@4.17.21/_/ffc0ea6b.js": "9c3f20833420019e26371ee0c3e90e3a2704e391d685d3297a78322eef4d62db", - "https://jspm.dev/npm:lodash-es@4.17.21/_arrayEach": "afcc5a28962d983cda016f265ff9918341e9b2218448c0935a71c6818ac489cd", - "https://jspm.dev/npm:lodash-es@4.17.21/_arrayEvery": "960bbd642b7fe2cce6d936f8ea714d9e31ada5673a18b5efb8c417b6c0a7ce52", - "https://jspm.dev/npm:lodash-es@4.17.21/_arrayFilter": "292cefd33bbd5b86d31bb10ef62bda753dddd0c6b03b47af2d80eaab214f1153", - "https://jspm.dev/npm:lodash-es@4.17.21/_arrayMap": "a832d5f9c633a539c3bd1ead4eab96c2e55a413f8df07946528c17c574107670", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseClone": "1500b9c33c0c4cf22be69a7e694a55af966c7c37817ce096a578884dec9a2845", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseEvery": "fb8712e564aa688d42f7bd8aac174bb8b7855b76ede1ec2242308ba739feb1da", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseForOwn": "6e44508de841e82bd162235708e69be04daafa4f41a28a87515cd4921502147a", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseHas": "62e58f125804f1a6ccb5a96d0966e921a20f7bb5a9cf0b5cb8ce5a76011ef710", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseIndexOf": "7f855822ccb438335ba078cc705d70d57412d577ce7a65848dbf991b7c4c8d5b", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseProperty": "0e64ba27c7c45d03954da0450457df1374cf082d555659d5e30ee9d2c287d668", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseRange": "8d369cafe5fff2c94b91cc6684d03c6b3f992fb56c65ca145469772a43665d80", - "https://jspm.dev/npm:lodash-es@4.17.21/_baseRest": "5ad9ff40a2ea3777c4efec69b7a354173e785e916dce915ac24457d436d830d0", - "https://jspm.dev/npm:lodash-es@4.17.21/_copyArray": "c1a8db9f2e96de5402b0c18c51d92e9a60eda26dca5875e1a351d4be40a3fe9f", - "https://jspm.dev/npm:lodash-es@4.17.21/_overRest": "3083837bb6e6c425dcf3907733bddcc1c00f3c5f0234e10754f09d1f95d66d9e", - "https://jspm.dev/npm:lodash-es@4.17.21/add.js": "1a244d164fa836db91e98f827fdcd2e405948841331a67963d2d104a4deee4fe", - "https://jspm.dev/npm:lodash-es@4.17.21/after.js": "40a42ac08f1de8fcc368309830f10ad950d35e4e1fb0ca9cd0d66565c8af956d", - "https://jspm.dev/npm:lodash-es@4.17.21/ary.js": "371e34ee852967a293b25cb8c13ab1ccfa8a3a69bca5f8ef6670144fcac70f12", - "https://jspm.dev/npm:lodash-es@4.17.21/assign": "d1128ddeb291b2a6ec867f55a75d57bba040c06592579d464339a87c459eb17a", - "https://jspm.dev/npm:lodash-es@4.17.21/assignIn.js": "2ef29b5c3d6e2e4c0e7688dc6150f721b53fe29f120b273b1ebfd17e5fe97f14", - "https://jspm.dev/npm:lodash-es@4.17.21/assignInWith.js": "28d2a5b338cc1d0ed4150e5b0fe08f36419a31e23e43d82e3ff99f93b0e5c87a", - "https://jspm.dev/npm:lodash-es@4.17.21/assignWith": "5b69a43ca901c554205b5ef18d5119180233028b46e38b256ec83e14802784e9", - "https://jspm.dev/npm:lodash-es@4.17.21/at": "b8a37cdca937bcc5382ecfc758085439e525bcd1e795e1f87dc347cf4e7224b7", - "https://jspm.dev/npm:lodash-es@4.17.21/attempt": "c605ec552de80c9acba609995def59deabf3414b5d09c2c47f43a29107928235", - "https://jspm.dev/npm:lodash-es@4.17.21/before.js": "ad21da9318faefd0c3f9323dd431040b6f1448fc7acfaf856ecc330547150eb0", - "https://jspm.dev/npm:lodash-es@4.17.21/bind": "2e807e953ab13235680bd15f5158f8b81fc0da43f9872b9c95a0deb7ea9aab62", - "https://jspm.dev/npm:lodash-es@4.17.21/bindAll.js": "d5bc48a0ffd79efcc6d1ff4db6c22d1d397184aacdc3e97adbfb0edc4e7bd562", - "https://jspm.dev/npm:lodash-es@4.17.21/bindKey.js": "a406389507d54551f85d9531e78bf2ebf681927fe229af1a3c1c6dbd7e589122", - "https://jspm.dev/npm:lodash-es@4.17.21/camelCase": "75fbbf93244ba1e76d3ac335b37761671e520b411bdff6a9a93bbddd1d289eba", - "https://jspm.dev/npm:lodash-es@4.17.21/capitalize": "9c63b6eb33e6f848089c593811afa762bcb85ce2a8290b1c5a22a3855f1a04b9", - "https://jspm.dev/npm:lodash-es@4.17.21/castArray": "4145d6e0746e5970e2aa800ef47cf26fb41983ab968778fba9b515c10b37b4c8", - "https://jspm.dev/npm:lodash-es@4.17.21/ceil.js": "18db70461ddfa7a437e9a1b7078dc659a082777927b10bed631994103b90e28e", - "https://jspm.dev/npm:lodash-es@4.17.21/chain.js": "fc72a2ec68d56e665aa085d6f3af561c021404010acbcb1217f32b3a840f1186", - "https://jspm.dev/npm:lodash-es@4.17.21/chunk": "bf4ff5d53fd0dfdc47dd37172a4b5598f4a4000dab75dbf3e79a80064d8886a9", - "https://jspm.dev/npm:lodash-es@4.17.21/clamp": "d904ae5dbd1fcec01e8ff50fd1e533340a8d5b5a5fb2eff36faba20ab53e5bc6", - "https://jspm.dev/npm:lodash-es@4.17.21/clone": "8d1337bebebbfd685d037215948bc50c3160aace2e85e40a221312aee40cb313", - "https://jspm.dev/npm:lodash-es@4.17.21/cloneDeep": "83b61c7188bd74358ed47ede85d25d7847751e7a1505ce6f5d9d6bfff6132b37", - "https://jspm.dev/npm:lodash-es@4.17.21/cloneDeepWith": "9e59fcbfdd4687cf4ffcfec3298d2ac3a379b41fb1c6e080f602de30604f3c34", - "https://jspm.dev/npm:lodash-es@4.17.21/cloneWith.js": "64b47470fb9a091513252ea58950b11e9d4ae10b57b7dc7d326c0cdba704f273", - "https://jspm.dev/npm:lodash-es@4.17.21/commit.js": "54daa6b6a9e0650fecfc1b7016950263ffd524060c17aab04bb862175a53a486", - "https://jspm.dev/npm:lodash-es@4.17.21/compact": "c0d33d79bab072010c1ef687413c958601a7b14286ad3199e40323a828c7c9e4", - "https://jspm.dev/npm:lodash-es@4.17.21/concat": "96194b27cb82c06eff603231f0ec32d4401e3515951f7c79b372ea8fac5bbd78", - "https://jspm.dev/npm:lodash-es@4.17.21/cond.js": "7485ae05c55c659c2e5bcd9d8e0f06fb07865a242ab908ef4f46fcb56ce7042b", - "https://jspm.dev/npm:lodash-es@4.17.21/conforms.js": "c1e704643485430be899f873cd3acaeba3d7bad5f969589f08e2ea96a067ff5d", - "https://jspm.dev/npm:lodash-es@4.17.21/conformsTo.js": "cc738abf20f685269ed3c8cb2fe206cd9932ee284d31ec367c445f919b1ee5ea", - "https://jspm.dev/npm:lodash-es@4.17.21/constant": "58b50a427440a5ff93ad7e5378bbb943e2f043123f5a7e4382c79a78e2a725b2", - "https://jspm.dev/npm:lodash-es@4.17.21/countBy": "7a52f9d1f3d0ded660e1c7f1b3fb59b41de7ab6203e78a4f839da02e2617c4d1", - "https://jspm.dev/npm:lodash-es@4.17.21/create.js": "3371e9ffc9f2fc42873cbde9c4892888cef37252649cccb7f2d287cbaffce7c6", - "https://jspm.dev/npm:lodash-es@4.17.21/curry": "28f16d7394b2446d77cda07f4813d7ffd5a1c28454da36d66f33be08e44bbb67", - "https://jspm.dev/npm:lodash-es@4.17.21/curryRight.js": "22697996cfbbbee79f9292cdfe78824bab07697aacd32c776f41c6443f1cd686", - "https://jspm.dev/npm:lodash-es@4.17.21/debounce": "7348f465b2f73be2cf57114a82526aded112e3037d3d942e8f42a89787dd9ebe", - "https://jspm.dev/npm:lodash-es@4.17.21/deburr": "c381eed450b9ea635b0eeaa97289b6dba6eb8a19fea9395bdafdb291348f685f", - "https://jspm.dev/npm:lodash-es@4.17.21/defaultTo": "deedf26555de4f37837e7ea161d032dc0ebd3899d5eb62972b7ba374a3b3dfc2", - "https://jspm.dev/npm:lodash-es@4.17.21/defaults": "8dd3734fdb1c307b1f5c1a2c99f471039d5b2ced0a0b689a192645c7e740eb9f", - "https://jspm.dev/npm:lodash-es@4.17.21/defaultsDeep": "9f2ad67e4cde41d286946a37a0161d5b6149ddfe62ae231cb8df495318c60c5d", - "https://jspm.dev/npm:lodash-es@4.17.21/defer": "734716e2d145426d806717880e5e660c46296e051a4aff1f206871b5e656bed9", - "https://jspm.dev/npm:lodash-es@4.17.21/delay": "472e971debb0bd7736679d4a6b765a9d6253aac451aa1e9bded6d899e31bf977", - "https://jspm.dev/npm:lodash-es@4.17.21/difference": "0b5b72bde60b37a1a172c495c78ac8d373e73ffc66de1da6177e75b4175c465e", - "https://jspm.dev/npm:lodash-es@4.17.21/differenceBy": "2df180c384f719e55bf9f94c1ddee7b14daa01f54c1df69cc823e94ae921a50d", - "https://jspm.dev/npm:lodash-es@4.17.21/differenceWith": "eb1b0c612465eaa5ae14ac36145d592d348dadcfd90d2fee4589597d04ca34fc", - "https://jspm.dev/npm:lodash-es@4.17.21/divide.js": "4ab52e3c1504e6641a7f5bbc7cdf88c610e99600eff75e4917d46c78581cd845", - "https://jspm.dev/npm:lodash-es@4.17.21/drop": "6c732193e5e681dff00f6dd135a36435c0b70ec6790208b782533d5cf5ddd79d", - "https://jspm.dev/npm:lodash-es@4.17.21/dropRight": "cd400b7bce9b92d244929e37d8dec3a284c230916b4fed3388b311c489a79593", - "https://jspm.dev/npm:lodash-es@4.17.21/dropRightWhile.js": "6ff589a0ba2795dc56aaafac35f0fb5607d8a5a125d4e7ea2bc39696acdc33f8", - "https://jspm.dev/npm:lodash-es@4.17.21/dropWhile.js": "8a46e9b4026f5e48cfd28f365778974e103fa0248dc4de1af69dccb12053aa55", - "https://jspm.dev/npm:lodash-es@4.17.21/each": "2615ee61c1b07fba411a4df3d95657fbe9857c1cb5f16674b95d7bd98ecffdf4", - "https://jspm.dev/npm:lodash-es@4.17.21/eachRight": "7ec260f20b32cdc9e1cb0a877e63649da245bfb811f64a0f9228a8413b7c5ca4", - "https://jspm.dev/npm:lodash-es@4.17.21/endsWith": "7c103441d2f28bcae9ec2c11673ae913702564bd2d49c65aa41e1e49108df2f5", - "https://jspm.dev/npm:lodash-es@4.17.21/entries": "b997a412de36d37dc5cd10b5818a993d3ad8aafc07f1042f94cec32989e87bc0", - "https://jspm.dev/npm:lodash-es@4.17.21/entriesIn.js": "bdb3972ed805d0a971f25cecf92d8425ae15f1de276ea3aaf8182d2829170e08", - "https://jspm.dev/npm:lodash-es@4.17.21/eq": "a6960b851bb2f92f51bcc8a398387da815f717f9cc083cc3ed594e9d82fe667e", - "https://jspm.dev/npm:lodash-es@4.17.21/escape.js": "d9ef15d72b3e9a7bb275a05d0278da592b7144684030b6c9bab153e54130c2b6", - "https://jspm.dev/npm:lodash-es@4.17.21/escapeRegExp": "d2db3897830c406f16baca56bddfb5c53a583ae4c9233c46d689a71f7c25796a", - "https://jspm.dev/npm:lodash-es@4.17.21/every": "d8cb1c33006a6f937682744bcd03306d32dfb93083f91724d46152bdcd516562", - "https://jspm.dev/npm:lodash-es@4.17.21/extend": "518814c7eeb2ff5b7aff8a4bfa29d35fb83be827bb41001d2f44500c01108565", - "https://jspm.dev/npm:lodash-es@4.17.21/extendWith": "cffcfaca39feaa7de87db7318fd07df5995a94f82692cf166b650083b6d3f505", - "https://jspm.dev/npm:lodash-es@4.17.21/fill": "0cb81c66f155aa979a3d42ddcccaef9ced584f3442f5095d0ddd69c9eddad25d", - "https://jspm.dev/npm:lodash-es@4.17.21/filter": "612c5fb488424976bb20e4e5e24d8e1f90c4744a16760417162fbfa81a57a399", - "https://jspm.dev/npm:lodash-es@4.17.21/find": "128407773c64cddd3d9fcd00130c4de0a3f8f21c2457e2214aaf4ff6cca07e0b", - "https://jspm.dev/npm:lodash-es@4.17.21/findIndex": "eb33f75a9824515c81a52d58a06722757ffec6892af160770dd6c8e22d030e1b", - "https://jspm.dev/npm:lodash-es@4.17.21/findKey": "93362f5a57b4997c7528266f755492ff5d9aa1a53df1fad1950d471f13bc06ca", - "https://jspm.dev/npm:lodash-es@4.17.21/findLast": "abf7a400942675894b0d327d711d11344500b9b83630c68bbc9bb75f15987a47", - "https://jspm.dev/npm:lodash-es@4.17.21/findLastIndex.js": "6ffea5aa4e47ccff4a95f6561f8d48e72fb13191e24cb2a4822fd390ded7b4e3", - "https://jspm.dev/npm:lodash-es@4.17.21/findLastKey.js": "72ece71fb81825378f0becf8dc799c25a913ee5c3b39dac6f38c44b501a2f5c4", - "https://jspm.dev/npm:lodash-es@4.17.21/first": "5ce0037fff3a845be31070f201058dbe4e0b19f321bc5ca1407f4cf7df68e55f", - "https://jspm.dev/npm:lodash-es@4.17.21/flatMap": "8c4202b819100033d25cc1a51206554c9fcc7c9d6e4dce309980fa20ce3606cb", - "https://jspm.dev/npm:lodash-es@4.17.21/flatMapDeep.js": "2c5923630b12d2b19481da1937de086ba534d460fba6e4a017f13c6c48595618", - "https://jspm.dev/npm:lodash-es@4.17.21/flatMapDepth.js": "bede4fa48f887d7cedcdaeee913a51bda3ac6f8067b2d2a5bd89f6ffb514f9be", - "https://jspm.dev/npm:lodash-es@4.17.21/flatten": "ea5f55d735fc9fdc36db6fdc89f1f9cf6ebc31472752b25f00e6a3509833367b", - "https://jspm.dev/npm:lodash-es@4.17.21/flattenDeep": "c2dbe1185458cd6d1c0679e37a668201a38b5c99d20ad250e942c53ab93696b0", - "https://jspm.dev/npm:lodash-es@4.17.21/flattenDepth": "2499e2145ac7c61e68a4d88fe0781490d7fe0a30d6e086f560e2e320f8022b13", - "https://jspm.dev/npm:lodash-es@4.17.21/flip.js": "caf7d0d68817076639431907db72dfa29ca5b760cb84ba563817e7d5ac0d98af", - "https://jspm.dev/npm:lodash-es@4.17.21/floor": "1d94073557253c18de194d2ee32d907f2382541cebe68c882327b4f836f2f254", - "https://jspm.dev/npm:lodash-es@4.17.21/flow": "a05f960aa3a48951ad7bc2c75239020de228dd6f2e23237e57bb4178b45a36b0", - "https://jspm.dev/npm:lodash-es@4.17.21/flowRight": "e852d72ea3f3924648f48c098cf54b9e193eae083d47f2cc891e36fba68df0cd", - "https://jspm.dev/npm:lodash-es@4.17.21/forEach": "a78a02c29af4b506af29257629f2a5ad9bdb9de4a4fa8f08ec0a30935967db9f", - "https://jspm.dev/npm:lodash-es@4.17.21/forEachRight": "95d4a09173d6f119802072f008d671a38d1e50aff8e611224170cdefd2414973", - "https://jspm.dev/npm:lodash-es@4.17.21/forIn": "ff17b7bec3acd8c8662d8d1a72b20c95a23ba42de552fabd47f86109493117a5", - "https://jspm.dev/npm:lodash-es@4.17.21/forInRight.js": "6f6bddfc0a36cec0c793e98955774a29bd9964ea655a71f6b58c25258b352f33", - "https://jspm.dev/npm:lodash-es@4.17.21/forOwn": "ab979e1b9241805349a917a2066273c93a6faca000f19074343b95c1a3ed4908", - "https://jspm.dev/npm:lodash-es@4.17.21/forOwnRight.js": "cba1a5b206c50d77e01027dab005492f1aa5300dc487b7959063835b2ce1025a", - "https://jspm.dev/npm:lodash-es@4.17.21/fromPairs": "a79d6b6b658743af350a25c2449b7c465e282954ea233570461b6a709438c562", - "https://jspm.dev/npm:lodash-es@4.17.21/functions.js": "5c9fd4f6ddaab88f063054741c451447423019243dfabd15b53ab01d83fbeae7", - "https://jspm.dev/npm:lodash-es@4.17.21/functionsIn.js": "26b2b543db13874ec5116644459db164b40157bb08d7548c8e5cf609663de1aa", - "https://jspm.dev/npm:lodash-es@4.17.21/get": "71d9f03aefdd53fc5963bb23125c3bd55610721af3020df59bbf830fbcf136f1", - "https://jspm.dev/npm:lodash-es@4.17.21/groupBy": "a7b7b4e37bc610b6bbf19b32de0bcaab289fafd3177abde3167ec152cc9024a4", - "https://jspm.dev/npm:lodash-es@4.17.21/gt": "3f941d219c74be4354e964b20e0d957395cf7632743d05221d109a91c9b22ac4", - "https://jspm.dev/npm:lodash-es@4.17.21/gte": "a39b98c684d433bcdaecef7418f7af624b385ff6493326e5cab019d070ecdf4c", - "https://jspm.dev/npm:lodash-es@4.17.21/has": "ba047d514ef7a6b5821f3562f793d9f69901f18b1b5e8c8d98376240ea0e3948", - "https://jspm.dev/npm:lodash-es@4.17.21/hasIn": "b4eae03f1a62d4117c8c8ce5c896825aec69d858dcf15841ad0ceee2d04eb102", - "https://jspm.dev/npm:lodash-es@4.17.21/head": "89f6db54146d6638267b3c8d14f955cd751427bc823db5f676e48d8091c8d416", - "https://jspm.dev/npm:lodash-es@4.17.21/identity": "513134ab65e6acdebddc3d90ab397a247fbb5a89453a757e8de1094a96294098", - "https://jspm.dev/npm:lodash-es@4.17.21/inRange": "2ffd2677970316749fe00407ad45063e7bb6783074c6a639758387117c6130bf", - "https://jspm.dev/npm:lodash-es@4.17.21/includes": "c9bb08835b433ae16727e434d39a39d68ac6483be4a693121181b97052442bbb", - "https://jspm.dev/npm:lodash-es@4.17.21/indexOf": "b606ffbfdd3f49f7678e83bfb91f6ec89b6abe635c5ff7dc33bf9d61a867afa3", - "https://jspm.dev/npm:lodash-es@4.17.21/initial.js": "b14b4098985db54029230a24e7e7597585592bc8441c9e55a38c57c9fd062ddd", - "https://jspm.dev/npm:lodash-es@4.17.21/intersection": "2afa7c154e61dd9e86f6069b9fa5aab698b2ed59fce3eba2546441003c02bed7", - "https://jspm.dev/npm:lodash-es@4.17.21/intersectionBy": "2aa99198bbe89f92192dfce837c33bca3e30de2229d4b2df6a70da2467e1a0f6", - "https://jspm.dev/npm:lodash-es@4.17.21/intersectionWith.js": "419bcc0777f530488a71c910b504af7a27c59e7b2479aabe010f4b861eff2edc", - "https://jspm.dev/npm:lodash-es@4.17.21/invert": "1e8d757667c1712225cc0b97b39ff27bac78ec790326d20338b92f32257c23fb", - "https://jspm.dev/npm:lodash-es@4.17.21/invertBy": "0d3de74f4f04e4afbccd45926f2cb9b418a1586fc167af69d81c52844163f346", - "https://jspm.dev/npm:lodash-es@4.17.21/invoke.js": "4ec87d0d09c4b4552baa4b50cca8735dafb64ebe8a82b937a2946884991d2459", - "https://jspm.dev/npm:lodash-es@4.17.21/invokeMap.js": "12a73e1c3161e0d69c3645c2e0595448098f24a7d8cda46aef2b5d2a37cf1bd6", - "https://jspm.dev/npm:lodash-es@4.17.21/isArguments.js": "dbfc6cbf445ae1dd34ffce399ce5142cf7bc012814efeafa63cfc3ef659f2816", - "https://jspm.dev/npm:lodash-es@4.17.21/isArray": "1c0ce93062b0066c590f56f71c76958365e09bb3dc7cbd9852c3e7555f2ac74e", - "https://jspm.dev/npm:lodash-es@4.17.21/isArrayBuffer.js": "b443ce56931c1e0742303fbafdc830bc97e86117b62d68c57d935d62dc8240ba", - "https://jspm.dev/npm:lodash-es@4.17.21/isArrayLike": "aa2cbfaebfb3335a1afdeed7a519123c5022cf903b9eae1a7d93ecdb14ead41d", - "https://jspm.dev/npm:lodash-es@4.17.21/isArrayLikeObject.js": "f8d0de0abb3ad4261e3fa40b3cc42ea710121db812bf99bd444976489025a93e", - "https://jspm.dev/npm:lodash-es@4.17.21/isBoolean": "bfea211893e2a1d340246b9c399b0957868962be3b941e8ae090ab999d414856", - "https://jspm.dev/npm:lodash-es@4.17.21/isBuffer.js": "47c2417a8b0476869583288bd95fdb85ff13fa93ca95f0fd607f012f5c6ce980", - "https://jspm.dev/npm:lodash-es@4.17.21/isDate": "beb9481a329f99ef966f1fbef82ba6d31a9bbbcfed587c3545172bd702535337", - "https://jspm.dev/npm:lodash-es@4.17.21/isElement": "0c32c3fc4c70a0e4467eddc9e2f0047602cb4b7abd3301ab24e64c96ccd0ec38", - "https://jspm.dev/npm:lodash-es@4.17.21/isEmpty": "5d078d9a0809d6cc0b6320eb6dbb67aef8b9fc1793fd58d134a77272bfb48150", - "https://jspm.dev/npm:lodash-es@4.17.21/isEqual": "25683bf56f1b4c10bd041fb6e677efa81411060ffdb24cbe0bd275f3cadd543d", - "https://jspm.dev/npm:lodash-es@4.17.21/isEqualWith": "b6d0e23770c0193e2c0e0a980ab71661db53ff3e8a665d12a2bb27c125d9f578", - "https://jspm.dev/npm:lodash-es@4.17.21/isError.js": "53e5e06022cfdbc256c2fdf4dec387198b745a86db3f7004020596ca9c2c2299", - "https://jspm.dev/npm:lodash-es@4.17.21/isFinite": "64c18834587722785105bffd28a996bef68603ffa04714449ef0755bda52aa54", - "https://jspm.dev/npm:lodash-es@4.17.21/isFunction": "f8ebf17d0b6cba27259841a7415439d3c7f52517d1a5ca47e637a21a746edc9c", - "https://jspm.dev/npm:lodash-es@4.17.21/isInteger": "8c5ce4e891ad1bdfd0ac9e9f233367bec3f885b06ff40fa2d92c6718086ee5bb", - "https://jspm.dev/npm:lodash-es@4.17.21/isLength.js": "6d4ccbfc19fe11a68d0a41415fa916ec571d5a119e16d7db5fb46097d83d3865", - "https://jspm.dev/npm:lodash-es@4.17.21/isMap": "a848128c7ef8664c82bd80b52e72345a3f45a01d3db67d2d19ea1bb8c525ab3b", - "https://jspm.dev/npm:lodash-es@4.17.21/isMatch": "4ac71ae1d0cd9c9e5affbefb0d734de2d862e5211092f1b05145e3044038f0d4", - "https://jspm.dev/npm:lodash-es@4.17.21/isMatchWith.js": "8a0c7b3fd6cdff3687926303d30f442f79485fcfe6ff010cb1ccfcf6c4a562bc", - "https://jspm.dev/npm:lodash-es@4.17.21/isNaN": "ced5350082e2342e9802c5a32ae6091a452484a58a6bd9b5ac0a0db6e793130a", - "https://jspm.dev/npm:lodash-es@4.17.21/isNative.js": "d98dbdf71d79fb8432b7971d2b486504a957da8da2b4d92f3694d6b2c2bde70b", - "https://jspm.dev/npm:lodash-es@4.17.21/isNil": "5abfd43ebfdf86b2df57a62ef5eca7b7795859572ba83fcccb7d329235aba38a", - "https://jspm.dev/npm:lodash-es@4.17.21/isNull": "040436160bb4bb2034ebc40faf725637c31b22dce2e363184c6c93d733c67b84", - "https://jspm.dev/npm:lodash-es@4.17.21/isNumber": "9547dd2679b1276f0ad449715dd8c83334cb114fde995dd1ff6339db4a0e5787", - "https://jspm.dev/npm:lodash-es@4.17.21/isObject": "978d0ce182b02604111d6ae8d210616897218f1336404f6eab6b422d10f7e84f", - "https://jspm.dev/npm:lodash-es@4.17.21/isObjectLike": "89210bfce73a34cfa1180fb69b93812775e50057e78b3a583ebcacc8c3f86af7", - "https://jspm.dev/npm:lodash-es@4.17.21/isPlainObject": "8e8d9108e08a7c6ac63d30657c596161eeedc41319c9ba8fc8ed8aeac1fc7e62", - "https://jspm.dev/npm:lodash-es@4.17.21/isRegExp": "b34515b0ebac383c406cae514ce09a7e3489729fadb30985b5a968c461a970ea", - "https://jspm.dev/npm:lodash-es@4.17.21/isSafeInteger.js": "03b436d1f515996fef9b4e03659978f46488a4b8af7c75184d17aa44687c7c82", - "https://jspm.dev/npm:lodash-es@4.17.21/isSet.js": "93f1595e1b7dcb80a1ec0cac14b912dc17c0a7bfec4aa45f474ce0818a357d38", - "https://jspm.dev/npm:lodash-es@4.17.21/isString": "d61cf99d7df5f3d34c721cce203864c895c42f8952bad13076b288b707e6ff45", - "https://jspm.dev/npm:lodash-es@4.17.21/isSymbol": "b3da76c5736896ae117de3cad1acab416da654430b0633bfa280784aa5ec9002", - "https://jspm.dev/npm:lodash-es@4.17.21/isTypedArray.js": "22ce8523fafc400813c7e5dc6a0431d69d85b902c05266442ea6220e7a035155", - "https://jspm.dev/npm:lodash-es@4.17.21/isUndefined": "e09d60068ad2610cdf18e36d2dfb46b643111ad1da730339c85e59df754a6200", - "https://jspm.dev/npm:lodash-es@4.17.21/isWeakMap.js": "fcfa6e0ca9b7e654edc36d457807c677ed105db894613e780eb529e82e1dc412", - "https://jspm.dev/npm:lodash-es@4.17.21/isWeakSet.js": "46a4f5684b5be06f957846baa9efc6cc103a863e941764a01d34b24c68f03206", - "https://jspm.dev/npm:lodash-es@4.17.21/iteratee": "9055bb4450e37cc3e45ae21b9b3e6a4250e37fd362f8845bd0b467b7d118470e", - "https://jspm.dev/npm:lodash-es@4.17.21/join": "e83f5c598cdc1b58bf51c29381e59e39c2968a18c2373b63dac3d88f47190152", - "https://jspm.dev/npm:lodash-es@4.17.21/kebabCase": "31ee12d63385aa251723be025073dbb44e79bf4c3b1aca87bc130801fd4fc4f1", - "https://jspm.dev/npm:lodash-es@4.17.21/keyBy": "4fec34e1ffbc37a22c859b36b5e624d6c4102f1258c8885d04ad9de1344d1d12", - "https://jspm.dev/npm:lodash-es@4.17.21/keys": "18cf4e46f8ea44a7bbd23ede005f3227a743085e117aefd2389f8a13a20095a9", - "https://jspm.dev/npm:lodash-es@4.17.21/keysIn.js": "1f342cf51df02bcee1b64efb7ba92c5bbe2f5ace95c762f2439939c7c4fb8de1", - "https://jspm.dev/npm:lodash-es@4.17.21/last": "f899fd583be1d49b492737882d85a722be10ce778747ba091e5a52f5f3cee0d5", - "https://jspm.dev/npm:lodash-es@4.17.21/lastIndexOf.js": "2e3909d4f5f5efd5130e864fa55dd283faee067b5a021b5fa78f5f2392db01d4", - "https://jspm.dev/npm:lodash-es@4.17.21/lodash.default.js": "e7a7d61e0dfdded617e205145da2135556c23a522fec611b21cb83877351d0cf", - "https://jspm.dev/npm:lodash-es@4.17.21/lowerCase": "667bea5d334a7c5525d3fc96c632b4db90095e66a82999c325829df3261f4aa8", - "https://jspm.dev/npm:lodash-es@4.17.21/lowerFirst.js": "1e30d7494797655483f33a663b0260f47bd1a1f8047427bff9337f5cdb1776f5", - "https://jspm.dev/npm:lodash-es@4.17.21/lt": "88f318d7e1fed8f0d7f413cbdd7f8ebec3a7084ad3aae3b2f9a51d5ef06fc1ed", - "https://jspm.dev/npm:lodash-es@4.17.21/lte": "5a79259a7e5609c63fd47575f670f5b8c0980648910cbb8c35ab32d60cf88197", - "https://jspm.dev/npm:lodash-es@4.17.21/map": "cd2105f2f4aa636ee5d21748b783a7f9eb3fc492f646de0a50ca381a704b602a", - "https://jspm.dev/npm:lodash-es@4.17.21/mapKeys": "14688535243c5a56bca6957847db4c0409782bf0d1b89c236f5c052a51cfda50", - "https://jspm.dev/npm:lodash-es@4.17.21/mapValues": "883c4a6cc12937de1ccb09622e0047faef3f358163be5e3ad6ec73ec6c7e04d1", - "https://jspm.dev/npm:lodash-es@4.17.21/matches.js": "09660e354eca82406b43723ff3f6419a7b6db96edda3083499a09a6ef24621f8", - "https://jspm.dev/npm:lodash-es@4.17.21/matchesProperty.js": "b1b469f1284d5211e1cb6e2fc6fcea38c3c84f7062c1a9c46c01d4c7c1ca239c", - "https://jspm.dev/npm:lodash-es@4.17.21/max": "8d3066190d9ead2ceba4567c41391310bfcd1072d8c078183224d4c8f7407196", - "https://jspm.dev/npm:lodash-es@4.17.21/maxBy": "fd87a7b69ca4aa66e2b9b486ab06ebb44cf835e8279417f2f21f1a1fb7fcd693", - "https://jspm.dev/npm:lodash-es@4.17.21/mean": "d9112b1343e390732f9119aec27b7e0c366a0446b15f42dc19be8096db0a91cd", - "https://jspm.dev/npm:lodash-es@4.17.21/meanBy": "d18b8a7582b3660774b5d8ae958e95cf91e093107e7791e71d070dbc8c13e775", - "https://jspm.dev/npm:lodash-es@4.17.21/memoize": "52b1e8d5e8b23eac69579284a91c0b4e3b6053a7775cf9b256a2af622dbb1109", - "https://jspm.dev/npm:lodash-es@4.17.21/merge": "51ece8b39ab531022a2d1614c14e35a4f9f8dfd918ecc973327fb8b9db6df5de", - "https://jspm.dev/npm:lodash-es@4.17.21/mergeWith": "7953db5ed70d0c214dde7023bcb52d342ef524cbed97602ed2f1ec49bfe2ad35", - "https://jspm.dev/npm:lodash-es@4.17.21/method.js": "1a9266fcfd7d6aa085a014b97cf7142747eec5f0a03bae03571795e74baf1a75", - "https://jspm.dev/npm:lodash-es@4.17.21/methodOf.js": "82a2ea5254872dfa943e81ca07f2a7c6a83b35ff9703abac1d5253f8c8620c64", - "https://jspm.dev/npm:lodash-es@4.17.21/min": "3ae2c7d6dd31f887fdd88ac29e92d9a35710067c98e5a8bf361aeb116028affc", - "https://jspm.dev/npm:lodash-es@4.17.21/minBy": "d47eae2f068d99b69ddde159a20ba364b91cea35821677ac93eb1a446b85fe0a", - "https://jspm.dev/npm:lodash-es@4.17.21/mixin.js": "5f08e4aade37c0dedf813a7129b7c4d11143c8fe3bed0428ffcfda77e533f5bb", - "https://jspm.dev/npm:lodash-es@4.17.21/multiply.js": "0427ccb31697a7c18cdcbe45b36a66c01c738153c71e0f6155048ad5e2aa1051", - "https://jspm.dev/npm:lodash-es@4.17.21/negate.js": "2c2f477799b6a06b011eaf69f04735288e380b40a7bb4ff3dda38a4a55f3fd93", - "https://jspm.dev/npm:lodash-es@4.17.21/next.js": "0df719fe02d42afc21f56bfd19d7a2cf649eafdb4c1413c20955f882567eaf04", - "https://jspm.dev/npm:lodash-es@4.17.21/noop": "6de4e9f36d685ba26b65ed3cf20c358d0e56454dff87f56c12b1e0b634e8adae", - "https://jspm.dev/npm:lodash-es@4.17.21/now": "14b83605a8a699d9e80c843243a7289a4526961b6f7381a818610dcb783d9866", - "https://jspm.dev/npm:lodash-es@4.17.21/nth": "e089c18fc72731b406b5d811da7f97d74d7a42871f9fcb1de3491c38b16a71af", - "https://jspm.dev/npm:lodash-es@4.17.21/nthArg.js": "2f1aa819dc4c87d989dbfef6d9f6e1bb1e3ec0ee1341eda0575986cc4b114e26", - "https://jspm.dev/npm:lodash-es@4.17.21/omit": "f4ec8901fc1e083a68934b1cdebe0077dc9abdd1de804de1f9c8e172a4310a9c", - "https://jspm.dev/npm:lodash-es@4.17.21/omitBy": "a8536c8eacea56fa3b38e5ea2486ccb74bf0b90865d09735e67049a8dc7fcad0", - "https://jspm.dev/npm:lodash-es@4.17.21/once.js": "03681e124fb45eb55f2878852d46dedc5bc2619bd7dc2a6a761b9bcae4f5ac5e", - "https://jspm.dev/npm:lodash-es@4.17.21/orderBy": "1635ee186574cb264addc0966d29705836b161f1fa4f9d04ef8e91155d0ef118", - "https://jspm.dev/npm:lodash-es@4.17.21/over.js": "1c99c9b42647e2f161c883876a7ec7b1c2679fbbcbd94c1e021bcba804dc919e", - "https://jspm.dev/npm:lodash-es@4.17.21/overArgs.js": "4244732ef6c2e224e08b2993ef44895364c95b1ebe9e5b894e6527f6cc4308bc", - "https://jspm.dev/npm:lodash-es@4.17.21/overEvery.js": "feec5f43759f8fa346a0bc2ac704f002e2f210cfda5acd306d68bf6157667aaf", - "https://jspm.dev/npm:lodash-es@4.17.21/overSome.js": "95b782d51da8dfdb8db71c871cdd0bc76ad07306d211aaa1e0a3408642339a5b", - "https://jspm.dev/npm:lodash-es@4.17.21/pad.js": "9d4b2c84495b2b3d8fa37ab666c1b9ff2310af2aa5461931be48e42e75944464", - "https://jspm.dev/npm:lodash-es@4.17.21/padEnd": "19ad106856f54878fedd49485b735fbe59b9b9d01ad04ecec6189bc388bd5868", - "https://jspm.dev/npm:lodash-es@4.17.21/padStart": "0e9495d03198d32fb5bbcf9dd4267d5cf98d43a28ea4282a91e204689c9cae25", - "https://jspm.dev/npm:lodash-es@4.17.21/parseInt.js": "78ff6f4cbb2ed85d56a66ea392d8575e2f41ddfcda6ea123aa1a4fa637e95081", - "https://jspm.dev/npm:lodash-es@4.17.21/partial": "e72e5a700f6fb35501d00e01ddb4d16717db2d33dbb3926cd3a5da156f4e0e83", - "https://jspm.dev/npm:lodash-es@4.17.21/partialRight": "65d425b664665c3fd8dd2fb40a16e62c06551d620756e35e44024e1724950982", - "https://jspm.dev/npm:lodash-es@4.17.21/partition": "e812cd45b6f1743bc62c3da45c493a75245cdc26168c0d6bfdef7201f250dadc", - "https://jspm.dev/npm:lodash-es@4.17.21/pick": "bb8fe879a04c53b387c616d0192647b90c95738b9effbae8a52c3c2f1d1c7845", - "https://jspm.dev/npm:lodash-es@4.17.21/pickBy": "6175c477381e0626e21d7023f8583a813ea2e48f11eab448f84ea1e6bb1646a2", - "https://jspm.dev/npm:lodash-es@4.17.21/plant.js": "1a0096dd0862dc85e38e44b4b7e41a43cce455843f7f74d8dd7400c1028816a0", - "https://jspm.dev/npm:lodash-es@4.17.21/property": "c122bcc2930c91463c08d2a835aefe0819a797e92ae5f4a4a0a1d572467cca15", - "https://jspm.dev/npm:lodash-es@4.17.21/propertyOf.js": "e28cbeb33c45295a8197703f5e61b0fb773cc88401654e44039e2c23ae22b63d", - "https://jspm.dev/npm:lodash-es@4.17.21/pull": "272bdddc8e82fe87df440c724dd6cff3a9936d6b70deee343ff7e952cae39577", - "https://jspm.dev/npm:lodash-es@4.17.21/pullAll": "82a352945ae8a17df7502c4c5b41383eae0f3cc039c6d3d4e8a7d2a65a2b096c", - "https://jspm.dev/npm:lodash-es@4.17.21/pullAllBy.js": "bed0d8f1a22f2bdf2083470c7cbb9d5ce12a8663825150621f58b28506f40ad1", - "https://jspm.dev/npm:lodash-es@4.17.21/pullAllWith.js": "6b0e038ea77957b4ca07604c75c11186577cc3c8c638fc050532d9e8cdca6a62", - "https://jspm.dev/npm:lodash-es@4.17.21/pullAt.js": "22713d053fff928b60bec8b6cc30bdea279022c736c9f69bea3f82c4da8f149e", - "https://jspm.dev/npm:lodash-es@4.17.21/random": "020932ff32cc01550951035844d8f205a2ad871d92fa3c063d19e7d79834f7d4", - "https://jspm.dev/npm:lodash-es@4.17.21/range": "4d786681240aa091b2790b687c22e2dc0b98cfc71aa16040eb12291b393bff13", - "https://jspm.dev/npm:lodash-es@4.17.21/rangeRight.js": "18a15f0a7afaa9ca718752776dba0d143505768870102ad6b5308f7295ab13cf", - "https://jspm.dev/npm:lodash-es@4.17.21/rearg.js": "ff12f4caebd2b5737e4cb1b7d563b075648e6e14bd5cdc830c0b85d243de838f", - "https://jspm.dev/npm:lodash-es@4.17.21/reduce": "24e5a68af293d800509455160a845ff9faa2125140d1d76bd5741e94f29ea05a", - "https://jspm.dev/npm:lodash-es@4.17.21/reduceRight.js": "9d921a3e72cd05d528298f86ef021e2451a945acb56392170d8a0810b788ba2d", - "https://jspm.dev/npm:lodash-es@4.17.21/reject": "cd7275241297d8a7bef75e663d515cb5c4a4516188beae1df07443731173f865", - "https://jspm.dev/npm:lodash-es@4.17.21/remove": "c83d48ae4b94aad679137ac40abd61cbf63f9d9750a232c81381149d3d779688", - "https://jspm.dev/npm:lodash-es@4.17.21/repeat": "0274ef236657832fbc83925b09e7734b735f2e290f5716408575b8a9d4c70d74", - "https://jspm.dev/npm:lodash-es@4.17.21/replace.js": "0821a30151ca933e7f81637493a0392ceb396c8482b15feb99ac788874e59346", - "https://jspm.dev/npm:lodash-es@4.17.21/rest.js": "6afe2ccc293a4efa62a908b73f0db34571a46ff49ec3a485813bdfbe4ae5d8e8", - "https://jspm.dev/npm:lodash-es@4.17.21/result.js": "1de5e24793b0bbdc6076b0c65c70471dd8279e88182c7399eb781a104a657748", - "https://jspm.dev/npm:lodash-es@4.17.21/reverse": "27643bae051dd4a36f460fc6e58231c32685ee8fd5c1e8c7ffcea14bcbc3eb48", - "https://jspm.dev/npm:lodash-es@4.17.21/round": "1524dbba644c752a59ff99b5e262051139958fb6c8f06927986977cc3a472537", - "https://jspm.dev/npm:lodash-es@4.17.21/sample": "8f4403070d93a583b2a14d544f542732c1b32dd3ee8dc14ce9a53969ca4c38f0", - "https://jspm.dev/npm:lodash-es@4.17.21/sampleSize.js": "df25ef16a04a0dbbe39045c8f26c78d4deb0cd93774207f4c6e9bb891749bd15", - "https://jspm.dev/npm:lodash-es@4.17.21/set": "e7b40055c9c28d79a92375056af6425176ac1857ea1512b76b11ddb575d7a798", - "https://jspm.dev/npm:lodash-es@4.17.21/setWith.js": "aa280adb7aa15e16c2f5fea80c5ef97b7994c79b8c3e189e6aab6dd9bf7f80ad", - "https://jspm.dev/npm:lodash-es@4.17.21/shuffle": "bf0eaf7dfa2fd2ff685704e4edd02d294648b85bab771e5f8ea779bc3dc894fb", - "https://jspm.dev/npm:lodash-es@4.17.21/size": "17ed763ec28d468e432cd0ae8f52235e583b8c1fa971486e23e5a0a69f0fcb03", - "https://jspm.dev/npm:lodash-es@4.17.21/slice": "e7a12e77c31d52049966944e2b5cdc85388f6f0fd2aa7d0f77c64affd681eebd", - "https://jspm.dev/npm:lodash-es@4.17.21/snakeCase": "95ce3ed393a2f362b7eae9805e8d276af29be0fd4ec4734a6b82329ad25093aa", - "https://jspm.dev/npm:lodash-es@4.17.21/some": "3d906e134ec9517db0b469323ff12b74c70e884fc4e743b27bc78211048ea6a3", - "https://jspm.dev/npm:lodash-es@4.17.21/sortBy": "c045e5df5d5da48c8ba230745c1c649580144742e8859ef00665289c631b677c", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedIndex.js": "3db7b0d022bcee1d5b63fd047ad84d545d0fc3a8981c542d6c49361cc3b6c224", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedIndexBy.js": "bfd5cb0f5a8066c675bc9a69606dc2d205cbc87722afd84a0af13dd269ec5c38", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedIndexOf.js": "7b888c5791c7bbf1351ab83154f643f79cb7f8a25ea40adf2afa5cb27e9237e5", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedLastIndex.js": "0d7ccfc1fafc5ae96b8a2505c36f02230afdd23f7d7d4cfdeaa4af41b9e4e345", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedLastIndexBy.js": "20d94a6ef13f00c743710c8bd8910ce4df3c6050f75567a8ba23b297a4c43e91", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedLastIndexOf.js": "7dd80643234877fbad42f00cc938f82866b13d834e3ca016cc86aac3eb0b4331", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedUniq": "ca8b11fcb9d7463f2cfae2e5ae5e12498daf73497b93622837bda08babf7049c", - "https://jspm.dev/npm:lodash-es@4.17.21/sortedUniqBy.js": "6c74893752313639c2056a42243b7f549882ba79775237aa4fdc64b1e547103b", - "https://jspm.dev/npm:lodash-es@4.17.21/split": "b8c5bbfb798317625cbe66f1607a40151c6a9d53b447b309da4cd400f7972c53", - "https://jspm.dev/npm:lodash-es@4.17.21/spread.js": "b80f419c750e09f7a7b4cc96ec704c80e46458421e89f50c55a3d188bdc43373", - "https://jspm.dev/npm:lodash-es@4.17.21/startCase": "6df312b3117a76cc7df353a1de942ed48fc2cec59364a41fb07ef7ccf13ad055", - "https://jspm.dev/npm:lodash-es@4.17.21/startsWith": "e5637c64b2920b3f2604a3e7f53afab861fe530d65ea48994682c9f3f916c005", - "https://jspm.dev/npm:lodash-es@4.17.21/stubArray.js": "01c07e5061d6e15dfd25cec5306dd37f37b50b178afab3cafbffb5c77f1986d8", - "https://jspm.dev/npm:lodash-es@4.17.21/stubFalse.js": "6723abc70044d7816db59795b915e37743dc9eafe5a9a79cd42eac11c7d219cc", - "https://jspm.dev/npm:lodash-es@4.17.21/stubObject.js": "96b0edc09e57d90a3e3d7a9e99927790aecd71a9102c97273eaaf47200eea4be", - "https://jspm.dev/npm:lodash-es@4.17.21/stubString.js": "8e6fd930f048db320e2fd73d70d0cfe5bee10947772ce65051d31c0ed760c37b", - "https://jspm.dev/npm:lodash-es@4.17.21/stubTrue.js": "fc9830f6f9e59a63d39f8281baf84142d71b58bb0172ff90087813351a3a90f7", - "https://jspm.dev/npm:lodash-es@4.17.21/subtract.js": "d003a1b9ff4ced49d73a9bc66eea8f34ac87ad65683af34835c462d26fc1e1d3", - "https://jspm.dev/npm:lodash-es@4.17.21/sum": "576a656dd1d1dbc24bbe237ebfce5d0118e196330be8779444f9b4bbe2ccd544", - "https://jspm.dev/npm:lodash-es@4.17.21/sumBy": "e806c0431e1a1783a938172af9b5015aaa57c192ed6c7bae093805b2426aed05", - "https://jspm.dev/npm:lodash-es@4.17.21/tail.js": "04f8773f7ea2f687b2a61acaef7633b4288b45253327e10bd6d9b5cada6dc302", - "https://jspm.dev/npm:lodash-es@4.17.21/take": "ea6a1e801c9ecae9adc4de027b8aa7c4f63089e854c50971820320778a4942f6", - "https://jspm.dev/npm:lodash-es@4.17.21/takeRight": "322b713a5fc47f048644997464ac1cc5cc19636eccd992202d9dadccc5561033", - "https://jspm.dev/npm:lodash-es@4.17.21/takeRightWhile.js": "971ba35d2f5ff9e4983bfe3373331ba2888b3eda09788ff2b8c4e206338fd1b8", - "https://jspm.dev/npm:lodash-es@4.17.21/takeWhile.js": "dd32a518ff1532b01aab342f5101d77c207295074e4bcc9dd274de3d4ecb3611", - "https://jspm.dev/npm:lodash-es@4.17.21/tap.js": "cd345adafe6c1a7f9820d29c3a0cff55fee0439f0b4b3b7dc823b32015ad60b6", - "https://jspm.dev/npm:lodash-es@4.17.21/template": "289486bf71ca9b667b0e0d3ea0396601f291dc9561c762ab922a7d8f484e8741", - "https://jspm.dev/npm:lodash-es@4.17.21/throttle": "23340d6dc5f0cb9655d3bb32250d3dd9b8cfe5cb9939dfd57d454570fa44ed2d", - "https://jspm.dev/npm:lodash-es@4.17.21/thru.js": "cccca5430e533a46d565cac9ab00fc7dff7a1117e740a1a762aeaa62f26a3f07", - "https://jspm.dev/npm:lodash-es@4.17.21/times": "05c829b3a7a71973c36a74727dcb0df08edb4de5d81696691149ca924b58e8e1", - "https://jspm.dev/npm:lodash-es@4.17.21/toArray": "fad1a3ad0cb8023a2615d30b1389036fbc222c81271050de1eca876cf2c62fb6", - "https://jspm.dev/npm:lodash-es@4.17.21/toFinite.js": "5a7a7e5bce9c93ae02031f0007d391f5469b5a1db55a4e59585b9779c483f3c2", - "https://jspm.dev/npm:lodash-es@4.17.21/toInteger": "95f7b7e6d74a50f866467a6c2b1978d18c48ca6c13159e412bba763582c97e41", - "https://jspm.dev/npm:lodash-es@4.17.21/toIterator.js": "44b4e3339cb9418659cd20d4c152467234566e98b90b9e44358b3879087c30e3", - "https://jspm.dev/npm:lodash-es@4.17.21/toJSON.js": "f2c4c71476b504a06747de41da96327e0a797778863a9919f93da03eb64887d2", - "https://jspm.dev/npm:lodash-es@4.17.21/toLength.js": "72844c6c2a22fdf1591c1a06642ee5e122c13d84360726eb9de3488b2f5cc2cd", - "https://jspm.dev/npm:lodash-es@4.17.21/toLower": "96b0fc5648389e49f6fa104e4ed4194e402b37c0687bb3f98e26c4ddaf0b8d11", - "https://jspm.dev/npm:lodash-es@4.17.21/toNumber": "99a8bcedb653be2c84974330861af557a89ab9a20df496ffa462ca6b1d29c716", - "https://jspm.dev/npm:lodash-es@4.17.21/toPairs": "aeb601ac38108e25c6164f94dda6d4c5795745ba2cb69a3173d64139f68c0ccb", - "https://jspm.dev/npm:lodash-es@4.17.21/toPairsIn.js": "4cc0a70ba169a8eef24e9e11ab45858365df7336d7fd462b52d5d8ac42cf01c6", - "https://jspm.dev/npm:lodash-es@4.17.21/toPath": "47497fdffd75215e63081cbaa59e629be96a742012cc46ed671f1d15b7e8e39d", - "https://jspm.dev/npm:lodash-es@4.17.21/toPlainObject.js": "257f6bfc718fe863b186f2aaf4a392e663b4ad52a12ed0fea1fd5865e7bd08dc", - "https://jspm.dev/npm:lodash-es@4.17.21/toSafeInteger": "3d4cf071898ac7e83a48b78d55e9ed55354002480ad3dadc0effbdadeb3658ef", - "https://jspm.dev/npm:lodash-es@4.17.21/toString": "a5312a2efafb718f0c710d955e25320e57e91320b1816858b8009aafdcfadbb1", - "https://jspm.dev/npm:lodash-es@4.17.21/toUpper.js": "23daafa57bb8c979919322d0b748b620a539cb16e7ce5a41b8432f2193e764a6", - "https://jspm.dev/npm:lodash-es@4.17.21/transform": "4b201cbaa96515d6be272af362c0a23c0f7f47ecdc5a2b342c67feff32134723", - "https://jspm.dev/npm:lodash-es@4.17.21/trim": "2e4292ede70c77943fe375b23eb5514de1db4233b3e258061a5a6241207a5ec9", - "https://jspm.dev/npm:lodash-es@4.17.21/trimEnd": "f3a641abdcdfa247cce0bd437c7970678ffaf668b3776b401247c65302b38ad4", - "https://jspm.dev/npm:lodash-es@4.17.21/trimStart": "fe71383b3daf7bac064e02f9f9ec734476747bb35032ce9f08bf36ec95effd80", - "https://jspm.dev/npm:lodash-es@4.17.21/truncate": "336184358996de54e9092b2173cd1e2bd8c063515c0be427cbcf33b9d74b8d26", - "https://jspm.dev/npm:lodash-es@4.17.21/unary.js": "5feac04d9027cfb6c1ba4f3f735903eba4462f88925fea60f93034e8a8e93704", - "https://jspm.dev/npm:lodash-es@4.17.21/unescape": "44766dd869dbddc1ffce574a9cd847320f2e048700cb74bd8aad26dcb7442f97", - "https://jspm.dev/npm:lodash-es@4.17.21/union": "7573090b84056293244fb317c9a636b856f39b7e5a4fb6d791647b30eb3577e9", - "https://jspm.dev/npm:lodash-es@4.17.21/unionBy": "e83e06a936dc9b1cb7f234cfcbdbc9a1a57830e1239346a9a8b20f78bcdcd826", - "https://jspm.dev/npm:lodash-es@4.17.21/unionWith.js": "a19bed55ed4e574c6e3a17bf243e05ff6d722f0567ac0fb69a46e043c424f1ba", - "https://jspm.dev/npm:lodash-es@4.17.21/uniq": "58a4dcc49f0ddc96785c72d7482192f91b8ebeeef14c92157a9e56ca8f5b039c", - "https://jspm.dev/npm:lodash-es@4.17.21/uniqBy": "f4c15d46e3b27d90a61fc365cbea6fbe7d0a3a318b0cbf1c8e7d910d5aa41b1e", - "https://jspm.dev/npm:lodash-es@4.17.21/uniqWith": "aa15983fd0b8ab3d04f0b6e91e587cbe1879d819c024a5aba74fcac9f795725e", - "https://jspm.dev/npm:lodash-es@4.17.21/uniqueId": "dbf44bce3a3259637a3c9e1b028d31fd8aab2685b8abeb1faa031993713622d7", - "https://jspm.dev/npm:lodash-es@4.17.21/unset": "8966d97bcdd5adc1c349a492a7ff42ce27512d00b54ad76e8ade50a0ab1ee342", - "https://jspm.dev/npm:lodash-es@4.17.21/unzip": "595861857a606d5d58dd74144c6a8c15f40983161199f5b596ca6353f4a0c852", - "https://jspm.dev/npm:lodash-es@4.17.21/unzipWith.js": "e09a67f7a31750bea4630c4d607014ac968f486e71b779a960ea680506ce4b0c", - "https://jspm.dev/npm:lodash-es@4.17.21/update.js": "85d4b78b0e822edbd0eb7736ced53c629c3c988b92975b195110a671ae7f4df8", - "https://jspm.dev/npm:lodash-es@4.17.21/updateWith.js": "d7ff72a422299ccf1c7e05a44333e00dbfa11f053ffdca423250a3db861aa319", - "https://jspm.dev/npm:lodash-es@4.17.21/upperCase": "c432a8ac9ed0dad24a4e4df4e2ffbf60352e19f8dee40cdd2ffddade8972171c", - "https://jspm.dev/npm:lodash-es@4.17.21/upperFirst": "600910c104a63b26c75fffabd807b5a3d839eb5b9e567c29c42762d591b99b75", - "https://jspm.dev/npm:lodash-es@4.17.21/value.js": "f2c4c71476b504a06747de41da96327e0a797778863a9919f93da03eb64887d2", - "https://jspm.dev/npm:lodash-es@4.17.21/valueOf.js": "f2c4c71476b504a06747de41da96327e0a797778863a9919f93da03eb64887d2", - "https://jspm.dev/npm:lodash-es@4.17.21/values": "49278417cefc379cff0bdd0e1b21d196136591e8f0f9ee2d6aadafde2b5cd03c", - "https://jspm.dev/npm:lodash-es@4.17.21/valuesIn.js": "22a998315fac7e36c37b8573cf6ef6578acf0393b35724b8c68fb5e897b39040", - "https://jspm.dev/npm:lodash-es@4.17.21/without": "61631aa957e30468385a43b8543f92dc5f45109af754e173b34ce039074f66ce", - "https://jspm.dev/npm:lodash-es@4.17.21/words": "637192d60f7599cf3eb4f8d64a32d80041819bfd6bfea62e5de51f618092234c", - "https://jspm.dev/npm:lodash-es@4.17.21/wrap.js": "4a46cfc19144c9c0d751fe65fc0129900df6bff64459c7bd64bfe8f37b8b5836", - "https://jspm.dev/npm:lodash-es@4.17.21/wrapperAt.js": "ebdf7dfe6515d56a2485bc5472580496ad918d1bfbe44d08e394bff60cec4b7a", - "https://jspm.dev/npm:lodash-es@4.17.21/wrapperChain.js": "54460671cef771f5bc42946302639505aca21dd48434f46c258f24ac4f950cd5", - "https://jspm.dev/npm:lodash-es@4.17.21/wrapperLodash.js": "9b202a80e7b1963facc2bfdf4b1c636e0c37e76ec336b5cf98b54038abf55ae2", - "https://jspm.dev/npm:lodash-es@4.17.21/wrapperReverse.js": "af14be24b2ddce246c0e979c6e1a33e13a805986cb61d648b5fbc346535574e0", - "https://jspm.dev/npm:lodash-es@4.17.21/xor.js": "97e897e2090c3e759c922b09ec722f851e6270762883157448ce0f361aa90c3a", - "https://jspm.dev/npm:lodash-es@4.17.21/xorBy.js": "3cc987d57c8e3d1e416222821826bd6bdfe8218a45aaf1ba40556cf64aff9629", - "https://jspm.dev/npm:lodash-es@4.17.21/xorWith.js": "27890d393d4b15947b703cf141d7b48be398f7443a0c2f2c8d44e27c71900975", - "https://jspm.dev/npm:lodash-es@4.17.21/zip": "ff1ff54d8b036388ac7e202c81ff1e3e867dcbde158b724e19cdf1e9e9c59e2a", - "https://jspm.dev/npm:lodash-es@4.17.21/zipObject": "b2d67732bd69d97113b64c7c1b6bec4372c28261ed078d2cd0e9e9bc33bdff83", - "https://jspm.dev/npm:lodash-es@4.17.21/zipObjectDeep": "c8e198647a365be25eb3f413104bb36b8e105d8058ce06b9440487ed00773dc5", - "https://jspm.dev/npm:lodash-es@4.17.21/zipWith": "4d329d4b574b05475659fda0400262007a2b4555ea6a08ca4b110783ec3489b0", - "https://jspm.dev/npm:uuid@9.0.0": "97f0953723efa7b59f8e817d29e17829e5ca65f84ad0ed307bf2a01d4527885e", - "https://jspm.dev/uuid": "f0e9c7616b2fcc3874269405b7ee0f63a0e8e9501a0dae44005006cd5ff019a6" - } -} diff --git a/apps/deno-vless/project.json b/apps/deno-vless/project.json deleted file mode 100644 index 7964189..0000000 --- a/apps/deno-vless/project.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "deno-vless", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/deno-vless/src", - "targets": { - "build": { - "executor": "@nrwl/deno:bundle", - "outputs": ["dist/apps/deno-vless"], - "options": { - "main": "apps/deno-vless/src/main.ts", - "outputFile": "dist/apps/deno-vless/main.js", - "denoConfig": "apps/deno-vless/deno.json" - } - }, - "serve": { - "executor": "@nrwl/deno:run", - "options": { - "buildTarget": "deno-vless:build", - "watch": true - } - }, - "deno-bunled": { - "executor": "nx:run-commands", - "options": { - "cwd": "apps/deno-vless", - "command": "deno bundle src/main.ts deno-bunled.js" - } - }, - "test": { - "executor": "@nrwl/deno:test", - "outputs": ["coverage/apps/deno-vless"], - "options": { - "coverageDirectory": "coverage/apps/deno-vless", - "denoConfig": "apps/deno-vless/deno.json" - } - }, - "lint": { - "executor": "@nrwl/deno:lint", - "options": { - "denoConfig": "apps/deno-vless/deno.json" - } - } - }, - "implicitDependencies": ["cf-page-vless"], - "tags": [] -} diff --git a/apps/deno-vless/src/client.ts b/apps/deno-vless/src/client.ts deleted file mode 100644 index 9c0e589..0000000 --- a/apps/deno-vless/src/client.ts +++ /dev/null @@ -1,54 +0,0 @@ -async function serveClient(req: Request, basePath: string) { - const url = new URL(req.url) - if (url.pathname.startsWith('/assets') || url.pathname.includes(basePath)) { - // const resp = await serveDir(req, { - // fsRoot: `${Deno.cwd()}/dist/apps/cf-page`, - // }); - // resp.headers.set('cache-control', 'public, max-age=2592000'); - let targetUrl = `https://raw.githubusercontent.com/zizifn/edgetunnel/main/dist/apps/cf-page${url.pathname}`; - if(url.pathname.includes(basePath)){ - targetUrl = `https://raw.githubusercontent.com/zizifn/edgetunnel/main/dist/apps/cf-page/index.html`; - } - console.log(targetUrl) - const resp = await fetch(targetUrl); - const modifiedHeaders = new Headers(resp.headers); - modifiedHeaders.delete('content-security-policy'); - if(url.pathname.endsWith('.js')){ - modifiedHeaders.set('content-type', 'application/javascript'); - }else if(url.pathname.endsWith('.css')){ - modifiedHeaders.set('content-type', 'text/css'); - }else if(url.pathname.includes(basePath)){ - modifiedHeaders.set('content-type', 'text/html; charset=utf-8'); - - } - return new Response( - resp.body, - { - status: resp.status, - headers: modifiedHeaders - } - ); - } - const basicAuth = req.headers.get('Authorization') || ''; - const authString = basicAuth.split(' ')?.[1] || ''; - if (atob(authString).includes(basePath)) { - console.log('302'); - return new Response(``, { - status: 302, - headers: { - 'content-type': 'text/html; charset=utf-8', - Location: `./${basePath}`, - }, - }); - } else { - return new Response(``, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic', - }, - }); - } -} - -export { serveClient }; diff --git a/apps/deno-vless/src/main.ts b/apps/deno-vless/src/main.ts deleted file mode 100644 index fd8e9e6..0000000 --- a/apps/deno-vless/src/main.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { serve } from 'https://deno.land/std@0.170.0/http/server.ts'; -import * as uuid from 'https://jspm.dev/uuid'; -import { serveClient } from './client.ts'; -import { - safeCloseWebSocket, - delay, - makeReadableWebSocketStream, - processVlessHeader, -} from 'vless-js'; - -const userID = Deno.env.get('UUID') || ''; -let isVaildUser = uuid.validate(userID); -if (!isVaildUser) { - console.log('not set valid UUID'); -} - -const handler = async (req: Request): Promise => { - if (!isVaildUser) { - const index401 = await Deno.readFile( - `${Deno.cwd()}/dist/apps/cf-page/401.html` - ); - return new Response(index401, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - }, - }); - } - const upgrade = req.headers.get('upgrade') || ''; - if (upgrade.toLowerCase() != 'websocket') { - return await serveClient(req, userID); - } - const { socket, response } = Deno.upgradeWebSocket(req); - socket.addEventListener('open', () => {}); - - // let test: Deno.TcpConn | null = null; - // test!.writable.abort(); - // - const earlyDataHeader = req.headers.get('sec-websocket-protocol') || ''; - - processWebSocket({ - userID, - webSocket: socket, - earlyDataHeader, - // rawTCPFactory: (port: number, hostname: string) => { - // return Deno.connect({ - // port, - // hostname, - // }); - // }, - }); - return response; -}; - -async function processWebSocket({ - userID, - webSocket, - earlyDataHeader, -}: // libs: { uuid, lodash }, -{ - userID: string; - webSocket: WebSocket; - earlyDataHeader: string; - // rawTCPFactory: (port: number, hostname: string) => Promise; - // libs: { uuid: any; lodash: any }; -}) { - let address = ''; - let portWithRandomLog = ''; - let remoteConnection: { - readable: any; - writable: any; - write: (arg0: Uint8Array) => any; - close: () => void; - } | null = null; - let remoteConnectionReadyResolve: Function; - try { - const log = (info: string, event?: any) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - const readableWebSocketStream = makeReadableWebSocketStream( - webSocket, - earlyDataHeader, - log - ); - let vlessResponseHeader: Uint8Array | null = null; - - // ws --> remote - readableWebSocketStream - .pipeTo( - new WritableStream({ - async write(chunk, controller) { - const vlessBuffer = chunk; - if (remoteConnection) { - const number = await remoteConnection.write( - new Uint8Array(vlessBuffer) - ); - return; - } - const { - hasError, - message, - portRemote, - addressRemote, - rawDataIndex, - vlessVersion, - isUDP, - } = processVlessHeader(vlessBuffer, userID); - address = addressRemote || ''; - portWithRandomLog = `${portRemote}--${Math.random()}`; - if (isUDP) { - console.log('udp'); - controller.error( - `[${address}:${portWithRandomLog}] command udp is not support ` - ); - return; - } - if (hasError) { - controller.error(`[${address}:${portWithRandomLog}] ${message} `); - } - // const addressType = requestAddr >> 4; - // const addressLength = requestAddr & 0x0f; - console.log(`[${address}:${portWithRandomLog}] connecting`); - remoteConnection = await Deno.connect({ - port: portRemote!, - hostname: address, - }); - vlessResponseHeader = new Uint8Array([vlessVersion![0], 0]); - const rawClientData = vlessBuffer.slice(rawDataIndex!); - await remoteConnection!.write(new Uint8Array(rawClientData)); - remoteConnectionReadyResolve(remoteConnection); - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is close` - ); - }, - abort(reason) { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, - JSON.stringify(reason) - ); - }, - }) - ) - .catch((error) => { - console.error( - `[${address}:${portWithRandomLog}] readableWebSocketStream pipeto has exception`, - error.stack || error - ); - // error is cancel readable stream anyway, no need close websocket in here - // safeCloseWebSocket(webSocket); - // close remote conn - // remoteConnection?.close(); - }); - await new Promise((resolve) => (remoteConnectionReadyResolve = resolve)); - let remoteChunkCount = 0; - let totoal = 0; - // remote --> ws - await remoteConnection!.readable.pipeTo( - new WritableStream({ - start() { - if (webSocket.readyState === webSocket.OPEN) { - webSocket.send(vlessResponseHeader!); - } - }, - async write(chunk: Uint8Array, controller) { - function send2WebSocket() { - if (webSocket.readyState !== webSocket.OPEN) { - controller.error( - `can't accept data from remoteConnection!.readable when client webSocket is close early` - ); - return; - } - webSocket.send(chunk); - } - - remoteChunkCount++; - //#region - // console.log( - // `${(totoal += - // chunk.length)}, count: ${remoteChunkCount.toString()}, ${ - // chunk.length - // }` - // ); - // https://github.com/zizifn/edgetunnel/issues/87, hack for this issue, maybe websocket sent too many small chunk, - // casue v2ray client can't process https://github.com/denoland/deno/issues/17332 - // limit X number count / bandwith, due to deno can't read bufferedAmount in deno, - // this is deno bug and this will not need in nodejs version - //#endregion - if (remoteChunkCount < 20) { - send2WebSocket(); - } else if (remoteChunkCount < 120) { - await delay(10); // 64kb * 100 = 6m/s - send2WebSocket(); - } else if (remoteChunkCount < 500) { - await delay(20); // (64kb * 1000/20) = 3m/s - send2WebSocket(); - } else { - await delay(50); // (64kb * 1000/50) /s - send2WebSocket(); - } - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] remoteConnection!.readable is close` - ); - }, - abort(reason) { - safeCloseWebSocket(webSocket); - console.error( - `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, - reason - ); - }, - }) - ); - } catch (error: any) { - console.error( - `[${address}:${portWithRandomLog}] processWebSocket has exception `, - error.stack || error - ); - safeCloseWebSocket(webSocket); - } - return; -} - -globalThis.addEventListener('beforeunload', (e) => { - console.log('About to exit...'); -}); - -globalThis.addEventListener('unload', (e) => { - console.log('Exiting'); -}); -serve(handler, { port: 8080, hostname: '0.0.0.0' }); diff --git a/apps/node-vless/.eslintrc.json b/apps/node-vless/.eslintrc.json deleted file mode 100644 index 9d9c0db..0000000 --- a/apps/node-vless/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": ["../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/apps/node-vless/jest.config.ts b/apps/node-vless/jest.config.ts deleted file mode 100644 index 14bc37b..0000000 --- a/apps/node-vless/jest.config.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'node-vless', - preset: '../../jest.preset.js', - globals: {}, - testEnvironment: 'node', - transform: { - '^.+\\.[tj]s$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/apps/node-vless', -}; diff --git a/apps/node-vless/project.json b/apps/node-vless/project.json deleted file mode 100644 index 3bb8fd9..0000000 --- a/apps/node-vless/project.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "node-vless", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/node-vless/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nx/webpack:webpack", - "outputs": ["{options.outputPath}"], - "options": { - "target": "node", - "compiler": "tsc", - "outputPath": "dist/apps/node-vless", - "main": "apps/node-vless/src/main.ts", - "tsConfig": "apps/node-vless/tsconfig.app.json", - "assets": ["apps/node-vless/src/assets"], - "webpackConfig": "apps/node-vless/webpack.config.js", - "isolatedConfig": true, - "babelUpwardRootMode": true, - "sourceMap": true - }, - "configurations": { - "production": { - "optimization": true, - "extractLicenses": true, - "inspect": false, - "fileReplacements": [ - { - "replace": "apps/node-vless/src/environments/environment.ts", - "with": "apps/node-vless/src/environments/environment.prod.ts" - } - ] - } - } - }, - "serve": { - "executor": "@nx/js:node", - "options": { - "buildTarget": "node-vless:build" - }, - "configurations": { - "production": { - "buildTarget": "node-vless:build:production" - } - } - }, - "lint": { - "executor": "@nx/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/node-vless/**/*.ts"] - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/node-vless/jest.config.ts", - "passWithNoTests": true - } - } - }, - "implicitDependencies": ["cf-page-vless"], - "tags": [] -} diff --git a/apps/node-vless/src/app/.gitkeep b/apps/node-vless/src/app/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/node-vless/src/app/utils.ts b/apps/node-vless/src/app/utils.ts deleted file mode 100644 index c1b74b2..0000000 --- a/apps/node-vless/src/app/utils.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { createReadStream, existsSync } from 'node:fs'; -import { IncomingMessage, ServerResponse } from 'node:http'; -import { resolve, join, extname } from 'node:path'; -import { cacheHeader } from 'pretty-cache-header'; - -const mimeLookup = { - '.js': 'application/javascript,charset=UTF-8', - '.html': 'text/html,charset=UTF-8', - '.css': 'text/css; charset=UTF-8', -}; -const staticPath = 'dist/apps/cf-page/'; -const file401 = 'dist/apps/node-vless/assets/401.html'; -let filepath = null; -export function serverStaticFile(req: IncomingMessage, resp: ServerResponse) { - const url = new URL(req.url, `http://${req.headers['host']}`); - let fileurl = url.pathname; - fileurl = join(staticPath, fileurl); - console.log('....', fileurl); - filepath = resolve(fileurl); - console.log(filepath); - - if (existsSync(filepath)) { - let fileExt = extname(filepath); - console.log('fileExt', fileExt); - let mimeType = mimeLookup[fileExt]; - - resp.writeHead(200, { - 'Content-Type': mimeType, - 'Cache-Control': cacheHeader({ - public: true, - maxAge: '1year', - staleWhileRevalidate: '1year', - }), - }); - return createReadStream(filepath).pipe(resp); - } else { - resp.writeHead(404); - resp.write('not found'); - resp.end(); - return resp; - } -} - -export function index401(req: IncomingMessage, resp: ServerResponse) { - const file401Path = resolve(file401); - if (existsSync(file401Path)) { - createReadStream(file401Path).pipe(resp); - } else { - resp.writeHead(401); - resp.write('UUID env not set'); - resp.end(); - } -} - -export function serverIndexPage( - req: IncomingMessage, - resp: ServerResponse, - uuid -) { - // if() -} diff --git a/apps/node-vless/src/assets/.gitkeep b/apps/node-vless/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/node-vless/src/assets/401.html b/apps/node-vless/src/assets/401.html deleted file mode 100644 index 38839d5..0000000 --- a/apps/node-vless/src/assets/401.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - 401 - UUID Not Valid - - - - -

Not set valid UUID in Environment Variables.

-

Please use tool to generate and remember UUID or use this one -

-

You must use same UUID for login this page after config valid UUID Environment Variables -

-

Please refer to deno - deploy guide -

- -

Or maybe check below GIF

- guide - - - - \ No newline at end of file diff --git a/apps/node-vless/src/environments/environment.prod.ts b/apps/node-vless/src/environments/environment.prod.ts deleted file mode 100644 index c966979..0000000 --- a/apps/node-vless/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true, -}; diff --git a/apps/node-vless/src/environments/environment.ts b/apps/node-vless/src/environments/environment.ts deleted file mode 100644 index a20cfe5..0000000 --- a/apps/node-vless/src/environments/environment.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: false, -}; diff --git a/apps/node-vless/src/main.ts b/apps/node-vless/src/main.ts deleted file mode 100644 index 526a73f..0000000 --- a/apps/node-vless/src/main.ts +++ /dev/null @@ -1,409 +0,0 @@ -import { createServer } from 'http'; -import { parse } from 'url'; -import { WebSocketServer, WebSocket } from 'ws'; -import { index401, serverStaticFile } from './app/utils'; -import { validate } from 'uuid'; -import { createReadStream } from 'node:fs'; -import { setDefaultResultOrder } from 'node:dns'; -import { createSocket, Socket as UDPSocket } from 'node:dgram'; - -import { - makeReadableWebSocketStream, - processVlessHeader, - delay, - closeWebSocket, -} from 'vless-js'; -import { connect, Socket } from 'node:net'; -import { Duplex, Readable, Writable } from 'stream'; -import { - TransformStream, - ReadableStream, - WritableStream, -} from 'node:stream/web'; -const port = process.env.PORT; -const smallRAM = process.env.SMALLRAM || false; -const userID = process.env.UUID || ''; -//'ipv4first' or 'verbatim' -const dnOder = process.env.DNSORDER || 'verbatim'; -if (dnOder === 'ipv4first') { - setDefaultResultOrder(dnOder); -} - -let isVaildUser = validate(userID); -if (!isVaildUser) { - console.log('not set valid UUID'); -} - -const server = createServer((req, resp) => { - if (!isVaildUser) { - return index401(req, resp); - } - const url = new URL(req.url, `http://${req.headers['host']}`); - // health check - if (req.method === 'GET' && url.pathname.startsWith('/health')) { - resp.writeHead(200); - resp.write('health 200'); - resp.end(); - return; - } - - // index page - if (url.pathname.includes(userID)) { - const index = 'dist/apps/cf-page/index.html'; - resp.writeHead(200, { - 'Content-Type': 'text/html,charset=UTF-8', - }); - return createReadStream(index).pipe(resp); - } - if (req.method === 'GET' && url.pathname.startsWith('/assets')) { - return serverStaticFile(req, resp); - } - - const basicAuth = req.headers.authorization || ''; - const authStringBase64 = basicAuth.split(' ')?.[1] || ''; - const authString = Buffer.from(authStringBase64, 'base64').toString('ascii'); - if (authString && authString.includes(userID)) { - resp.writeHead(302, { - 'content-type': 'text/html; charset=utf-8', - Location: `./${userID}`, - }); - resp.end(); - } else { - resp.writeHead(401, { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic', - }); - resp.end(); - } -}); -const vlessWServer = new WebSocketServer({ noServer: true }); - -vlessWServer.on('connection', async function connection(ws, request) { - let address = ''; - let portWithRandomLog = ''; - try { - const log = (info: string, event?: any) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - let remoteConnection: Duplex = null; - let udpClientStream: TransformStream = null; - let remoteConnectionReadyResolve: Function; - const earlyDataHeader = request.headers['sec-websocket-protocol']; - const readableWebSocketStream = makeReadableWebSocketStream( - ws, - earlyDataHeader, - log - ); - let vlessResponseHeader: Uint8Array | null = null; - - // ws --> remote - readableWebSocketStream - .pipeTo( - new WritableStream({ - async write(chunk: Buffer, controller) { - if (!Buffer.isBuffer(chunk)) { - chunk = Buffer.from(chunk); - } - if (udpClientStream) { - const writer = udpClientStream.writable.getWriter(); - // nodejs buffer to ArrayBuffer issue - // https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#bufbuffer - await writer.write( - chunk.buffer.slice( - chunk.byteOffset, - chunk.byteOffset + chunk.length - ) - ); - writer.releaseLock(); - return; - } - if (remoteConnection) { - await socketAsyncWrite(remoteConnection, chunk); - // remoteConnection.write(chunk); - return; - } - const vlessBuffer = chunk.buffer.slice( - chunk.byteOffset, - chunk.byteOffset + chunk.length - ); - const { - hasError, - message, - portRemote, - addressRemote, - rawDataIndex, - vlessVersion, - isUDP, - } = processVlessHeader(vlessBuffer, userID); - address = addressRemote || ''; - portWithRandomLog = `${portRemote}--${Math.random()} ${ - isUDP ? 'udp ' : 'tcp ' - } `; - if (hasError) { - controller.error(`[${address}:${portWithRandomLog}] ${message} `); - return; - } - // const addressType = requestAddr >> 42 - // const addressLength = requestAddr & 0x0f; - console.log(`[${address}:${portWithRandomLog}] connecting`); - vlessResponseHeader = new Uint8Array([vlessVersion![0], 0]); - const rawClientData = vlessBuffer.slice(rawDataIndex!); - if (isUDP) { - // 如果仅仅是针对DNS, 这样是没有必要的。因为xray 客户端 DNS A/AAA query 都有长度 header, - // 所以直接和 DNS server over TCP。所以无需 runtime 支持 UDP API。 - // DNS over UDP 和 TCP 唯一的区别就是 Header section format 多了长度 - // https://www.rfc-editor.org/rfc/rfc1035#section-4.2.2 - udpClientStream = makeUDPSocketStream(portRemote, address); - const writer = udpClientStream.writable.getWriter(); - writer.write(rawClientData).catch((error) => console.log); - writer.releaseLock(); - remoteConnectionReadyResolve(udpClientStream); - } else { - remoteConnection = await connect2Remote(portRemote, address, log); - remoteConnection.write(new Uint8Array(rawClientData)); - remoteConnectionReadyResolve(remoteConnection); - } - }, - close() { - // if (udpClientStream ) { - // udpClientStream.writable.close(); - // } - // (remoteConnection as Socket).end(); - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is close` - ); - }, - abort(reason) { - // TODO: log can be remove, abort will catch by catch block - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, - JSON.stringify(reason) - ); - }, - }) - ) - .catch((error) => { - console.error( - `[${address}:${portWithRandomLog}] readableWebSocketStream pipeto has exception`, - error.stack || error - ); - // error is cancel readable stream anyway, no need close websocket in here - // closeWebSocket(webSocket); - // close remote conn - // remoteConnection?.close(); - }); - - await new Promise((resolve) => (remoteConnectionReadyResolve = resolve)); - // remote --> ws - let responseStream = udpClientStream?.readable; - if (remoteConnection) { - // ignore type error - // @ts-ignore - responseStream = Readable.toWeb(remoteConnection, { - strategy: { - // due to nodejs issue https://github.com/nodejs/node/issues/46347 - highWaterMark: smallRAM ? 100 : 1000, // 1000 * tcp mtu(64kb) = 64mb - }, - }); - } - let count = 0; - - // ws.send(vlessResponseHeader!); - // remoteConnection.pipe( - // new Writable({ - // async write(chunk: Uint8Array, encoding, callback) { - // count += chunk.byteLength; - // console.log('ws write', count / (1024 * 1024)); - // console.log( - // '-----++++', - // (remoteConnection as Socket).bytesRead / (1024 * 1024) - // ); - // if (ws.readyState === ws.OPEN) { - // await wsAsyncWrite(ws, chunk); - // callback(); - // } - // }, - // }) - // ); - // if readable not pipe can't wait fro writeable write method - await responseStream.pipeTo( - new WritableStream({ - start() { - if (ws.readyState === ws.OPEN) { - ws.send(vlessResponseHeader!); - } - }, - async write(chunk: Uint8Array, controller) { - // count += chunk.byteLength; - // console.log('ws write', count / (1024 * 1024)); - // console.log( - // '-----++++', - // (remoteConnection as Socket).bytesRead / (1024 * 1024), - // (remoteConnection as Socket).readableHighWaterMark - // ); - // we have issue there, maybe beacsue nodejs web stream has bug. - // socket web stream will read more data from socket - if (ws.readyState === ws.OPEN) { - await wsAsyncWrite(ws, chunk); - } else { - if (!(remoteConnection as Socket).destroyed) { - (remoteConnection as Socket).destroy(); - } - } - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] remoteConnection!.readable is close` - ); - }, - abort(reason) { - closeWebSocket(ws); - console.error( - `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, - reason - ); - }, - }) - ); - } catch (error) { - console.error( - `[${address}:${portWithRandomLog}] processWebSocket has exception `, - error.stack || error - ); - closeWebSocket(ws); - } -}); - -server.on('upgrade', function upgrade(request, socket, head) { - const { pathname } = parse(request.url); - - vlessWServer.handleUpgrade(request, socket, head, function done(ws) { - vlessWServer.emit('connection', ws, request); - }); -}); - -server.listen( - { - port: port, - host: '::', - // host: '0.0.0.0', - }, - () => { - console.log(`server listen in http://127.0.0.1:${port}`); - } -); - -async function connect2Remote(port, host, log: Function): Promise { - return new Promise((resole, reject) => { - const remoteSocket = connect( - { - port: port, - host: host, - // https://github.com/nodejs/node/pull/46587 - // autoSelectFamily: true, - }, - () => { - log(`connected`); - resole(remoteSocket); - } - ); - remoteSocket.addListener('error', () => { - reject('remoteSocket has error'); - }); - }); -} - -async function socketAsyncWrite(ws: Duplex, chunk: Buffer) { - return new Promise((resolve, reject) => { - ws.write(chunk, (error) => { - if (error) { - reject(error); - } else { - resolve(''); - } - }); - }); -} - -async function wsAsyncWrite(ws: WebSocket, chunk: Uint8Array) { - return new Promise((resolve, reject) => { - ws.send(chunk, (error) => { - if (error) { - reject(error); - } else { - resolve(''); - } - }); - }); -} - -function makeUDPSocketStream(portRemote, address) { - const udpClient = createSocket('udp4'); - const transformStream = new TransformStream({ - start(controller) { - /* … */ - udpClient.on('message', (message, info) => { - // console.log( - // `udp package received ${info.size} bytes from ${info.address}:${info.port}`, - // Buffer.from(message).toString('hex') - // ); - controller.enqueue( - Buffer.concat([ - new Uint8Array([(info.size >> 8) & 0xff, info.size & 0xff]), - message, - ]) - ); - }); - udpClient.on('error', (error) => { - console.log('udpClient error event', error); - controller.error(error); - }); - }, - - async transform(chunk: ArrayBuffer, controller) { - //seems v2ray will use same web socket for dns query.. - //And v2ray will combine A record and AAAA record into one ws message and use 2 btye for dns query length - for (let index = 0; index < chunk.byteLength; ) { - const lengthBuffer = chunk.slice(index, index + 2); - const udpPakcetLength = new DataView(lengthBuffer).getInt16(0); - const udpData = new Uint8Array( - chunk.slice(index + 2, index + 2 + udpPakcetLength) - ); - index = index + 2 + udpPakcetLength; - await new Promise((resolve, reject) => { - udpClient.send(udpData, portRemote, address, (err) => { - if (err) { - console.log('udps send error', err); - controller.error(`Failed to send UDP packet !! ${err}`); - safeCloseUDP(udpClient); - } - // console.log( - // 'udp package sent', - // Buffer.from(udpData).toString('hex') - // ); - resolve(true); - }); - }); - index = index; - } - - // console.log('dns chunk', chunk); - // console.log(portRemote, address); - // port is big-Endian in raw data etc 80 == 0x005d - }, - - flush(controller) { - safeCloseUDP(udpClient); - controller.terminate(); - }, - }); - return transformStream; -} - -function safeCloseUDP(client: UDPSocket) { - try { - client.close(); - } catch (error) { - console.log('error close udp', error); - } -} diff --git a/apps/node-vless/tsconfig.app.json b/apps/node-vless/tsconfig.app.json deleted file mode 100644 index 0d16dce..0000000 --- a/apps/node-vless/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["node"] - }, - "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"], - "include": ["**/*.ts"] -} diff --git a/apps/node-vless/tsconfig.json b/apps/node-vless/tsconfig.json deleted file mode 100644 index 63dbe35..0000000 --- a/apps/node-vless/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] -} diff --git a/apps/node-vless/tsconfig.spec.json b/apps/node-vless/tsconfig.spec.json deleted file mode 100644 index 546f128..0000000 --- a/apps/node-vless/tsconfig.spec.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] -} diff --git a/apps/node-vless/webpack.config.js b/apps/node-vless/webpack.config.js deleted file mode 100644 index 588bfa0..0000000 --- a/apps/node-vless/webpack.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const { composePlugins, withNx } = require('@nx/webpack'); - -// Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/packages/webpack/documents/webpack-config-setup - return config; -}); diff --git a/babel.config.json b/babel.config.json deleted file mode 100644 index 065aee7..0000000 --- a/babel.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "babelrcRoots": ["*"] -} diff --git a/client-config/cf-proxy.js b/client-config/cf-proxy.js deleted file mode 100644 index 526bfdd..0000000 --- a/client-config/cf-proxy.js +++ /dev/null @@ -1,9 +0,0 @@ -export default { - async fetch(request, env) { - let url = new URL(request.url); - url.hostname = '' - let new_request = new Request(url, request); - console.log('-----', new_request.url) - return fetch(new_request); - }, -}; \ No newline at end of file diff --git a/client-config/config-client-with-dns-lcoal.json b/client-config/config-client-with-dns-lcoal.json deleted file mode 100644 index cd37300..0000000 --- a/client-config/config-client-with-dns-lcoal.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "log": { - "loglevel": "debug" - }, - "inbounds": [ - { - "listen": "0.0.0.0", - "port": "4080", - "protocol": "socks", - "settings": { - "auth": "noauth", - "udp": true, - "ip": "0.0.0.0" - } - }, - { - "listen": "0.0.0.0", - "port": "4081", - "protocol": "http" - } - ], - "dns": { - "servers": ["8.8.8.8"] - }, - "outbounds": [ - { - "protocol": "vless", - "settings": { - "vnext": [ - { - "address": "127.0.0.1", - "port": 8788, - "users": [ - { - "id": "1a403b79-039b-4dc2-9b45-1ad13197b99a", - "encryption": "none", - "level": 0 - } - ] - } - ] - }, - "streamSettings": { - "network": "ws", - "wsSettings": { - "path": "/vless" - } - // "security": "tls" - }, - "tag": "zizi-ws" - }, - { - "protocol": "freedom", - "tag": "direct" - } - ], - "routing": { - "domainStrategy": "IPIfNonMatch", - "rules": [ - { - "type": "field", - "ip": ["8.8.8.8"], - "outboundTag": "zizi-ws" - }, - { - "type": "field", - "ip": ["geoip:private"], - "outboundTag": "zizi-ws" - } - ] - } -} diff --git a/client-config/config-client-without-dns-lcoal.json b/client-config/config-client-without-dns-lcoal.json deleted file mode 100644 index 77af096..0000000 --- a/client-config/config-client-without-dns-lcoal.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "log": { - "loglevel": "debug" - }, - "inbounds": [ - { - "listen": "0.0.0.0", - "port": "4080", - "protocol": "socks", - "settings": { - "auth": "noauth", - "udp": true, - "ip": "0.0.0.0" - } - }, - { - "listen": "0.0.0.0", - "port": "4081", - "protocol": "http" - } - ], - "dns": { - "servers": ["8.8.8.8"] - }, - "outbounds": [ - { - "protocol": "vless", - "settings": { - "vnext": [ - { - "address": "127.0.0.1", - "port": 8787, - "users": [ - { - "id": "1a403b79-039b-4dc2-9b45-1ad13197b99a", - "encryption": "none", - "level": 0 - } - ] - } - ] - }, - "streamSettings": { - "network": "ws" - // "wsSettings": { - // "path": "/node-vless" - // } - // "security": "tls" - }, - "tag": "zizi-ws" - }, - { - "protocol": "freedom", - "tag": "direct" - } - ], - "routing": { - "domainStrategy": "IPIfNonMatch", - "rules": [ - { - "type": "field", - "ip": ["8.8.8.8"], - "outboundTag": "zizi-ws" - }, - { - "type": "field", - "ip": ["geoip:private"], - "outboundTag": "zizi-ws" - } - ] - } -} diff --git a/client-config/config-client.json b/client-config/config-client.json deleted file mode 100644 index baf1f4d..0000000 --- a/client-config/config-client.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "log": { - "loglevel": "debug" - }, - "inbounds": [ - { - "listen": "0.0.0.0", - "port": "4080", - "protocol": "socks", - "settings": { - "auth": "noauth", - "udp": true, - "ip": "0.0.0.0" - } - }, - { - "listen": "0.0.0.0", - "port": "4081", - "protocol": "http" - } - ], - "dns": { - "servers": ["8.8.8.8"] - }, - "outbounds": [ - { - "protocol": "vless", - "settings": { - "vnext": [ - { - "address": "192.203.230.111", - "port": 80, - "users": [ - { - "id": "1a403b79-039b-4dc2-9b45-1ad13197b99a", - "encryption": "none", - "level": 0 - } - ] - } - ] - }, - "streamSettings": { - "network": "ws", - "wsSettings": { - "headers": { - "Host": "xxxxx.xxxx.xyz" - } - } - // "security": "tls" - }, - "tag": "zizi-ws" - }, - { - "protocol": "freedom", - "tag": "direct" - } - ], - "routing": { - "domainStrategy": "AsIs", - "rules": [ - // { - // "type": "field", - // "ip": ["8.8.8.8"], - // "outboundTag": "zizi-ws" - // }, - { - "type": "field", - "ip": ["geoip:private"], - "outboundTag": "zizi-ws" - } - ] - } -} diff --git a/client-config/readme.md b/client-config/readme.md deleted file mode 100644 index fb086c7..0000000 --- a/client-config/readme.md +++ /dev/null @@ -1 +0,0 @@ -# Test local with DNS proxy diff --git a/config.json b/config.json deleted file mode 100644 index f326e3d..0000000 --- a/config.json +++ /dev/null @@ -1 +0,0 @@ -{"port":"8134","address":"https://cute-goose-13.deno.dev/","uuid":"james","save":true} \ No newline at end of file diff --git a/dist/apps/node-vless/assets/.gitkeep b/dist/apps/node-vless/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/dist/apps/node-vless/assets/401.html b/dist/apps/node-vless/assets/401.html deleted file mode 100644 index 38839d5..0000000 --- a/dist/apps/node-vless/assets/401.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - 401 - UUID Not Valid - - - - -

Not set valid UUID in Environment Variables.

-

Please use tool to generate and remember UUID or use this one -

-

You must use same UUID for login this page after config valid UUID Environment Variables -

-

Please refer to deno - deploy guide -

- -

Or maybe check below GIF

- guide - - - - \ No newline at end of file diff --git a/dist/apps/node-vless/main.js b/dist/apps/node-vless/main.js deleted file mode 100644 index d7d8933..0000000 --- a/dist/apps/node-vless/main.js +++ /dev/null @@ -1,6374 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ([ -/* 0 */, -/* 1 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "__assign": () => (/* binding */ __assign), -/* harmony export */ "__asyncDelegator": () => (/* binding */ __asyncDelegator), -/* harmony export */ "__asyncGenerator": () => (/* binding */ __asyncGenerator), -/* harmony export */ "__asyncValues": () => (/* binding */ __asyncValues), -/* harmony export */ "__await": () => (/* binding */ __await), -/* harmony export */ "__awaiter": () => (/* binding */ __awaiter), -/* harmony export */ "__classPrivateFieldGet": () => (/* binding */ __classPrivateFieldGet), -/* harmony export */ "__classPrivateFieldIn": () => (/* binding */ __classPrivateFieldIn), -/* harmony export */ "__classPrivateFieldSet": () => (/* binding */ __classPrivateFieldSet), -/* harmony export */ "__createBinding": () => (/* binding */ __createBinding), -/* harmony export */ "__decorate": () => (/* binding */ __decorate), -/* harmony export */ "__esDecorate": () => (/* binding */ __esDecorate), -/* harmony export */ "__exportStar": () => (/* binding */ __exportStar), -/* harmony export */ "__extends": () => (/* binding */ __extends), -/* harmony export */ "__generator": () => (/* binding */ __generator), -/* harmony export */ "__importDefault": () => (/* binding */ __importDefault), -/* harmony export */ "__importStar": () => (/* binding */ __importStar), -/* harmony export */ "__makeTemplateObject": () => (/* binding */ __makeTemplateObject), -/* harmony export */ "__metadata": () => (/* binding */ __metadata), -/* harmony export */ "__param": () => (/* binding */ __param), -/* harmony export */ "__propKey": () => (/* binding */ __propKey), -/* harmony export */ "__read": () => (/* binding */ __read), -/* harmony export */ "__rest": () => (/* binding */ __rest), -/* harmony export */ "__runInitializers": () => (/* binding */ __runInitializers), -/* harmony export */ "__setFunctionName": () => (/* binding */ __setFunctionName), -/* harmony export */ "__spread": () => (/* binding */ __spread), -/* harmony export */ "__spreadArray": () => (/* binding */ __spreadArray), -/* harmony export */ "__spreadArrays": () => (/* binding */ __spreadArrays), -/* harmony export */ "__values": () => (/* binding */ __values) -/* harmony export */ }); -/****************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -var __assign = function() { - __assign = Object.assign || function __assign(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; - } - return t; - } - return __assign.apply(this, arguments); -} - -function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -} - -function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} - -function __param(paramIndex, decorator) { - return function (target, key) { decorator(target, key, paramIndex); } -} - -function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { - function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } - var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; - var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; - var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); - var _, done = false; - for (var i = decorators.length - 1; i >= 0; i--) { - var context = {}; - for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; - for (var p in contextIn.access) context.access[p] = contextIn.access[p]; - context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; - var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); - if (kind === "accessor") { - if (result === void 0) continue; - if (result === null || typeof result !== "object") throw new TypeError("Object expected"); - if (_ = accept(result.get)) descriptor.get = _; - if (_ = accept(result.set)) descriptor.set = _; - if (_ = accept(result.init)) initializers.push(_); - } - else if (_ = accept(result)) { - if (kind === "field") initializers.push(_); - else descriptor[key] = _; - } - } - if (target) Object.defineProperty(target, contextIn.name, descriptor); - done = true; -}; - -function __runInitializers(thisArg, initializers, value) { - var useValue = arguments.length > 2; - for (var i = 0; i < initializers.length; i++) { - value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); - } - return useValue ? value : void 0; -}; - -function __propKey(x) { - return typeof x === "symbol" ? x : "".concat(x); -}; - -function __setFunctionName(f, name, prefix) { - if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; - return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); -}; - -function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); -} - -function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -var __createBinding = Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -}); - -function __exportStar(m, o) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); -} - -function __values(o) { - var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; - if (m) return m.call(o); - if (o && typeof o.length === "number") return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; - throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); -} - -function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -} - -/** @deprecated */ -function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; -} - -/** @deprecated */ -function __spreadArrays() { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; -} - -function __spreadArray(to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -} - -function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); -} - -function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; - function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } - function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } - function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } - function fulfill(value) { resume("next", value); } - function reject(value) { resume("throw", value); } - function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } -} - -function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; - function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } -} - -function __asyncValues(o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } -} - -function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } - return cooked; -}; - -var __setModuleDefault = Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}; - -function __importStar(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -} - -function __importDefault(mod) { - return (mod && mod.__esModule) ? mod : { default: mod }; -} - -function __classPrivateFieldGet(receiver, state, kind, f) { - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); -} - -function __classPrivateFieldSet(receiver, state, value, kind, f) { - if (kind === "m") throw new TypeError("Private method is not writable"); - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); - return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; -} - -function __classPrivateFieldIn(state, receiver) { - if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); - return typeof state === "function" ? receiver === state : state.has(receiver); -} - - -/***/ }), -/* 2 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("http"); - -/***/ }), -/* 3 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("url"); - -/***/ }), -/* 4 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const WebSocket = __webpack_require__(5); - -WebSocket.createWebSocketStream = __webpack_require__(23); -WebSocket.Server = __webpack_require__(24); -WebSocket.Receiver = __webpack_require__(17); -WebSocket.Sender = __webpack_require__(20); - -WebSocket.WebSocket = WebSocket; -WebSocket.WebSocketServer = WebSocket.Server; - -module.exports = WebSocket; - - -/***/ }), -/* 5 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; -/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Readable$" }] */ - - - -const EventEmitter = __webpack_require__(6); -const https = __webpack_require__(7); -const http = __webpack_require__(2); -const net = __webpack_require__(8); -const tls = __webpack_require__(9); -const { randomBytes, createHash } = __webpack_require__(10); -const { Readable } = __webpack_require__(11); -const { URL } = __webpack_require__(3); - -const PerMessageDeflate = __webpack_require__(12); -const Receiver = __webpack_require__(17); -const Sender = __webpack_require__(20); -const { - BINARY_TYPES, - EMPTY_BUFFER, - GUID, - kForOnEventAttribute, - kListener, - kStatusCode, - kWebSocket, - NOOP -} = __webpack_require__(15); -const { - EventTarget: { addEventListener, removeEventListener } -} = __webpack_require__(21); -const { format, parse } = __webpack_require__(22); -const { toBuffer } = __webpack_require__(14); - -const closeTimeout = 30 * 1000; -const kAborted = Symbol('kAborted'); -const protocolVersions = [8, 13]; -const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']; -const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/; - -/** - * Class representing a WebSocket. - * - * @extends EventEmitter - */ -class WebSocket extends EventEmitter { - /** - * Create a new `WebSocket`. - * - * @param {(String|URL)} address The URL to which to connect - * @param {(String|String[])} [protocols] The subprotocols - * @param {Object} [options] Connection options - */ - constructor(address, protocols, options) { - super(); - - this._binaryType = BINARY_TYPES[0]; - this._closeCode = 1006; - this._closeFrameReceived = false; - this._closeFrameSent = false; - this._closeMessage = EMPTY_BUFFER; - this._closeTimer = null; - this._extensions = {}; - this._paused = false; - this._protocol = ''; - this._readyState = WebSocket.CONNECTING; - this._receiver = null; - this._sender = null; - this._socket = null; - - if (address !== null) { - this._bufferedAmount = 0; - this._isServer = false; - this._redirects = 0; - - if (protocols === undefined) { - protocols = []; - } else if (!Array.isArray(protocols)) { - if (typeof protocols === 'object' && protocols !== null) { - options = protocols; - protocols = []; - } else { - protocols = [protocols]; - } - } - - initAsClient(this, address, protocols, options); - } else { - this._isServer = true; - } - } - - /** - * This deviates from the WHATWG interface since ws doesn't support the - * required default "blob" type (instead we define a custom "nodebuffer" - * type). - * - * @type {String} - */ - get binaryType() { - return this._binaryType; - } - - set binaryType(type) { - if (!BINARY_TYPES.includes(type)) return; - - this._binaryType = type; - - // - // Allow to change `binaryType` on the fly. - // - if (this._receiver) this._receiver._binaryType = type; - } - - /** - * @type {Number} - */ - get bufferedAmount() { - if (!this._socket) return this._bufferedAmount; - - return this._socket._writableState.length + this._sender._bufferedBytes; - } - - /** - * @type {String} - */ - get extensions() { - return Object.keys(this._extensions).join(); - } - - /** - * @type {Boolean} - */ - get isPaused() { - return this._paused; - } - - /** - * @type {Function} - */ - /* istanbul ignore next */ - get onclose() { - return null; - } - - /** - * @type {Function} - */ - /* istanbul ignore next */ - get onerror() { - return null; - } - - /** - * @type {Function} - */ - /* istanbul ignore next */ - get onopen() { - return null; - } - - /** - * @type {Function} - */ - /* istanbul ignore next */ - get onmessage() { - return null; - } - - /** - * @type {String} - */ - get protocol() { - return this._protocol; - } - - /** - * @type {Number} - */ - get readyState() { - return this._readyState; - } - - /** - * @type {String} - */ - get url() { - return this._url; - } - - /** - * Set up the socket and the internal resources. - * - * @param {(net.Socket|tls.Socket)} socket The network socket between the - * server and client - * @param {Buffer} head The first packet of the upgraded stream - * @param {Object} options Options object - * @param {Function} [options.generateMask] The function used to generate the - * masking key - * @param {Number} [options.maxPayload=0] The maximum allowed message size - * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or - * not to skip UTF-8 validation for text and close messages - * @private - */ - setSocket(socket, head, options) { - const receiver = new Receiver({ - binaryType: this.binaryType, - extensions: this._extensions, - isServer: this._isServer, - maxPayload: options.maxPayload, - skipUTF8Validation: options.skipUTF8Validation - }); - - this._sender = new Sender(socket, this._extensions, options.generateMask); - this._receiver = receiver; - this._socket = socket; - - receiver[kWebSocket] = this; - socket[kWebSocket] = this; - - receiver.on('conclude', receiverOnConclude); - receiver.on('drain', receiverOnDrain); - receiver.on('error', receiverOnError); - receiver.on('message', receiverOnMessage); - receiver.on('ping', receiverOnPing); - receiver.on('pong', receiverOnPong); - - socket.setTimeout(0); - socket.setNoDelay(); - - if (head.length > 0) socket.unshift(head); - - socket.on('close', socketOnClose); - socket.on('data', socketOnData); - socket.on('end', socketOnEnd); - socket.on('error', socketOnError); - - this._readyState = WebSocket.OPEN; - this.emit('open'); - } - - /** - * Emit the `'close'` event. - * - * @private - */ - emitClose() { - if (!this._socket) { - this._readyState = WebSocket.CLOSED; - this.emit('close', this._closeCode, this._closeMessage); - return; - } - - if (this._extensions[PerMessageDeflate.extensionName]) { - this._extensions[PerMessageDeflate.extensionName].cleanup(); - } - - this._receiver.removeAllListeners(); - this._readyState = WebSocket.CLOSED; - this.emit('close', this._closeCode, this._closeMessage); - } - - /** - * Start a closing handshake. - * - * +----------+ +-----------+ +----------+ - * - - -|ws.close()|-->|close frame|-->|ws.close()|- - - - * | +----------+ +-----------+ +----------+ | - * +----------+ +-----------+ | - * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING - * +----------+ +-----------+ | - * | | | +---+ | - * +------------------------+-->|fin| - - - - - * | +---+ | +---+ - * - - - - -|fin|<---------------------+ - * +---+ - * - * @param {Number} [code] Status code explaining why the connection is closing - * @param {(String|Buffer)} [data] The reason why the connection is - * closing - * @public - */ - close(code, data) { - if (this.readyState === WebSocket.CLOSED) return; - if (this.readyState === WebSocket.CONNECTING) { - const msg = 'WebSocket was closed before the connection was established'; - abortHandshake(this, this._req, msg); - return; - } - - if (this.readyState === WebSocket.CLOSING) { - if ( - this._closeFrameSent && - (this._closeFrameReceived || this._receiver._writableState.errorEmitted) - ) { - this._socket.end(); - } - - return; - } - - this._readyState = WebSocket.CLOSING; - this._sender.close(code, data, !this._isServer, (err) => { - // - // This error is handled by the `'error'` listener on the socket. We only - // want to know if the close frame has been sent here. - // - if (err) return; - - this._closeFrameSent = true; - - if ( - this._closeFrameReceived || - this._receiver._writableState.errorEmitted - ) { - this._socket.end(); - } - }); - - // - // Specify a timeout for the closing handshake to complete. - // - this._closeTimer = setTimeout( - this._socket.destroy.bind(this._socket), - closeTimeout - ); - } - - /** - * Pause the socket. - * - * @public - */ - pause() { - if ( - this.readyState === WebSocket.CONNECTING || - this.readyState === WebSocket.CLOSED - ) { - return; - } - - this._paused = true; - this._socket.pause(); - } - - /** - * Send a ping. - * - * @param {*} [data] The data to send - * @param {Boolean} [mask] Indicates whether or not to mask `data` - * @param {Function} [cb] Callback which is executed when the ping is sent - * @public - */ - ping(data, mask, cb) { - if (this.readyState === WebSocket.CONNECTING) { - throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); - } - - if (typeof data === 'function') { - cb = data; - data = mask = undefined; - } else if (typeof mask === 'function') { - cb = mask; - mask = undefined; - } - - if (typeof data === 'number') data = data.toString(); - - if (this.readyState !== WebSocket.OPEN) { - sendAfterClose(this, data, cb); - return; - } - - if (mask === undefined) mask = !this._isServer; - this._sender.ping(data || EMPTY_BUFFER, mask, cb); - } - - /** - * Send a pong. - * - * @param {*} [data] The data to send - * @param {Boolean} [mask] Indicates whether or not to mask `data` - * @param {Function} [cb] Callback which is executed when the pong is sent - * @public - */ - pong(data, mask, cb) { - if (this.readyState === WebSocket.CONNECTING) { - throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); - } - - if (typeof data === 'function') { - cb = data; - data = mask = undefined; - } else if (typeof mask === 'function') { - cb = mask; - mask = undefined; - } - - if (typeof data === 'number') data = data.toString(); - - if (this.readyState !== WebSocket.OPEN) { - sendAfterClose(this, data, cb); - return; - } - - if (mask === undefined) mask = !this._isServer; - this._sender.pong(data || EMPTY_BUFFER, mask, cb); - } - - /** - * Resume the socket. - * - * @public - */ - resume() { - if ( - this.readyState === WebSocket.CONNECTING || - this.readyState === WebSocket.CLOSED - ) { - return; - } - - this._paused = false; - if (!this._receiver._writableState.needDrain) this._socket.resume(); - } - - /** - * Send a data message. - * - * @param {*} data The message to send - * @param {Object} [options] Options object - * @param {Boolean} [options.binary] Specifies whether `data` is binary or - * text - * @param {Boolean} [options.compress] Specifies whether or not to compress - * `data` - * @param {Boolean} [options.fin=true] Specifies whether the fragment is the - * last one - * @param {Boolean} [options.mask] Specifies whether or not to mask `data` - * @param {Function} [cb] Callback which is executed when data is written out - * @public - */ - send(data, options, cb) { - if (this.readyState === WebSocket.CONNECTING) { - throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); - } - - if (typeof options === 'function') { - cb = options; - options = {}; - } - - if (typeof data === 'number') data = data.toString(); - - if (this.readyState !== WebSocket.OPEN) { - sendAfterClose(this, data, cb); - return; - } - - const opts = { - binary: typeof data !== 'string', - mask: !this._isServer, - compress: true, - fin: true, - ...options - }; - - if (!this._extensions[PerMessageDeflate.extensionName]) { - opts.compress = false; - } - - this._sender.send(data || EMPTY_BUFFER, opts, cb); - } - - /** - * Forcibly close the connection. - * - * @public - */ - terminate() { - if (this.readyState === WebSocket.CLOSED) return; - if (this.readyState === WebSocket.CONNECTING) { - const msg = 'WebSocket was closed before the connection was established'; - abortHandshake(this, this._req, msg); - return; - } - - if (this._socket) { - this._readyState = WebSocket.CLOSING; - this._socket.destroy(); - } - } -} - -/** - * @constant {Number} CONNECTING - * @memberof WebSocket - */ -Object.defineProperty(WebSocket, 'CONNECTING', { - enumerable: true, - value: readyStates.indexOf('CONNECTING') -}); - -/** - * @constant {Number} CONNECTING - * @memberof WebSocket.prototype - */ -Object.defineProperty(WebSocket.prototype, 'CONNECTING', { - enumerable: true, - value: readyStates.indexOf('CONNECTING') -}); - -/** - * @constant {Number} OPEN - * @memberof WebSocket - */ -Object.defineProperty(WebSocket, 'OPEN', { - enumerable: true, - value: readyStates.indexOf('OPEN') -}); - -/** - * @constant {Number} OPEN - * @memberof WebSocket.prototype - */ -Object.defineProperty(WebSocket.prototype, 'OPEN', { - enumerable: true, - value: readyStates.indexOf('OPEN') -}); - -/** - * @constant {Number} CLOSING - * @memberof WebSocket - */ -Object.defineProperty(WebSocket, 'CLOSING', { - enumerable: true, - value: readyStates.indexOf('CLOSING') -}); - -/** - * @constant {Number} CLOSING - * @memberof WebSocket.prototype - */ -Object.defineProperty(WebSocket.prototype, 'CLOSING', { - enumerable: true, - value: readyStates.indexOf('CLOSING') -}); - -/** - * @constant {Number} CLOSED - * @memberof WebSocket - */ -Object.defineProperty(WebSocket, 'CLOSED', { - enumerable: true, - value: readyStates.indexOf('CLOSED') -}); - -/** - * @constant {Number} CLOSED - * @memberof WebSocket.prototype - */ -Object.defineProperty(WebSocket.prototype, 'CLOSED', { - enumerable: true, - value: readyStates.indexOf('CLOSED') -}); - -[ - 'binaryType', - 'bufferedAmount', - 'extensions', - 'isPaused', - 'protocol', - 'readyState', - 'url' -].forEach((property) => { - Object.defineProperty(WebSocket.prototype, property, { enumerable: true }); -}); - -// -// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes. -// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface -// -['open', 'error', 'close', 'message'].forEach((method) => { - Object.defineProperty(WebSocket.prototype, `on${method}`, { - enumerable: true, - get() { - for (const listener of this.listeners(method)) { - if (listener[kForOnEventAttribute]) return listener[kListener]; - } - - return null; - }, - set(handler) { - for (const listener of this.listeners(method)) { - if (listener[kForOnEventAttribute]) { - this.removeListener(method, listener); - break; - } - } - - if (typeof handler !== 'function') return; - - this.addEventListener(method, handler, { - [kForOnEventAttribute]: true - }); - } - }); -}); - -WebSocket.prototype.addEventListener = addEventListener; -WebSocket.prototype.removeEventListener = removeEventListener; - -module.exports = WebSocket; - -/** - * Initialize a WebSocket client. - * - * @param {WebSocket} websocket The client to initialize - * @param {(String|URL)} address The URL to which to connect - * @param {Array} protocols The subprotocols - * @param {Object} [options] Connection options - * @param {Boolean} [options.followRedirects=false] Whether or not to follow - * redirects - * @param {Function} [options.generateMask] The function used to generate the - * masking key - * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the - * handshake request - * @param {Number} [options.maxPayload=104857600] The maximum allowed message - * size - * @param {Number} [options.maxRedirects=10] The maximum number of redirects - * allowed - * @param {String} [options.origin] Value of the `Origin` or - * `Sec-WebSocket-Origin` header - * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable - * permessage-deflate - * @param {Number} [options.protocolVersion=13] Value of the - * `Sec-WebSocket-Version` header - * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or - * not to skip UTF-8 validation for text and close messages - * @private - */ -function initAsClient(websocket, address, protocols, options) { - const opts = { - protocolVersion: protocolVersions[1], - maxPayload: 100 * 1024 * 1024, - skipUTF8Validation: false, - perMessageDeflate: true, - followRedirects: false, - maxRedirects: 10, - ...options, - createConnection: undefined, - socketPath: undefined, - hostname: undefined, - protocol: undefined, - timeout: undefined, - method: 'GET', - host: undefined, - path: undefined, - port: undefined - }; - - if (!protocolVersions.includes(opts.protocolVersion)) { - throw new RangeError( - `Unsupported protocol version: ${opts.protocolVersion} ` + - `(supported versions: ${protocolVersions.join(', ')})` - ); - } - - let parsedUrl; - - if (address instanceof URL) { - parsedUrl = address; - websocket._url = address.href; - } else { - try { - parsedUrl = new URL(address); - } catch (e) { - throw new SyntaxError(`Invalid URL: ${address}`); - } - - websocket._url = address; - } - - const isSecure = parsedUrl.protocol === 'wss:'; - const isIpcUrl = parsedUrl.protocol === 'ws+unix:'; - let invalidUrlMessage; - - if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) { - invalidUrlMessage = - 'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"'; - } else if (isIpcUrl && !parsedUrl.pathname) { - invalidUrlMessage = "The URL's pathname is empty"; - } else if (parsedUrl.hash) { - invalidUrlMessage = 'The URL contains a fragment identifier'; - } - - if (invalidUrlMessage) { - const err = new SyntaxError(invalidUrlMessage); - - if (websocket._redirects === 0) { - throw err; - } else { - emitErrorAndClose(websocket, err); - return; - } - } - - const defaultPort = isSecure ? 443 : 80; - const key = randomBytes(16).toString('base64'); - const request = isSecure ? https.request : http.request; - const protocolSet = new Set(); - let perMessageDeflate; - - opts.createConnection = isSecure ? tlsConnect : netConnect; - opts.defaultPort = opts.defaultPort || defaultPort; - opts.port = parsedUrl.port || defaultPort; - opts.host = parsedUrl.hostname.startsWith('[') - ? parsedUrl.hostname.slice(1, -1) - : parsedUrl.hostname; - opts.headers = { - ...opts.headers, - 'Sec-WebSocket-Version': opts.protocolVersion, - 'Sec-WebSocket-Key': key, - Connection: 'Upgrade', - Upgrade: 'websocket' - }; - opts.path = parsedUrl.pathname + parsedUrl.search; - opts.timeout = opts.handshakeTimeout; - - if (opts.perMessageDeflate) { - perMessageDeflate = new PerMessageDeflate( - opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, - false, - opts.maxPayload - ); - opts.headers['Sec-WebSocket-Extensions'] = format({ - [PerMessageDeflate.extensionName]: perMessageDeflate.offer() - }); - } - if (protocols.length) { - for (const protocol of protocols) { - if ( - typeof protocol !== 'string' || - !subprotocolRegex.test(protocol) || - protocolSet.has(protocol) - ) { - throw new SyntaxError( - 'An invalid or duplicated subprotocol was specified' - ); - } - - protocolSet.add(protocol); - } - - opts.headers['Sec-WebSocket-Protocol'] = protocols.join(','); - } - if (opts.origin) { - if (opts.protocolVersion < 13) { - opts.headers['Sec-WebSocket-Origin'] = opts.origin; - } else { - opts.headers.Origin = opts.origin; - } - } - if (parsedUrl.username || parsedUrl.password) { - opts.auth = `${parsedUrl.username}:${parsedUrl.password}`; - } - - if (isIpcUrl) { - const parts = opts.path.split(':'); - - opts.socketPath = parts[0]; - opts.path = parts[1]; - } - - let req; - - if (opts.followRedirects) { - if (websocket._redirects === 0) { - websocket._originalIpc = isIpcUrl; - websocket._originalSecure = isSecure; - websocket._originalHostOrSocketPath = isIpcUrl - ? opts.socketPath - : parsedUrl.host; - - const headers = options && options.headers; - - // - // Shallow copy the user provided options so that headers can be changed - // without mutating the original object. - // - options = { ...options, headers: {} }; - - if (headers) { - for (const [key, value] of Object.entries(headers)) { - options.headers[key.toLowerCase()] = value; - } - } - } else if (websocket.listenerCount('redirect') === 0) { - const isSameHost = isIpcUrl - ? websocket._originalIpc - ? opts.socketPath === websocket._originalHostOrSocketPath - : false - : websocket._originalIpc - ? false - : parsedUrl.host === websocket._originalHostOrSocketPath; - - if (!isSameHost || (websocket._originalSecure && !isSecure)) { - // - // Match curl 7.77.0 behavior and drop the following headers. These - // headers are also dropped when following a redirect to a subdomain. - // - delete opts.headers.authorization; - delete opts.headers.cookie; - - if (!isSameHost) delete opts.headers.host; - - opts.auth = undefined; - } - } - - // - // Match curl 7.77.0 behavior and make the first `Authorization` header win. - // If the `Authorization` header is set, then there is nothing to do as it - // will take precedence. - // - if (opts.auth && !options.headers.authorization) { - options.headers.authorization = - 'Basic ' + Buffer.from(opts.auth).toString('base64'); - } - - req = websocket._req = request(opts); - - if (websocket._redirects) { - // - // Unlike what is done for the `'upgrade'` event, no early exit is - // triggered here if the user calls `websocket.close()` or - // `websocket.terminate()` from a listener of the `'redirect'` event. This - // is because the user can also call `request.destroy()` with an error - // before calling `websocket.close()` or `websocket.terminate()` and this - // would result in an error being emitted on the `request` object with no - // `'error'` event listeners attached. - // - websocket.emit('redirect', websocket.url, req); - } - } else { - req = websocket._req = request(opts); - } - - if (opts.timeout) { - req.on('timeout', () => { - abortHandshake(websocket, req, 'Opening handshake has timed out'); - }); - } - - req.on('error', (err) => { - if (req === null || req[kAborted]) return; - - req = websocket._req = null; - emitErrorAndClose(websocket, err); - }); - - req.on('response', (res) => { - const location = res.headers.location; - const statusCode = res.statusCode; - - if ( - location && - opts.followRedirects && - statusCode >= 300 && - statusCode < 400 - ) { - if (++websocket._redirects > opts.maxRedirects) { - abortHandshake(websocket, req, 'Maximum redirects exceeded'); - return; - } - - req.abort(); - - let addr; - - try { - addr = new URL(location, address); - } catch (e) { - const err = new SyntaxError(`Invalid URL: ${location}`); - emitErrorAndClose(websocket, err); - return; - } - - initAsClient(websocket, addr, protocols, options); - } else if (!websocket.emit('unexpected-response', req, res)) { - abortHandshake( - websocket, - req, - `Unexpected server response: ${res.statusCode}` - ); - } - }); - - req.on('upgrade', (res, socket, head) => { - websocket.emit('upgrade', res); - - // - // The user may have closed the connection from a listener of the - // `'upgrade'` event. - // - if (websocket.readyState !== WebSocket.CONNECTING) return; - - req = websocket._req = null; - - if (res.headers.upgrade.toLowerCase() !== 'websocket') { - abortHandshake(websocket, socket, 'Invalid Upgrade header'); - return; - } - - const digest = createHash('sha1') - .update(key + GUID) - .digest('base64'); - - if (res.headers['sec-websocket-accept'] !== digest) { - abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header'); - return; - } - - const serverProt = res.headers['sec-websocket-protocol']; - let protError; - - if (serverProt !== undefined) { - if (!protocolSet.size) { - protError = 'Server sent a subprotocol but none was requested'; - } else if (!protocolSet.has(serverProt)) { - protError = 'Server sent an invalid subprotocol'; - } - } else if (protocolSet.size) { - protError = 'Server sent no subprotocol'; - } - - if (protError) { - abortHandshake(websocket, socket, protError); - return; - } - - if (serverProt) websocket._protocol = serverProt; - - const secWebSocketExtensions = res.headers['sec-websocket-extensions']; - - if (secWebSocketExtensions !== undefined) { - if (!perMessageDeflate) { - const message = - 'Server sent a Sec-WebSocket-Extensions header but no extension ' + - 'was requested'; - abortHandshake(websocket, socket, message); - return; - } - - let extensions; - - try { - extensions = parse(secWebSocketExtensions); - } catch (err) { - const message = 'Invalid Sec-WebSocket-Extensions header'; - abortHandshake(websocket, socket, message); - return; - } - - const extensionNames = Object.keys(extensions); - - if ( - extensionNames.length !== 1 || - extensionNames[0] !== PerMessageDeflate.extensionName - ) { - const message = 'Server indicated an extension that was not requested'; - abortHandshake(websocket, socket, message); - return; - } - - try { - perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]); - } catch (err) { - const message = 'Invalid Sec-WebSocket-Extensions header'; - abortHandshake(websocket, socket, message); - return; - } - - websocket._extensions[PerMessageDeflate.extensionName] = - perMessageDeflate; - } - - websocket.setSocket(socket, head, { - generateMask: opts.generateMask, - maxPayload: opts.maxPayload, - skipUTF8Validation: opts.skipUTF8Validation - }); - }); - - if (opts.finishRequest) { - opts.finishRequest(req, websocket); - } else { - req.end(); - } -} - -/** - * Emit the `'error'` and `'close'` events. - * - * @param {WebSocket} websocket The WebSocket instance - * @param {Error} The error to emit - * @private - */ -function emitErrorAndClose(websocket, err) { - websocket._readyState = WebSocket.CLOSING; - websocket.emit('error', err); - websocket.emitClose(); -} - -/** - * Create a `net.Socket` and initiate a connection. - * - * @param {Object} options Connection options - * @return {net.Socket} The newly created socket used to start the connection - * @private - */ -function netConnect(options) { - options.path = options.socketPath; - return net.connect(options); -} - -/** - * Create a `tls.TLSSocket` and initiate a connection. - * - * @param {Object} options Connection options - * @return {tls.TLSSocket} The newly created socket used to start the connection - * @private - */ -function tlsConnect(options) { - options.path = undefined; - - if (!options.servername && options.servername !== '') { - options.servername = net.isIP(options.host) ? '' : options.host; - } - - return tls.connect(options); -} - -/** - * Abort the handshake and emit an error. - * - * @param {WebSocket} websocket The WebSocket instance - * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to - * abort or the socket to destroy - * @param {String} message The error message - * @private - */ -function abortHandshake(websocket, stream, message) { - websocket._readyState = WebSocket.CLOSING; - - const err = new Error(message); - Error.captureStackTrace(err, abortHandshake); - - if (stream.setHeader) { - stream[kAborted] = true; - stream.abort(); - - if (stream.socket && !stream.socket.destroyed) { - // - // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if - // called after the request completed. See - // https://github.com/websockets/ws/issues/1869. - // - stream.socket.destroy(); - } - - process.nextTick(emitErrorAndClose, websocket, err); - } else { - stream.destroy(err); - stream.once('error', websocket.emit.bind(websocket, 'error')); - stream.once('close', websocket.emitClose.bind(websocket)); - } -} - -/** - * Handle cases where the `ping()`, `pong()`, or `send()` methods are called - * when the `readyState` attribute is `CLOSING` or `CLOSED`. - * - * @param {WebSocket} websocket The WebSocket instance - * @param {*} [data] The data to send - * @param {Function} [cb] Callback - * @private - */ -function sendAfterClose(websocket, data, cb) { - if (data) { - const length = toBuffer(data).length; - - // - // The `_bufferedAmount` property is used only when the peer is a client and - // the opening handshake fails. Under these circumstances, in fact, the - // `setSocket()` method is not called, so the `_socket` and `_sender` - // properties are set to `null`. - // - if (websocket._socket) websocket._sender._bufferedBytes += length; - else websocket._bufferedAmount += length; - } - - if (cb) { - const err = new Error( - `WebSocket is not open: readyState ${websocket.readyState} ` + - `(${readyStates[websocket.readyState]})` - ); - process.nextTick(cb, err); - } -} - -/** - * The listener of the `Receiver` `'conclude'` event. - * - * @param {Number} code The status code - * @param {Buffer} reason The reason for closing - * @private - */ -function receiverOnConclude(code, reason) { - const websocket = this[kWebSocket]; - - websocket._closeFrameReceived = true; - websocket._closeMessage = reason; - websocket._closeCode = code; - - if (websocket._socket[kWebSocket] === undefined) return; - - websocket._socket.removeListener('data', socketOnData); - process.nextTick(resume, websocket._socket); - - if (code === 1005) websocket.close(); - else websocket.close(code, reason); -} - -/** - * The listener of the `Receiver` `'drain'` event. - * - * @private - */ -function receiverOnDrain() { - const websocket = this[kWebSocket]; - - if (!websocket.isPaused) websocket._socket.resume(); -} - -/** - * The listener of the `Receiver` `'error'` event. - * - * @param {(RangeError|Error)} err The emitted error - * @private - */ -function receiverOnError(err) { - const websocket = this[kWebSocket]; - - if (websocket._socket[kWebSocket] !== undefined) { - websocket._socket.removeListener('data', socketOnData); - - // - // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See - // https://github.com/websockets/ws/issues/1940. - // - process.nextTick(resume, websocket._socket); - - websocket.close(err[kStatusCode]); - } - - websocket.emit('error', err); -} - -/** - * The listener of the `Receiver` `'finish'` event. - * - * @private - */ -function receiverOnFinish() { - this[kWebSocket].emitClose(); -} - -/** - * The listener of the `Receiver` `'message'` event. - * - * @param {Buffer|ArrayBuffer|Buffer[])} data The message - * @param {Boolean} isBinary Specifies whether the message is binary or not - * @private - */ -function receiverOnMessage(data, isBinary) { - this[kWebSocket].emit('message', data, isBinary); -} - -/** - * The listener of the `Receiver` `'ping'` event. - * - * @param {Buffer} data The data included in the ping frame - * @private - */ -function receiverOnPing(data) { - const websocket = this[kWebSocket]; - - websocket.pong(data, !websocket._isServer, NOOP); - websocket.emit('ping', data); -} - -/** - * The listener of the `Receiver` `'pong'` event. - * - * @param {Buffer} data The data included in the pong frame - * @private - */ -function receiverOnPong(data) { - this[kWebSocket].emit('pong', data); -} - -/** - * Resume a readable stream - * - * @param {Readable} stream The readable stream - * @private - */ -function resume(stream) { - stream.resume(); -} - -/** - * The listener of the `net.Socket` `'close'` event. - * - * @private - */ -function socketOnClose() { - const websocket = this[kWebSocket]; - - this.removeListener('close', socketOnClose); - this.removeListener('data', socketOnData); - this.removeListener('end', socketOnEnd); - - websocket._readyState = WebSocket.CLOSING; - - let chunk; - - // - // The close frame might not have been received or the `'end'` event emitted, - // for example, if the socket was destroyed due to an error. Ensure that the - // `receiver` stream is closed after writing any remaining buffered data to - // it. If the readable side of the socket is in flowing mode then there is no - // buffered data as everything has been already written and `readable.read()` - // will return `null`. If instead, the socket is paused, any possible buffered - // data will be read as a single chunk. - // - if ( - !this._readableState.endEmitted && - !websocket._closeFrameReceived && - !websocket._receiver._writableState.errorEmitted && - (chunk = websocket._socket.read()) !== null - ) { - websocket._receiver.write(chunk); - } - - websocket._receiver.end(); - - this[kWebSocket] = undefined; - - clearTimeout(websocket._closeTimer); - - if ( - websocket._receiver._writableState.finished || - websocket._receiver._writableState.errorEmitted - ) { - websocket.emitClose(); - } else { - websocket._receiver.on('error', receiverOnFinish); - websocket._receiver.on('finish', receiverOnFinish); - } -} - -/** - * The listener of the `net.Socket` `'data'` event. - * - * @param {Buffer} chunk A chunk of data - * @private - */ -function socketOnData(chunk) { - if (!this[kWebSocket]._receiver.write(chunk)) { - this.pause(); - } -} - -/** - * The listener of the `net.Socket` `'end'` event. - * - * @private - */ -function socketOnEnd() { - const websocket = this[kWebSocket]; - - websocket._readyState = WebSocket.CLOSING; - websocket._receiver.end(); - this.end(); -} - -/** - * The listener of the `net.Socket` `'error'` event. - * - * @private - */ -function socketOnError() { - const websocket = this[kWebSocket]; - - this.removeListener('error', socketOnError); - this.on('error', NOOP); - - if (websocket) { - websocket._readyState = WebSocket.CLOSING; - this.destroy(); - } -} - - -/***/ }), -/* 6 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("events"); - -/***/ }), -/* 7 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("https"); - -/***/ }), -/* 8 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("net"); - -/***/ }), -/* 9 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("tls"); - -/***/ }), -/* 10 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("crypto"); - -/***/ }), -/* 11 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("stream"); - -/***/ }), -/* 12 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const zlib = __webpack_require__(13); - -const bufferUtil = __webpack_require__(14); -const Limiter = __webpack_require__(16); -const { kStatusCode } = __webpack_require__(15); - -const FastBuffer = Buffer[Symbol.species]; -const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]); -const kPerMessageDeflate = Symbol('permessage-deflate'); -const kTotalLength = Symbol('total-length'); -const kCallback = Symbol('callback'); -const kBuffers = Symbol('buffers'); -const kError = Symbol('error'); - -// -// We limit zlib concurrency, which prevents severe memory fragmentation -// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913 -// and https://github.com/websockets/ws/issues/1202 -// -// Intentionally global; it's the global thread pool that's an issue. -// -let zlibLimiter; - -/** - * permessage-deflate implementation. - */ -class PerMessageDeflate { - /** - * Creates a PerMessageDeflate instance. - * - * @param {Object} [options] Configuration options - * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support - * for, or request, a custom client window size - * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ - * acknowledge disabling of client context takeover - * @param {Number} [options.concurrencyLimit=10] The number of concurrent - * calls to zlib - * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the - * use of a custom server window size - * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept - * disabling of server context takeover - * @param {Number} [options.threshold=1024] Size (in bytes) below which - * messages should not be compressed if context takeover is disabled - * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on - * deflate - * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on - * inflate - * @param {Boolean} [isServer=false] Create the instance in either server or - * client mode - * @param {Number} [maxPayload=0] The maximum allowed message length - */ - constructor(options, isServer, maxPayload) { - this._maxPayload = maxPayload | 0; - this._options = options || {}; - this._threshold = - this._options.threshold !== undefined ? this._options.threshold : 1024; - this._isServer = !!isServer; - this._deflate = null; - this._inflate = null; - - this.params = null; - - if (!zlibLimiter) { - const concurrency = - this._options.concurrencyLimit !== undefined - ? this._options.concurrencyLimit - : 10; - zlibLimiter = new Limiter(concurrency); - } - } - - /** - * @type {String} - */ - static get extensionName() { - return 'permessage-deflate'; - } - - /** - * Create an extension negotiation offer. - * - * @return {Object} Extension parameters - * @public - */ - offer() { - const params = {}; - - if (this._options.serverNoContextTakeover) { - params.server_no_context_takeover = true; - } - if (this._options.clientNoContextTakeover) { - params.client_no_context_takeover = true; - } - if (this._options.serverMaxWindowBits) { - params.server_max_window_bits = this._options.serverMaxWindowBits; - } - if (this._options.clientMaxWindowBits) { - params.client_max_window_bits = this._options.clientMaxWindowBits; - } else if (this._options.clientMaxWindowBits == null) { - params.client_max_window_bits = true; - } - - return params; - } - - /** - * Accept an extension negotiation offer/response. - * - * @param {Array} configurations The extension negotiation offers/reponse - * @return {Object} Accepted configuration - * @public - */ - accept(configurations) { - configurations = this.normalizeParams(configurations); - - this.params = this._isServer - ? this.acceptAsServer(configurations) - : this.acceptAsClient(configurations); - - return this.params; - } - - /** - * Releases all resources used by the extension. - * - * @public - */ - cleanup() { - if (this._inflate) { - this._inflate.close(); - this._inflate = null; - } - - if (this._deflate) { - const callback = this._deflate[kCallback]; - - this._deflate.close(); - this._deflate = null; - - if (callback) { - callback( - new Error( - 'The deflate stream was closed while data was being processed' - ) - ); - } - } - } - - /** - * Accept an extension negotiation offer. - * - * @param {Array} offers The extension negotiation offers - * @return {Object} Accepted configuration - * @private - */ - acceptAsServer(offers) { - const opts = this._options; - const accepted = offers.find((params) => { - if ( - (opts.serverNoContextTakeover === false && - params.server_no_context_takeover) || - (params.server_max_window_bits && - (opts.serverMaxWindowBits === false || - (typeof opts.serverMaxWindowBits === 'number' && - opts.serverMaxWindowBits > params.server_max_window_bits))) || - (typeof opts.clientMaxWindowBits === 'number' && - !params.client_max_window_bits) - ) { - return false; - } - - return true; - }); - - if (!accepted) { - throw new Error('None of the extension offers can be accepted'); - } - - if (opts.serverNoContextTakeover) { - accepted.server_no_context_takeover = true; - } - if (opts.clientNoContextTakeover) { - accepted.client_no_context_takeover = true; - } - if (typeof opts.serverMaxWindowBits === 'number') { - accepted.server_max_window_bits = opts.serverMaxWindowBits; - } - if (typeof opts.clientMaxWindowBits === 'number') { - accepted.client_max_window_bits = opts.clientMaxWindowBits; - } else if ( - accepted.client_max_window_bits === true || - opts.clientMaxWindowBits === false - ) { - delete accepted.client_max_window_bits; - } - - return accepted; - } - - /** - * Accept the extension negotiation response. - * - * @param {Array} response The extension negotiation response - * @return {Object} Accepted configuration - * @private - */ - acceptAsClient(response) { - const params = response[0]; - - if ( - this._options.clientNoContextTakeover === false && - params.client_no_context_takeover - ) { - throw new Error('Unexpected parameter "client_no_context_takeover"'); - } - - if (!params.client_max_window_bits) { - if (typeof this._options.clientMaxWindowBits === 'number') { - params.client_max_window_bits = this._options.clientMaxWindowBits; - } - } else if ( - this._options.clientMaxWindowBits === false || - (typeof this._options.clientMaxWindowBits === 'number' && - params.client_max_window_bits > this._options.clientMaxWindowBits) - ) { - throw new Error( - 'Unexpected or invalid parameter "client_max_window_bits"' - ); - } - - return params; - } - - /** - * Normalize parameters. - * - * @param {Array} configurations The extension negotiation offers/reponse - * @return {Array} The offers/response with normalized parameters - * @private - */ - normalizeParams(configurations) { - configurations.forEach((params) => { - Object.keys(params).forEach((key) => { - let value = params[key]; - - if (value.length > 1) { - throw new Error(`Parameter "${key}" must have only a single value`); - } - - value = value[0]; - - if (key === 'client_max_window_bits') { - if (value !== true) { - const num = +value; - if (!Number.isInteger(num) || num < 8 || num > 15) { - throw new TypeError( - `Invalid value for parameter "${key}": ${value}` - ); - } - value = num; - } else if (!this._isServer) { - throw new TypeError( - `Invalid value for parameter "${key}": ${value}` - ); - } - } else if (key === 'server_max_window_bits') { - const num = +value; - if (!Number.isInteger(num) || num < 8 || num > 15) { - throw new TypeError( - `Invalid value for parameter "${key}": ${value}` - ); - } - value = num; - } else if ( - key === 'client_no_context_takeover' || - key === 'server_no_context_takeover' - ) { - if (value !== true) { - throw new TypeError( - `Invalid value for parameter "${key}": ${value}` - ); - } - } else { - throw new Error(`Unknown parameter "${key}"`); - } - - params[key] = value; - }); - }); - - return configurations; - } - - /** - * Decompress data. Concurrency limited. - * - * @param {Buffer} data Compressed data - * @param {Boolean} fin Specifies whether or not this is the last fragment - * @param {Function} callback Callback - * @public - */ - decompress(data, fin, callback) { - zlibLimiter.add((done) => { - this._decompress(data, fin, (err, result) => { - done(); - callback(err, result); - }); - }); - } - - /** - * Compress data. Concurrency limited. - * - * @param {(Buffer|String)} data Data to compress - * @param {Boolean} fin Specifies whether or not this is the last fragment - * @param {Function} callback Callback - * @public - */ - compress(data, fin, callback) { - zlibLimiter.add((done) => { - this._compress(data, fin, (err, result) => { - done(); - callback(err, result); - }); - }); - } - - /** - * Decompress data. - * - * @param {Buffer} data Compressed data - * @param {Boolean} fin Specifies whether or not this is the last fragment - * @param {Function} callback Callback - * @private - */ - _decompress(data, fin, callback) { - const endpoint = this._isServer ? 'client' : 'server'; - - if (!this._inflate) { - const key = `${endpoint}_max_window_bits`; - const windowBits = - typeof this.params[key] !== 'number' - ? zlib.Z_DEFAULT_WINDOWBITS - : this.params[key]; - - this._inflate = zlib.createInflateRaw({ - ...this._options.zlibInflateOptions, - windowBits - }); - this._inflate[kPerMessageDeflate] = this; - this._inflate[kTotalLength] = 0; - this._inflate[kBuffers] = []; - this._inflate.on('error', inflateOnError); - this._inflate.on('data', inflateOnData); - } - - this._inflate[kCallback] = callback; - - this._inflate.write(data); - if (fin) this._inflate.write(TRAILER); - - this._inflate.flush(() => { - const err = this._inflate[kError]; - - if (err) { - this._inflate.close(); - this._inflate = null; - callback(err); - return; - } - - const data = bufferUtil.concat( - this._inflate[kBuffers], - this._inflate[kTotalLength] - ); - - if (this._inflate._readableState.endEmitted) { - this._inflate.close(); - this._inflate = null; - } else { - this._inflate[kTotalLength] = 0; - this._inflate[kBuffers] = []; - - if (fin && this.params[`${endpoint}_no_context_takeover`]) { - this._inflate.reset(); - } - } - - callback(null, data); - }); - } - - /** - * Compress data. - * - * @param {(Buffer|String)} data Data to compress - * @param {Boolean} fin Specifies whether or not this is the last fragment - * @param {Function} callback Callback - * @private - */ - _compress(data, fin, callback) { - const endpoint = this._isServer ? 'server' : 'client'; - - if (!this._deflate) { - const key = `${endpoint}_max_window_bits`; - const windowBits = - typeof this.params[key] !== 'number' - ? zlib.Z_DEFAULT_WINDOWBITS - : this.params[key]; - - this._deflate = zlib.createDeflateRaw({ - ...this._options.zlibDeflateOptions, - windowBits - }); - - this._deflate[kTotalLength] = 0; - this._deflate[kBuffers] = []; - - this._deflate.on('data', deflateOnData); - } - - this._deflate[kCallback] = callback; - - this._deflate.write(data); - this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { - if (!this._deflate) { - // - // The deflate stream was closed while data was being processed. - // - return; - } - - let data = bufferUtil.concat( - this._deflate[kBuffers], - this._deflate[kTotalLength] - ); - - if (fin) { - data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4); - } - - // - // Ensure that the callback will not be called again in - // `PerMessageDeflate#cleanup()`. - // - this._deflate[kCallback] = null; - - this._deflate[kTotalLength] = 0; - this._deflate[kBuffers] = []; - - if (fin && this.params[`${endpoint}_no_context_takeover`]) { - this._deflate.reset(); - } - - callback(null, data); - }); - } -} - -module.exports = PerMessageDeflate; - -/** - * The listener of the `zlib.DeflateRaw` stream `'data'` event. - * - * @param {Buffer} chunk A chunk of data - * @private - */ -function deflateOnData(chunk) { - this[kBuffers].push(chunk); - this[kTotalLength] += chunk.length; -} - -/** - * The listener of the `zlib.InflateRaw` stream `'data'` event. - * - * @param {Buffer} chunk A chunk of data - * @private - */ -function inflateOnData(chunk) { - this[kTotalLength] += chunk.length; - - if ( - this[kPerMessageDeflate]._maxPayload < 1 || - this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload - ) { - this[kBuffers].push(chunk); - return; - } - - this[kError] = new RangeError('Max payload size exceeded'); - this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'; - this[kError][kStatusCode] = 1009; - this.removeListener('data', inflateOnData); - this.reset(); -} - -/** - * The listener of the `zlib.InflateRaw` stream `'error'` event. - * - * @param {Error} err The emitted error - * @private - */ -function inflateOnError(err) { - // - // There is no need to call `Zlib#close()` as the handle is automatically - // closed when an error is emitted. - // - this[kPerMessageDeflate]._inflate = null; - err[kStatusCode] = 1007; - this[kCallback](err); -} - - -/***/ }), -/* 13 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("zlib"); - -/***/ }), -/* 14 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { EMPTY_BUFFER } = __webpack_require__(15); - -const FastBuffer = Buffer[Symbol.species]; - -/** - * Merges an array of buffers into a new buffer. - * - * @param {Buffer[]} list The array of buffers to concat - * @param {Number} totalLength The total length of buffers in the list - * @return {Buffer} The resulting buffer - * @public - */ -function concat(list, totalLength) { - if (list.length === 0) return EMPTY_BUFFER; - if (list.length === 1) return list[0]; - - const target = Buffer.allocUnsafe(totalLength); - let offset = 0; - - for (let i = 0; i < list.length; i++) { - const buf = list[i]; - target.set(buf, offset); - offset += buf.length; - } - - if (offset < totalLength) { - return new FastBuffer(target.buffer, target.byteOffset, offset); - } - - return target; -} - -/** - * Masks a buffer using the given mask. - * - * @param {Buffer} source The buffer to mask - * @param {Buffer} mask The mask to use - * @param {Buffer} output The buffer where to store the result - * @param {Number} offset The offset at which to start writing - * @param {Number} length The number of bytes to mask. - * @public - */ -function _mask(source, mask, output, offset, length) { - for (let i = 0; i < length; i++) { - output[offset + i] = source[i] ^ mask[i & 3]; - } -} - -/** - * Unmasks a buffer using the given mask. - * - * @param {Buffer} buffer The buffer to unmask - * @param {Buffer} mask The mask to use - * @public - */ -function _unmask(buffer, mask) { - for (let i = 0; i < buffer.length; i++) { - buffer[i] ^= mask[i & 3]; - } -} - -/** - * Converts a buffer to an `ArrayBuffer`. - * - * @param {Buffer} buf The buffer to convert - * @return {ArrayBuffer} Converted buffer - * @public - */ -function toArrayBuffer(buf) { - if (buf.length === buf.buffer.byteLength) { - return buf.buffer; - } - - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length); -} - -/** - * Converts `data` to a `Buffer`. - * - * @param {*} data The data to convert - * @return {Buffer} The buffer - * @throws {TypeError} - * @public - */ -function toBuffer(data) { - toBuffer.readOnly = true; - - if (Buffer.isBuffer(data)) return data; - - let buf; - - if (data instanceof ArrayBuffer) { - buf = new FastBuffer(data); - } else if (ArrayBuffer.isView(data)) { - buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength); - } else { - buf = Buffer.from(data); - toBuffer.readOnly = false; - } - - return buf; -} - -module.exports = { - concat, - mask: _mask, - toArrayBuffer, - toBuffer, - unmask: _unmask -}; - -/* istanbul ignore else */ -if (!process.env.WS_NO_BUFFER_UTIL) { - try { - const bufferUtil = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'bufferutil'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())); - - module.exports.mask = function (source, mask, output, offset, length) { - if (length < 48) _mask(source, mask, output, offset, length); - else bufferUtil.mask(source, mask, output, offset, length); - }; - - module.exports.unmask = function (buffer, mask) { - if (buffer.length < 32) _unmask(buffer, mask); - else bufferUtil.unmask(buffer, mask); - }; - } catch (e) { - // Continue regardless of the error. - } -} - - -/***/ }), -/* 15 */ -/***/ ((module) => { - -"use strict"; - - -module.exports = { - BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'], - EMPTY_BUFFER: Buffer.alloc(0), - GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', - kForOnEventAttribute: Symbol('kIsForOnEventAttribute'), - kListener: Symbol('kListener'), - kStatusCode: Symbol('status-code'), - kWebSocket: Symbol('websocket'), - NOOP: () => {} -}; - - -/***/ }), -/* 16 */ -/***/ ((module) => { - -"use strict"; - - -const kDone = Symbol('kDone'); -const kRun = Symbol('kRun'); - -/** - * A very simple job queue with adjustable concurrency. Adapted from - * https://github.com/STRML/async-limiter - */ -class Limiter { - /** - * Creates a new `Limiter`. - * - * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed - * to run concurrently - */ - constructor(concurrency) { - this[kDone] = () => { - this.pending--; - this[kRun](); - }; - this.concurrency = concurrency || Infinity; - this.jobs = []; - this.pending = 0; - } - - /** - * Adds a job to the queue. - * - * @param {Function} job The job to run - * @public - */ - add(job) { - this.jobs.push(job); - this[kRun](); - } - - /** - * Removes a job from the queue and runs it if possible. - * - * @private - */ - [kRun]() { - if (this.pending === this.concurrency) return; - - if (this.jobs.length) { - const job = this.jobs.shift(); - - this.pending++; - job(this[kDone]); - } - } -} - -module.exports = Limiter; - - -/***/ }), -/* 17 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { Writable } = __webpack_require__(11); - -const PerMessageDeflate = __webpack_require__(12); -const { - BINARY_TYPES, - EMPTY_BUFFER, - kStatusCode, - kWebSocket -} = __webpack_require__(15); -const { concat, toArrayBuffer, unmask } = __webpack_require__(14); -const { isValidStatusCode, isValidUTF8 } = __webpack_require__(18); - -const FastBuffer = Buffer[Symbol.species]; -const GET_INFO = 0; -const GET_PAYLOAD_LENGTH_16 = 1; -const GET_PAYLOAD_LENGTH_64 = 2; -const GET_MASK = 3; -const GET_DATA = 4; -const INFLATING = 5; - -/** - * HyBi Receiver implementation. - * - * @extends Writable - */ -class Receiver extends Writable { - /** - * Creates a Receiver instance. - * - * @param {Object} [options] Options object - * @param {String} [options.binaryType=nodebuffer] The type for binary data - * @param {Object} [options.extensions] An object containing the negotiated - * extensions - * @param {Boolean} [options.isServer=false] Specifies whether to operate in - * client or server mode - * @param {Number} [options.maxPayload=0] The maximum allowed message length - * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or - * not to skip UTF-8 validation for text and close messages - */ - constructor(options = {}) { - super(); - - this._binaryType = options.binaryType || BINARY_TYPES[0]; - this._extensions = options.extensions || {}; - this._isServer = !!options.isServer; - this._maxPayload = options.maxPayload | 0; - this._skipUTF8Validation = !!options.skipUTF8Validation; - this[kWebSocket] = undefined; - - this._bufferedBytes = 0; - this._buffers = []; - - this._compressed = false; - this._payloadLength = 0; - this._mask = undefined; - this._fragmented = 0; - this._masked = false; - this._fin = false; - this._opcode = 0; - - this._totalPayloadLength = 0; - this._messageLength = 0; - this._fragments = []; - - this._state = GET_INFO; - this._loop = false; - } - - /** - * Implements `Writable.prototype._write()`. - * - * @param {Buffer} chunk The chunk of data to write - * @param {String} encoding The character encoding of `chunk` - * @param {Function} cb Callback - * @private - */ - _write(chunk, encoding, cb) { - if (this._opcode === 0x08 && this._state == GET_INFO) return cb(); - - this._bufferedBytes += chunk.length; - this._buffers.push(chunk); - this.startLoop(cb); - } - - /** - * Consumes `n` bytes from the buffered data. - * - * @param {Number} n The number of bytes to consume - * @return {Buffer} The consumed bytes - * @private - */ - consume(n) { - this._bufferedBytes -= n; - - if (n === this._buffers[0].length) return this._buffers.shift(); - - if (n < this._buffers[0].length) { - const buf = this._buffers[0]; - this._buffers[0] = new FastBuffer( - buf.buffer, - buf.byteOffset + n, - buf.length - n - ); - - return new FastBuffer(buf.buffer, buf.byteOffset, n); - } - - const dst = Buffer.allocUnsafe(n); - - do { - const buf = this._buffers[0]; - const offset = dst.length - n; - - if (n >= buf.length) { - dst.set(this._buffers.shift(), offset); - } else { - dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset); - this._buffers[0] = new FastBuffer( - buf.buffer, - buf.byteOffset + n, - buf.length - n - ); - } - - n -= buf.length; - } while (n > 0); - - return dst; - } - - /** - * Starts the parsing loop. - * - * @param {Function} cb Callback - * @private - */ - startLoop(cb) { - let err; - this._loop = true; - - do { - switch (this._state) { - case GET_INFO: - err = this.getInfo(); - break; - case GET_PAYLOAD_LENGTH_16: - err = this.getPayloadLength16(); - break; - case GET_PAYLOAD_LENGTH_64: - err = this.getPayloadLength64(); - break; - case GET_MASK: - this.getMask(); - break; - case GET_DATA: - err = this.getData(cb); - break; - default: - // `INFLATING` - this._loop = false; - return; - } - } while (this._loop); - - cb(err); - } - - /** - * Reads the first two bytes of a frame. - * - * @return {(RangeError|undefined)} A possible error - * @private - */ - getInfo() { - if (this._bufferedBytes < 2) { - this._loop = false; - return; - } - - const buf = this.consume(2); - - if ((buf[0] & 0x30) !== 0x00) { - this._loop = false; - return error( - RangeError, - 'RSV2 and RSV3 must be clear', - true, - 1002, - 'WS_ERR_UNEXPECTED_RSV_2_3' - ); - } - - const compressed = (buf[0] & 0x40) === 0x40; - - if (compressed && !this._extensions[PerMessageDeflate.extensionName]) { - this._loop = false; - return error( - RangeError, - 'RSV1 must be clear', - true, - 1002, - 'WS_ERR_UNEXPECTED_RSV_1' - ); - } - - this._fin = (buf[0] & 0x80) === 0x80; - this._opcode = buf[0] & 0x0f; - this._payloadLength = buf[1] & 0x7f; - - if (this._opcode === 0x00) { - if (compressed) { - this._loop = false; - return error( - RangeError, - 'RSV1 must be clear', - true, - 1002, - 'WS_ERR_UNEXPECTED_RSV_1' - ); - } - - if (!this._fragmented) { - this._loop = false; - return error( - RangeError, - 'invalid opcode 0', - true, - 1002, - 'WS_ERR_INVALID_OPCODE' - ); - } - - this._opcode = this._fragmented; - } else if (this._opcode === 0x01 || this._opcode === 0x02) { - if (this._fragmented) { - this._loop = false; - return error( - RangeError, - `invalid opcode ${this._opcode}`, - true, - 1002, - 'WS_ERR_INVALID_OPCODE' - ); - } - - this._compressed = compressed; - } else if (this._opcode > 0x07 && this._opcode < 0x0b) { - if (!this._fin) { - this._loop = false; - return error( - RangeError, - 'FIN must be set', - true, - 1002, - 'WS_ERR_EXPECTED_FIN' - ); - } - - if (compressed) { - this._loop = false; - return error( - RangeError, - 'RSV1 must be clear', - true, - 1002, - 'WS_ERR_UNEXPECTED_RSV_1' - ); - } - - if ( - this._payloadLength > 0x7d || - (this._opcode === 0x08 && this._payloadLength === 1) - ) { - this._loop = false; - return error( - RangeError, - `invalid payload length ${this._payloadLength}`, - true, - 1002, - 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH' - ); - } - } else { - this._loop = false; - return error( - RangeError, - `invalid opcode ${this._opcode}`, - true, - 1002, - 'WS_ERR_INVALID_OPCODE' - ); - } - - if (!this._fin && !this._fragmented) this._fragmented = this._opcode; - this._masked = (buf[1] & 0x80) === 0x80; - - if (this._isServer) { - if (!this._masked) { - this._loop = false; - return error( - RangeError, - 'MASK must be set', - true, - 1002, - 'WS_ERR_EXPECTED_MASK' - ); - } - } else if (this._masked) { - this._loop = false; - return error( - RangeError, - 'MASK must be clear', - true, - 1002, - 'WS_ERR_UNEXPECTED_MASK' - ); - } - - if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16; - else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64; - else return this.haveLength(); - } - - /** - * Gets extended payload length (7+16). - * - * @return {(RangeError|undefined)} A possible error - * @private - */ - getPayloadLength16() { - if (this._bufferedBytes < 2) { - this._loop = false; - return; - } - - this._payloadLength = this.consume(2).readUInt16BE(0); - return this.haveLength(); - } - - /** - * Gets extended payload length (7+64). - * - * @return {(RangeError|undefined)} A possible error - * @private - */ - getPayloadLength64() { - if (this._bufferedBytes < 8) { - this._loop = false; - return; - } - - const buf = this.consume(8); - const num = buf.readUInt32BE(0); - - // - // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned - // if payload length is greater than this number. - // - if (num > Math.pow(2, 53 - 32) - 1) { - this._loop = false; - return error( - RangeError, - 'Unsupported WebSocket frame: payload length > 2^53 - 1', - false, - 1009, - 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH' - ); - } - - this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); - return this.haveLength(); - } - - /** - * Payload length has been read. - * - * @return {(RangeError|undefined)} A possible error - * @private - */ - haveLength() { - if (this._payloadLength && this._opcode < 0x08) { - this._totalPayloadLength += this._payloadLength; - if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { - this._loop = false; - return error( - RangeError, - 'Max payload size exceeded', - false, - 1009, - 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH' - ); - } - } - - if (this._masked) this._state = GET_MASK; - else this._state = GET_DATA; - } - - /** - * Reads mask bytes. - * - * @private - */ - getMask() { - if (this._bufferedBytes < 4) { - this._loop = false; - return; - } - - this._mask = this.consume(4); - this._state = GET_DATA; - } - - /** - * Reads data bytes. - * - * @param {Function} cb Callback - * @return {(Error|RangeError|undefined)} A possible error - * @private - */ - getData(cb) { - let data = EMPTY_BUFFER; - - if (this._payloadLength) { - if (this._bufferedBytes < this._payloadLength) { - this._loop = false; - return; - } - - data = this.consume(this._payloadLength); - - if ( - this._masked && - (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0 - ) { - unmask(data, this._mask); - } - } - - if (this._opcode > 0x07) return this.controlMessage(data); - - if (this._compressed) { - this._state = INFLATING; - this.decompress(data, cb); - return; - } - - if (data.length) { - // - // This message is not compressed so its length is the sum of the payload - // length of all fragments. - // - this._messageLength = this._totalPayloadLength; - this._fragments.push(data); - } - - return this.dataMessage(); - } - - /** - * Decompresses data. - * - * @param {Buffer} data Compressed data - * @param {Function} cb Callback - * @private - */ - decompress(data, cb) { - const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; - - perMessageDeflate.decompress(data, this._fin, (err, buf) => { - if (err) return cb(err); - - if (buf.length) { - this._messageLength += buf.length; - if (this._messageLength > this._maxPayload && this._maxPayload > 0) { - return cb( - error( - RangeError, - 'Max payload size exceeded', - false, - 1009, - 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH' - ) - ); - } - - this._fragments.push(buf); - } - - const er = this.dataMessage(); - if (er) return cb(er); - - this.startLoop(cb); - }); - } - - /** - * Handles a data message. - * - * @return {(Error|undefined)} A possible error - * @private - */ - dataMessage() { - if (this._fin) { - const messageLength = this._messageLength; - const fragments = this._fragments; - - this._totalPayloadLength = 0; - this._messageLength = 0; - this._fragmented = 0; - this._fragments = []; - - if (this._opcode === 2) { - let data; - - if (this._binaryType === 'nodebuffer') { - data = concat(fragments, messageLength); - } else if (this._binaryType === 'arraybuffer') { - data = toArrayBuffer(concat(fragments, messageLength)); - } else { - data = fragments; - } - - this.emit('message', data, true); - } else { - const buf = concat(fragments, messageLength); - - if (!this._skipUTF8Validation && !isValidUTF8(buf)) { - this._loop = false; - return error( - Error, - 'invalid UTF-8 sequence', - true, - 1007, - 'WS_ERR_INVALID_UTF8' - ); - } - - this.emit('message', buf, false); - } - } - - this._state = GET_INFO; - } - - /** - * Handles a control message. - * - * @param {Buffer} data Data to handle - * @return {(Error|RangeError|undefined)} A possible error - * @private - */ - controlMessage(data) { - if (this._opcode === 0x08) { - this._loop = false; - - if (data.length === 0) { - this.emit('conclude', 1005, EMPTY_BUFFER); - this.end(); - } else { - const code = data.readUInt16BE(0); - - if (!isValidStatusCode(code)) { - return error( - RangeError, - `invalid status code ${code}`, - true, - 1002, - 'WS_ERR_INVALID_CLOSE_CODE' - ); - } - - const buf = new FastBuffer( - data.buffer, - data.byteOffset + 2, - data.length - 2 - ); - - if (!this._skipUTF8Validation && !isValidUTF8(buf)) { - return error( - Error, - 'invalid UTF-8 sequence', - true, - 1007, - 'WS_ERR_INVALID_UTF8' - ); - } - - this.emit('conclude', code, buf); - this.end(); - } - } else if (this._opcode === 0x09) { - this.emit('ping', data); - } else { - this.emit('pong', data); - } - - this._state = GET_INFO; - } -} - -module.exports = Receiver; - -/** - * Builds an error object. - * - * @param {function(new:Error|RangeError)} ErrorCtor The error constructor - * @param {String} message The error message - * @param {Boolean} prefix Specifies whether or not to add a default prefix to - * `message` - * @param {Number} statusCode The status code - * @param {String} errorCode The exposed error code - * @return {(Error|RangeError)} The error - * @private - */ -function error(ErrorCtor, message, prefix, statusCode, errorCode) { - const err = new ErrorCtor( - prefix ? `Invalid WebSocket frame: ${message}` : message - ); - - Error.captureStackTrace(err, error); - err.code = errorCode; - err[kStatusCode] = statusCode; - return err; -} - - -/***/ }), -/* 18 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { isUtf8 } = __webpack_require__(19); - -// -// Allowed token characters: -// -// '!', '#', '$', '%', '&', ''', '*', '+', '-', -// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~' -// -// tokenChars[32] === 0 // ' ' -// tokenChars[33] === 1 // '!' -// tokenChars[34] === 0 // '"' -// ... -// -// prettier-ignore -const tokenChars = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 - 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63 - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127 -]; - -/** - * Checks if a status code is allowed in a close frame. - * - * @param {Number} code The status code - * @return {Boolean} `true` if the status code is valid, else `false` - * @public - */ -function isValidStatusCode(code) { - return ( - (code >= 1000 && - code <= 1014 && - code !== 1004 && - code !== 1005 && - code !== 1006) || - (code >= 3000 && code <= 4999) - ); -} - -/** - * Checks if a given buffer contains only correct UTF-8. - * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by - * Markus Kuhn. - * - * @param {Buffer} buf The buffer to check - * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false` - * @public - */ -function _isValidUTF8(buf) { - const len = buf.length; - let i = 0; - - while (i < len) { - if ((buf[i] & 0x80) === 0) { - // 0xxxxxxx - i++; - } else if ((buf[i] & 0xe0) === 0xc0) { - // 110xxxxx 10xxxxxx - if ( - i + 1 === len || - (buf[i + 1] & 0xc0) !== 0x80 || - (buf[i] & 0xfe) === 0xc0 // Overlong - ) { - return false; - } - - i += 2; - } else if ((buf[i] & 0xf0) === 0xe0) { - // 1110xxxx 10xxxxxx 10xxxxxx - if ( - i + 2 >= len || - (buf[i + 1] & 0xc0) !== 0x80 || - (buf[i + 2] & 0xc0) !== 0x80 || - (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong - (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF) - ) { - return false; - } - - i += 3; - } else if ((buf[i] & 0xf8) === 0xf0) { - // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if ( - i + 3 >= len || - (buf[i + 1] & 0xc0) !== 0x80 || - (buf[i + 2] & 0xc0) !== 0x80 || - (buf[i + 3] & 0xc0) !== 0x80 || - (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong - (buf[i] === 0xf4 && buf[i + 1] > 0x8f) || - buf[i] > 0xf4 // > U+10FFFF - ) { - return false; - } - - i += 4; - } else { - return false; - } - } - - return true; -} - -module.exports = { - isValidStatusCode, - isValidUTF8: _isValidUTF8, - tokenChars -}; - -if (isUtf8) { - module.exports.isValidUTF8 = function (buf) { - return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf); - }; -} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) { - try { - const isValidUTF8 = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'utf-8-validate'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())); - - module.exports.isValidUTF8 = function (buf) { - return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf); - }; - } catch (e) { - // Continue regardless of the error. - } -} - - -/***/ }), -/* 19 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("buffer"); - -/***/ }), -/* 20 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; -/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls$" }] */ - - - -const net = __webpack_require__(8); -const tls = __webpack_require__(9); -const { randomFillSync } = __webpack_require__(10); - -const PerMessageDeflate = __webpack_require__(12); -const { EMPTY_BUFFER } = __webpack_require__(15); -const { isValidStatusCode } = __webpack_require__(18); -const { mask: applyMask, toBuffer } = __webpack_require__(14); - -const kByteLength = Symbol('kByteLength'); -const maskBuffer = Buffer.alloc(4); - -/** - * HyBi Sender implementation. - */ -class Sender { - /** - * Creates a Sender instance. - * - * @param {(net.Socket|tls.Socket)} socket The connection socket - * @param {Object} [extensions] An object containing the negotiated extensions - * @param {Function} [generateMask] The function used to generate the masking - * key - */ - constructor(socket, extensions, generateMask) { - this._extensions = extensions || {}; - - if (generateMask) { - this._generateMask = generateMask; - this._maskBuffer = Buffer.alloc(4); - } - - this._socket = socket; - - this._firstFragment = true; - this._compress = false; - - this._bufferedBytes = 0; - this._deflating = false; - this._queue = []; - } - - /** - * Frames a piece of data according to the HyBi WebSocket protocol. - * - * @param {(Buffer|String)} data The data to frame - * @param {Object} options Options object - * @param {Boolean} [options.fin=false] Specifies whether or not to set the - * FIN bit - * @param {Function} [options.generateMask] The function used to generate the - * masking key - * @param {Boolean} [options.mask=false] Specifies whether or not to mask - * `data` - * @param {Buffer} [options.maskBuffer] The buffer used to store the masking - * key - * @param {Number} options.opcode The opcode - * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be - * modified - * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the - * RSV1 bit - * @return {(Buffer|String)[]} The framed data - * @public - */ - static frame(data, options) { - let mask; - let merge = false; - let offset = 2; - let skipMasking = false; - - if (options.mask) { - mask = options.maskBuffer || maskBuffer; - - if (options.generateMask) { - options.generateMask(mask); - } else { - randomFillSync(mask, 0, 4); - } - - skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; - offset = 6; - } - - let dataLength; - - if (typeof data === 'string') { - if ( - (!options.mask || skipMasking) && - options[kByteLength] !== undefined - ) { - dataLength = options[kByteLength]; - } else { - data = Buffer.from(data); - dataLength = data.length; - } - } else { - dataLength = data.length; - merge = options.mask && options.readOnly && !skipMasking; - } - - let payloadLength = dataLength; - - if (dataLength >= 65536) { - offset += 8; - payloadLength = 127; - } else if (dataLength > 125) { - offset += 2; - payloadLength = 126; - } - - const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset); - - target[0] = options.fin ? options.opcode | 0x80 : options.opcode; - if (options.rsv1) target[0] |= 0x40; - - target[1] = payloadLength; - - if (payloadLength === 126) { - target.writeUInt16BE(dataLength, 2); - } else if (payloadLength === 127) { - target[2] = target[3] = 0; - target.writeUIntBE(dataLength, 4, 6); - } - - if (!options.mask) return [target, data]; - - target[1] |= 0x80; - target[offset - 4] = mask[0]; - target[offset - 3] = mask[1]; - target[offset - 2] = mask[2]; - target[offset - 1] = mask[3]; - - if (skipMasking) return [target, data]; - - if (merge) { - applyMask(data, mask, target, offset, dataLength); - return [target]; - } - - applyMask(data, mask, data, 0, dataLength); - return [target, data]; - } - - /** - * Sends a close message to the other peer. - * - * @param {Number} [code] The status code component of the body - * @param {(String|Buffer)} [data] The message component of the body - * @param {Boolean} [mask=false] Specifies whether or not to mask the message - * @param {Function} [cb] Callback - * @public - */ - close(code, data, mask, cb) { - let buf; - - if (code === undefined) { - buf = EMPTY_BUFFER; - } else if (typeof code !== 'number' || !isValidStatusCode(code)) { - throw new TypeError('First argument must be a valid error code number'); - } else if (data === undefined || !data.length) { - buf = Buffer.allocUnsafe(2); - buf.writeUInt16BE(code, 0); - } else { - const length = Buffer.byteLength(data); - - if (length > 123) { - throw new RangeError('The message must not be greater than 123 bytes'); - } - - buf = Buffer.allocUnsafe(2 + length); - buf.writeUInt16BE(code, 0); - - if (typeof data === 'string') { - buf.write(data, 2); - } else { - buf.set(data, 2); - } - } - - const options = { - [kByteLength]: buf.length, - fin: true, - generateMask: this._generateMask, - mask, - maskBuffer: this._maskBuffer, - opcode: 0x08, - readOnly: false, - rsv1: false - }; - - if (this._deflating) { - this.enqueue([this.dispatch, buf, false, options, cb]); - } else { - this.sendFrame(Sender.frame(buf, options), cb); - } - } - - /** - * Sends a ping message to the other peer. - * - * @param {*} data The message to send - * @param {Boolean} [mask=false] Specifies whether or not to mask `data` - * @param {Function} [cb] Callback - * @public - */ - ping(data, mask, cb) { - let byteLength; - let readOnly; - - if (typeof data === 'string') { - byteLength = Buffer.byteLength(data); - readOnly = false; - } else { - data = toBuffer(data); - byteLength = data.length; - readOnly = toBuffer.readOnly; - } - - if (byteLength > 125) { - throw new RangeError('The data size must not be greater than 125 bytes'); - } - - const options = { - [kByteLength]: byteLength, - fin: true, - generateMask: this._generateMask, - mask, - maskBuffer: this._maskBuffer, - opcode: 0x09, - readOnly, - rsv1: false - }; - - if (this._deflating) { - this.enqueue([this.dispatch, data, false, options, cb]); - } else { - this.sendFrame(Sender.frame(data, options), cb); - } - } - - /** - * Sends a pong message to the other peer. - * - * @param {*} data The message to send - * @param {Boolean} [mask=false] Specifies whether or not to mask `data` - * @param {Function} [cb] Callback - * @public - */ - pong(data, mask, cb) { - let byteLength; - let readOnly; - - if (typeof data === 'string') { - byteLength = Buffer.byteLength(data); - readOnly = false; - } else { - data = toBuffer(data); - byteLength = data.length; - readOnly = toBuffer.readOnly; - } - - if (byteLength > 125) { - throw new RangeError('The data size must not be greater than 125 bytes'); - } - - const options = { - [kByteLength]: byteLength, - fin: true, - generateMask: this._generateMask, - mask, - maskBuffer: this._maskBuffer, - opcode: 0x0a, - readOnly, - rsv1: false - }; - - if (this._deflating) { - this.enqueue([this.dispatch, data, false, options, cb]); - } else { - this.sendFrame(Sender.frame(data, options), cb); - } - } - - /** - * Sends a data message to the other peer. - * - * @param {*} data The message to send - * @param {Object} options Options object - * @param {Boolean} [options.binary=false] Specifies whether `data` is binary - * or text - * @param {Boolean} [options.compress=false] Specifies whether or not to - * compress `data` - * @param {Boolean} [options.fin=false] Specifies whether the fragment is the - * last one - * @param {Boolean} [options.mask=false] Specifies whether or not to mask - * `data` - * @param {Function} [cb] Callback - * @public - */ - send(data, options, cb) { - const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; - let opcode = options.binary ? 2 : 1; - let rsv1 = options.compress; - - let byteLength; - let readOnly; - - if (typeof data === 'string') { - byteLength = Buffer.byteLength(data); - readOnly = false; - } else { - data = toBuffer(data); - byteLength = data.length; - readOnly = toBuffer.readOnly; - } - - if (this._firstFragment) { - this._firstFragment = false; - if ( - rsv1 && - perMessageDeflate && - perMessageDeflate.params[ - perMessageDeflate._isServer - ? 'server_no_context_takeover' - : 'client_no_context_takeover' - ] - ) { - rsv1 = byteLength >= perMessageDeflate._threshold; - } - this._compress = rsv1; - } else { - rsv1 = false; - opcode = 0; - } - - if (options.fin) this._firstFragment = true; - - if (perMessageDeflate) { - const opts = { - [kByteLength]: byteLength, - fin: options.fin, - generateMask: this._generateMask, - mask: options.mask, - maskBuffer: this._maskBuffer, - opcode, - readOnly, - rsv1 - }; - - if (this._deflating) { - this.enqueue([this.dispatch, data, this._compress, opts, cb]); - } else { - this.dispatch(data, this._compress, opts, cb); - } - } else { - this.sendFrame( - Sender.frame(data, { - [kByteLength]: byteLength, - fin: options.fin, - generateMask: this._generateMask, - mask: options.mask, - maskBuffer: this._maskBuffer, - opcode, - readOnly, - rsv1: false - }), - cb - ); - } - } - - /** - * Dispatches a message. - * - * @param {(Buffer|String)} data The message to send - * @param {Boolean} [compress=false] Specifies whether or not to compress - * `data` - * @param {Object} options Options object - * @param {Boolean} [options.fin=false] Specifies whether or not to set the - * FIN bit - * @param {Function} [options.generateMask] The function used to generate the - * masking key - * @param {Boolean} [options.mask=false] Specifies whether or not to mask - * `data` - * @param {Buffer} [options.maskBuffer] The buffer used to store the masking - * key - * @param {Number} options.opcode The opcode - * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be - * modified - * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the - * RSV1 bit - * @param {Function} [cb] Callback - * @private - */ - dispatch(data, compress, options, cb) { - if (!compress) { - this.sendFrame(Sender.frame(data, options), cb); - return; - } - - const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; - - this._bufferedBytes += options[kByteLength]; - this._deflating = true; - perMessageDeflate.compress(data, options.fin, (_, buf) => { - if (this._socket.destroyed) { - const err = new Error( - 'The socket was closed while data was being compressed' - ); - - if (typeof cb === 'function') cb(err); - - for (let i = 0; i < this._queue.length; i++) { - const params = this._queue[i]; - const callback = params[params.length - 1]; - - if (typeof callback === 'function') callback(err); - } - - return; - } - - this._bufferedBytes -= options[kByteLength]; - this._deflating = false; - options.readOnly = false; - this.sendFrame(Sender.frame(buf, options), cb); - this.dequeue(); - }); - } - - /** - * Executes queued send operations. - * - * @private - */ - dequeue() { - while (!this._deflating && this._queue.length) { - const params = this._queue.shift(); - - this._bufferedBytes -= params[3][kByteLength]; - Reflect.apply(params[0], this, params.slice(1)); - } - } - - /** - * Enqueues a send operation. - * - * @param {Array} params Send operation parameters. - * @private - */ - enqueue(params) { - this._bufferedBytes += params[3][kByteLength]; - this._queue.push(params); - } - - /** - * Sends a frame. - * - * @param {Buffer[]} list The frame to send - * @param {Function} [cb] Callback - * @private - */ - sendFrame(list, cb) { - if (list.length === 2) { - this._socket.cork(); - this._socket.write(list[0]); - this._socket.write(list[1], cb); - this._socket.uncork(); - } else { - this._socket.write(list[0], cb); - } - } -} - -module.exports = Sender; - - -/***/ }), -/* 21 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { kForOnEventAttribute, kListener } = __webpack_require__(15); - -const kCode = Symbol('kCode'); -const kData = Symbol('kData'); -const kError = Symbol('kError'); -const kMessage = Symbol('kMessage'); -const kReason = Symbol('kReason'); -const kTarget = Symbol('kTarget'); -const kType = Symbol('kType'); -const kWasClean = Symbol('kWasClean'); - -/** - * Class representing an event. - */ -class Event { - /** - * Create a new `Event`. - * - * @param {String} type The name of the event - * @throws {TypeError} If the `type` argument is not specified - */ - constructor(type) { - this[kTarget] = null; - this[kType] = type; - } - - /** - * @type {*} - */ - get target() { - return this[kTarget]; - } - - /** - * @type {String} - */ - get type() { - return this[kType]; - } -} - -Object.defineProperty(Event.prototype, 'target', { enumerable: true }); -Object.defineProperty(Event.prototype, 'type', { enumerable: true }); - -/** - * Class representing a close event. - * - * @extends Event - */ -class CloseEvent extends Event { - /** - * Create a new `CloseEvent`. - * - * @param {String} type The name of the event - * @param {Object} [options] A dictionary object that allows for setting - * attributes via object members of the same name - * @param {Number} [options.code=0] The status code explaining why the - * connection was closed - * @param {String} [options.reason=''] A human-readable string explaining why - * the connection was closed - * @param {Boolean} [options.wasClean=false] Indicates whether or not the - * connection was cleanly closed - */ - constructor(type, options = {}) { - super(type); - - this[kCode] = options.code === undefined ? 0 : options.code; - this[kReason] = options.reason === undefined ? '' : options.reason; - this[kWasClean] = options.wasClean === undefined ? false : options.wasClean; - } - - /** - * @type {Number} - */ - get code() { - return this[kCode]; - } - - /** - * @type {String} - */ - get reason() { - return this[kReason]; - } - - /** - * @type {Boolean} - */ - get wasClean() { - return this[kWasClean]; - } -} - -Object.defineProperty(CloseEvent.prototype, 'code', { enumerable: true }); -Object.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true }); -Object.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true }); - -/** - * Class representing an error event. - * - * @extends Event - */ -class ErrorEvent extends Event { - /** - * Create a new `ErrorEvent`. - * - * @param {String} type The name of the event - * @param {Object} [options] A dictionary object that allows for setting - * attributes via object members of the same name - * @param {*} [options.error=null] The error that generated this event - * @param {String} [options.message=''] The error message - */ - constructor(type, options = {}) { - super(type); - - this[kError] = options.error === undefined ? null : options.error; - this[kMessage] = options.message === undefined ? '' : options.message; - } - - /** - * @type {*} - */ - get error() { - return this[kError]; - } - - /** - * @type {String} - */ - get message() { - return this[kMessage]; - } -} - -Object.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true }); -Object.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true }); - -/** - * Class representing a message event. - * - * @extends Event - */ -class MessageEvent extends Event { - /** - * Create a new `MessageEvent`. - * - * @param {String} type The name of the event - * @param {Object} [options] A dictionary object that allows for setting - * attributes via object members of the same name - * @param {*} [options.data=null] The message content - */ - constructor(type, options = {}) { - super(type); - - this[kData] = options.data === undefined ? null : options.data; - } - - /** - * @type {*} - */ - get data() { - return this[kData]; - } -} - -Object.defineProperty(MessageEvent.prototype, 'data', { enumerable: true }); - -/** - * This provides methods for emulating the `EventTarget` interface. It's not - * meant to be used directly. - * - * @mixin - */ -const EventTarget = { - /** - * Register an event listener. - * - * @param {String} type A string representing the event type to listen for - * @param {(Function|Object)} handler The listener to add - * @param {Object} [options] An options object specifies characteristics about - * the event listener - * @param {Boolean} [options.once=false] A `Boolean` indicating that the - * listener should be invoked at most once after being added. If `true`, - * the listener would be automatically removed when invoked. - * @public - */ - addEventListener(type, handler, options = {}) { - for (const listener of this.listeners(type)) { - if ( - !options[kForOnEventAttribute] && - listener[kListener] === handler && - !listener[kForOnEventAttribute] - ) { - return; - } - } - - let wrapper; - - if (type === 'message') { - wrapper = function onMessage(data, isBinary) { - const event = new MessageEvent('message', { - data: isBinary ? data : data.toString() - }); - - event[kTarget] = this; - callListener(handler, this, event); - }; - } else if (type === 'close') { - wrapper = function onClose(code, message) { - const event = new CloseEvent('close', { - code, - reason: message.toString(), - wasClean: this._closeFrameReceived && this._closeFrameSent - }); - - event[kTarget] = this; - callListener(handler, this, event); - }; - } else if (type === 'error') { - wrapper = function onError(error) { - const event = new ErrorEvent('error', { - error, - message: error.message - }); - - event[kTarget] = this; - callListener(handler, this, event); - }; - } else if (type === 'open') { - wrapper = function onOpen() { - const event = new Event('open'); - - event[kTarget] = this; - callListener(handler, this, event); - }; - } else { - return; - } - - wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute]; - wrapper[kListener] = handler; - - if (options.once) { - this.once(type, wrapper); - } else { - this.on(type, wrapper); - } - }, - - /** - * Remove an event listener. - * - * @param {String} type A string representing the event type to remove - * @param {(Function|Object)} handler The listener to remove - * @public - */ - removeEventListener(type, handler) { - for (const listener of this.listeners(type)) { - if (listener[kListener] === handler && !listener[kForOnEventAttribute]) { - this.removeListener(type, listener); - break; - } - } - } -}; - -module.exports = { - CloseEvent, - ErrorEvent, - Event, - EventTarget, - MessageEvent -}; - -/** - * Call an event listener - * - * @param {(Function|Object)} listener The listener to call - * @param {*} thisArg The value to use as `this`` when calling the listener - * @param {Event} event The event to pass to the listener - * @private - */ -function callListener(listener, thisArg, event) { - if (typeof listener === 'object' && listener.handleEvent) { - listener.handleEvent.call(listener, event); - } else { - listener.call(thisArg, event); - } -} - - -/***/ }), -/* 22 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { tokenChars } = __webpack_require__(18); - -/** - * Adds an offer to the map of extension offers or a parameter to the map of - * parameters. - * - * @param {Object} dest The map of extension offers or parameters - * @param {String} name The extension or parameter name - * @param {(Object|Boolean|String)} elem The extension parameters or the - * parameter value - * @private - */ -function push(dest, name, elem) { - if (dest[name] === undefined) dest[name] = [elem]; - else dest[name].push(elem); -} - -/** - * Parses the `Sec-WebSocket-Extensions` header into an object. - * - * @param {String} header The field value of the header - * @return {Object} The parsed object - * @public - */ -function parse(header) { - const offers = Object.create(null); - let params = Object.create(null); - let mustUnescape = false; - let isEscaping = false; - let inQuotes = false; - let extensionName; - let paramName; - let start = -1; - let code = -1; - let end = -1; - let i = 0; - - for (; i < header.length; i++) { - code = header.charCodeAt(i); - - if (extensionName === undefined) { - if (end === -1 && tokenChars[code] === 1) { - if (start === -1) start = i; - } else if ( - i !== 0 && - (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */ - ) { - if (end === -1 && start !== -1) end = i; - } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) { - if (start === -1) { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - - if (end === -1) end = i; - const name = header.slice(start, end); - if (code === 0x2c) { - push(offers, name, params); - params = Object.create(null); - } else { - extensionName = name; - } - - start = end = -1; - } else { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - } else if (paramName === undefined) { - if (end === -1 && tokenChars[code] === 1) { - if (start === -1) start = i; - } else if (code === 0x20 || code === 0x09) { - if (end === -1 && start !== -1) end = i; - } else if (code === 0x3b || code === 0x2c) { - if (start === -1) { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - - if (end === -1) end = i; - push(params, header.slice(start, end), true); - if (code === 0x2c) { - push(offers, extensionName, params); - params = Object.create(null); - extensionName = undefined; - } - - start = end = -1; - } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) { - paramName = header.slice(start, i); - start = end = -1; - } else { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - } else { - // - // The value of a quoted-string after unescaping must conform to the - // token ABNF, so only token characters are valid. - // Ref: https://tools.ietf.org/html/rfc6455#section-9.1 - // - if (isEscaping) { - if (tokenChars[code] !== 1) { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - if (start === -1) start = i; - else if (!mustUnescape) mustUnescape = true; - isEscaping = false; - } else if (inQuotes) { - if (tokenChars[code] === 1) { - if (start === -1) start = i; - } else if (code === 0x22 /* '"' */ && start !== -1) { - inQuotes = false; - end = i; - } else if (code === 0x5c /* '\' */) { - isEscaping = true; - } else { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) { - inQuotes = true; - } else if (end === -1 && tokenChars[code] === 1) { - if (start === -1) start = i; - } else if (start !== -1 && (code === 0x20 || code === 0x09)) { - if (end === -1) end = i; - } else if (code === 0x3b || code === 0x2c) { - if (start === -1) { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - - if (end === -1) end = i; - let value = header.slice(start, end); - if (mustUnescape) { - value = value.replace(/\\/g, ''); - mustUnescape = false; - } - push(params, paramName, value); - if (code === 0x2c) { - push(offers, extensionName, params); - params = Object.create(null); - extensionName = undefined; - } - - paramName = undefined; - start = end = -1; - } else { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - } - } - - if (start === -1 || inQuotes || code === 0x20 || code === 0x09) { - throw new SyntaxError('Unexpected end of input'); - } - - if (end === -1) end = i; - const token = header.slice(start, end); - if (extensionName === undefined) { - push(offers, token, params); - } else { - if (paramName === undefined) { - push(params, token, true); - } else if (mustUnescape) { - push(params, paramName, token.replace(/\\/g, '')); - } else { - push(params, paramName, token); - } - push(offers, extensionName, params); - } - - return offers; -} - -/** - * Builds the `Sec-WebSocket-Extensions` header field value. - * - * @param {Object} extensions The map of extensions and parameters to format - * @return {String} A string representing the given object - * @public - */ -function format(extensions) { - return Object.keys(extensions) - .map((extension) => { - let configurations = extensions[extension]; - if (!Array.isArray(configurations)) configurations = [configurations]; - return configurations - .map((params) => { - return [extension] - .concat( - Object.keys(params).map((k) => { - let values = params[k]; - if (!Array.isArray(values)) values = [values]; - return values - .map((v) => (v === true ? k : `${k}=${v}`)) - .join('; '); - }) - ) - .join('; '); - }) - .join(', '); - }) - .join(', '); -} - -module.exports = { format, parse }; - - -/***/ }), -/* 23 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { Duplex } = __webpack_require__(11); - -/** - * Emits the `'close'` event on a stream. - * - * @param {Duplex} stream The stream. - * @private - */ -function emitClose(stream) { - stream.emit('close'); -} - -/** - * The listener of the `'end'` event. - * - * @private - */ -function duplexOnEnd() { - if (!this.destroyed && this._writableState.finished) { - this.destroy(); - } -} - -/** - * The listener of the `'error'` event. - * - * @param {Error} err The error - * @private - */ -function duplexOnError(err) { - this.removeListener('error', duplexOnError); - this.destroy(); - if (this.listenerCount('error') === 0) { - // Do not suppress the throwing behavior. - this.emit('error', err); - } -} - -/** - * Wraps a `WebSocket` in a duplex stream. - * - * @param {WebSocket} ws The `WebSocket` to wrap - * @param {Object} [options] The options for the `Duplex` constructor - * @return {Duplex} The duplex stream - * @public - */ -function createWebSocketStream(ws, options) { - let terminateOnDestroy = true; - - const duplex = new Duplex({ - ...options, - autoDestroy: false, - emitClose: false, - objectMode: false, - writableObjectMode: false - }); - - ws.on('message', function message(msg, isBinary) { - const data = - !isBinary && duplex._readableState.objectMode ? msg.toString() : msg; - - if (!duplex.push(data)) ws.pause(); - }); - - ws.once('error', function error(err) { - if (duplex.destroyed) return; - - // Prevent `ws.terminate()` from being called by `duplex._destroy()`. - // - // - If the `'error'` event is emitted before the `'open'` event, then - // `ws.terminate()` is a noop as no socket is assigned. - // - Otherwise, the error is re-emitted by the listener of the `'error'` - // event of the `Receiver` object. The listener already closes the - // connection by calling `ws.close()`. This allows a close frame to be - // sent to the other peer. If `ws.terminate()` is called right after this, - // then the close frame might not be sent. - terminateOnDestroy = false; - duplex.destroy(err); - }); - - ws.once('close', function close() { - if (duplex.destroyed) return; - - duplex.push(null); - }); - - duplex._destroy = function (err, callback) { - if (ws.readyState === ws.CLOSED) { - callback(err); - process.nextTick(emitClose, duplex); - return; - } - - let called = false; - - ws.once('error', function error(err) { - called = true; - callback(err); - }); - - ws.once('close', function close() { - if (!called) callback(err); - process.nextTick(emitClose, duplex); - }); - - if (terminateOnDestroy) ws.terminate(); - }; - - duplex._final = function (callback) { - if (ws.readyState === ws.CONNECTING) { - ws.once('open', function open() { - duplex._final(callback); - }); - return; - } - - // If the value of the `_socket` property is `null` it means that `ws` is a - // client websocket and the handshake failed. In fact, when this happens, a - // socket is never assigned to the websocket. Wait for the `'error'` event - // that will be emitted by the websocket. - if (ws._socket === null) return; - - if (ws._socket._writableState.finished) { - callback(); - if (duplex._readableState.endEmitted) duplex.destroy(); - } else { - ws._socket.once('finish', function finish() { - // `duplex` is not destroyed here because the `'end'` event will be - // emitted on `duplex` after this `'finish'` event. The EOF signaling - // `null` chunk is, in fact, pushed when the websocket emits `'close'`. - callback(); - }); - ws.close(); - } - }; - - duplex._read = function () { - if (ws.isPaused) ws.resume(); - }; - - duplex._write = function (chunk, encoding, callback) { - if (ws.readyState === ws.CONNECTING) { - ws.once('open', function open() { - duplex._write(chunk, encoding, callback); - }); - return; - } - - ws.send(chunk, callback); - }; - - duplex.on('end', duplexOnEnd); - duplex.on('error', duplexOnError); - return duplex; -} - -module.exports = createWebSocketStream; - - -/***/ }), -/* 24 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; -/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls|https$" }] */ - - - -const EventEmitter = __webpack_require__(6); -const http = __webpack_require__(2); -const https = __webpack_require__(7); -const net = __webpack_require__(8); -const tls = __webpack_require__(9); -const { createHash } = __webpack_require__(10); - -const extension = __webpack_require__(22); -const PerMessageDeflate = __webpack_require__(12); -const subprotocol = __webpack_require__(25); -const WebSocket = __webpack_require__(5); -const { GUID, kWebSocket } = __webpack_require__(15); - -const keyRegex = /^[+/0-9A-Za-z]{22}==$/; - -const RUNNING = 0; -const CLOSING = 1; -const CLOSED = 2; - -/** - * Class representing a WebSocket server. - * - * @extends EventEmitter - */ -class WebSocketServer extends EventEmitter { - /** - * Create a `WebSocketServer` instance. - * - * @param {Object} options Configuration options - * @param {Number} [options.backlog=511] The maximum length of the queue of - * pending connections - * @param {Boolean} [options.clientTracking=true] Specifies whether or not to - * track clients - * @param {Function} [options.handleProtocols] A hook to handle protocols - * @param {String} [options.host] The hostname where to bind the server - * @param {Number} [options.maxPayload=104857600] The maximum allowed message - * size - * @param {Boolean} [options.noServer=false] Enable no server mode - * @param {String} [options.path] Accept only connections matching this path - * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable - * permessage-deflate - * @param {Number} [options.port] The port where to bind the server - * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S - * server to use - * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or - * not to skip UTF-8 validation for text and close messages - * @param {Function} [options.verifyClient] A hook to reject connections - * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket` - * class to use. It must be the `WebSocket` class or class that extends it - * @param {Function} [callback] A listener for the `listening` event - */ - constructor(options, callback) { - super(); - - options = { - maxPayload: 100 * 1024 * 1024, - skipUTF8Validation: false, - perMessageDeflate: false, - handleProtocols: null, - clientTracking: true, - verifyClient: null, - noServer: false, - backlog: null, // use default (511 as implemented in net.js) - server: null, - host: null, - path: null, - port: null, - WebSocket, - ...options - }; - - if ( - (options.port == null && !options.server && !options.noServer) || - (options.port != null && (options.server || options.noServer)) || - (options.server && options.noServer) - ) { - throw new TypeError( - 'One and only one of the "port", "server", or "noServer" options ' + - 'must be specified' - ); - } - - if (options.port != null) { - this._server = http.createServer((req, res) => { - const body = http.STATUS_CODES[426]; - - res.writeHead(426, { - 'Content-Length': body.length, - 'Content-Type': 'text/plain' - }); - res.end(body); - }); - this._server.listen( - options.port, - options.host, - options.backlog, - callback - ); - } else if (options.server) { - this._server = options.server; - } - - if (this._server) { - const emitConnection = this.emit.bind(this, 'connection'); - - this._removeListeners = addListeners(this._server, { - listening: this.emit.bind(this, 'listening'), - error: this.emit.bind(this, 'error'), - upgrade: (req, socket, head) => { - this.handleUpgrade(req, socket, head, emitConnection); - } - }); - } - - if (options.perMessageDeflate === true) options.perMessageDeflate = {}; - if (options.clientTracking) { - this.clients = new Set(); - this._shouldEmitClose = false; - } - - this.options = options; - this._state = RUNNING; - } - - /** - * Returns the bound address, the address family name, and port of the server - * as reported by the operating system if listening on an IP socket. - * If the server is listening on a pipe or UNIX domain socket, the name is - * returned as a string. - * - * @return {(Object|String|null)} The address of the server - * @public - */ - address() { - if (this.options.noServer) { - throw new Error('The server is operating in "noServer" mode'); - } - - if (!this._server) return null; - return this._server.address(); - } - - /** - * Stop the server from accepting new connections and emit the `'close'` event - * when all existing connections are closed. - * - * @param {Function} [cb] A one-time listener for the `'close'` event - * @public - */ - close(cb) { - if (this._state === CLOSED) { - if (cb) { - this.once('close', () => { - cb(new Error('The server is not running')); - }); - } - - process.nextTick(emitClose, this); - return; - } - - if (cb) this.once('close', cb); - - if (this._state === CLOSING) return; - this._state = CLOSING; - - if (this.options.noServer || this.options.server) { - if (this._server) { - this._removeListeners(); - this._removeListeners = this._server = null; - } - - if (this.clients) { - if (!this.clients.size) { - process.nextTick(emitClose, this); - } else { - this._shouldEmitClose = true; - } - } else { - process.nextTick(emitClose, this); - } - } else { - const server = this._server; - - this._removeListeners(); - this._removeListeners = this._server = null; - - // - // The HTTP/S server was created internally. Close it, and rely on its - // `'close'` event. - // - server.close(() => { - emitClose(this); - }); - } - } - - /** - * See if a given request should be handled by this server instance. - * - * @param {http.IncomingMessage} req Request object to inspect - * @return {Boolean} `true` if the request is valid, else `false` - * @public - */ - shouldHandle(req) { - if (this.options.path) { - const index = req.url.indexOf('?'); - const pathname = index !== -1 ? req.url.slice(0, index) : req.url; - - if (pathname !== this.options.path) return false; - } - - return true; - } - - /** - * Handle a HTTP Upgrade request. - * - * @param {http.IncomingMessage} req The request object - * @param {(net.Socket|tls.Socket)} socket The network socket between the - * server and client - * @param {Buffer} head The first packet of the upgraded stream - * @param {Function} cb Callback - * @public - */ - handleUpgrade(req, socket, head, cb) { - socket.on('error', socketOnError); - - const key = req.headers['sec-websocket-key']; - const version = +req.headers['sec-websocket-version']; - - if (req.method !== 'GET') { - const message = 'Invalid HTTP method'; - abortHandshakeOrEmitwsClientError(this, req, socket, 405, message); - return; - } - - if (req.headers.upgrade.toLowerCase() !== 'websocket') { - const message = 'Invalid Upgrade header'; - abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); - return; - } - - if (!key || !keyRegex.test(key)) { - const message = 'Missing or invalid Sec-WebSocket-Key header'; - abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); - return; - } - - if (version !== 8 && version !== 13) { - const message = 'Missing or invalid Sec-WebSocket-Version header'; - abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); - return; - } - - if (!this.shouldHandle(req)) { - abortHandshake(socket, 400); - return; - } - - const secWebSocketProtocol = req.headers['sec-websocket-protocol']; - let protocols = new Set(); - - if (secWebSocketProtocol !== undefined) { - try { - protocols = subprotocol.parse(secWebSocketProtocol); - } catch (err) { - const message = 'Invalid Sec-WebSocket-Protocol header'; - abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); - return; - } - } - - const secWebSocketExtensions = req.headers['sec-websocket-extensions']; - const extensions = {}; - - if ( - this.options.perMessageDeflate && - secWebSocketExtensions !== undefined - ) { - const perMessageDeflate = new PerMessageDeflate( - this.options.perMessageDeflate, - true, - this.options.maxPayload - ); - - try { - const offers = extension.parse(secWebSocketExtensions); - - if (offers[PerMessageDeflate.extensionName]) { - perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]); - extensions[PerMessageDeflate.extensionName] = perMessageDeflate; - } - } catch (err) { - const message = - 'Invalid or unacceptable Sec-WebSocket-Extensions header'; - abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); - return; - } - } - - // - // Optionally call external client verification handler. - // - if (this.options.verifyClient) { - const info = { - origin: - req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`], - secure: !!(req.socket.authorized || req.socket.encrypted), - req - }; - - if (this.options.verifyClient.length === 2) { - this.options.verifyClient(info, (verified, code, message, headers) => { - if (!verified) { - return abortHandshake(socket, code || 401, message, headers); - } - - this.completeUpgrade( - extensions, - key, - protocols, - req, - socket, - head, - cb - ); - }); - return; - } - - if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); - } - - this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); - } - - /** - * Upgrade the connection to WebSocket. - * - * @param {Object} extensions The accepted extensions - * @param {String} key The value of the `Sec-WebSocket-Key` header - * @param {Set} protocols The subprotocols - * @param {http.IncomingMessage} req The request object - * @param {(net.Socket|tls.Socket)} socket The network socket between the - * server and client - * @param {Buffer} head The first packet of the upgraded stream - * @param {Function} cb Callback - * @throws {Error} If called more than once with the same socket - * @private - */ - completeUpgrade(extensions, key, protocols, req, socket, head, cb) { - // - // Destroy the socket if the client has already sent a FIN packet. - // - if (!socket.readable || !socket.writable) return socket.destroy(); - - if (socket[kWebSocket]) { - throw new Error( - 'server.handleUpgrade() was called more than once with the same ' + - 'socket, possibly due to a misconfiguration' - ); - } - - if (this._state > RUNNING) return abortHandshake(socket, 503); - - const digest = createHash('sha1') - .update(key + GUID) - .digest('base64'); - - const headers = [ - 'HTTP/1.1 101 Switching Protocols', - 'Upgrade: websocket', - 'Connection: Upgrade', - `Sec-WebSocket-Accept: ${digest}` - ]; - - const ws = new this.options.WebSocket(null); - - if (protocols.size) { - // - // Optionally call external protocol selection handler. - // - const protocol = this.options.handleProtocols - ? this.options.handleProtocols(protocols, req) - : protocols.values().next().value; - - if (protocol) { - headers.push(`Sec-WebSocket-Protocol: ${protocol}`); - ws._protocol = protocol; - } - } - - if (extensions[PerMessageDeflate.extensionName]) { - const params = extensions[PerMessageDeflate.extensionName].params; - const value = extension.format({ - [PerMessageDeflate.extensionName]: [params] - }); - headers.push(`Sec-WebSocket-Extensions: ${value}`); - ws._extensions = extensions; - } - - // - // Allow external modification/inspection of handshake headers. - // - this.emit('headers', headers, req); - - socket.write(headers.concat('\r\n').join('\r\n')); - socket.removeListener('error', socketOnError); - - ws.setSocket(socket, head, { - maxPayload: this.options.maxPayload, - skipUTF8Validation: this.options.skipUTF8Validation - }); - - if (this.clients) { - this.clients.add(ws); - ws.on('close', () => { - this.clients.delete(ws); - - if (this._shouldEmitClose && !this.clients.size) { - process.nextTick(emitClose, this); - } - }); - } - - cb(ws, req); - } -} - -module.exports = WebSocketServer; - -/** - * Add event listeners on an `EventEmitter` using a map of - * pairs. - * - * @param {EventEmitter} server The event emitter - * @param {Object.} map The listeners to add - * @return {Function} A function that will remove the added listeners when - * called - * @private - */ -function addListeners(server, map) { - for (const event of Object.keys(map)) server.on(event, map[event]); - - return function removeListeners() { - for (const event of Object.keys(map)) { - server.removeListener(event, map[event]); - } - }; -} - -/** - * Emit a `'close'` event on an `EventEmitter`. - * - * @param {EventEmitter} server The event emitter - * @private - */ -function emitClose(server) { - server._state = CLOSED; - server.emit('close'); -} - -/** - * Handle socket errors. - * - * @private - */ -function socketOnError() { - this.destroy(); -} - -/** - * Close the connection when preconditions are not fulfilled. - * - * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request - * @param {Number} code The HTTP response status code - * @param {String} [message] The HTTP response body - * @param {Object} [headers] Additional HTTP response headers - * @private - */ -function abortHandshake(socket, code, message, headers) { - // - // The socket is writable unless the user destroyed or ended it before calling - // `server.handleUpgrade()` or in the `verifyClient` function, which is a user - // error. Handling this does not make much sense as the worst that can happen - // is that some of the data written by the user might be discarded due to the - // call to `socket.end()` below, which triggers an `'error'` event that in - // turn causes the socket to be destroyed. - // - message = message || http.STATUS_CODES[code]; - headers = { - Connection: 'close', - 'Content-Type': 'text/html', - 'Content-Length': Buffer.byteLength(message), - ...headers - }; - - socket.once('finish', socket.destroy); - - socket.end( - `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + - Object.keys(headers) - .map((h) => `${h}: ${headers[h]}`) - .join('\r\n') + - '\r\n\r\n' + - message - ); -} - -/** - * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least - * one listener for it, otherwise call `abortHandshake()`. - * - * @param {WebSocketServer} server The WebSocket server - * @param {http.IncomingMessage} req The request object - * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request - * @param {Number} code The HTTP response status code - * @param {String} message The HTTP response body - * @private - */ -function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) { - if (server.listenerCount('wsClientError')) { - const err = new Error(message); - Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError); - - server.emit('wsClientError', err, socket, req); - } else { - abortHandshake(socket, code, message); - } -} - - -/***/ }), -/* 25 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const { tokenChars } = __webpack_require__(18); - -/** - * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names. - * - * @param {String} header The field value of the header - * @return {Set} The subprotocol names - * @public - */ -function parse(header) { - const protocols = new Set(); - let start = -1; - let end = -1; - let i = 0; - - for (i; i < header.length; i++) { - const code = header.charCodeAt(i); - - if (end === -1 && tokenChars[code] === 1) { - if (start === -1) start = i; - } else if ( - i !== 0 && - (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */ - ) { - if (end === -1 && start !== -1) end = i; - } else if (code === 0x2c /* ',' */) { - if (start === -1) { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - - if (end === -1) end = i; - - const protocol = header.slice(start, end); - - if (protocols.has(protocol)) { - throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); - } - - protocols.add(protocol); - start = end = -1; - } else { - throw new SyntaxError(`Unexpected character at index ${i}`); - } - } - - if (start === -1 || end !== -1) { - throw new SyntaxError('Unexpected end of input'); - } - - const protocol = header.slice(start, i); - - if (protocols.has(protocol)) { - throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); - } - - protocols.add(protocol); - return protocols; -} - -module.exports = { parse }; - - -/***/ }), -/* 26 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.serverIndexPage = exports.index401 = exports.serverStaticFile = void 0; -const node_fs_1 = __webpack_require__(27); -const node_path_1 = __webpack_require__(28); -const pretty_cache_header_1 = __webpack_require__(29); -const mimeLookup = { - '.js': 'application/javascript,charset=UTF-8', - '.html': 'text/html,charset=UTF-8', - '.css': 'text/css; charset=UTF-8', -}; -const staticPath = 'dist/apps/cf-page/'; -const file401 = 'dist/apps/node-vless/assets/401.html'; -let filepath = null; -function serverStaticFile(req, resp) { - const url = new URL(req.url, `http://${req.headers['host']}`); - let fileurl = url.pathname; - fileurl = (0, node_path_1.join)(staticPath, fileurl); - console.log('....', fileurl); - filepath = (0, node_path_1.resolve)(fileurl); - console.log(filepath); - if ((0, node_fs_1.existsSync)(filepath)) { - let fileExt = (0, node_path_1.extname)(filepath); - console.log('fileExt', fileExt); - let mimeType = mimeLookup[fileExt]; - resp.writeHead(200, { - 'Content-Type': mimeType, - 'Cache-Control': (0, pretty_cache_header_1.cacheHeader)({ - public: true, - maxAge: '1year', - staleWhileRevalidate: '1year', - }), - }); - return (0, node_fs_1.createReadStream)(filepath).pipe(resp); - } - else { - resp.writeHead(404); - resp.write('not found'); - resp.end(); - return resp; - } -} -exports.serverStaticFile = serverStaticFile; -function index401(req, resp) { - const file401Path = (0, node_path_1.resolve)(file401); - if ((0, node_fs_1.existsSync)(file401Path)) { - (0, node_fs_1.createReadStream)(file401Path).pipe(resp); - } - else { - resp.writeHead(401); - resp.write('UUID env not set'); - resp.end(); - } -} -exports.index401 = index401; -function serverIndexPage(req, resp, uuid) { - // if() -} -exports.serverIndexPage = serverIndexPage; - - -/***/ }), -/* 27 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("node:fs"); - -/***/ }), -/* 28 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("node:path"); - -/***/ }), -/* 29 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// src/index.ts -var src_exports = {}; -__export(src_exports, { - cacheHeader: () => cacheHeader -}); -module.exports = __toCommonJS(src_exports); - -// src/cache-header.ts -var import_timestring = __toESM(__webpack_require__(30), 1); -function cacheHeader(params) { - const transformed = Object.entries(params).reduce((acc, [key, value]) => { - const kebabKey = key.replace(/[A-Z]/g, (char) => "-" + char.toLowerCase()); - return typeof value === "string" || value === true ? [...acc, value === true ? kebabKey : `${kebabKey}=${(0, import_timestring.default)(value)}`] : acc; - }, []); - return transformed.join(", "); -} -// Annotate the CommonJS export names for ESM import in node: -0 && (0); -//# sourceMappingURL=index.cjs.map - -/***/ }), -/* 30 */ -/***/ ((module) => { - -/** - * Exports - */ - -module.exports = parseTimestring - -/** - * Default options to use when parsing a timestring - * - * @type {Object} - */ - -const DEFAULT_OPTS = { - hoursPerDay: 24, - daysPerWeek: 7, - weeksPerMonth: 4, - monthsPerYear: 12, - daysPerYear: 365.25 -} - -/** - * Map of accepted strings to unit - * - * @type {Object} - */ - -const UNIT_MAP = { - ms: ['ms', 'milli', 'millisecond', 'milliseconds'], - s: ['s', 'sec', 'secs', 'second', 'seconds'], - m: ['m', 'min', 'mins', 'minute', 'minutes'], - h: ['h', 'hr', 'hrs', 'hour', 'hours'], - d: ['d', 'day', 'days'], - w: ['w', 'week', 'weeks'], - mth: ['mon', 'mth', 'mths', 'month', 'months'], - y: ['y', 'yr', 'yrs', 'year', 'years'] -} - -/** - * Parse a timestring - * - * @param {String} string - * @param {String} returnUnit - * @param {Object} opts - * @return {Number} - */ - -function parseTimestring (string, returnUnit, opts) { - opts = Object.assign({}, DEFAULT_OPTS, opts || {}) - - let totalSeconds = 0 - let unitValues = getUnitValues(opts) - let groups = string - .toLowerCase() - .replace(/[^.\w+-]+/g, '') - .match(/[-+]?[0-9.]+[a-z]+/g) - - if (groups === null) { - throw new Error(`The string [${string}] could not be parsed by timestring`) - } - - groups.forEach(group => { - let value = group.match(/[0-9.]+/g)[0] - let unit = group.match(/[a-z]+/g)[0] - - totalSeconds += getSeconds(value, unit, unitValues) - }) - - if (returnUnit) { - return convert(totalSeconds, returnUnit, unitValues) - } - - return totalSeconds -} - -/** - * Get unit values based on the passed options - * - * @param {Object} opts - * @returns {Object} - */ - -function getUnitValues (opts) { - let unitValues = { - ms: 0.001, - s: 1, - m: 60, - h: 3600 - } - - unitValues.d = opts.hoursPerDay * unitValues.h - unitValues.w = opts.daysPerWeek * unitValues.d - unitValues.mth = (opts.daysPerYear / opts.monthsPerYear) * unitValues.d - unitValues.y = opts.daysPerYear * unitValues.d - - return unitValues -} - -/** - * Get the key for a unit - * - * @param {String} unit - * @returns {String} - */ - -function getUnitKey (unit) { - for (let key of Object.keys(UNIT_MAP)) { - if (UNIT_MAP[key].indexOf(unit) > -1) { - return key - } - } - - throw new Error(`The unit [${unit}] is not supported by timestring`) -} - -/** - * Get the number of seconds for a value, based on the unit - * - * @param {Number} value - * @param {String} unit - * @param {Object} unitValues - * @returns {Number} - */ - -function getSeconds (value, unit, unitValues) { - return value * unitValues[getUnitKey(unit)] -} - -/** - * Convert a value from its existing unit to a new unit - * - * @param {Number} value - * @param {String} unit - * @param {Object} unitValues - * @returns {Number} - */ - -function convert (value, unit, unitValues) { - return value / unitValues[getUnitKey(unit)] -} - - -/***/ }), -/* 31 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -// ESM COMPAT FLAG -__webpack_require__.r(__webpack_exports__); - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "NIL": () => (/* reexport */ nil), - "parse": () => (/* reexport */ esm_node_parse), - "stringify": () => (/* reexport */ esm_node_stringify), - "v1": () => (/* reexport */ esm_node_v1), - "v3": () => (/* reexport */ esm_node_v3), - "v4": () => (/* reexport */ esm_node_v4), - "v5": () => (/* reexport */ esm_node_v5), - "validate": () => (/* reexport */ esm_node_validate), - "version": () => (/* reexport */ esm_node_version) -}); - -// EXTERNAL MODULE: external "crypto" -var external_crypto_ = __webpack_require__(10); -var external_crypto_default = /*#__PURE__*/__webpack_require__.n(external_crypto_); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/rng.js - -const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate - -let poolPtr = rnds8Pool.length; -function rng() { - if (poolPtr > rnds8Pool.length - 16) { - external_crypto_default().randomFillSync(rnds8Pool); - poolPtr = 0; - } - - return rnds8Pool.slice(poolPtr, poolPtr += 16); -} -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/regex.js -/* harmony default export */ const regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/validate.js - - -function validate(uuid) { - return typeof uuid === 'string' && regex.test(uuid); -} - -/* harmony default export */ const esm_node_validate = (validate); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/stringify.js - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ - -const byteToHex = []; - -for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).slice(1)); -} - -function unsafeStringify(arr, offset = 0) { - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); -} - -function stringify(arr, offset = 0) { - const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields - - if (!esm_node_validate(uuid)) { - throw TypeError('Stringified UUID is invalid'); - } - - return uuid; -} - -/* harmony default export */ const esm_node_stringify = (stringify); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/v1.js - - // **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -let _nodeId; - -let _clockseq; // Previous uuid creation time - - -let _lastMSecs = 0; -let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details - -function v1(options, buf, offset) { - let i = buf && offset || 0; - const b = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || rng)(); - - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } - - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - - - let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - - let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) - - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression - - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - - - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } // Per 4.2.1.2 Throw error if too many uuids are requested - - - if (nsecs >= 10000) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - - msecs += 12219292800000; // `time_low` - - const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; // `time_mid` - - const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; // `time_high_and_version` - - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - - b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - - b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` - - b[i++] = clockseq & 0xff; // `node` - - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf || unsafeStringify(b); -} - -/* harmony default export */ const esm_node_v1 = (v1); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/parse.js - - -function parse(uuid) { - if (!esm_node_validate(uuid)) { - throw TypeError('Invalid UUID'); - } - - let v; - const arr = new Uint8Array(16); // Parse ########-....-....-....-............ - - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 0xff; - arr[2] = v >>> 8 & 0xff; - arr[3] = v & 0xff; // Parse ........-####-....-....-............ - - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 0xff; // Parse ........-....-####-....-............ - - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 0xff; // Parse ........-....-....-####-............ - - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 0xff; // Parse ........-....-....-....-############ - // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) - - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; - arr[11] = v / 0x100000000 & 0xff; - arr[12] = v >>> 24 & 0xff; - arr[13] = v >>> 16 & 0xff; - arr[14] = v >>> 8 & 0xff; - arr[15] = v & 0xff; - return arr; -} - -/* harmony default export */ const esm_node_parse = (parse); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/v35.js - - - -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape - - const bytes = []; - - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); - } - - return bytes; -} - -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -function v35(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - var _namespace; - - if (typeof value === 'string') { - value = stringToBytes(value); - } - - if (typeof namespace === 'string') { - namespace = esm_node_parse(namespace); - } - - if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; - } - - return unsafeStringify(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/md5.js - - -function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } - - return external_crypto_default().createHash('md5').update(bytes).digest(); -} - -/* harmony default export */ const esm_node_md5 = (md5); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/v3.js - - -const v3 = v35('v3', 0x30, esm_node_md5); -/* harmony default export */ const esm_node_v3 = (v3); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/native.js - -/* harmony default export */ const esm_node_native = ({ - randomUUID: (external_crypto_default()).randomUUID -}); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/v4.js - - - - -function v4(options, buf, offset) { - if (esm_node_native.randomUUID && !buf && !options) { - return esm_node_native.randomUUID(); - } - - options = options || {}; - const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; - } - - return buf; - } - - return unsafeStringify(rnds); -} - -/* harmony default export */ const esm_node_v4 = (v4); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/sha1.js - - -function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } - - return external_crypto_default().createHash('sha1').update(bytes).digest(); -} - -/* harmony default export */ const esm_node_sha1 = (sha1); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/v5.js - - -const v5 = v35('v5', 0x50, esm_node_sha1); -/* harmony default export */ const esm_node_v5 = (v5); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/nil.js -/* harmony default export */ const nil = ('00000000-0000-0000-0000-000000000000'); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/version.js - - -function version(uuid) { - if (!esm_node_validate(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.slice(14, 15), 16); -} - -/* harmony default export */ const esm_node_version = (version); -;// CONCATENATED MODULE: ../../node_modules/uuid/dist/esm-node/index.js - - - - - - - - - - -/***/ }), -/* 32 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("node:dns"); - -/***/ }), -/* 33 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("node:dgram"); - -/***/ }), -/* 34 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.vlessJs = exports.processVlessHeader = exports.closeWebSocket = exports.makeReadableWebSocketStream = exports.delay = void 0; -var vless_js_1 = __webpack_require__(35); -Object.defineProperty(exports, "delay", ({ enumerable: true, get: function () { return vless_js_1.delay; } })); -Object.defineProperty(exports, "makeReadableWebSocketStream", ({ enumerable: true, get: function () { return vless_js_1.makeReadableWebSocketStream; } })); -Object.defineProperty(exports, "closeWebSocket", ({ enumerable: true, get: function () { return vless_js_1.safeCloseWebSocket; } })); -Object.defineProperty(exports, "processVlessHeader", ({ enumerable: true, get: function () { return vless_js_1.processVlessHeader; } })); -Object.defineProperty(exports, "vlessJs", ({ enumerable: true, get: function () { return vless_js_1.vlessJs; } })); - - -/***/ }), -/* 35 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.processVlessHeader = exports.safeCloseWebSocket = exports.makeReadableWebSocketStream = exports.delay = exports.vlessJs = void 0; -const tslib_1 = __webpack_require__(1); -const uuid_1 = __webpack_require__(31); -function vlessJs() { - return 'vless-js'; -} -exports.vlessJs = vlessJs; -function delay(ms) { - return new Promise((resolve, rej) => { - setTimeout(resolve, ms); - }); -} -exports.delay = delay; -function makeReadableWebSocketStream(ws, earlyDataHeader, log) { - let readableStreamCancel = false; - return new ReadableStream({ - start(controller) { - ws.addEventListener('message', (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { - // is stream is cancel, skip controller.enqueue - if (readableStreamCancel) { - return; - } - const vlessBuffer = e.data; - // console.log('MESSAGE', vlessBuffer); - // console.log(`message is ${vlessBuffer.byteLength}`); - // this is not backpressure, but backpressure is depends on underying websocket can pasue - // https://streams.spec.whatwg.org/#example-rs-push-backpressure - controller.enqueue(vlessBuffer); - })); - ws.addEventListener('error', (e) => { - log('socket has error'); - readableStreamCancel = true; - controller.error(e); - }); - ws.addEventListener('close', () => { - try { - log('webSocket is close'); - // is stream is cancel, skip controller.close - if (readableStreamCancel) { - return; - } - controller.close(); - } - catch (error) { - log(`websocketStream can't close DUE to `, error); - } - }); - // header ws 0rtt - const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader); - if (error) { - log(`earlyDataHeader has invaild base64`); - safeCloseWebSocket(ws); - return; - } - if (earlyData) { - controller.enqueue(earlyData); - } - }, - pull(controller) { - // if ws can stop read if stream is full, we can implement backpressure - // https://streams.spec.whatwg.org/#example-rs-push-backpressure - }, - cancel(reason) { - // TODO: log can be remove, if writestream has error, write stream will has log - log(`websocketStream is cancel DUE to `, reason); - if (readableStreamCancel) { - return; - } - readableStreamCancel = true; - safeCloseWebSocket(ws); - }, - }); -} -exports.makeReadableWebSocketStream = makeReadableWebSocketStream; -function base64ToArrayBuffer(base64Str) { - if (!base64Str) { - return { error: null }; - } - try { - // go use modified Base64 for URL rfc4648 which js atob not support - base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/'); - const decode = atob(base64Str); - const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); - return { earlyData: arryBuffer.buffer, error: null }; - } - catch (error) { - return { error }; - } -} -function safeCloseWebSocket(socket) { - try { - if (socket.readyState === socket.OPEN) { - socket.close(); - } - } - catch (error) { - console.error('safeCloseWebSocket error', error); - } -} -exports.safeCloseWebSocket = safeCloseWebSocket; -//https://github.com/v2ray/v2ray-core/issues/2636 -// 1 字节 16 字节 1 字节 M 字节 1 字节 2 字节 1 字节 S 字节 X 字节 -// 协议版本 等价 UUID 附加信息长度 M (附加信息 ProtoBuf) 指令(udp/tcp) 端口 地址类型 地址 请求数据 -// 00 00 01 01bb(443) 02(ip/host) -// 1 字节 1 字节 N 字节 Y 字节 -// 协议版本,与请求的一致 附加信息长度 N 附加信息 ProtoBuf 响应数据 -function processVlessHeader(vlessBuffer, userID -// uuidLib: any, -// lodash: any -) { - if (vlessBuffer.byteLength < 24) { - // console.log('invalid data'); - // controller.error('invalid data'); - return { - hasError: true, - message: 'invalid data', - }; - } - const version = new Uint8Array(vlessBuffer.slice(0, 1)); - let isValidUser = false; - let isUDP = false; - if ((0, uuid_1.stringify)(new Uint8Array(vlessBuffer.slice(1, 17))) === userID) { - isValidUser = true; - } - if (!isValidUser) { - // console.log('in valid user'); - // controller.error('in valid user'); - return { - hasError: true, - message: 'invalid user', - }; - } - const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0]; - //skip opt for now - const command = new Uint8Array(vlessBuffer.slice(18 + optLength, 18 + optLength + 1))[0]; - // 0x01 TCP - // 0x02 UDP - // 0x03 MUX - if (command === 1) { - } - else if (command === 2) { - isUDP = true; - } - else { - return { - hasError: true, - message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`, - }; - } - const portIndex = 18 + optLength + 1; - const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2); - // port is big-Endian in raw data etc 80 == 0x005d - const portRemote = new DataView(portBuffer).getInt16(0); - let addressIndex = portIndex + 2; - const addressBuffer = new Uint8Array(vlessBuffer.slice(addressIndex, addressIndex + 1)); - // 1--> ipv4 addressLength =4 - // 2--> domain name addressLength=addressBuffer[1] - // 3--> ipv6 addressLength =16 - const addressType = addressBuffer[0]; - let addressLength = 0; - let addressValueIndex = addressIndex + 1; - let addressValue = ''; - switch (addressType) { - case 1: - addressLength = 4; - addressValue = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)).join('.'); - break; - case 2: - addressLength = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + 1))[0]; - addressValueIndex += 1; - addressValue = new TextDecoder().decode(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); - break; - case 3: - addressLength = 16; - const dataView = new DataView(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); - // 2001:0db8:85a3:0000:0000:8a2e:0370:7334 - const ipv6 = []; - for (let i = 0; i < 8; i++) { - ipv6.push(dataView.getUint16(i * 2).toString(16)); - } - addressValue = ipv6.join(':'); - // console.log('---------', addressValue) - // seems no need add [] for ipv6 - // if (addressValue) { - // addressValue = `[${addressValue}]`; - // } - break; - default: - console.log(`invild addressType is ${addressType}`); - } - if (!addressValue) { - // console.log(`[${address}:${port}] addressValue is empty`); - // controller.error(`[${address}:${portWithRandomLog}] addressValue is empty`); - return { - hasError: true, - message: `addressValue is empty, addressType is ${addressType}`, - }; - } - return { - hasError: false, - addressRemote: addressValue, - portRemote, - rawDataIndex: addressValueIndex + addressLength, - vlessVersion: version, - isUDP, - }; -} -exports.processVlessHeader = processVlessHeader; - - -/***/ }), -/* 36 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("node:net"); - -/***/ }), -/* 37 */ -/***/ ((module) => { - -"use strict"; -module.exports = require("node:stream/web"); - -/***/ }) -/******/ ]); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => (module['default']) : -/******/ () => (module); -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be in strict mode. -(() => { -"use strict"; -var exports = __webpack_exports__; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -const tslib_1 = __webpack_require__(1); -const http_1 = __webpack_require__(2); -const url_1 = __webpack_require__(3); -const ws_1 = __webpack_require__(4); -const utils_1 = __webpack_require__(26); -const uuid_1 = __webpack_require__(31); -const node_fs_1 = __webpack_require__(27); -const node_dns_1 = __webpack_require__(32); -const node_dgram_1 = __webpack_require__(33); -const vless_js_1 = __webpack_require__(34); -const node_net_1 = __webpack_require__(36); -const stream_1 = __webpack_require__(11); -const web_1 = __webpack_require__(37); -const port = process.env.PORT; -const smallRAM = process.env.SMALLRAM || false; -const userID = process.env.UUID || ''; -//'ipv4first' or 'verbatim' -const dnOder = process.env.DNSORDER || 'verbatim'; -if (dnOder === 'ipv4first') { - (0, node_dns_1.setDefaultResultOrder)(dnOder); -} -let isVaildUser = (0, uuid_1.validate)(userID); -if (!isVaildUser) { - console.log('not set valid UUID'); -} -const server = (0, http_1.createServer)((req, resp) => { - var _a; - if (!isVaildUser) { - return (0, utils_1.index401)(req, resp); - } - const url = new URL(req.url, `http://${req.headers['host']}`); - // health check - if (req.method === 'GET' && url.pathname.startsWith('/health')) { - resp.writeHead(200); - resp.write('health 200'); - resp.end(); - return; - } - // index page - if (url.pathname.includes(userID)) { - const index = 'dist/apps/cf-page/index.html'; - resp.writeHead(200, { - 'Content-Type': 'text/html,charset=UTF-8', - }); - return (0, node_fs_1.createReadStream)(index).pipe(resp); - } - if (req.method === 'GET' && url.pathname.startsWith('/assets')) { - return (0, utils_1.serverStaticFile)(req, resp); - } - const basicAuth = req.headers.authorization || ''; - const authStringBase64 = ((_a = basicAuth.split(' ')) === null || _a === void 0 ? void 0 : _a[1]) || ''; - const authString = Buffer.from(authStringBase64, 'base64').toString('ascii'); - if (authString && authString.includes(userID)) { - resp.writeHead(302, { - 'content-type': 'text/html; charset=utf-8', - Location: `./${userID}`, - }); - resp.end(); - } - else { - resp.writeHead(401, { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic', - }); - resp.end(); - } -}); -const vlessWServer = new ws_1.WebSocketServer({ noServer: true }); -vlessWServer.on('connection', function connection(ws, request) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - let address = ''; - let portWithRandomLog = ''; - try { - const log = (info, event) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - let remoteConnection = null; - let udpClientStream = null; - let remoteConnectionReadyResolve; - const earlyDataHeader = request.headers['sec-websocket-protocol']; - const readableWebSocketStream = (0, vless_js_1.makeReadableWebSocketStream)(ws, earlyDataHeader, log); - let vlessResponseHeader = null; - // ws --> remote - readableWebSocketStream - .pipeTo(new web_1.WritableStream({ - write(chunk, controller) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - if (!Buffer.isBuffer(chunk)) { - chunk = Buffer.from(chunk); - } - if (udpClientStream) { - const writer = udpClientStream.writable.getWriter(); - // nodejs buffer to ArrayBuffer issue - // https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#bufbuffer - yield writer.write(chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.length)); - writer.releaseLock(); - return; - } - if (remoteConnection) { - yield socketAsyncWrite(remoteConnection, chunk); - // remoteConnection.write(chunk); - return; - } - const vlessBuffer = chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.length); - const { hasError, message, portRemote, addressRemote, rawDataIndex, vlessVersion, isUDP, } = (0, vless_js_1.processVlessHeader)(vlessBuffer, userID); - address = addressRemote || ''; - portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? 'udp ' : 'tcp '} `; - if (hasError) { - controller.error(`[${address}:${portWithRandomLog}] ${message} `); - return; - } - // const addressType = requestAddr >> 42 - // const addressLength = requestAddr & 0x0f; - console.log(`[${address}:${portWithRandomLog}] connecting`); - vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]); - const rawClientData = vlessBuffer.slice(rawDataIndex); - if (isUDP) { - // 如果仅仅是针对DNS, 这样是没有必要的。因为xray 客户端 DNS A/AAA query 都有长度 header, - // 所以直接和 DNS server over TCP。所以无需 runtime 支持 UDP API。 - // DNS over UDP 和 TCP 唯一的区别就是 Header section format 多了长度 - // https://www.rfc-editor.org/rfc/rfc1035#section-4.2.2 - udpClientStream = makeUDPSocketStream(portRemote, address); - const writer = udpClientStream.writable.getWriter(); - writer.write(rawClientData).catch((error) => console.log); - writer.releaseLock(); - remoteConnectionReadyResolve(udpClientStream); - } - else { - remoteConnection = yield connect2Remote(portRemote, address, log); - remoteConnection.write(new Uint8Array(rawClientData)); - remoteConnectionReadyResolve(remoteConnection); - } - }); - }, - close() { - // if (udpClientStream ) { - // udpClientStream.writable.close(); - // } - // (remoteConnection as Socket).end(); - console.log(`[${address}:${portWithRandomLog}] readableWebSocketStream is close`); - }, - abort(reason) { - // TODO: log can be remove, abort will catch by catch block - console.log(`[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, JSON.stringify(reason)); - }, - })) - .catch((error) => { - console.error(`[${address}:${portWithRandomLog}] readableWebSocketStream pipeto has exception`, error.stack || error); - // error is cancel readable stream anyway, no need close websocket in here - // closeWebSocket(webSocket); - // close remote conn - // remoteConnection?.close(); - }); - yield new Promise((resolve) => (remoteConnectionReadyResolve = resolve)); - // remote --> ws - let responseStream = udpClientStream === null || udpClientStream === void 0 ? void 0 : udpClientStream.readable; - if (remoteConnection) { - // ignore type error - // @ts-ignore - responseStream = stream_1.Readable.toWeb(remoteConnection, { - strategy: { - // due to nodejs issue https://github.com/nodejs/node/issues/46347 - highWaterMark: smallRAM ? 100 : 1000, // 1000 * tcp mtu(64kb) = 64mb - }, - }); - } - let count = 0; - // ws.send(vlessResponseHeader!); - // remoteConnection.pipe( - // new Writable({ - // async write(chunk: Uint8Array, encoding, callback) { - // count += chunk.byteLength; - // console.log('ws write', count / (1024 * 1024)); - // console.log( - // '-----++++', - // (remoteConnection as Socket).bytesRead / (1024 * 1024) - // ); - // if (ws.readyState === ws.OPEN) { - // await wsAsyncWrite(ws, chunk); - // callback(); - // } - // }, - // }) - // ); - // if readable not pipe can't wait fro writeable write method - yield responseStream.pipeTo(new web_1.WritableStream({ - start() { - if (ws.readyState === ws.OPEN) { - ws.send(vlessResponseHeader); - } - }, - write(chunk, controller) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - // count += chunk.byteLength; - // console.log('ws write', count / (1024 * 1024)); - // console.log( - // '-----++++', - // (remoteConnection as Socket).bytesRead / (1024 * 1024), - // (remoteConnection as Socket).readableHighWaterMark - // ); - // we have issue there, maybe beacsue nodejs web stream has bug. - // socket web stream will read more data from socket - if (ws.readyState === ws.OPEN) { - yield wsAsyncWrite(ws, chunk); - } - else { - if (!remoteConnection.destroyed) { - remoteConnection.destroy(); - } - } - }); - }, - close() { - console.log(`[${address}:${portWithRandomLog}] remoteConnection!.readable is close`); - }, - abort(reason) { - (0, vless_js_1.closeWebSocket)(ws); - console.error(`[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, reason); - }, - })); - } - catch (error) { - console.error(`[${address}:${portWithRandomLog}] processWebSocket has exception `, error.stack || error); - (0, vless_js_1.closeWebSocket)(ws); - } - }); -}); -server.on('upgrade', function upgrade(request, socket, head) { - const { pathname } = (0, url_1.parse)(request.url); - vlessWServer.handleUpgrade(request, socket, head, function done(ws) { - vlessWServer.emit('connection', ws, request); - }); -}); -server.listen({ - port: port, - host: '::', - // host: '0.0.0.0', -}, () => { - console.log(`server listen in http://127.0.0.1:${port}`); -}); -function connect2Remote(port, host, log) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - return new Promise((resole, reject) => { - const remoteSocket = (0, node_net_1.connect)({ - port: port, - host: host, - // https://github.com/nodejs/node/pull/46587 - // autoSelectFamily: true, - }, () => { - log(`connected`); - resole(remoteSocket); - }); - remoteSocket.addListener('error', () => { - reject('remoteSocket has error'); - }); - }); - }); -} -function socketAsyncWrite(ws, chunk) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { - ws.write(chunk, (error) => { - if (error) { - reject(error); - } - else { - resolve(''); - } - }); - }); - }); -} -function wsAsyncWrite(ws, chunk) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { - ws.send(chunk, (error) => { - if (error) { - reject(error); - } - else { - resolve(''); - } - }); - }); - }); -} -function makeUDPSocketStream(portRemote, address) { - const udpClient = (0, node_dgram_1.createSocket)('udp4'); - const transformStream = new web_1.TransformStream({ - start(controller) { - /* … */ - udpClient.on('message', (message, info) => { - // console.log( - // `udp package received ${info.size} bytes from ${info.address}:${info.port}`, - // Buffer.from(message).toString('hex') - // ); - controller.enqueue(Buffer.concat([ - new Uint8Array([(info.size >> 8) & 0xff, info.size & 0xff]), - message, - ])); - }); - udpClient.on('error', (error) => { - console.log('udpClient error event', error); - controller.error(error); - }); - }, - transform(chunk, controller) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - //seems v2ray will use same web socket for dns query.. - //And v2ray will combine A record and AAAA record into one ws message and use 2 btye for dns query length - for (let index = 0; index < chunk.byteLength;) { - const lengthBuffer = chunk.slice(index, index + 2); - const udpPakcetLength = new DataView(lengthBuffer).getInt16(0); - const udpData = new Uint8Array(chunk.slice(index + 2, index + 2 + udpPakcetLength)); - index = index + 2 + udpPakcetLength; - yield new Promise((resolve, reject) => { - udpClient.send(udpData, portRemote, address, (err) => { - if (err) { - console.log('udps send error', err); - controller.error(`Failed to send UDP packet !! ${err}`); - safeCloseUDP(udpClient); - } - // console.log( - // 'udp package sent', - // Buffer.from(udpData).toString('hex') - // ); - resolve(true); - }); - }); - index = index; - } - // console.log('dns chunk', chunk); - // console.log(portRemote, address); - // port is big-Endian in raw data etc 80 == 0x005d - }); - }, - flush(controller) { - safeCloseUDP(udpClient); - controller.terminate(); - }, - }); - return transformStream; -} -function safeCloseUDP(client) { - try { - client.close(); - } - catch (error) { - console.log('error close udp', error); - } -} - -})(); - -var __webpack_export_target__ = exports; -for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i]; -if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true }); -/******/ })() -; -//# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/dist/apps/node-vless/main.js.map b/dist/apps/node-vless/main.js.map deleted file mode 100644 index b72eb6d..0000000 --- a/dist/apps/node-vless/main.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"main.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB,sCAAsC,kBAAkB;AACnF,0BAA0B;AAC1B;AACA;AACA;AACO;AACP;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACO;AACP;AACA,iDAAiD,OAAO;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,6DAA6D,cAAc;AAC3E;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACO;AACP,oCAAoC;AACpC;AACA;AACO;AACP,yBAAyB,uFAAuF;AAChH;AACA;AACA,2GAA2G;AAC3G;AACA,wCAAwC,QAAQ;AAChD;AACA,kEAAkE;AAClE;AACA,gDAAgD,yFAAyF;AACzI,gEAAgE,2CAA2C;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA,oBAAoB,yBAAyB;AAC7C;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACO;AACP;AACA,8CAA8C,yEAAyE;AACvH;AACA;AACO;AACP;AACA;AACA;AACO;AACP,4BAA4B,+DAA+D,iBAAiB;AAC5G;AACA,oCAAoC,MAAM,+BAA+B,YAAY;AACrF,mCAAmC,MAAM,mCAAmC,YAAY;AACxF,gCAAgC;AAChC;AACA,KAAK;AACL;AACA;AACO;AACP,cAAc,6BAA6B,0BAA0B,cAAc,qBAAqB;AACxG,iBAAiB,oDAAoD,qEAAqE,cAAc;AACxJ,uBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC,mCAAmC,SAAS;AAC5C,mCAAmC,WAAW,UAAU;AACxD,0CAA0C,cAAc;AACxD;AACA,8GAA8G,OAAO;AACrH,iFAAiF,iBAAiB;AAClG,yDAAyD,gBAAgB,QAAQ;AACjF,+CAA+C,gBAAgB,gBAAgB;AAC/E;AACA,kCAAkC;AAClC;AACA;AACA,UAAU,YAAY,aAAa,SAAS,UAAU;AACtD,oCAAoC,SAAS;AAC7C;AACA;AACA;AACO;AACP;AACA;AACA;AACA,iBAAiB,oCAAoC;AACrD;AACA;AACA,CAAC;AACD;AACA;AACA,CAAC;AACD;AACO;AACP;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACO;AACP,6BAA6B,sBAAsB;AACnD;AACA;AACA;AACA;AACA;AACO;AACP,kDAAkD,QAAQ;AAC1D,yCAAyC,QAAQ;AACjD,yDAAyD,QAAQ;AACjE;AACA;AACA;AACA;AACO;AACP,6EAA6E,OAAO;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACO;AACP;AACA;AACA,iBAAiB,uFAAuF,cAAc;AACtH,uBAAuB,gCAAgC,qCAAqC,2CAA2C;AACvI,4BAA4B,MAAM,iBAAiB,YAAY;AAC/D,uBAAuB;AACvB,8BAA8B;AAC9B,6BAA6B;AAC7B,4BAA4B;AAC5B;AACA;AACO;AACP;AACA,iBAAiB,6CAA6C,UAAU,sDAAsD,cAAc;AAC5I,0BAA0B,6BAA6B,oBAAoB,uCAAuC,kBAAkB;AACpI;AACA;AACO;AACP;AACA;AACA,2GAA2G,uFAAuF,cAAc;AAChN,uBAAuB,8BAA8B,gDAAgD,wDAAwD;AAC7J,6CAA6C,sCAAsC,UAAU,mBAAmB,IAAI;AACpH;AACA;AACO;AACP,iCAAiC,uCAAuC,YAAY,KAAK,OAAO;AAChG;AACA;AACA;AACA;AACA,0CAA0C,4BAA4B;AACtE,CAAC;AACD;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP,6CAA6C;AAC7C;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;;;;;;;;ACpSA;;;;;;;ACAA;;;;;;;ACAa;;AAEb,kBAAkB,mBAAO,CAAC,CAAiB;;AAE3C,kCAAkC,mBAAO,CAAC,EAAc;AACxD,mBAAmB,mBAAO,CAAC,EAAwB;AACnD,qBAAqB,mBAAO,CAAC,EAAgB;AAC7C,mBAAmB,mBAAO,CAAC,EAAc;;AAEzC;AACA;;AAEA;;;;;;;;ACZA,sCAAsC,mCAAmC;;AAE5D;;AAEb,qBAAqB,mBAAO,CAAC,CAAQ;AACrC,cAAc,mBAAO,CAAC,CAAO;AAC7B,aAAa,mBAAO,CAAC,CAAM;AAC3B,YAAY,mBAAO,CAAC,CAAK;AACzB,YAAY,mBAAO,CAAC,CAAK;AACzB,QAAQ,0BAA0B,EAAE,mBAAO,CAAC,EAAQ;AACpD,QAAQ,WAAW,EAAE,mBAAO,CAAC,EAAQ;AACrC,QAAQ,MAAM,EAAE,mBAAO,CAAC,CAAK;;AAE7B,0BAA0B,mBAAO,CAAC,EAAsB;AACxD,iBAAiB,mBAAO,CAAC,EAAY;AACrC,eAAe,mBAAO,CAAC,EAAU;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,EAAE,mBAAO,CAAC,EAAa;AACzB;AACA,iBAAiB;AACjB,EAAE,EAAE,mBAAO,CAAC,EAAgB;AAC5B,QAAQ,gBAAgB,EAAE,mBAAO,CAAC,EAAa;AAC/C,QAAQ,WAAW,EAAE,mBAAO,CAAC,EAAe;;AAE5C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,cAAc;AAC3B,aAAa,mBAAmB;AAChC,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,yBAAyB;AACtC;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,GAAG;AAChB,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,GAAG;AAChB,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,GAAG;AAChB,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,kBAAkB;AAC3E,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,OAAO;AACP;AACA,GAAG;AACH,CAAC;;AAED;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,cAAc;AACzB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,WAAW,UAAU;AACrB;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,kBAAkB;AAC7B;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uCAAuC,sBAAsB;AAC7D,gCAAgC,4BAA4B;AAC5D;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,MAAM;AACN,4CAA4C,QAAQ;AACpD;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,mEAAmE;AACnE;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,mBAAmB,mBAAmB,GAAG,mBAAmB;AAC5D;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB;;AAElB;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAQ;AACR,oDAAoD,SAAS;AAC7D;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA,uCAAuC,eAAe;AACtD;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,YAAY;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,eAAe;AAC3B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,4CAA4C;AACvD;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,GAAG;AACd,WAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2CAA2C,sBAAsB;AACjE,YAAY,kCAAkC;AAC9C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;AC9xCA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAa;;AAEb,aAAa,mBAAO,CAAC,EAAM;;AAE3B,mBAAmB,mBAAO,CAAC,EAAe;AAC1C,gBAAgB,mBAAO,CAAC,EAAW;AACnC,QAAQ,cAAc,EAAE,mBAAO,CAAC,EAAa;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,kBAAkB;AAC/B;AACA,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,kBAAkB;AAC/B;AACA,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wCAAwC,IAAI;AAC5C;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,gDAAgD,IAAI,KAAK,MAAM;AAC/D;AACA;AACA;AACA,YAAY;AACZ;AACA,8CAA8C,IAAI,KAAK,MAAM;AAC7D;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,8CAA8C,IAAI,KAAK,MAAM;AAC7D;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,8CAA8C,IAAI,KAAK,MAAM;AAC7D;AACA;AACA,UAAU;AACV,gDAAgD,IAAI;AACpD;;AAEA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;;AAEA,kCAAkC,SAAS;AAC3C;AACA;AACA;;AAEA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,gCAAgC,SAAS;AACzC;AACA;;AAEA;AACA,KAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACjgBA;;;;;;;ACAa;;AAEb,QAAQ,eAAe,EAAE,mBAAO,CAAC,EAAa;;AAE9C;;AAEA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,QAAQ;AACnB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA,kBAAkB,YAAY;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA,kBAAkB,mBAAmB;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,GAAG;AACd,YAAY,QAAQ;AACpB,YAAY;AACZ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,uBAAuB,mBAAO,CAAC,yIAAY;;AAE3C,IAAI,mBAAmB;AACvB;AACA;AACA;;AAEA,IAAI,qBAAqB;AACzB;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;;;;;;;AClIa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACXa;;AAEb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;ACtDa;;AAEb,QAAQ,WAAW,EAAE,mBAAO,CAAC,EAAQ;;AAErC,0BAA0B,mBAAO,CAAC,EAAsB;AACxD;AACA;AACA;AACA;AACA;AACA,EAAE,EAAE,mBAAO,CAAC,EAAa;AACzB,QAAQ,gCAAgC,EAAE,mBAAO,CAAC,EAAe;AACjE,QAAQ,iCAAiC,EAAE,mBAAO,CAAC,EAAc;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA;AACA,0BAA0B;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;;AAEN;AACA;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA;;AAEA;AACA;AACA;AACA,cAAc,wBAAwB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,4BAA4B,aAAa;AACzC;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,oBAAoB;AACxD;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,wBAAwB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,wBAAwB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,wBAAwB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,cAAc,mBAAmB;AACjC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;;AAEA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA,mCAAmC,KAAK;AACxC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW,gCAAgC;AAC3C,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA,yCAAyC,QAAQ;AACjD;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;AClnBa;;AAEb,QAAQ,SAAS,EAAE,mBAAO,CAAC,EAAQ;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAE,0BAA0B;AAC5B;AACA;AACA,EAAE;AACF;AACA,wBAAwB,mBAAO,CAAC,6IAAgB;;AAEhD,IAAI,0BAA0B;AAC9B;AACA;AACA,IAAI;AACJ;AACA;AACA;;;;;;;;ACjIA;;;;;;;ACAA,sCAAsC,kCAAkC;;AAE3D;;AAEb,YAAY,mBAAO,CAAC,CAAK;AACzB,YAAY,mBAAO,CAAC,CAAK;AACzB,QAAQ,iBAAiB,EAAE,mBAAO,CAAC,EAAQ;;AAE3C,0BAA0B,mBAAO,CAAC,EAAsB;AACxD,QAAQ,eAAe,EAAE,mBAAO,CAAC,EAAa;AAC9C,QAAQ,oBAAoB,EAAE,mBAAO,CAAC,EAAc;AACpD,QAAQ,4BAA4B,EAAE,mBAAO,CAAC,EAAe;;AAE7D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAyB;AACtC,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA,aAAa,UAAU;AACvB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,cAAc,mBAAmB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,iBAAiB;AAC9B,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,GAAG;AAChB,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,GAAG;AAChB,aAAa,SAAS;AACtB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,GAAG;AAChB,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA,aAAa,UAAU;AACvB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,wBAAwB,wBAAwB;AAChD;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;;;;;;;;AC7da;;AAEb,QAAQ,kCAAkC,EAAE,mBAAO,CAAC,EAAa;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA,mDAAmD,kBAAkB;AACrE,iDAAiD,kBAAkB;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA;AACA,gCAAgC;AAChC;;AAEA;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA,sDAAsD,kBAAkB;AACxE,wDAAwD,kBAAkB;AAC1E,0DAA0D,kBAAkB;;AAE5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,GAAG;AAChB,aAAa,QAAQ;AACrB;AACA,gCAAgC;AAChC;;AAEA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA,uDAAuD,kBAAkB;AACzE,yDAAyD,kBAAkB;;AAE3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,GAAG;AAChB;AACA,gCAAgC;AAChC;;AAEA;AACA;;AAEA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA,wDAAwD,kBAAkB;;AAE1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,mBAAmB;AAChC,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,mBAAmB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,mBAAmB;AAC9B,WAAW,GAAG;AACd,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;;;;;;;ACnSa;;AAEb,QAAQ,aAAa,EAAE,mBAAO,CAAC,EAAc;;AAE7C;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAS,mBAAmB;AAC5B;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ,4BAA4B;AACpC;AACA,iEAAiE,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;;AAEA;AACA,QAAQ;AACR,+DAA+D,EAAE;AACjE;AACA,MAAM;AACN;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA,iEAAiE,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,QAAQ;AACR;AACA;AACA,QAAQ;AACR,+DAA+D,EAAE;AACjE;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,EAAE;AACnE;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV,iEAAiE,EAAE;AACnE;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA,iEAAiE,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR,+DAA+D,EAAE;AACjE;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,EAAE,GAAG,EAAE;AAC1D,2BAA2B;AAC3B,eAAe;AACf;AACA,qBAAqB;AACrB,SAAS;AACT;AACA,KAAK;AACL;AACA;;AAEA,mBAAmB;;;;;;;;AC1MN;;AAEb,QAAQ,SAAS,EAAE,mBAAO,CAAC,EAAQ;;AAEnC;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,QAAQ;AACnB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;;;;;;AC9JA,sCAAsC,wCAAwC;;AAEjE;;AAEb,qBAAqB,mBAAO,CAAC,CAAQ;AACrC,aAAa,mBAAO,CAAC,CAAM;AAC3B,cAAc,mBAAO,CAAC,CAAO;AAC7B,YAAY,mBAAO,CAAC,CAAK;AACzB,YAAY,mBAAO,CAAC,CAAK;AACzB,QAAQ,aAAa,EAAE,mBAAO,CAAC,EAAQ;;AAEvC,kBAAkB,mBAAO,CAAC,EAAa;AACvC,0BAA0B,mBAAO,CAAC,EAAsB;AACxD,oBAAoB,mBAAO,CAAC,EAAe;AAC3C,kBAAkB,mBAAO,CAAC,CAAa;AACvC,QAAQ,mBAAmB,EAAE,mBAAO,CAAC,EAAa;;AAElD,iCAAiC,GAAG;;AAEpC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,UAAU;AACvB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB,aAAa,QAAQ;AACrB,aAAa,kBAAkB;AAC/B;AACA,aAAa,QAAQ;AACrB,aAAa,4BAA4B;AACzC;AACA,aAAa,SAAS;AACtB;AACA,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB;AACA,aAAa,UAAU;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,sBAAsB;AACpC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,QAAQ;AACR;AACA;AACA,MAAM;AACN;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,aAAa,sBAAsB;AACnC,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,sBAAsB;AACnC,aAAa,yBAAyB;AACtC;AACA,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kDAAkD;AAC3E;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,KAAK;AAClB,aAAa,sBAAsB;AACnC,aAAa,yBAAyB;AACtC;AACA,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+BAA+B,OAAO;AACtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gDAAgD,SAAS;AACzD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP,gDAAgD,MAAM;AACtD;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,WAAW,cAAc;AACzB,WAAW,2BAA2B;AACtC,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,yBAAyB;AACpC,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,gBAAgB,MAAM,EAAE,wBAAwB;AAChD;AACA,uBAAuB,EAAE,IAAI,WAAW;AACxC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B,WAAW,sBAAsB;AACjC,WAAW,yBAAyB;AACpC,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;AACA;AACA;;;;;;;;ACthBa;;AAEb,QAAQ,aAAa,EAAE,mBAAO,CAAC,EAAc;;AAE7C;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,KAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAU,mBAAmB;AAC7B;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,+DAA+D,EAAE;AACjE;;AAEA;;AAEA;;AAEA;AACA,sCAAsC,SAAS;AAC/C;;AAEA;AACA;AACA,MAAM;AACN,6DAA6D,EAAE;AAC/D;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,kCAAkC,SAAS;AAC3C;;AAEA;AACA;AACA;;AAEA,mBAAmB;;;;;;;;;;;AC7DnB,0CAAuD;AAEvD,4CAAmD;AACnD,sDAAkD;AAElD,MAAM,UAAU,GAAG;IACjB,KAAK,EAAE,sCAAsC;IAC7C,OAAO,EAAE,yBAAyB;IAClC,MAAM,EAAE,yBAAyB;CAClC,CAAC;AACF,MAAM,UAAU,GAAG,oBAAoB,CAAC;AACxC,MAAM,OAAO,GAAG,sCAAsC,CAAC;AACvD,IAAI,QAAQ,GAAG,IAAI,CAAC;AACpB,SAAgB,gBAAgB,CAAC,GAAoB,EAAE,IAAoB;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9D,IAAI,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC3B,OAAO,GAAG,oBAAI,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,GAAG,uBAAO,EAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEtB,IAAI,wBAAU,EAAC,QAAQ,CAAC,EAAE;QACxB,IAAI,OAAO,GAAG,uBAAO,EAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAChC,IAAI,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClB,cAAc,EAAE,QAAQ;YACxB,eAAe,EAAE,qCAAW,EAAC;gBAC3B,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,OAAO;gBACf,oBAAoB,EAAE,OAAO;aAC9B,CAAC;SACH,CAAC,CAAC;QACH,OAAO,8BAAgB,EAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC9C;SAAM;QACL,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AA5BD,4CA4BC;AAED,SAAgB,QAAQ,CAAC,GAAoB,EAAE,IAAoB;IACjE,MAAM,WAAW,GAAG,uBAAO,EAAC,OAAO,CAAC,CAAC;IACrC,IAAI,wBAAU,EAAC,WAAW,CAAC,EAAE;QAC3B,8BAAgB,EAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC1C;SAAM;QACL,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;KACZ;AACH,CAAC;AATD,4BASC;AAED,SAAgB,eAAe,CAC7B,GAAoB,EACpB,IAAoB,EACpB,IAAI;IAEJ,OAAO;AACT,CAAC;AAND,0CAMC;;;;;;;;AC5DD;;;;;;;ACAA;;;;;;;ACAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,kCAAkC;AAChE;AACA;AACA;AACA;AACA;AACA,6BAA6B,4FAA4F;AACzH;AACA;AACA;AACA,mGAAmG;AACnG,yEAAyE,8BAA8B;AACvG;AACA;AACA,oDAAoD,kBAAkB,aAAa;;AAEnF;AACA;AACA;AACA;AACA,CAAC;AACD;;AAEA;AACA,gCAAgC,mBAAO,CAAC,EAAY;AACpD;AACA;AACA;AACA,iGAAiG,SAAS,GAAG,sCAAsC;AACnJ,GAAG;AACH;AACA;AACA;AACA,MAAM,CAEL;AACD;;;;;;AC7CA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY;AACZ;;AAEA;AACA,yBAAyB,0BAA0B;;AAEnD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mCAAmC,OAAO;AAC1C;;AAEA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA+B,KAAK;AACpC;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa;AACb;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa;AACb;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1I4B;AAC5B,uCAAuC;;AAEvC;AACe;AACf;AACA,IAAI,wCAAqB;AACzB;AACA;;AAEA;AACA;;ACXA,4CAAe,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,GAAG,yCAAyC;;ACArG;;AAE/B;AACA,qCAAqC,UAAU;AAC/C;;AAEA,wDAAe,QAAQ;;ACNc;AACrC;AACA;AACA;AACA;;AAEA;;AAEA,gBAAgB,SAAS;AACzB;AACA;;AAEO;AACP;AACA;AACA;AACA;;AAEA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;;AAEA,OAAO,iBAAQ;AACf;AACA;;AAEA;AACA;;AAEA,yDAAe,SAAS;;AChCG;AACsB,CAAC;AAClD;AACA;AACA;;AAEA;;AAEA,eAAe;;;AAGf;AACA,oBAAoB;;AAEpB;AACA;AACA;AACA;AACA;AACA,gFAAgF;AAChF;AACA;;AAEA;AACA,wDAAwD,GAAG;;AAE3D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;;AAGA,wEAAwE;AACxE;;AAEA,4EAA4E;;AAE5E,gEAAgE;;AAEhE;AACA;AACA,IAAI;AACJ;;;AAGA;AACA;AACA,IAAI;;;AAGJ;AACA;AACA;;AAEA;AACA;AACA,wBAAwB;;AAExB,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA,uBAAuB;;AAEvB,oCAAoC;;AAEpC,8BAA8B;;AAE9B,kCAAkC;;AAElC,4BAA4B;;AAE5B,kBAAkB,OAAO;AACzB;AACA;;AAEA,gBAAgB,eAAe;AAC/B;;AAEA,kDAAe,EAAE;;AC9FoB;;AAErC;AACA,OAAO,iBAAQ;AACf;AACA;;AAEA;AACA,kCAAkC;;AAElC;AACA;AACA;AACA,qBAAqB;;AAErB;AACA,qBAAqB;;AAErB;AACA,qBAAqB;;AAErB;AACA,qBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qDAAe,KAAK;;AClC6B;AAClB;;AAE/B;AACA,2CAA2C;;AAE3C;;AAEA,kBAAkB,gBAAgB;AAClC;AACA;;AAEA;AACA;;AAEO;AACA;AACQ;AACf;AACA;;AAEA;AACA;AACA;;AAEA;AACA,kBAAkB,cAAK;AACvB;;AAEA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,sBAAsB,QAAQ;AAC9B;AACA;;AAEA;AACA;;AAEA,WAAW,eAAe;AAC1B,IAAI;;;AAGJ;AACA,8BAA8B;AAC9B,IAAI,eAAe;;;AAGnB;AACA;AACA;AACA;;ACjE4B;;AAE5B;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA,SAAS,oCAAiB;AAC1B;;AAEA,mDAAe,GAAG;;ACZS;AACA;AAC3B,WAAW,GAAG,aAAa,YAAG;AAC9B,kDAAe,EAAE;;ACHW;AAC5B,sDAAe;AACf,cAAc,sCAAiB;AAC/B,CAAC;;ACHgC;AACN;AACsB;;AAEjD;AACA,MAAM,0BAAiB;AACvB,WAAW,0BAAiB;AAC5B;;AAEA;AACA,iDAAiD,GAAG,KAAK;;AAEzD;AACA,mCAAmC;;AAEnC;AACA;;AAEA,oBAAoB,QAAQ;AAC5B;AACA;;AAEA;AACA;;AAEA,SAAS,eAAe;AACxB;;AAEA,kDAAe,EAAE;;AC5BW;;AAE5B;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA,SAAS,oCAAiB;AAC1B;;AAEA,oDAAe,IAAI;;ACZQ;AACE;AAC7B,WAAW,GAAG,aAAa,aAAI;AAC/B,kDAAe,EAAE;;ACHjB,0CAAe,sCAAsC;;ACAhB;;AAErC;AACA,OAAO,iBAAQ;AACf;AACA;;AAEA;AACA;;AAEA,uDAAe,OAAO;;ACVkB;AACA;AACA;AACA;AACE;AACQ;AACE;AACE;;;;;;;;ACPtD;;;;;;;ACAA;;;;;;;;;;ACAA,yCAMwB;AALtB,uGAAK;AACL,mJAA2B;AAC3B,6HAAkB,QAAkB;AACpC,iIAAkB;AAClB,2GAAO;;;;;;;;;;;;ACLT,uCAAiC;AACjC,SAAgB,OAAO;IACrB,OAAO,UAAU,CAAC;AACpB,CAAC;AAFD,0BAEC;AAED,SAAgB,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;QAClC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAJD,sBAIC;AAED,SAAgB,2BAA2B,CACzC,EAAmB,EACnB,eAAuB,EACvB,GAAa;IAEb,IAAI,oBAAoB,GAAG,KAAK,CAAC;IACjC,OAAO,IAAI,cAAc,CAAc;QACrC,KAAK,CAAC,UAAU;YACd,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAO,CAAwB,EAAE,EAAE;gBAChE,+CAA+C;gBAC/C,IAAI,oBAAoB,EAAE;oBACxB,OAAO;iBACR;gBACD,MAAM,WAAW,GAAgB,CAAC,CAAC,IAAI,CAAC;gBACxC,uCAAuC;gBACvC,uDAAuD;gBACvD,yFAAyF;gBACzF,gEAAgE;gBAChE,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAClC,CAAC,EAAC,CAAC;YACH,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAM,EAAE,EAAE;gBACtC,GAAG,CAAC,kBAAkB,CAAC,CAAC;gBACxB,oBAAoB,GAAG,IAAI,CAAC;gBAC5B,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;gBAChC,IAAI;oBACF,GAAG,CAAC,oBAAoB,CAAC,CAAC;oBAC1B,6CAA6C;oBAC7C,IAAI,oBAAoB,EAAE;wBACxB,OAAO;qBACR;oBACD,UAAU,CAAC,KAAK,EAAE,CAAC;iBACpB;gBAAC,OAAO,KAAK,EAAE;oBACd,GAAG,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;iBACnD;YACH,CAAC,CAAC,CAAC;YACH,iBAAiB;YACjB,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;YAClE,IAAI,KAAK,EAAE;gBACT,GAAG,CAAC,oCAAoC,CAAC,CAAC;gBAC1C,kBAAkB,CAAC,EAAE,CAAC,CAAC;gBACvB,OAAO;aACR;YACD,IAAI,SAAS,EAAE;gBACb,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;aAC/B;QACH,CAAC;QACD,IAAI,CAAC,UAAU;YACb,uEAAuE;YACvE,gEAAgE;QAClE,CAAC;QACD,MAAM,CAAC,MAAM;YACX,+EAA+E;YAC/E,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC,CAAC;YACjD,IAAI,oBAAoB,EAAE;gBACxB,OAAO;aACR;YACD,oBAAoB,GAAG,IAAI,CAAC;YAC5B,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AA9DD,kEA8DC;AAED,SAAS,mBAAmB,CAAC,SAAiB;IAC5C,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;KACxB;IACD,IAAI;QACF,mEAAmE;QACnE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;KACtD;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,EAAE,KAAK,EAAE,CAAC;KAClB;AACH,CAAC;AAED,SAAgB,kBAAkB,CAAC,MAAuB;IACxD,IAAI;QACF,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,IAAI,EAAE;YACrC,MAAM,CAAC,KAAK,EAAE,CAAC;SAChB;KACF;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;KAClD;AACH,CAAC;AARD,gDAQC;AAED,iDAAiD;AACjD,yGAAyG;AACzG,gGAAgG;AAChG,sGAAsG;AACtG,mDAAmD;AACnD,0CAA0C;AAC1C,SAAgB,kBAAkB,CAChC,WAAwB,EACxB,MAAc;AACd,gBAAgB;AAChB,cAAc;;IAEd,IAAI,WAAW,CAAC,UAAU,GAAG,EAAE,EAAE;QAC/B,+BAA+B;QAC/B,oCAAoC;QACpC,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,cAAc;SACxB,CAAC;KACH;IACD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,oBAAS,EAAC,IAAI,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE;QAClE,WAAW,GAAG,IAAI,CAAC;KACpB;IACD,IAAI,CAAC,WAAW,EAAE;QAChB,gCAAgC;QAChC,qCAAqC;QACrC,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,cAAc;SACxB,CAAC;KACH;IAED,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,kBAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,UAAU,CAC5B,WAAW,CAAC,KAAK,CAAC,EAAE,GAAG,SAAS,EAAE,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC,CACtD,CAAC,CAAC,CAAC,CAAC;IAEL,WAAW;IACX,WAAW;IACX,WAAW;IACX,IAAI,OAAO,KAAK,CAAC,EAAE;KAClB;SAAM,IAAI,OAAO,KAAK,CAAC,EAAE;QACxB,KAAK,GAAG,IAAI,CAAC;KACd;SAAM;QACL,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,WAAW,OAAO,+CAA+C;SAC3E,CAAC;KACH;IACD,MAAM,SAAS,GAAG,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;IAC/D,kDAAkD;IAClD,MAAM,UAAU,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAExD,IAAI,YAAY,GAAG,SAAS,GAAG,CAAC,CAAC;IACjC,MAAM,aAAa,GAAG,IAAI,UAAU,CAClC,WAAW,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,GAAG,CAAC,CAAC,CAClD,CAAC;IAEF,8BAA8B;IAC9B,kDAAkD;IAClD,+BAA+B;IAC/B,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACrC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,iBAAiB,GAAG,YAAY,GAAG,CAAC,CAAC;IACzC,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,QAAQ,WAAW,EAAE;QACnB,KAAK,CAAC;YACJ,aAAa,GAAG,CAAC,CAAC;YAClB,YAAY,GAAG,IAAI,UAAU,CAC3B,WAAW,CAAC,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,aAAa,CAAC,CACxE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,MAAM;QACR,KAAK,CAAC;YACJ,aAAa,GAAG,IAAI,UAAU,CAC5B,WAAW,CAAC,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,CAAC,CAAC,CAC5D,CAAC,CAAC,CAAC,CAAC;YACL,iBAAiB,IAAI,CAAC,CAAC;YACvB,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CACrC,WAAW,CAAC,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,aAAa,CAAC,CACxE,CAAC;YACF,MAAM;QACR,KAAK,CAAC;YACJ,aAAa,GAAG,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,WAAW,CAAC,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,aAAa,CAAC,CACxE,CAAC;YACF,0CAA0C;YAC1C,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;aACnD;YACD,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9B,yCAAyC;YACzC,gCAAgC;YAChC,sBAAsB;YACtB,wCAAwC;YACxC,IAAI;YACJ,MAAM;QACR;YACE,OAAO,CAAC,GAAG,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;KACxD;IACD,IAAI,CAAC,YAAY,EAAE;QACjB,6DAA6D;QAC7D,+EAA+E;QAC/E,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,yCAAyC,WAAW,EAAE;SAChE,CAAC;KACH;IAED,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,aAAa,EAAE,YAAY;QAC3B,UAAU;QACV,YAAY,EAAE,iBAAiB,GAAG,aAAa;QAC/C,YAAY,EAAE,OAAO;QACrB,KAAK;KACN,CAAC;AACJ,CAAC;AAtHD,gDAsHC;;;;;;;;AChOD;;;;;;;ACAA;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCtBA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;;;;;;;;ACNA,sCAAoC;AACpC,qCAA4B;AAC5B,oCAAgD;AAChD,wCAAyD;AACzD,uCAAgC;AAChC,0CAA2C;AAC3C,2CAAiD;AACjD,6CAA+D;AAE/D,2CAKkB;AAClB,2CAA2C;AAC3C,yCAAoD;AACpD,sCAIyB;AACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC;AAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;AACtC,2BAA2B;AAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,UAAU,CAAC;AAClD,IAAI,MAAM,KAAK,WAAW,EAAE;IAC1B,oCAAqB,EAAC,MAAM,CAAC,CAAC;CAC/B;AAED,IAAI,WAAW,GAAG,mBAAQ,EAAC,MAAM,CAAC,CAAC;AACnC,IAAI,CAAC,WAAW,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,GAAG,uBAAY,EAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;;IACxC,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,oBAAQ,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;KAC5B;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9D,eAAe;IACf,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,OAAO;KACR;IAED,aAAa;IACb,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QACjC,MAAM,KAAK,GAAG,8BAA8B,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClB,cAAc,EAAE,yBAAyB;SAC1C,CAAC,CAAC;QACH,OAAO,8BAAgB,EAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC3C;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QAC9D,OAAO,4BAAgB,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;KACpC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAClD,MAAM,gBAAgB,GAAG,gBAAS,CAAC,KAAK,CAAC,GAAG,CAAC,0CAAG,CAAC,CAAC,KAAI,EAAE,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7E,IAAI,UAAU,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClB,cAAc,EAAE,0BAA0B;YAC1C,QAAQ,EAAE,KAAK,MAAM,EAAE;SACxB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE,CAAC;KACZ;SAAM;QACL,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClB,cAAc,EAAE,0BAA0B;YAC1C,kBAAkB,EAAE,OAAO;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE,CAAC;KACZ;AACH,CAAC,CAAC,CAAC;AACH,MAAM,YAAY,GAAG,IAAI,oBAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAE7D,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,SAAe,UAAU,CAAC,EAAE,EAAE,OAAO;;QACjE,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,iBAAiB,GAAG,EAAE,CAAC;QAC3B,IAAI;YACF,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,KAAW,EAAE,EAAE;gBACxC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,iBAAiB,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC;YACF,IAAI,gBAAgB,GAAW,IAAI,CAAC;YACpC,IAAI,eAAe,GAAoB,IAAI,CAAC;YAC5C,IAAI,4BAAsC,CAAC;YAC3C,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;YAClE,MAAM,uBAAuB,GAAG,0CAA2B,EACzD,EAAE,EACF,eAAe,EACf,GAAG,CACJ,CAAC;YACF,IAAI,mBAAmB,GAAsB,IAAI,CAAC;YAElD,iBAAiB;YACjB,uBAAuB;iBACpB,MAAM,CACL,IAAI,oBAAc,CAAC;gBACX,KAAK,CAAC,KAAa,EAAE,UAAU;;wBACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;4BAC3B,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;yBAC5B;wBACD,IAAI,eAAe,EAAE;4BACnB,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;4BACpD,qCAAqC;4BACrC,sEAAsE;4BACtE,MAAM,MAAM,CAAC,KAAK,CAChB,KAAK,CAAC,MAAM,CAAC,KAAK,CAChB,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAChC,CACF,CAAC;4BACF,MAAM,CAAC,WAAW,EAAE,CAAC;4BACrB,OAAO;yBACR;wBACD,IAAI,gBAAgB,EAAE;4BACpB,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;4BAChD,iCAAiC;4BACjC,OAAO;yBACR;wBACD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CACpC,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAChC,CAAC;wBACF,MAAM,EACJ,QAAQ,EACR,OAAO,EACP,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,KAAK,GACN,GAAG,iCAAkB,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;wBAC5C,OAAO,GAAG,aAAa,IAAI,EAAE,CAAC;wBAC9B,iBAAiB,GAAG,GAAG,UAAU,KAAK,IAAI,CAAC,MAAM,EAAE,IACjD,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MACnB,GAAG,CAAC;wBACJ,IAAI,QAAQ,EAAE;4BACZ,UAAU,CAAC,KAAK,CAAC,IAAI,OAAO,IAAI,iBAAiB,KAAK,OAAO,GAAG,CAAC,CAAC;4BAClE,OAAO;yBACR;wBACD,wCAAwC;wBACxC,4CAA4C;wBAC5C,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,iBAAiB,cAAc,CAAC,CAAC;wBAC5D,mBAAmB,GAAG,IAAI,UAAU,CAAC,CAAC,YAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC5D,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,YAAa,CAAC,CAAC;wBACvD,IAAI,KAAK,EAAE;4BACT,+DAA+D;4BAC/D,qDAAqD;4BACrD,wDAAwD;4BACxD,wDAAwD;4BACxD,eAAe,GAAG,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;4BAC3D,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;4BACpD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;4BAC1D,MAAM,CAAC,WAAW,EAAE,CAAC;4BACrB,4BAA4B,CAAC,eAAe,CAAC,CAAC;yBAC/C;6BAAM;4BACL,gBAAgB,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;4BAClE,gBAAgB,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC;4BACtD,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;yBAChD;oBACH,CAAC;iBAAA;gBACD,KAAK;oBACH,0BAA0B;oBAC1B,sCAAsC;oBACtC,IAAI;oBACJ,sCAAsC;oBACtC,OAAO,CAAC,GAAG,CACT,IAAI,OAAO,IAAI,iBAAiB,oCAAoC,CACrE,CAAC;gBACJ,CAAC;gBACD,KAAK,CAAC,MAAM;oBACV,2DAA2D;oBAC3D,OAAO,CAAC,GAAG,CACT,IAAI,OAAO,IAAI,iBAAiB,oCAAoC,EACpE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CACvB,CAAC;gBACJ,CAAC;aACF,CAAC,CACH;iBACA,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,OAAO,CAAC,KAAK,CACX,IAAI,OAAO,IAAI,iBAAiB,gDAAgD,EAChF,KAAK,CAAC,KAAK,IAAI,KAAK,CACrB,CAAC;gBACF,0EAA0E;gBAC1E,6BAA6B;gBAC7B,oBAAoB;gBACpB,6BAA6B;YAC/B,CAAC,CAAC,CAAC;YAEL,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,4BAA4B,GAAG,OAAO,CAAC,CAAC,CAAC;YACzE,gBAAgB;YAChB,IAAI,cAAc,GAAG,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,CAAC;YAC/C,IAAI,gBAAgB,EAAE;gBACpB,oBAAoB;gBACpB,aAAa;gBACb,cAAc,GAAG,iBAAQ,CAAC,KAAK,CAAC,gBAAgB,EAAE;oBAChD,QAAQ,EAAE;wBACR,kEAAkE;wBAClE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,8BAA8B;qBACrE;iBACF,CAAC,CAAC;aACJ;YACD,IAAI,KAAK,GAAG,CAAC,CAAC;YAEd,iCAAiC;YACjC,yBAAyB;YACzB,mBAAmB;YACnB,2DAA2D;YAC3D,mCAAmC;YACnC,wDAAwD;YACxD,qBAAqB;YACrB,uBAAuB;YACvB,iEAAiE;YACjE,WAAW;YACX,yCAAyC;YACzC,yCAAyC;YACzC,sBAAsB;YACtB,UAAU;YACV,SAAS;YACT,OAAO;YACP,KAAK;YACL,6DAA6D;YAC7D,MAAM,cAAc,CAAC,MAAM,CACzB,IAAI,oBAAc,CAAC;gBACjB,KAAK;oBACH,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI,EAAE;wBAC7B,EAAE,CAAC,IAAI,CAAC,mBAAoB,CAAC,CAAC;qBAC/B;gBACH,CAAC;gBACK,KAAK,CAAC,KAAiB,EAAE,UAAU;;wBACvC,6BAA6B;wBAC7B,kDAAkD;wBAClD,eAAe;wBACf,iBAAiB;wBACjB,4DAA4D;wBAC5D,uDAAuD;wBACvD,KAAK;wBACL,gEAAgE;wBAChE,oDAAoD;wBACpD,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI,EAAE;4BAC7B,MAAM,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;yBAC/B;6BAAM;4BACL,IAAI,CAAE,gBAA2B,CAAC,SAAS,EAAE;gCAC1C,gBAA2B,CAAC,OAAO,EAAE,CAAC;6BACxC;yBACF;oBACH,CAAC;iBAAA;gBACD,KAAK;oBACH,OAAO,CAAC,GAAG,CACT,IAAI,OAAO,IAAI,iBAAiB,uCAAuC,CACxE,CAAC;gBACJ,CAAC;gBACD,KAAK,CAAC,MAAM;oBACV,6BAAc,EAAC,EAAE,CAAC,CAAC;oBACnB,OAAO,CAAC,KAAK,CACX,IAAI,OAAO,IAAI,iBAAiB,oCAAoC,EACpE,MAAM,CACP,CAAC;gBACJ,CAAC;aACF,CAAC,CACH,CAAC;SACH;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CACX,IAAI,OAAO,IAAI,iBAAiB,mCAAmC,EACnE,KAAK,CAAC,KAAK,IAAI,KAAK,CACrB,CAAC;YACF,6BAAc,EAAC,EAAE,CAAC,CAAC;SACpB;IACH,CAAC;CAAA,CAAC,CAAC;AAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI;IACzD,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAK,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAExC,YAAY,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC,EAAE;QAChE,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,CACX;IACE,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,mBAAmB;CACpB,EACD,GAAG,EAAE;IACH,OAAO,CAAC,GAAG,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC,CACF,CAAC;AAEF,SAAe,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAa;;QACrD,OAAO,IAAI,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;YACpC,MAAM,YAAY,GAAG,sBAAO,EAC1B;gBACE,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,IAAI;gBACV,4CAA4C;gBAC5C,0BAA0B;aAC3B,EACD,GAAG,EAAE;gBACH,GAAG,CAAC,WAAW,CAAC,CAAC;gBACjB,MAAM,CAAC,YAAY,CAAC,CAAC;YACvB,CAAC,CACF,CAAC;YACF,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE;gBACrC,MAAM,CAAC,wBAAwB,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAAA;AAED,SAAe,gBAAgB,CAAC,EAAU,EAAE,KAAa;;QACvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;gBACxB,IAAI,KAAK,EAAE;oBACT,MAAM,CAAC,KAAK,CAAC,CAAC;iBACf;qBAAM;oBACL,OAAO,CAAC,EAAE,CAAC,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAAA;AAED,SAAe,YAAY,CAAC,EAAa,EAAE,KAAiB;;QAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;gBACvB,IAAI,KAAK,EAAE;oBACT,MAAM,CAAC,KAAK,CAAC,CAAC;iBACf;qBAAM;oBACL,OAAO,CAAC,EAAE,CAAC,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAAA;AAED,SAAS,mBAAmB,CAAC,UAAU,EAAE,OAAO;IAC9C,MAAM,SAAS,GAAG,6BAAY,EAAC,MAAM,CAAC,CAAC;IACvC,MAAM,eAAe,GAAG,IAAI,qBAAe,CAAC;QAC1C,KAAK,CAAC,UAAU;YACd,OAAO;YACP,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;gBACxC,eAAe;gBACf,iFAAiF;gBACjF,yCAAyC;gBACzC,KAAK;gBACL,UAAU,CAAC,OAAO,CAChB,MAAM,CAAC,MAAM,CAAC;oBACZ,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;oBAC3D,OAAO;iBACR,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC9B,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;gBAC5C,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;QAEK,SAAS,CAAC,KAAkB,EAAE,UAAU;;gBAC5C,sDAAsD;gBACtD,yGAAyG;gBACzG,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,UAAU,GAAI;oBAC9C,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oBACnD,MAAM,eAAe,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC/D,MAAM,OAAO,GAAG,IAAI,UAAU,CAC5B,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,eAAe,CAAC,CACpD,CAAC;oBACF,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,eAAe,CAAC;oBACpC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBACpC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;4BACnD,IAAI,GAAG,EAAE;gCACP,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;gCACpC,UAAU,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;gCACxD,YAAY,CAAC,SAAS,CAAC,CAAC;6BACzB;4BACD,eAAe;4BACf,wBAAwB;4BACxB,yCAAyC;4BACzC,KAAK;4BACL,OAAO,CAAC,IAAI,CAAC,CAAC;wBAChB,CAAC,CAAC,CAAC;oBACL,CAAC,CAAC,CAAC;oBACH,KAAK,GAAG,KAAK,CAAC;iBACf;gBAED,mCAAmC;gBACnC,oCAAoC;gBACpC,kDAAkD;YACpD,CAAC;SAAA;QAED,KAAK,CAAC,UAAU;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,UAAU,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;KACF,CAAC,CAAC;IACH,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,MAAiB;IACrC,IAAI;QACF,MAAM,CAAC,KAAK,EAAE,CAAC;KAChB;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;KACvC;AACH,CAAC","sources":["webpack:///../../node_modules/tslib/tslib.es6.js","webpack:///external node-commonjs \"http\"","webpack:///external node-commonjs \"url\"","webpack:///../../node_modules/ws/index.js","webpack:///../../node_modules/ws/lib/websocket.js","webpack:///external node-commonjs \"events\"","webpack:///external node-commonjs \"https\"","webpack:///external node-commonjs \"net\"","webpack:///external node-commonjs \"tls\"","webpack:///external node-commonjs \"crypto\"","webpack:///external node-commonjs \"stream\"","webpack:///../../node_modules/ws/lib/permessage-deflate.js","webpack:///external node-commonjs \"zlib\"","webpack:///../../node_modules/ws/lib/buffer-util.js","webpack:///../../node_modules/ws/lib/constants.js","webpack:///../../node_modules/ws/lib/limiter.js","webpack:///../../node_modules/ws/lib/receiver.js","webpack:///../../node_modules/ws/lib/validation.js","webpack:///external node-commonjs \"buffer\"","webpack:///../../node_modules/ws/lib/sender.js","webpack:///../../node_modules/ws/lib/event-target.js","webpack:///../../node_modules/ws/lib/extension.js","webpack:///../../node_modules/ws/lib/stream.js","webpack:///../../node_modules/ws/lib/websocket-server.js","webpack:///../../node_modules/ws/lib/subprotocol.js","webpack:///./src/app/utils.ts","webpack:///external node-commonjs \"node:fs\"","webpack:///external node-commonjs \"node:path\"","webpack:///../../node_modules/pretty-cache-header/dist/index.cjs","webpack:///../../node_modules/timestring/index.js","webpack:///../../node_modules/uuid/dist/esm-node/rng.js","webpack:///../../node_modules/uuid/dist/esm-node/regex.js","webpack:///../../node_modules/uuid/dist/esm-node/validate.js","webpack:///../../node_modules/uuid/dist/esm-node/stringify.js","webpack:///../../node_modules/uuid/dist/esm-node/v1.js","webpack:///../../node_modules/uuid/dist/esm-node/parse.js","webpack:///../../node_modules/uuid/dist/esm-node/v35.js","webpack:///../../node_modules/uuid/dist/esm-node/md5.js","webpack:///../../node_modules/uuid/dist/esm-node/v3.js","webpack:///../../node_modules/uuid/dist/esm-node/native.js","webpack:///../../node_modules/uuid/dist/esm-node/v4.js","webpack:///../../node_modules/uuid/dist/esm-node/sha1.js","webpack:///../../node_modules/uuid/dist/esm-node/v5.js","webpack:///../../node_modules/uuid/dist/esm-node/nil.js","webpack:///../../node_modules/uuid/dist/esm-node/version.js","webpack:///../../node_modules/uuid/dist/esm-node/index.js","webpack:///external node-commonjs \"node:dns\"","webpack:///external node-commonjs \"node:dgram\"","webpack:///../../libs/vless-js/src/index.ts","webpack:///../../libs/vless-js/src/lib/vless-js.ts","webpack:///external node-commonjs \"node:net\"","webpack:///external node-commonjs \"node:stream/web\"","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///webpack/runtime/make namespace object","webpack:///./src/main.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.push(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.push(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","module.exports = require(\"http\");","module.exports = require(\"url\");","'use strict';\n\nconst WebSocket = require('./lib/websocket');\n\nWebSocket.createWebSocketStream = require('./lib/stream');\nWebSocket.Server = require('./lib/websocket-server');\nWebSocket.Receiver = require('./lib/receiver');\nWebSocket.Sender = require('./lib/sender');\n\nWebSocket.WebSocket = WebSocket;\nWebSocket.WebSocketServer = WebSocket.Server;\n\nmodule.exports = WebSocket;\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Readable$\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._isServer = true;\n }\n }\n\n /**\n * This deviates from the WHATWG interface since ws doesn't support the\n * required default \"blob\" type (instead we define a custom \"nodebuffer\"\n * type).\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n this._sender = new Sender(socket, this._extensions, options.generateMask);\n this._receiver = receiver;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n socket.setTimeout(0);\n socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n //\n // Specify a timeout for the closing handshake to complete.\n //\n this._closeTimer = setTimeout(\n this._socket.destroy.bind(this._socket),\n closeTimeout\n );\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n createConnection: undefined,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n websocket._url = address.href;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n\n websocket._url = address;\n }\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection = isSecure ? tlsConnect : netConnect;\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n let req;\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl\n ? opts.socketPath\n : parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl\n ? websocket._originalIpc\n ? opts.socketPath === websocket._originalHostOrSocketPath\n : false\n : websocket._originalIpc\n ? false\n : parsedUrl.host === websocket._originalHostOrSocketPath;\n\n if (!isSameHost || (websocket._originalSecure && !isSecure)) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n\n if (!isSameHost) delete opts.headers.host;\n\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n\n req = websocket._req = request(opts);\n\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req[kAborted]) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n if (res.headers.upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n websocket.emit('error', err);\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n websocket.pong(data, !websocket._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The listener of the `net.Socket` `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the `net.Socket` `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the `net.Socket` `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the `net.Socket` `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n","module.exports = require(\"events\");","module.exports = require(\"https\");","module.exports = require(\"net\");","module.exports = require(\"tls\");","module.exports = require(\"crypto\");","module.exports = require(\"stream\");","'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) {\n data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);\n }\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n","module.exports = require(\"zlib\");","'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) {\n return new FastBuffer(target.buffer, target.byteOffset, offset);\n }\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.length === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = new FastBuffer(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\nmodule.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n};\n\n/* istanbul ignore else */\nif (!process.env.WS_NO_BUFFER_UTIL) {\n try {\n const bufferUtil = require('bufferutil');\n\n module.exports.mask = function (source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n };\n\n module.exports.unmask = function (buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n","'use strict';\n\nmodule.exports = {\n BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'],\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n","'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n","'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._state = GET_INFO;\n this._loop = false;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n\n return new FastBuffer(buf.buffer, buf.byteOffset, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n let err;\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n err = this.getInfo();\n break;\n case GET_PAYLOAD_LENGTH_16:\n err = this.getPayloadLength16();\n break;\n case GET_PAYLOAD_LENGTH_64:\n err = this.getPayloadLength64();\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n err = this.getData(cb);\n break;\n default:\n // `INFLATING`\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n cb(err);\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getInfo() {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n if (!this._fragmented) {\n this._loop = false;\n return error(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n this._loop = false;\n return error(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n this._loop = false;\n return error(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n }\n\n if (compressed) {\n this._loop = false;\n return error(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n }\n\n if (\n this._payloadLength > 0x7d ||\n (this._opcode === 0x08 && this._payloadLength === 1)\n ) {\n this._loop = false;\n return error(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n }\n } else {\n this._loop = false;\n return error(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n this._loop = false;\n return error(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n }\n } else if (this._masked) {\n this._loop = false;\n return error(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else return this.haveLength();\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getPayloadLength16() {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n return this.haveLength();\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n getPayloadLength64() {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n this._loop = false;\n return error(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n return this.haveLength();\n }\n\n /**\n * Payload length has been read.\n *\n * @return {(RangeError|undefined)} A possible error\n * @private\n */\n haveLength() {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n this._loop = false;\n return error(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) return this.controlMessage(data);\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n return this.dataMessage();\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n return cb(\n error(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n )\n );\n }\n\n this._fragments.push(buf);\n }\n\n const er = this.dataMessage();\n if (er) return cb(er);\n\n this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @return {(Error|undefined)} A possible error\n * @private\n */\n dataMessage() {\n if (this._fin) {\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else {\n data = fragments;\n }\n\n this.emit('message', data, true);\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n this._loop = false;\n return error(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n }\n\n this.emit('message', buf, false);\n }\n }\n\n this._state = GET_INFO;\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data) {\n if (this._opcode === 0x08) {\n this._loop = false;\n\n if (data.length === 0) {\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n return error(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n }\n\n const buf = new FastBuffer(\n data.buffer,\n data.byteOffset + 2,\n data.length - 2\n );\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n return error(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n }\n\n this.emit('conclude', code, buf);\n this.end();\n }\n } else if (this._opcode === 0x09) {\n this.emit('ping', data);\n } else {\n this.emit('pong', data);\n }\n\n this._state = GET_INFO;\n }\n}\n\nmodule.exports = Receiver;\n\n/**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\nfunction error(ErrorCtor, message, prefix, statusCode, errorCode) {\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, error);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n}\n","'use strict';\n\nconst { isUtf8 } = require('buffer');\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\nmodule.exports = {\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n};\n\nif (isUtf8) {\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);\n };\n} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {\n try {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n","module.exports = require(\"buffer\");","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^net|tls$\" }] */\n\n'use strict';\n\nconst net = require('net');\nconst tls = require('tls');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER } = require('./constants');\nconst { isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {(net.Socket|tls.Socket)} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._deflating = false;\n this._queue = [];\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n randomFillSync(mask, 0, 4);\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n if (perMessageDeflate) {\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (this._deflating) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n } else {\n this.sendFrame(\n Sender.frame(data, {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1: false\n }),\n cb\n );\n }\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._deflating = true;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < this._queue.length; i++) {\n const params = this._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._deflating = false;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (!this._deflating && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {Buffer[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n","'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {(Function|Object)} handler The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, handler, options = {}) {\n for (const listener of this.listeners(type)) {\n if (\n !options[kForOnEventAttribute] &&\n listener[kListener] === handler &&\n !listener[kForOnEventAttribute]\n ) {\n return;\n }\n }\n\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = handler;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {(Function|Object)} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n\n/**\n * Call an event listener\n *\n * @param {(Function|Object)} listener The listener to call\n * @param {*} thisArg The value to use as `this`` when calling the listener\n * @param {Event} event The event to pass to the listener\n * @private\n */\nfunction callListener(listener, thisArg, event) {\n if (typeof listener === 'object' && listener.handleEvent) {\n listener.handleEvent.call(listener, event);\n } else {\n listener.call(thisArg, event);\n }\n}\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n","'use strict';\n\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^net|tls|https$\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst https = require('https');\nconst net = require('net');\nconst tls = require('tls');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key = req.headers['sec-websocket-key'];\n const version = +req.headers['sec-websocket-version'];\n\n if (req.method !== 'GET') {\n const message = 'Invalid HTTP method';\n abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);\n return;\n }\n\n if (req.headers.upgrade.toLowerCase() !== 'websocket') {\n const message = 'Invalid Upgrade header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (!key || !keyRegex.test(key)) {\n const message = 'Missing or invalid Sec-WebSocket-Key header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (version !== 8 && version !== 13) {\n const message = 'Missing or invalid Sec-WebSocket-Version header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (!this.shouldHandle(req)) {\n abortHandshake(socket, 400);\n return;\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Protocol header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n const message =\n 'Invalid or unacceptable Sec-WebSocket-Extensions header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The network socket between the\n * server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of \n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n //\n // The socket is writable unless the user destroyed or ended it before calling\n // `server.handleUpgrade()` or in the `verifyClient` function, which is a user\n // error. Handling this does not make much sense as the worst that can happen\n // is that some of the data written by the user might be discarded due to the\n // call to `socket.end()` below, which triggers an `'error'` event that in\n // turn causes the socket to be destroyed.\n //\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.once('finish', socket.destroy);\n\n socket.end(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n}\n\n/**\n * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least\n * one listener for it, otherwise call `abortHandshake()`.\n *\n * @param {WebSocketServer} server The WebSocket server\n * @param {http.IncomingMessage} req The request object\n * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} message The HTTP response body\n * @private\n */\nfunction abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {\n if (server.listenerCount('wsClientError')) {\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);\n\n server.emit('wsClientError', err, socket, req);\n } else {\n abortHandshake(socket, code, message);\n }\n}\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n","import { createReadStream, existsSync } from 'node:fs';\r\nimport { IncomingMessage, ServerResponse } from 'node:http';\r\nimport { resolve, join, extname } from 'node:path';\r\nimport { cacheHeader } from 'pretty-cache-header';\r\n\r\nconst mimeLookup = {\r\n '.js': 'application/javascript,charset=UTF-8',\r\n '.html': 'text/html,charset=UTF-8',\r\n '.css': 'text/css; charset=UTF-8',\r\n};\r\nconst staticPath = 'dist/apps/cf-page/';\r\nconst file401 = 'dist/apps/node-vless/assets/401.html';\r\nlet filepath = null;\r\nexport function serverStaticFile(req: IncomingMessage, resp: ServerResponse) {\r\n const url = new URL(req.url, `http://${req.headers['host']}`);\r\n let fileurl = url.pathname;\r\n fileurl = join(staticPath, fileurl);\r\n console.log('....', fileurl);\r\n filepath = resolve(fileurl);\r\n console.log(filepath);\r\n\r\n if (existsSync(filepath)) {\r\n let fileExt = extname(filepath);\r\n console.log('fileExt', fileExt);\r\n let mimeType = mimeLookup[fileExt];\r\n\r\n resp.writeHead(200, {\r\n 'Content-Type': mimeType,\r\n 'Cache-Control': cacheHeader({\r\n public: true,\r\n maxAge: '1year',\r\n staleWhileRevalidate: '1year',\r\n }),\r\n });\r\n return createReadStream(filepath).pipe(resp);\r\n } else {\r\n resp.writeHead(404);\r\n resp.write('not found');\r\n resp.end();\r\n return resp;\r\n }\r\n}\r\n\r\nexport function index401(req: IncomingMessage, resp: ServerResponse) {\r\n const file401Path = resolve(file401);\r\n if (existsSync(file401Path)) {\r\n createReadStream(file401Path).pipe(resp);\r\n } else {\r\n resp.writeHead(401);\r\n resp.write('UUID env not set');\r\n resp.end();\r\n }\r\n}\r\n\r\nexport function serverIndexPage(\r\n req: IncomingMessage,\r\n resp: ServerResponse,\r\n uuid\r\n) {\r\n // if()\r\n}\r\n","module.exports = require(\"node:fs\");","module.exports = require(\"node:path\");","\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/index.ts\nvar src_exports = {};\n__export(src_exports, {\n cacheHeader: () => cacheHeader\n});\nmodule.exports = __toCommonJS(src_exports);\n\n// src/cache-header.ts\nvar import_timestring = __toESM(require(\"timestring\"), 1);\nfunction cacheHeader(params) {\n const transformed = Object.entries(params).reduce((acc, [key, value]) => {\n const kebabKey = key.replace(/[A-Z]/g, (char) => \"-\" + char.toLowerCase());\n return typeof value === \"string\" || value === true ? [...acc, value === true ? kebabKey : `${kebabKey}=${(0, import_timestring.default)(value)}`] : acc;\n }, []);\n return transformed.join(\", \");\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n cacheHeader\n});\n//# sourceMappingURL=index.cjs.map","/**\n * Exports\n */\n\nmodule.exports = parseTimestring\n\n/**\n * Default options to use when parsing a timestring\n *\n * @type {Object}\n */\n\nconst DEFAULT_OPTS = {\n hoursPerDay: 24,\n daysPerWeek: 7,\n weeksPerMonth: 4,\n monthsPerYear: 12,\n daysPerYear: 365.25\n}\n\n/**\n * Map of accepted strings to unit\n *\n * @type {Object}\n */\n\nconst UNIT_MAP = {\n ms: ['ms', 'milli', 'millisecond', 'milliseconds'],\n s: ['s', 'sec', 'secs', 'second', 'seconds'],\n m: ['m', 'min', 'mins', 'minute', 'minutes'],\n h: ['h', 'hr', 'hrs', 'hour', 'hours'],\n d: ['d', 'day', 'days'],\n w: ['w', 'week', 'weeks'],\n mth: ['mon', 'mth', 'mths', 'month', 'months'],\n y: ['y', 'yr', 'yrs', 'year', 'years']\n}\n\n/**\n * Parse a timestring\n *\n * @param {String} string\n * @param {String} returnUnit\n * @param {Object} opts\n * @return {Number}\n */\n\nfunction parseTimestring (string, returnUnit, opts) {\n opts = Object.assign({}, DEFAULT_OPTS, opts || {})\n\n let totalSeconds = 0\n let unitValues = getUnitValues(opts)\n let groups = string\n .toLowerCase()\n .replace(/[^.\\w+-]+/g, '')\n .match(/[-+]?[0-9.]+[a-z]+/g)\n\n if (groups === null) {\n throw new Error(`The string [${string}] could not be parsed by timestring`)\n }\n\n groups.forEach(group => {\n let value = group.match(/[0-9.]+/g)[0]\n let unit = group.match(/[a-z]+/g)[0]\n\n totalSeconds += getSeconds(value, unit, unitValues)\n })\n\n if (returnUnit) {\n return convert(totalSeconds, returnUnit, unitValues)\n }\n\n return totalSeconds\n}\n\n/**\n * Get unit values based on the passed options\n *\n * @param {Object} opts\n * @returns {Object}\n */\n\nfunction getUnitValues (opts) {\n let unitValues = {\n ms: 0.001,\n s: 1,\n m: 60,\n h: 3600\n }\n\n unitValues.d = opts.hoursPerDay * unitValues.h\n unitValues.w = opts.daysPerWeek * unitValues.d\n unitValues.mth = (opts.daysPerYear / opts.monthsPerYear) * unitValues.d\n unitValues.y = opts.daysPerYear * unitValues.d\n\n return unitValues\n}\n\n/**\n * Get the key for a unit\n *\n * @param {String} unit\n * @returns {String}\n */\n\nfunction getUnitKey (unit) {\n for (let key of Object.keys(UNIT_MAP)) {\n if (UNIT_MAP[key].indexOf(unit) > -1) {\n return key\n }\n }\n\n throw new Error(`The unit [${unit}] is not supported by timestring`)\n}\n\n/**\n * Get the number of seconds for a value, based on the unit\n *\n * @param {Number} value\n * @param {String} unit\n * @param {Object} unitValues\n * @returns {Number}\n */\n\nfunction getSeconds (value, unit, unitValues) {\n return value * unitValues[getUnitKey(unit)]\n}\n\n/**\n * Convert a value from its existing unit to a new unit\n *\n * @param {Number} value\n * @param {String} unit\n * @param {Object} unitValues\n * @returns {Number}\n */\n\nfunction convert (value, unit, unitValues) {\n return value / unitValues[getUnitKey(unit)]\n}\n","import crypto from 'crypto';\nconst rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate\n\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n crypto.randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n\n return rnds8Pool.slice(poolPtr, poolPtr += 16);\n}","export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;","import REGEX from './regex.js';\n\nfunction validate(uuid) {\n return typeof uuid === 'string' && REGEX.test(uuid);\n}\n\nexport default validate;","import validate from './validate.js';\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\n\nconst byteToHex = [];\n\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\n\nexport function unsafeStringify(arr, offset = 0) {\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();\n}\n\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n\n return uuid;\n}\n\nexport default stringify;","import rng from './rng.js';\nimport { unsafeStringify } from './stringify.js'; // **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nlet _nodeId;\n\nlet _clockseq; // Previous uuid creation time\n\n\nlet _lastMSecs = 0;\nlet _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details\n\nfunction v1(options, buf, offset) {\n let i = buf && offset || 0;\n const b = buf || new Array(16);\n options = options || {};\n let node = options.node || _nodeId;\n let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n\n if (node == null || clockseq == null) {\n const seedBytes = options.random || (options.rng || rng)();\n\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];\n }\n\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n } // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n\n\n let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n\n let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)\n\n const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression\n\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n\n\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n } // Per 4.2.1.2 Throw error if too many uuids are requested\n\n\n if (nsecs >= 10000) {\n throw new Error(\"uuid.v1(): Can't create more than 10M uuids/sec\");\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n\n msecs += 12219292800000; // `time_low`\n\n const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff; // `time_mid`\n\n const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff; // `time_high_and_version`\n\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n\n b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n\n b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`\n\n b[i++] = clockseq & 0xff; // `node`\n\n for (let n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf || unsafeStringify(b);\n}\n\nexport default v1;","import validate from './validate.js';\n\nfunction parse(uuid) {\n if (!validate(uuid)) {\n throw TypeError('Invalid UUID');\n }\n\n let v;\n const arr = new Uint8Array(16); // Parse ########-....-....-....-............\n\n arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;\n arr[1] = v >>> 16 & 0xff;\n arr[2] = v >>> 8 & 0xff;\n arr[3] = v & 0xff; // Parse ........-####-....-....-............\n\n arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;\n arr[5] = v & 0xff; // Parse ........-....-####-....-............\n\n arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;\n arr[7] = v & 0xff; // Parse ........-....-....-####-............\n\n arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;\n arr[9] = v & 0xff; // Parse ........-....-....-....-############\n // (Use \"/\" to avoid 32-bit truncation when bit-shifting high-order bytes)\n\n arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;\n arr[11] = v / 0x100000000 & 0xff;\n arr[12] = v >>> 24 & 0xff;\n arr[13] = v >>> 16 & 0xff;\n arr[14] = v >>> 8 & 0xff;\n arr[15] = v & 0xff;\n return arr;\n}\n\nexport default parse;","import { unsafeStringify } from './stringify.js';\nimport parse from './parse.js';\n\nfunction stringToBytes(str) {\n str = unescape(encodeURIComponent(str)); // UTF8 escape\n\n const bytes = [];\n\n for (let i = 0; i < str.length; ++i) {\n bytes.push(str.charCodeAt(i));\n }\n\n return bytes;\n}\n\nexport const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\nexport const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\nexport default function v35(name, version, hashfunc) {\n function generateUUID(value, namespace, buf, offset) {\n var _namespace;\n\n if (typeof value === 'string') {\n value = stringToBytes(value);\n }\n\n if (typeof namespace === 'string') {\n namespace = parse(namespace);\n }\n\n if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {\n throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');\n } // Compute hash of namespace and value, Per 4.3\n // Future: Use spread syntax when supported on all platforms, e.g. `bytes =\n // hashfunc([...namespace, ... value])`\n\n\n let bytes = new Uint8Array(16 + value.length);\n bytes.set(namespace);\n bytes.set(value, namespace.length);\n bytes = hashfunc(bytes);\n bytes[6] = bytes[6] & 0x0f | version;\n bytes[8] = bytes[8] & 0x3f | 0x80;\n\n if (buf) {\n offset = offset || 0;\n\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = bytes[i];\n }\n\n return buf;\n }\n\n return unsafeStringify(bytes);\n } // Function#name is not settable on some platforms (#270)\n\n\n try {\n generateUUID.name = name; // eslint-disable-next-line no-empty\n } catch (err) {} // For CommonJS default export support\n\n\n generateUUID.DNS = DNS;\n generateUUID.URL = URL;\n return generateUUID;\n}","import crypto from 'crypto';\n\nfunction md5(bytes) {\n if (Array.isArray(bytes)) {\n bytes = Buffer.from(bytes);\n } else if (typeof bytes === 'string') {\n bytes = Buffer.from(bytes, 'utf8');\n }\n\n return crypto.createHash('md5').update(bytes).digest();\n}\n\nexport default md5;","import v35 from './v35.js';\nimport md5 from './md5.js';\nconst v3 = v35('v3', 0x30, md5);\nexport default v3;","import crypto from 'crypto';\nexport default {\n randomUUID: crypto.randomUUID\n};","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\n\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n\n options = options || {};\n const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n if (buf) {\n offset = offset || 0;\n\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n\n return buf;\n }\n\n return unsafeStringify(rnds);\n}\n\nexport default v4;","import crypto from 'crypto';\n\nfunction sha1(bytes) {\n if (Array.isArray(bytes)) {\n bytes = Buffer.from(bytes);\n } else if (typeof bytes === 'string') {\n bytes = Buffer.from(bytes, 'utf8');\n }\n\n return crypto.createHash('sha1').update(bytes).digest();\n}\n\nexport default sha1;","import v35 from './v35.js';\nimport sha1 from './sha1.js';\nconst v5 = v35('v5', 0x50, sha1);\nexport default v5;","export default '00000000-0000-0000-0000-000000000000';","import validate from './validate.js';\n\nfunction version(uuid) {\n if (!validate(uuid)) {\n throw TypeError('Invalid UUID');\n }\n\n return parseInt(uuid.slice(14, 15), 16);\n}\n\nexport default version;","export { default as v1 } from './v1.js';\nexport { default as v3 } from './v3.js';\nexport { default as v4 } from './v4.js';\nexport { default as v5 } from './v5.js';\nexport { default as NIL } from './nil.js';\nexport { default as version } from './version.js';\nexport { default as validate } from './validate.js';\nexport { default as stringify } from './stringify.js';\nexport { default as parse } from './parse.js';","module.exports = require(\"node:dns\");","module.exports = require(\"node:dgram\");","export {\r\n delay,\r\n makeReadableWebSocketStream,\r\n safeCloseWebSocket as closeWebSocket,\r\n processVlessHeader,\r\n vlessJs,\r\n} from './lib/vless-js';\r\n","import { stringify } from 'uuid';\r\nexport function vlessJs(): string {\r\n return 'vless-js';\r\n}\r\n\r\nexport function delay(ms: number) {\r\n return new Promise((resolve, rej) => {\r\n setTimeout(resolve, ms);\r\n });\r\n}\r\n\r\nexport function makeReadableWebSocketStream(\r\n ws: WebSocket | any,\r\n earlyDataHeader: string,\r\n log: Function\r\n) {\r\n let readableStreamCancel = false;\r\n return new ReadableStream({\r\n start(controller) {\r\n ws.addEventListener('message', async (e: { data: ArrayBuffer }) => {\r\n // is stream is cancel, skip controller.enqueue\r\n if (readableStreamCancel) {\r\n return;\r\n }\r\n const vlessBuffer: ArrayBuffer = e.data;\r\n // console.log('MESSAGE', vlessBuffer);\r\n // console.log(`message is ${vlessBuffer.byteLength}`);\r\n // this is not backpressure, but backpressure is depends on underying websocket can pasue\r\n // https://streams.spec.whatwg.org/#example-rs-push-backpressure\r\n controller.enqueue(vlessBuffer);\r\n });\r\n ws.addEventListener('error', (e: any) => {\r\n log('socket has error');\r\n readableStreamCancel = true;\r\n controller.error(e);\r\n });\r\n ws.addEventListener('close', () => {\r\n try {\r\n log('webSocket is close');\r\n // is stream is cancel, skip controller.close\r\n if (readableStreamCancel) {\r\n return;\r\n }\r\n controller.close();\r\n } catch (error) {\r\n log(`websocketStream can't close DUE to `, error);\r\n }\r\n });\r\n // header ws 0rtt\r\n const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader);\r\n if (error) {\r\n log(`earlyDataHeader has invaild base64`);\r\n safeCloseWebSocket(ws);\r\n return;\r\n }\r\n if (earlyData) {\r\n controller.enqueue(earlyData);\r\n }\r\n },\r\n pull(controller) {\r\n // if ws can stop read if stream is full, we can implement backpressure\r\n // https://streams.spec.whatwg.org/#example-rs-push-backpressure\r\n },\r\n cancel(reason) {\r\n // TODO: log can be remove, if writestream has error, write stream will has log\r\n log(`websocketStream is cancel DUE to `, reason);\r\n if (readableStreamCancel) {\r\n return;\r\n }\r\n readableStreamCancel = true;\r\n safeCloseWebSocket(ws);\r\n },\r\n });\r\n}\r\n\r\nfunction base64ToArrayBuffer(base64Str: string) {\r\n if (!base64Str) {\r\n return { error: null };\r\n }\r\n try {\r\n // go use modified Base64 for URL rfc4648 which js atob not support\r\n base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/');\r\n const decode = atob(base64Str);\r\n const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0));\r\n return { earlyData: arryBuffer.buffer, error: null };\r\n } catch (error) {\r\n return { error };\r\n }\r\n}\r\n\r\nexport function safeCloseWebSocket(socket: WebSocket | any) {\r\n try {\r\n if (socket.readyState === socket.OPEN) {\r\n socket.close();\r\n }\r\n } catch (error) {\r\n console.error('safeCloseWebSocket error', error);\r\n }\r\n}\r\n\r\n//https://github.com/v2ray/v2ray-core/issues/2636\r\n// 1 字节\t 16 字节 1 字节\t M 字节\t 1 字节 2 字节 1 字节\t S 字节\t X 字节\r\n// 协议版本\t 等价 UUID\t 附加信息长度 M\t(附加信息 ProtoBuf) 指令(udp/tcp)\t 端口\t 地址类型 地址\t 请求数据\r\n// 00 00 01 01bb(443) 02(ip/host)\r\n// 1 字节\t 1 字节\t N 字节\t Y 字节\r\n// 协议版本,与请求的一致\t附加信息长度 N\t附加信息 ProtoBuf\t响应数据\r\nexport function processVlessHeader(\r\n vlessBuffer: ArrayBuffer,\r\n userID: string\r\n // uuidLib: any,\r\n // lodash: any\r\n) {\r\n if (vlessBuffer.byteLength < 24) {\r\n // console.log('invalid data');\r\n // controller.error('invalid data');\r\n return {\r\n hasError: true,\r\n message: 'invalid data',\r\n };\r\n }\r\n const version = new Uint8Array(vlessBuffer.slice(0, 1));\r\n let isValidUser = false;\r\n let isUDP = false;\r\n if (stringify(new Uint8Array(vlessBuffer.slice(1, 17))) === userID) {\r\n isValidUser = true;\r\n }\r\n if (!isValidUser) {\r\n // console.log('in valid user');\r\n // controller.error('in valid user');\r\n return {\r\n hasError: true,\r\n message: 'invalid user',\r\n };\r\n }\r\n\r\n const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0];\r\n //skip opt for now\r\n\r\n const command = new Uint8Array(\r\n vlessBuffer.slice(18 + optLength, 18 + optLength + 1)\r\n )[0];\r\n\r\n // 0x01 TCP\r\n // 0x02 UDP\r\n // 0x03 MUX\r\n if (command === 1) {\r\n } else if (command === 2) {\r\n isUDP = true;\r\n } else {\r\n return {\r\n hasError: true,\r\n message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`,\r\n };\r\n }\r\n const portIndex = 18 + optLength + 1;\r\n const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2);\r\n // port is big-Endian in raw data etc 80 == 0x005d\r\n const portRemote = new DataView(portBuffer).getInt16(0);\r\n\r\n let addressIndex = portIndex + 2;\r\n const addressBuffer = new Uint8Array(\r\n vlessBuffer.slice(addressIndex, addressIndex + 1)\r\n );\r\n\r\n // 1--> ipv4 addressLength =4\r\n // 2--> domain name addressLength=addressBuffer[1]\r\n // 3--> ipv6 addressLength =16\r\n const addressType = addressBuffer[0];\r\n let addressLength = 0;\r\n let addressValueIndex = addressIndex + 1;\r\n let addressValue = '';\r\n switch (addressType) {\r\n case 1:\r\n addressLength = 4;\r\n addressValue = new Uint8Array(\r\n vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)\r\n ).join('.');\r\n break;\r\n case 2:\r\n addressLength = new Uint8Array(\r\n vlessBuffer.slice(addressValueIndex, addressValueIndex + 1)\r\n )[0];\r\n addressValueIndex += 1;\r\n addressValue = new TextDecoder().decode(\r\n vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)\r\n );\r\n break;\r\n case 3:\r\n addressLength = 16;\r\n const dataView = new DataView(\r\n vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)\r\n );\r\n // 2001:0db8:85a3:0000:0000:8a2e:0370:7334\r\n const ipv6 = [];\r\n for (let i = 0; i < 8; i++) {\r\n ipv6.push(dataView.getUint16(i * 2).toString(16));\r\n }\r\n addressValue = ipv6.join(':');\r\n // console.log('---------', addressValue)\r\n // seems no need add [] for ipv6\r\n // if (addressValue) {\r\n // addressValue = `[${addressValue}]`;\r\n // }\r\n break;\r\n default:\r\n console.log(`invild addressType is ${addressType}`);\r\n }\r\n if (!addressValue) {\r\n // console.log(`[${address}:${port}] addressValue is empty`);\r\n // controller.error(`[${address}:${portWithRandomLog}] addressValue is empty`);\r\n return {\r\n hasError: true,\r\n message: `addressValue is empty, addressType is ${addressType}`,\r\n };\r\n }\r\n\r\n return {\r\n hasError: false,\r\n addressRemote: addressValue,\r\n portRemote,\r\n rawDataIndex: addressValueIndex + addressLength,\r\n vlessVersion: version,\r\n isUDP,\r\n };\r\n}\r\n","module.exports = require(\"node:net\");","module.exports = require(\"node:stream/web\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { createServer } from 'http';\r\nimport { parse } from 'url';\r\nimport { WebSocketServer, WebSocket } from 'ws';\r\nimport { index401, serverStaticFile } from './app/utils';\r\nimport { validate } from 'uuid';\r\nimport { createReadStream } from 'node:fs';\r\nimport { setDefaultResultOrder } from 'node:dns';\r\nimport { createSocket, Socket as UDPSocket } from 'node:dgram';\r\n\r\nimport {\r\n makeReadableWebSocketStream,\r\n processVlessHeader,\r\n delay,\r\n closeWebSocket,\r\n} from 'vless-js';\r\nimport { connect, Socket } from 'node:net';\r\nimport { Duplex, Readable, Writable } from 'stream';\r\nimport {\r\n TransformStream,\r\n ReadableStream,\r\n WritableStream,\r\n} from 'node:stream/web';\r\nconst port = process.env.PORT;\r\nconst smallRAM = process.env.SMALLRAM || false;\r\nconst userID = process.env.UUID || '';\r\n//'ipv4first' or 'verbatim'\r\nconst dnOder = process.env.DNSORDER || 'verbatim';\r\nif (dnOder === 'ipv4first') {\r\n setDefaultResultOrder(dnOder);\r\n}\r\n\r\nlet isVaildUser = validate(userID);\r\nif (!isVaildUser) {\r\n console.log('not set valid UUID');\r\n}\r\n\r\nconst server = createServer((req, resp) => {\r\n if (!isVaildUser) {\r\n return index401(req, resp);\r\n }\r\n const url = new URL(req.url, `http://${req.headers['host']}`);\r\n // health check\r\n if (req.method === 'GET' && url.pathname.startsWith('/health')) {\r\n resp.writeHead(200);\r\n resp.write('health 200');\r\n resp.end();\r\n return;\r\n }\r\n\r\n // index page\r\n if (url.pathname.includes(userID)) {\r\n const index = 'dist/apps/cf-page/index.html';\r\n resp.writeHead(200, {\r\n 'Content-Type': 'text/html,charset=UTF-8',\r\n });\r\n return createReadStream(index).pipe(resp);\r\n }\r\n if (req.method === 'GET' && url.pathname.startsWith('/assets')) {\r\n return serverStaticFile(req, resp);\r\n }\r\n\r\n const basicAuth = req.headers.authorization || '';\r\n const authStringBase64 = basicAuth.split(' ')?.[1] || '';\r\n const authString = Buffer.from(authStringBase64, 'base64').toString('ascii');\r\n if (authString && authString.includes(userID)) {\r\n resp.writeHead(302, {\r\n 'content-type': 'text/html; charset=utf-8',\r\n Location: `./${userID}`,\r\n });\r\n resp.end();\r\n } else {\r\n resp.writeHead(401, {\r\n 'content-type': 'text/html; charset=utf-8',\r\n 'WWW-Authenticate': 'Basic',\r\n });\r\n resp.end();\r\n }\r\n});\r\nconst vlessWServer = new WebSocketServer({ noServer: true });\r\n\r\nvlessWServer.on('connection', async function connection(ws, request) {\r\n let address = '';\r\n let portWithRandomLog = '';\r\n try {\r\n const log = (info: string, event?: any) => {\r\n console.log(`[${address}:${portWithRandomLog}] ${info}`, event || '');\r\n };\r\n let remoteConnection: Duplex = null;\r\n let udpClientStream: TransformStream = null;\r\n let remoteConnectionReadyResolve: Function;\r\n const earlyDataHeader = request.headers['sec-websocket-protocol'];\r\n const readableWebSocketStream = makeReadableWebSocketStream(\r\n ws,\r\n earlyDataHeader,\r\n log\r\n );\r\n let vlessResponseHeader: Uint8Array | null = null;\r\n\r\n // ws --> remote\r\n readableWebSocketStream\r\n .pipeTo(\r\n new WritableStream({\r\n async write(chunk: Buffer, controller) {\r\n if (!Buffer.isBuffer(chunk)) {\r\n chunk = Buffer.from(chunk);\r\n }\r\n if (udpClientStream) {\r\n const writer = udpClientStream.writable.getWriter();\r\n // nodejs buffer to ArrayBuffer issue\r\n // https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#bufbuffer\r\n await writer.write(\r\n chunk.buffer.slice(\r\n chunk.byteOffset,\r\n chunk.byteOffset + chunk.length\r\n )\r\n );\r\n writer.releaseLock();\r\n return;\r\n }\r\n if (remoteConnection) {\r\n await socketAsyncWrite(remoteConnection, chunk);\r\n // remoteConnection.write(chunk);\r\n return;\r\n }\r\n const vlessBuffer = chunk.buffer.slice(\r\n chunk.byteOffset,\r\n chunk.byteOffset + chunk.length\r\n );\r\n const {\r\n hasError,\r\n message,\r\n portRemote,\r\n addressRemote,\r\n rawDataIndex,\r\n vlessVersion,\r\n isUDP,\r\n } = processVlessHeader(vlessBuffer, userID);\r\n address = addressRemote || '';\r\n portWithRandomLog = `${portRemote}--${Math.random()} ${\r\n isUDP ? 'udp ' : 'tcp '\r\n } `;\r\n if (hasError) {\r\n controller.error(`[${address}:${portWithRandomLog}] ${message} `);\r\n return;\r\n }\r\n // const addressType = requestAddr >> 42\r\n // const addressLength = requestAddr & 0x0f;\r\n console.log(`[${address}:${portWithRandomLog}] connecting`);\r\n vlessResponseHeader = new Uint8Array([vlessVersion![0], 0]);\r\n const rawClientData = vlessBuffer.slice(rawDataIndex!);\r\n if (isUDP) {\r\n // 如果仅仅是针对DNS, 这样是没有必要的。因为xray 客户端 DNS A/AAA query 都有长度 header,\r\n // 所以直接和 DNS server over TCP。所以无需 runtime 支持 UDP API。\r\n // DNS over UDP 和 TCP 唯一的区别就是 Header section format 多了长度\r\n // https://www.rfc-editor.org/rfc/rfc1035#section-4.2.2\r\n udpClientStream = makeUDPSocketStream(portRemote, address);\r\n const writer = udpClientStream.writable.getWriter();\r\n writer.write(rawClientData).catch((error) => console.log);\r\n writer.releaseLock();\r\n remoteConnectionReadyResolve(udpClientStream);\r\n } else {\r\n remoteConnection = await connect2Remote(portRemote, address, log);\r\n remoteConnection.write(new Uint8Array(rawClientData));\r\n remoteConnectionReadyResolve(remoteConnection);\r\n }\r\n },\r\n close() {\r\n // if (udpClientStream ) {\r\n // udpClientStream.writable.close();\r\n // }\r\n // (remoteConnection as Socket).end();\r\n console.log(\r\n `[${address}:${portWithRandomLog}] readableWebSocketStream is close`\r\n );\r\n },\r\n abort(reason) {\r\n // TODO: log can be remove, abort will catch by catch block\r\n console.log(\r\n `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`,\r\n JSON.stringify(reason)\r\n );\r\n },\r\n })\r\n )\r\n .catch((error) => {\r\n console.error(\r\n `[${address}:${portWithRandomLog}] readableWebSocketStream pipeto has exception`,\r\n error.stack || error\r\n );\r\n // error is cancel readable stream anyway, no need close websocket in here\r\n // closeWebSocket(webSocket);\r\n // close remote conn\r\n // remoteConnection?.close();\r\n });\r\n\r\n await new Promise((resolve) => (remoteConnectionReadyResolve = resolve));\r\n // remote --> ws\r\n let responseStream = udpClientStream?.readable;\r\n if (remoteConnection) {\r\n // ignore type error\r\n // @ts-ignore\r\n responseStream = Readable.toWeb(remoteConnection, {\r\n strategy: {\r\n // due to nodejs issue https://github.com/nodejs/node/issues/46347\r\n highWaterMark: smallRAM ? 100 : 1000, // 1000 * tcp mtu(64kb) = 64mb\r\n },\r\n });\r\n }\r\n let count = 0;\r\n\r\n // ws.send(vlessResponseHeader!);\r\n // remoteConnection.pipe(\r\n // new Writable({\r\n // async write(chunk: Uint8Array, encoding, callback) {\r\n // count += chunk.byteLength;\r\n // console.log('ws write', count / (1024 * 1024));\r\n // console.log(\r\n // '-----++++',\r\n // (remoteConnection as Socket).bytesRead / (1024 * 1024)\r\n // );\r\n // if (ws.readyState === ws.OPEN) {\r\n // await wsAsyncWrite(ws, chunk);\r\n // callback();\r\n // }\r\n // },\r\n // })\r\n // );\r\n // if readable not pipe can't wait fro writeable write method\r\n await responseStream.pipeTo(\r\n new WritableStream({\r\n start() {\r\n if (ws.readyState === ws.OPEN) {\r\n ws.send(vlessResponseHeader!);\r\n }\r\n },\r\n async write(chunk: Uint8Array, controller) {\r\n // count += chunk.byteLength;\r\n // console.log('ws write', count / (1024 * 1024));\r\n // console.log(\r\n // '-----++++',\r\n // (remoteConnection as Socket).bytesRead / (1024 * 1024),\r\n // (remoteConnection as Socket).readableHighWaterMark\r\n // );\r\n // we have issue there, maybe beacsue nodejs web stream has bug.\r\n // socket web stream will read more data from socket\r\n if (ws.readyState === ws.OPEN) {\r\n await wsAsyncWrite(ws, chunk);\r\n } else {\r\n if (!(remoteConnection as Socket).destroyed) {\r\n (remoteConnection as Socket).destroy();\r\n }\r\n }\r\n },\r\n close() {\r\n console.log(\r\n `[${address}:${portWithRandomLog}] remoteConnection!.readable is close`\r\n );\r\n },\r\n abort(reason) {\r\n closeWebSocket(ws);\r\n console.error(\r\n `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`,\r\n reason\r\n );\r\n },\r\n })\r\n );\r\n } catch (error) {\r\n console.error(\r\n `[${address}:${portWithRandomLog}] processWebSocket has exception `,\r\n error.stack || error\r\n );\r\n closeWebSocket(ws);\r\n }\r\n});\r\n\r\nserver.on('upgrade', function upgrade(request, socket, head) {\r\n const { pathname } = parse(request.url);\r\n\r\n vlessWServer.handleUpgrade(request, socket, head, function done(ws) {\r\n vlessWServer.emit('connection', ws, request);\r\n });\r\n});\r\n\r\nserver.listen(\r\n {\r\n port: port,\r\n host: '::',\r\n // host: '0.0.0.0',\r\n },\r\n () => {\r\n console.log(`server listen in http://127.0.0.1:${port}`);\r\n }\r\n);\r\n\r\nasync function connect2Remote(port, host, log: Function): Promise {\r\n return new Promise((resole, reject) => {\r\n const remoteSocket = connect(\r\n {\r\n port: port,\r\n host: host,\r\n // https://github.com/nodejs/node/pull/46587\r\n // autoSelectFamily: true,\r\n },\r\n () => {\r\n log(`connected`);\r\n resole(remoteSocket);\r\n }\r\n );\r\n remoteSocket.addListener('error', () => {\r\n reject('remoteSocket has error');\r\n });\r\n });\r\n}\r\n\r\nasync function socketAsyncWrite(ws: Duplex, chunk: Buffer) {\r\n return new Promise((resolve, reject) => {\r\n ws.write(chunk, (error) => {\r\n if (error) {\r\n reject(error);\r\n } else {\r\n resolve('');\r\n }\r\n });\r\n });\r\n}\r\n\r\nasync function wsAsyncWrite(ws: WebSocket, chunk: Uint8Array) {\r\n return new Promise((resolve, reject) => {\r\n ws.send(chunk, (error) => {\r\n if (error) {\r\n reject(error);\r\n } else {\r\n resolve('');\r\n }\r\n });\r\n });\r\n}\r\n\r\nfunction makeUDPSocketStream(portRemote, address) {\r\n const udpClient = createSocket('udp4');\r\n const transformStream = new TransformStream({\r\n start(controller) {\r\n /* … */\r\n udpClient.on('message', (message, info) => {\r\n // console.log(\r\n // `udp package received ${info.size} bytes from ${info.address}:${info.port}`,\r\n // Buffer.from(message).toString('hex')\r\n // );\r\n controller.enqueue(\r\n Buffer.concat([\r\n new Uint8Array([(info.size >> 8) & 0xff, info.size & 0xff]),\r\n message,\r\n ])\r\n );\r\n });\r\n udpClient.on('error', (error) => {\r\n console.log('udpClient error event', error);\r\n controller.error(error);\r\n });\r\n },\r\n\r\n async transform(chunk: ArrayBuffer, controller) {\r\n //seems v2ray will use same web socket for dns query..\r\n //And v2ray will combine A record and AAAA record into one ws message and use 2 btye for dns query length\r\n for (let index = 0; index < chunk.byteLength; ) {\r\n const lengthBuffer = chunk.slice(index, index + 2);\r\n const udpPakcetLength = new DataView(lengthBuffer).getInt16(0);\r\n const udpData = new Uint8Array(\r\n chunk.slice(index + 2, index + 2 + udpPakcetLength)\r\n );\r\n index = index + 2 + udpPakcetLength;\r\n await new Promise((resolve, reject) => {\r\n udpClient.send(udpData, portRemote, address, (err) => {\r\n if (err) {\r\n console.log('udps send error', err);\r\n controller.error(`Failed to send UDP packet !! ${err}`);\r\n safeCloseUDP(udpClient);\r\n }\r\n // console.log(\r\n // 'udp package sent',\r\n // Buffer.from(udpData).toString('hex')\r\n // );\r\n resolve(true);\r\n });\r\n });\r\n index = index;\r\n }\r\n\r\n // console.log('dns chunk', chunk);\r\n // console.log(portRemote, address);\r\n // port is big-Endian in raw data etc 80 == 0x005d\r\n },\r\n\r\n flush(controller) {\r\n safeCloseUDP(udpClient);\r\n controller.terminate();\r\n },\r\n });\r\n return transformStream;\r\n}\r\n\r\nfunction safeCloseUDP(client: UDPSocket) {\r\n try {\r\n client.close();\r\n } catch (error) {\r\n console.log('error close udp', error);\r\n }\r\n}\r\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/doc/andriod_v2rayn.jpg b/doc/andriod_v2rayn.jpg deleted file mode 100644 index cba311a..0000000 Binary files a/doc/andriod_v2rayn.jpg and /dev/null differ diff --git a/doc/cf-worker.md b/doc/cf-worker.md deleted file mode 100644 index 6df1657..0000000 --- a/doc/cf-worker.md +++ /dev/null @@ -1,8 +0,0 @@ - -## TOS - -https://www.cloudflare.com/supplemental-terms/ - -``` -Unlike most Cloudflare products, the Developer Platform can be used to host content. Content stored on the Developer Platform (whether in conjunction with a Cloudflare storage offering or not) that we determine in our sole judgment to be illegal, harmful, or in violation of Section 5 of the Cloudflare Developer Platforms Supplemental Terms may be blocked or removed, and use of the Developer Platform for storage of such illegal or harmful content may result in suspension or termination of Cloudflare Services. While we generally try to provide notice of such action, we reserve the right to take action without notice as appropriate. For these purposes, illegal or harmful content includes but is not limited to: (a) content containing, promoting, or facilitating child sexual abuse material or human trafficking; (b) content that infringes on another person’s intellectual property rights or is otherwise unlawful; (c) content that discloses sensitive personal information, incites or exploits violence, or is intended to defraud the public; and (d) content that seeks to distribute malware, facilitate phishing, or otherwise constitutes technical abuse. -``` \ No newline at end of file diff --git a/doc/client-log.jpg b/doc/client-log.jpg deleted file mode 100644 index 4f9a403..0000000 Binary files a/doc/client-log.jpg and /dev/null differ diff --git a/doc/deno-deploy.gif b/doc/deno-deploy.gif deleted file mode 100644 index 0781466..0000000 Binary files a/doc/deno-deploy.gif and /dev/null differ diff --git a/doc/deno-deploy.jpg b/doc/deno-deploy.jpg deleted file mode 100644 index 6f0c426..0000000 Binary files a/doc/deno-deploy.jpg and /dev/null differ diff --git a/doc/deno-deploy2.gif b/doc/deno-deploy2.gif deleted file mode 100644 index cd5e652..0000000 Binary files a/doc/deno-deploy2.gif and /dev/null differ diff --git a/doc/deno-link.jpg b/doc/deno-link.jpg deleted file mode 100644 index 232d205..0000000 Binary files a/doc/deno-link.jpg and /dev/null differ diff --git a/doc/edge-tunnel-deno.md b/doc/edge-tunnel-deno.md deleted file mode 100644 index 1b17d6a..0000000 --- a/doc/edge-tunnel-deno.md +++ /dev/null @@ -1,51 +0,0 @@ -# Deno deploy Install - -## 风险提示 - -`Deno deploy` 采用 [fair use policy](https://deno.com/deploy/docs/fair-use-policy), 翻译成中文就是`看良心使用`。 违反可能会封号。 - -## Fork 本项目到自己 Github 下 - -![fork](./fork.jpg) - -**请定期按照 github 的提示,同步 code 到自己的项目**。 -![sync](./sync.jpg) - -## 登录 Deno deploy - -用 Github 账户登录 https://deno.com/deploy - -> 相关免费策略,https://deno.com/deploy/pricing - -## New Project - -请在配置过程中 **记住 UUID**, 并且选择正确的部署入口文件。`apps\deno-vless\src\main.ts` -![deno-link](./deno-link.jpg) - -### 流程演示 - -> GIF 仅仅是流程演示,具体入口文件,请看上图。 - -https://raw.githubusercontent.com/zizifn/edgetunnel/main/doc/deno-deploy.gif - -如果 UUID 忘记 或者入口文件有变化,也可以在 deno 管理界面修改项目的配置。 - -https://raw.githubusercontent.com/zizifn/edgetunnel/main/doc/deno-deploy2.gif - -其他更多配置,比如使用量,请自行探索。 - -## 项目地址 - -点击 View 项目会自动打开。一开始返回 `401`. - -> 如果遇到 deno 生成域名不能访问的情况,请自己在 setting 里面绑定自己域名。 -> -> 只要 deno 网站可以访问,你生成的服务就应该可以访问。 -> -> 目前移动宽带貌似有这种问题。 - -不要慌张, 把你设置的 `UUID` 输入到弹出的用户名或者密码中。 - -然后会自动跳转到如下界面。 - -![index](./index.jpg) diff --git a/doc/firewall.jpg b/doc/firewall.jpg deleted file mode 100644 index 4f33481..0000000 Binary files a/doc/firewall.jpg and /dev/null differ diff --git a/doc/fork.jpg b/doc/fork.jpg deleted file mode 100644 index 125780b..0000000 Binary files a/doc/fork.jpg and /dev/null differ diff --git a/doc/index.jpg b/doc/index.jpg deleted file mode 100644 index 04d958d..0000000 Binary files a/doc/index.jpg and /dev/null differ diff --git a/doc/render.md b/doc/render.md deleted file mode 100644 index c550442..0000000 --- a/doc/render.md +++ /dev/null @@ -1,41 +0,0 @@ -# Render - -## 登录 render 账户 - -## Render Web APP 每月有 100GB 出站流量限制 - -如果使用 AWS ip 注册 Render 账户,会被要求绑定信用卡才能使用 Web APP。如果出现需要绑卡提示,建议更换 ip 注册。 - -https://render.com/ - -## 访问 https://dashboard.render.com/ - -## New Project - -![render1](./render1.jpg) - -## 关联 github 账户 - -![render2](./render2.jpg) - -## 部署新项目 - -需要填写如下信息,具体请参考下图. - -> Render 入口为 Cloudflare cdn,如果可以优选到亚洲地区 cloudflare ip,新加坡区速度最好。否则 cloudflare 默认美国线路,选美区速度最好。 - -![render3](./render3-1.png) - -> 如果你不喜欢docker,可以直接写 npm 命令。 -> -> | 选项 | 值 | -> | ------------- | --------------------------------------- | -> | Build Command | `npm install; npm run node-vless:build` | -> | Start Command | `npm run node-vless:start` | - -**⚠️ 添加环境变量 UUID** -![render4](./render4-1.png) - -## 访问主页面 - -输入UUID,就可以访问服务。 diff --git a/doc/render1.jpg b/doc/render1.jpg deleted file mode 100644 index aa46ad3..0000000 Binary files a/doc/render1.jpg and /dev/null differ diff --git a/doc/render2.jpg b/doc/render2.jpg deleted file mode 100644 index 143719d..0000000 Binary files a/doc/render2.jpg and /dev/null differ diff --git a/doc/render3-1.png b/doc/render3-1.png deleted file mode 100644 index b1638dc..0000000 Binary files a/doc/render3-1.png and /dev/null differ diff --git a/doc/render3.jpg b/doc/render3.jpg deleted file mode 100644 index 3368eef..0000000 Binary files a/doc/render3.jpg and /dev/null differ diff --git a/doc/render4-1.png b/doc/render4-1.png deleted file mode 100644 index e471de6..0000000 Binary files a/doc/render4-1.png and /dev/null differ diff --git a/doc/render4.jpg b/doc/render4.jpg deleted file mode 100644 index fc38637..0000000 Binary files a/doc/render4.jpg and /dev/null differ diff --git a/doc/switchyomega2.jpg b/doc/switchyomega2.jpg deleted file mode 100644 index 8d43043..0000000 Binary files a/doc/switchyomega2.jpg and /dev/null differ diff --git a/doc/sync.jpg b/doc/sync.jpg deleted file mode 100644 index 93b50d2..0000000 Binary files a/doc/sync.jpg and /dev/null differ diff --git a/doc/tel.jpg b/doc/tel.jpg deleted file mode 100644 index 3ed4405..0000000 Binary files a/doc/tel.jpg and /dev/null differ diff --git a/doc/v2rayn.jpg b/doc/v2rayn.jpg deleted file mode 100644 index 8c5c4fb..0000000 Binary files a/doc/v2rayn.jpg and /dev/null differ diff --git a/functions/_middleware.ts b/functions/_middleware.ts deleted file mode 100644 index 21f8c35..0000000 --- a/functions/_middleware.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { index401, page404 } from './util'; -import { parse, stringify, validate } from 'uuid'; - -async function errorHandling(context: EventContext) { - try { - return await context.next(); - } catch (err) { - return new Response(`${err.message}\n${err.stack}`, { status: 500 }); - } -} - -async function authentication( - context: EventContext< - any, - any, - { - digestUUID: string; - } - > -) { - // context.data It’s an arbitrary object you can attach data to that will persist during the request. The most common use-cases are for middleware that handles auth and may need to set context.data.username or similar. - // if not set UUID, return 401 page - const userID = context.env['UUID'] || ''; - let isVaildUser = validate(userID); - if (!isVaildUser) { - return new Response(index401, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - }, - }); - } - // skip authentication - const url = new URL(context.request.url); - if ( - // if url has uuid, skip auth - context.request.url.includes(userID) - ) { - return context.next(); - } - // static page - const basicAuth = context.request.headers.get('Authorization') || ''; - const authString = basicAuth.split(' ')?.[1] || ''; - if (!atob(authString).includes(userID)) { - return new Response(``, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic', - }, - }); - } else { - const url = new URL(context.request.url); - if (url.pathname === '/') { - const wspath = `/vless/${userID}`; - return new Response(``, { - status: 302, - headers: { - 'content-type': 'text/html; charset=utf-8', - Location: `./${userID}?wspath=${encodeURIComponent(wspath)}`, - }, - }); - } - if (url.pathname.startsWith('/assets')) { - return context.next(); - } - return new Response(page404, { - status: 404, - headers: { - 'content-type': 'text/html; charset=utf-8', - }, - }); - } -} - -export const onRequest = [errorHandling, authentication]; diff --git a/functions/sample/connect.ts b/functions/sample/connect.ts deleted file mode 100644 index a7dcaaa..0000000 --- a/functions/sample/connect.ts +++ /dev/null @@ -1,33 +0,0 @@ -// ignore the typescropt error -// @ts-ignore -import { connect } from 'cloudflare:sockets'; - -export const onRequest: PagesFunction = async (context) => { - context.params.user; - console.log('start fetch'); - const socket = connect({ - hostname: 'neverssl.com', - port: 80, - }); - - const writer = socket.writable.getWriter(); - const encoder = new TextEncoder(); - const encoded = encoder.encode( - 'GET / HTTP/1.1\r\nHost: neverssl.com\r\n\r\n' - ); - await writer.write(encoded); - - const reader = socket.readable.getReader(); - const decoder = new TextDecoder(); - let response = ''; - while (true) { - const res = await reader.read(); - if (res.done) { - console.log('Stream done, socket connection has been closed.'); - break; - } - response += decoder.decode(res.value); - } - - return new Response(response); -}; diff --git a/functions/sample/hello.ts b/functions/sample/hello.ts deleted file mode 100644 index bc54b95..0000000 --- a/functions/sample/hello.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { vlessJs } from 'vless-js'; -interface Env { - KV: KVNamespace; -} - -export const onRequest: PagesFunction = async (context) => { - console.log('xxxxx', context.env, vlessJs()); - return new Response(`Hello, world! ${context.request.url}--${vlessJs()}`); -}; diff --git a/functions/sample/http2.ts b/functions/sample/http2.ts deleted file mode 100644 index 774d534..0000000 --- a/functions/sample/http2.ts +++ /dev/null @@ -1,28 +0,0 @@ -interface Env { - KV: KVNamespace; -} - -export const onRequest: PagesFunction = async (context) => { - let count = 0; - console.log('test11', Date.now()); - await new Promise((resolve, rej) => { - setTimeout(() => { - resolve(''); - }, 100); - }); - console.log('test11', Date.now()); - const transformStream = - context.request.body?.pipeThrough(new TextDecoderStream()).pipeThrough( - new TransformStream({ - transform(chunk, controller) { - console.log('test', Date.now()); - controller.enqueue( - new TextEncoder().encode(`${chunk} + ${count++} ${new Date()}`) - ); - }, - }) - ) || 'default'; - return new Response(transformStream, { - headers: { 'content-type': 'text/plain' }, - }); -}; diff --git a/functions/sample/ws.ts b/functions/sample/ws.ts deleted file mode 100644 index 00ea14d..0000000 --- a/functions/sample/ws.ts +++ /dev/null @@ -1,25 +0,0 @@ -interface Env { - KV: KVNamespace; -} - -export const onRequest: PagesFunction = async ({ request, data }) => { - console.log(data); - const upgradeHeader = request.headers.get('Upgrade'); - if (!upgradeHeader || upgradeHeader !== 'websocket') { - return new Response('Expected Upgrade: websocket', { status: 426 }); - } - - const webSocketPair = new WebSocketPair(); - const [client, server] = Object.values(webSocketPair); - - server.accept(); - server.addEventListener('message', (event) => { - console.log(event.data); - server.send(`server reponse after client sent ${event.data}`); - }); - server.send(`client sned`); - return new Response(null, { - status: 101, - webSocket: client, - }); -}; diff --git a/functions/setup.md b/functions/setup.md deleted file mode 100644 index 8edab7c..0000000 --- a/functions/setup.md +++ /dev/null @@ -1 +0,0 @@ -for local env, create `.dev.vars` env file diff --git a/functions/tsconfig.json b/functions/tsconfig.json deleted file mode 100644 index 8417f80..0000000 --- a/functions/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "lib": ["esnext"], - "types": ["@cloudflare/workers-types"], - "paths": { - "vless-js": ["../libs/vless-js/src/index.ts"] - } - } -} diff --git a/functions/util.ts b/functions/util.ts deleted file mode 100644 index 25d2479..0000000 --- a/functions/util.ts +++ /dev/null @@ -1,55 +0,0 @@ -const index401 = ` - - - - - - - - 401 - UUID Not Valid - - - - -

Not set valid UUID in Environment Variables.

-

Please use tool to generate and remember UUID or use this one -

-

You must use same UUID for login this page after config valid UUID Environment Variables -

-

- Please refer to - Cloudflare pages deploy guide -

- - - -`; - -const page404 = ` - -404 Not Found - -

404 Not Found

-
nginx/1.23.4
- - -`; - -async function digestMessage(message: string) { - const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array - const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8); // hash the message - const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array - const hashHex = hashArray - .map((b) => b.toString(16).padStart(2, '0')) - .join(''); // convert bytes to hex string - return hashHex; -} - -export { index401, page404, digestMessage }; diff --git a/functions/vless/[wspath].ts b/functions/vless/[wspath].ts deleted file mode 100644 index 4d7921f..0000000 --- a/functions/vless/[wspath].ts +++ /dev/null @@ -1,192 +0,0 @@ -import { - makeReadableWebSocketStream, - processVlessHeader, - vlessJs, -} from 'vless-js'; -import { connect } from 'cloudflare:sockets'; -import { page404 } from '../util'; - -interface Env { - KV: KVNamespace; - UUID: string; -} - -export const onRequest: PagesFunction = async (context) => { - const userID = context.env['UUID']; - if (context.params.wspath !== userID) { - return new Response(``, { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic', - }, - }); - } - console.log(context.params.wspath); - let address = ''; - let portWithRandomLog = ''; - - const log = (info: string, event?: any) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - - const upgradeHeader = context.request.headers.get('Upgrade'); - // index page - if (!upgradeHeader || upgradeHeader !== 'websocket') { - return new Response(`need Upgrade to ws`, { - status: 200, - headers: { - 'content-type': 'text/html; charset=utf-8', - }, - }); - } - - const webSocketPair = new WebSocketPair(); - const [client, webSocket] = Object.values(webSocketPair); - - const earlyDataHeader = - context.request.headers.get('sec-websocket-protocol') || ''; - let remoteSocket: TransformStream = null; - webSocket.accept(); - - const readableWebSocketStream = makeReadableWebSocketStream( - webSocket, - earlyDataHeader, - log - ); - let vlessResponseHeader = new Uint8Array([0, 0]); - let remoteConnectionReadyResolve: Function; - - // ws-->remote - - readableWebSocketStream.pipeTo( - new WritableStream({ - async write(chunk, controller) { - if (remoteSocket) { - const writer = remoteSocket.writable.getWriter(); - await writer.write(chunk); - writer.releaseLock(); - return; - } - - const { - hasError, - message, - portRemote, - addressRemote, - rawDataIndex, - vlessVersion, - isUDP, - } = processVlessHeader(chunk, userID); - address = addressRemote || ''; - portWithRandomLog = `${portRemote}--${Math.random()} ${ - isUDP ? 'udp ' : 'tcp ' - } `; - // if UDP but port not DNS port, close it - if (isUDP && portRemote != 53) { - controller.error('UDP proxy only enable for DNS which is port 53'); - webSocket.close(); // server close will not casuse worker throw error - return; - } - if (hasError) { - controller.error(message); - webSocket.close(); // server close will not casuse worker throw error - return; - } - vlessResponseHeader = new Uint8Array([vlessVersion![0], 0]); - const rawClientData = chunk.slice(rawDataIndex!); - remoteSocket = connect({ - hostname: addressRemote, - port: portRemote, - }); - log(`connected`); - - const writer = remoteSocket.writable.getWriter(); - await writer.write(rawClientData); // first write, nomal is tls client hello - writer.releaseLock(); - - // remoteSocket ready - remoteConnectionReadyResolve(remoteSocket); - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is close` - ); - }, - abort(reason) { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, - JSON.stringify(reason) - ); - }, - }) - ); - - (async () => { - await new Promise((resolve) => (remoteConnectionReadyResolve = resolve)); - - // remote--> ws - let count = 0; - remoteSocket.readable - .pipeTo( - new WritableStream({ - start() { - if (webSocket.readyState === WebSocket.READY_STATE_OPEN) { - webSocket.send(vlessResponseHeader!); - } - }, - async write(chunk: Uint8Array, controller) { - if (webSocket.readyState === WebSocket.READY_STATE_OPEN) { - if (count++ > 20000) { - // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M - await delay(1); - } - webSocket.send(chunk); - // console.log(chunk.byteLength); - } else { - controller.error('webSocket.readyState is not open, maybe close'); - } - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] remoteConnection!.readable is close` - ); - }, - abort(reason) { - console.error( - `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, - reason - ); - }, - }) - ) - .catch((error) => { - console.error( - `[${address}:${portWithRandomLog}] processWebSocket has exception `, - error.stack || error - ); - safeCloseWebSocket(webSocket); - }); - })(); - - return new Response(null, { - status: 101, - webSocket: client, - }); -}; - -function safeCloseWebSocket(ws: WebSocket) { - try { - if (ws.readyState !== WebSocket.READY_STATE_CLOSED) { - ws.close(); - } - } catch (error) { - console.error('safeCloseWebSocket error', error); - } -} - -function delay(ms) { - return new Promise((resolve, rej) => { - setTimeout(resolve, ms); - }); -} diff --git a/import_map.json b/import_map.json deleted file mode 100644 index 9d432e6..0000000 --- a/import_map.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "imports": { - "vless-js": "./libs/vless-js/src/lib/vless-js.ts", - "uuid": "https://jspm.dev/uuid", - "lodash": "https://jspm.dev/lodash-es" - } -} diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index d0dbd1b..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { getJestProjects } from '@nx/jest'; - -export default { - projects: getJestProjects(), -}; diff --git a/jest.preset.js b/jest.preset.js deleted file mode 100644 index c1c3c4c..0000000 --- a/jest.preset.js +++ /dev/null @@ -1,15 +0,0 @@ -const nxPreset = require('@nx/jest/preset').default; - -module.exports = { - ...nxPreset, - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; diff --git a/libs/.gitkeep b/libs/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/libs/cf-worker-vless/.eslintrc.json b/libs/cf-worker-vless/.eslintrc.json deleted file mode 100644 index 9d9c0db..0000000 --- a/libs/cf-worker-vless/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": ["../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/libs/cf-worker-vless/README.md b/libs/cf-worker-vless/README.md deleted file mode 100644 index da94231..0000000 --- a/libs/cf-worker-vless/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# cf-worker-vless - -This library was generated with [Nx](https://nx.dev). - -## Building - -Run `nx build cf-worker-vless` to build the library. - -## Running unit tests - -Run `nx test cf-worker-vless` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/cf-worker-vless/cf-worker-vless-dev.js b/libs/cf-worker-vless/cf-worker-vless-dev.js deleted file mode 100644 index 3dc7536..0000000 --- a/libs/cf-worker-vless/cf-worker-vless-dev.js +++ /dev/null @@ -1,351 +0,0 @@ -// node_modules/uuid/dist/esm-browser/regex.js -var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; - -// node_modules/uuid/dist/esm-browser/validate.js -function validate(uuid) { - return typeof uuid === "string" && regex_default.test(uuid); -} -var validate_default = validate; - -// node_modules/uuid/dist/esm-browser/stringify.js -var byteToHex = []; -for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 256).toString(16).slice(1)); -} -function unsafeStringify(arr, offset = 0) { - return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); -} -function stringify(arr, offset = 0) { - const uuid = unsafeStringify(arr, offset); - if (!validate_default(uuid)) { - throw TypeError("Stringified UUID is invalid"); - } - return uuid; -} -var stringify_default = stringify; - -// libs/vless-js/src/lib/vless-js.ts -var WS_READY_STATE_OPEN = 1; -function makeReadableWebSocketStream(ws, earlyDataHeader, log) { - let readableStreamCancel = false; - return new ReadableStream({ - start(controller) { - ws.addEventListener("message", async (e) => { - if (readableStreamCancel) { - return; - } - const vlessBuffer = e.data; - controller.enqueue(vlessBuffer); - }); - ws.addEventListener("error", (e) => { - log("socket has error"); - readableStreamCancel = true; - controller.error(e); - }); - ws.addEventListener("close", () => { - try { - log("webSocket is close"); - if (readableStreamCancel) { - return; - } - controller.close(); - } catch (error2) { - log(`websocketStream can't close DUE to `, error2); - } - }); - const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader); - if (error) { - log(`earlyDataHeader has invaild base64`); - safeCloseWebSocket(ws); - return; - } - if (earlyData) { - controller.enqueue(earlyData); - } - }, - pull(controller) { - }, - cancel(reason) { - log(`websocketStream is cancel DUE to `, reason); - if (readableStreamCancel) { - return; - } - readableStreamCancel = true; - safeCloseWebSocket(ws); - } - }); -} -function base64ToArrayBuffer(base64Str) { - if (!base64Str) { - return { error: null }; - } - try { - base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/"); - const decode = atob(base64Str); - const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); - return { earlyData: arryBuffer.buffer, error: null }; - } catch (error) { - return { error }; - } -} -function safeCloseWebSocket(socket) { - try { - if (socket.readyState === WS_READY_STATE_OPEN) { - socket.close(); - } - } catch (error) { - console.error("safeCloseWebSocket error", error); - } -} -function processVlessHeader(vlessBuffer, userID) { - if (vlessBuffer.byteLength < 24) { - return { - hasError: true, - message: "invalid data" - }; - } - const version = new Uint8Array(vlessBuffer.slice(0, 1)); - let isValidUser = false; - let isUDP = false; - if (stringify_default(new Uint8Array(vlessBuffer.slice(1, 17))) === userID) { - isValidUser = true; - } - if (!isValidUser) { - return { - hasError: true, - message: "invalid user" - }; - } - const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0]; - const command = new Uint8Array( - vlessBuffer.slice(18 + optLength, 18 + optLength + 1) - )[0]; - if (command === 1) { - } else if (command === 2) { - isUDP = true; - } else { - return { - hasError: true, - message: `command ${command} is not support, command 01-tcp,02-udp,03-mux` - }; - } - const portIndex = 18 + optLength + 1; - const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2); - const portRemote = new DataView(portBuffer).getInt16(0); - let addressIndex = portIndex + 2; - const addressBuffer = new Uint8Array( - vlessBuffer.slice(addressIndex, addressIndex + 1) - ); - const addressType = addressBuffer[0]; - let addressLength = 0; - let addressValueIndex = addressIndex + 1; - let addressValue = ""; - switch (addressType) { - case 1: - addressLength = 4; - addressValue = new Uint8Array( - vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength) - ).join("."); - break; - case 2: - addressLength = new Uint8Array( - vlessBuffer.slice(addressValueIndex, addressValueIndex + 1) - )[0]; - addressValueIndex += 1; - addressValue = new TextDecoder().decode( - vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength) - ); - break; - case 3: - addressLength = 16; - const dataView = new DataView( - vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength) - ); - const ipv6 = []; - for (let i = 0; i < 8; i++) { - ipv6.push(dataView.getUint16(i * 2).toString(16)); - } - addressValue = ipv6.join(":"); - break; - default: - console.log(`invild addressType is ${addressType}`); - } - if (!addressValue) { - return { - hasError: true, - message: `addressValue is empty, addressType is ${addressType}` - }; - } - return { - hasError: false, - addressRemote: addressValue, - portRemote, - rawDataIndex: addressValueIndex + addressLength, - vlessVersion: version, - isUDP - }; -} - -// libs/cf-worker-vless/src/cf-worker-vless.ts -import { connect } from "cloudflare:sockets"; -function delay2(ms) { - return new Promise((resolve, rej) => { - setTimeout(resolve, ms); - }); -} -var cf_worker_vless_default = { - async fetch(request, env, ctx) { - let address = ""; - let portWithRandomLog = ""; - const userID = env.UUID || "7f14e42a-f453-4c39-a762-019ee493237d"; - const isVaildUUID = validate_default(userID); - const log = (info, event) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ""); - }; - const upgradeHeader = request.headers.get("Upgrade"); - if (!upgradeHeader || upgradeHeader !== "websocket") { - return new Response( - ` -404 Not Found - -

404 Not Found ${isVaildUUID ? "_-_" : ""}

-
nginx/1.23.4
- -`, - { - status: 404, - headers: { - "content-type": "text/html; charset=utf-8", - "WWW-Authenticate": "Basic" - } - } - ); - } - const webSocketPair = new WebSocketPair(); - const [client, webSocket] = Object.values(webSocketPair); - const earlyDataHeader = request.headers.get("sec-websocket-protocol") || ""; - let remoteSocket = null; - webSocket.accept(); - const readableWebSocketStream = makeReadableWebSocketStream( - webSocket, - earlyDataHeader, - log - ); - let vlessResponseHeader = new Uint8Array([0, 0]); - let remoteConnectionReadyResolve; - readableWebSocketStream.pipeTo( - new WritableStream({ - async write(chunk, controller) { - if (remoteSocket) { - const writer2 = remoteSocket.writable.getWriter(); - await writer2.write(chunk); - writer2.releaseLock(); - return; - } - const { - hasError, - message, - portRemote, - addressRemote, - rawDataIndex, - vlessVersion, - isUDP - } = processVlessHeader(chunk, userID); - address = addressRemote || ""; - portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? "udp " : "tcp "} `; - if (isUDP && portRemote != 53) { - controller.error("UDP proxy only enable for DNS which is port 53"); - webSocket.close(); - return; - } - if (hasError) { - controller.error(message); - webSocket.close(); - return; - } - vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]); - const rawClientData = chunk.slice(rawDataIndex); - remoteSocket = connect({ - hostname: addressRemote, - port: portRemote - }); - log(`connected`); - const writer = remoteSocket.writable.getWriter(); - await writer.write(rawClientData); - writer.releaseLock(); - remoteConnectionReadyResolve(remoteSocket); - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is close` - ); - }, - abort(reason) { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, - JSON.stringify(reason) - ); - } - }) - ); - (async () => { - await new Promise((resolve) => remoteConnectionReadyResolve = resolve); - let count = 0; - remoteSocket.readable.pipeTo( - new WritableStream({ - start() { - if (webSocket.readyState === WebSocket.READY_STATE_OPEN) { - webSocket.send(vlessResponseHeader); - } - }, - async write(chunk, controller) { - if (webSocket.readyState === WebSocket.READY_STATE_OPEN) { - if (count++ > 2e4) { - await delay2(1); - } - webSocket.send(chunk); - } else { - controller.error( - "webSocket.readyState is not open, maybe close" - ); - } - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] remoteConnection!.readable is close` - ); - }, - abort(reason) { - console.error( - `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, - reason - ); - } - }) - ).catch((error) => { - console.error( - `[${address}:${portWithRandomLog}] processWebSocket has exception `, - error.stack || error - ); - safeCloseWebSocket2(webSocket); - }); - })(); - return new Response(null, { - status: 101, - webSocket: client - }); - } -}; -function safeCloseWebSocket2(ws) { - try { - if (ws.readyState !== WebSocket.READY_STATE_CLOSED) { - ws.close(); - } - } catch (error) { - console.error("safeCloseWebSocket error", error); - } -} -export { - cf_worker_vless_default as default -}; -//# sourceMappingURL=cf-worker-vless.js.map diff --git a/libs/cf-worker-vless/jest.config.ts b/libs/cf-worker-vless/jest.config.ts deleted file mode 100644 index 58c788e..0000000 --- a/libs/cf-worker-vless/jest.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'cf-worker-vless', - preset: '../../jest.preset.js', - transform: { - '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/libs/cf-worker-vless', -}; diff --git a/libs/cf-worker-vless/package.json b/libs/cf-worker-vless/package.json deleted file mode 100644 index ea16bd4..0000000 --- a/libs/cf-worker-vless/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@edge-bypass/cf-worker-vless", - "version": "0.0.1", - "type": "commonjs" -} diff --git a/libs/cf-worker-vless/project.json b/libs/cf-worker-vless/project.json deleted file mode 100644 index 654d34c..0000000 --- a/libs/cf-worker-vless/project.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "cf-worker-vless", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/cf-worker-vless/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nx/js:tsc", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/cf-worker-vless", - "main": "libs/cf-worker-vless/src/index.ts", - "tsConfig": "libs/cf-worker-vless/tsconfig.lib.json", - "assets": ["libs/cf-worker-vless/*.md"] - } - }, - "lint": { - "executor": "@nx/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/cf-worker-vless/**/*.ts"] - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/cf-worker-vless/jest.config.ts", - "passWithNoTests": true - }, - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true - } - } - } - }, - "tags": [] -} diff --git a/libs/cf-worker-vless/src/cf-worker-vless.ts b/libs/cf-worker-vless/src/cf-worker-vless.ts deleted file mode 100644 index 5f4c9c6..0000000 --- a/libs/cf-worker-vless/src/cf-worker-vless.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { - makeReadableWebSocketStream, - processVlessHeader, - vlessJs, -} from 'vless-js'; -import { connect } from 'cloudflare:sockets'; -import { Buffer } from 'node:buffer'; -import { validate } from 'uuid'; - -function delay(ms) { - return new Promise((resolve, rej) => { - setTimeout(resolve, ms); - }); -} - -interface Env { - UUID: string; -} - -export default { - async fetch(request: Request, env: Env, ctx: ExecutionContext) { - let address = ''; - let portWithRandomLog = ''; - const userID = env.UUID || '7f14e42a-f453-4c39-a762-019ee493237d'; - const isVaildUUID = validate(userID); - - const log = (info: string, event?: any) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - - const upgradeHeader = request.headers.get('Upgrade'); - if (!upgradeHeader || upgradeHeader !== 'websocket') { - return new Response( - ` -404 Not Found - -

404 Not Found ${isVaildUUID ? '_-_' : ''}

-
nginx/1.23.4
- -`, - { - status: 404, - headers: { - 'content-type': 'text/html; charset=utf-8', - 'WWW-Authenticate': 'Basic', - }, - } - ); - } - - const webSocketPair = new WebSocketPair(); - const [client, webSocket] = Object.values(webSocketPair); - - const earlyDataHeader = request.headers.get('sec-websocket-protocol') || ''; - let remoteSocket: TransformStream = null; - webSocket.accept(); - - const readableWebSocketStream = makeReadableWebSocketStream( - webSocket, - earlyDataHeader, - log - ); - let vlessResponseHeader = new Uint8Array([0, 0]); - let remoteConnectionReadyResolve: Function; - - // ws-->remote - - readableWebSocketStream.pipeTo( - new WritableStream({ - async write(chunk, controller) { - if (remoteSocket) { - const writer = remoteSocket.writable.getWriter(); - await writer.write(chunk); - writer.releaseLock(); - return; - } - - const { - hasError, - message, - portRemote, - addressRemote, - rawDataIndex, - vlessVersion, - isUDP, - } = processVlessHeader(chunk, userID); - address = addressRemote || ''; - portWithRandomLog = `${portRemote}--${Math.random()} ${ - isUDP ? 'udp ' : 'tcp ' - } `; - // if UDP but port not DNS port, close it - if (isUDP && portRemote != 53) { - controller.error('UDP proxy only enable for DNS which is port 53'); - webSocket.close(); // server close will not casuse worker throw error - return; - } - if (hasError) { - controller.error(message); - webSocket.close(); // server close will not casuse worker throw error - return; - } - vlessResponseHeader = new Uint8Array([vlessVersion![0], 0]); - const rawClientData = chunk.slice(rawDataIndex!); - remoteSocket = connect({ - hostname: addressRemote, - port: portRemote, - }); - log(`connected`); - - const writer = remoteSocket.writable.getWriter(); - await writer.write(rawClientData); // first write, nomal is tls client hello - writer.releaseLock(); - - // remoteSocket ready - remoteConnectionReadyResolve(remoteSocket); - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is close` - ); - }, - abort(reason) { - console.log( - `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`, - JSON.stringify(reason) - ); - }, - }) - ); - - (async () => { - await new Promise((resolve) => (remoteConnectionReadyResolve = resolve)); - - // remote--> ws - let count = 0; - remoteSocket.readable - .pipeTo( - new WritableStream({ - start() { - if (webSocket.readyState === WebSocket.READY_STATE_OPEN) { - webSocket.send(vlessResponseHeader!); - } - }, - async write(chunk: Uint8Array, controller) { - if (webSocket.readyState === WebSocket.READY_STATE_OPEN) { - if (count++ > 20000) { - // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M - await delay(1); - } - webSocket.send(chunk); - // console.log(chunk.byteLength); - } else { - controller.error( - 'webSocket.readyState is not open, maybe close' - ); - } - }, - close() { - console.log( - `[${address}:${portWithRandomLog}] remoteConnection!.readable is close` - ); - }, - abort(reason) { - console.error( - `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`, - reason - ); - }, - }) - ) - .catch((error) => { - console.error( - `[${address}:${portWithRandomLog}] processWebSocket has exception `, - error.stack || error - ); - safeCloseWebSocket(webSocket); - }); - })(); - - return new Response(null, { - status: 101, - webSocket: client, - }); - }, -}; - -function safeCloseWebSocket(ws: WebSocket) { - try { - if (ws.readyState !== WebSocket.READY_STATE_CLOSED) { - ws.close(); - } - } catch (error) { - console.error('safeCloseWebSocket error', error); - } -} diff --git a/libs/cf-worker-vless/src/index2.ts b/libs/cf-worker-vless/src/index2.ts deleted file mode 100644 index 2ec7f36..0000000 --- a/libs/cf-worker-vless/src/index2.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { connect } from 'cloudflare:sockets'; - -interface Env { - UUID: string; -} - -export default { - async fetch(request: Request, env: Env, ctx: ExecutionContext) { - console.log('start fetch'); - const socket = connect({ - hostname: 'neverssl.com', - port: 80, - }); - - const writer = socket.writable.getWriter(); - const encoder = new TextEncoder(); - const encoded = encoder.encode( - 'GET / HTTP/1.1\r\nHost: neverssl.com\r\n\r\n' - ); - await writer.write(encoded); - - const reader = socket.readable.getReader(); - const decoder = new TextDecoder(); - let response = ''; - while (true) { - const res = await reader.read(); - if (res.done) { - console.log('Stream done, socket connection has been closed.'); - break; - } - response += decoder.decode(res.value); - } - - return new Response(response); - }, -}; diff --git a/libs/cf-worker-vless/src/ws.ts b/libs/cf-worker-vless/src/ws.ts deleted file mode 100644 index dcc8d03..0000000 --- a/libs/cf-worker-vless/src/ws.ts +++ /dev/null @@ -1,48 +0,0 @@ -export default { - async fetch(request: Request) { - let address = ''; - let portWithRandomLog = ''; - - const log = (info: string, event?: any) => { - console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); - }; - - const upgradeHeader = request.headers.get('Upgrade'); - if (!upgradeHeader || upgradeHeader !== 'websocket') { - return new Response('Expected Upgrade: websocket', { status: 426 }); - } - - const webSocketPair = new WebSocketPair(); - const [client, webSocket] = Object.values(webSocketPair); - const earlyDataHeader = request.headers.get('sec-websocket-protocol') || ''; - webSocket.accept(); - webSocket.addEventListener('message', (event) => { - console.log(event.data); - webSocket.send(`server reponse after client sent ${event.data}`); - if (event.data === 'close') { - webSocket.close(); - } - }); - webSocket.addEventListener('close', async (event) => { - console.log( - '-------------close-----------------', - event, - webSocket.readyState - ); - webSocket.close(); - }); - - webSocket.addEventListener('error', () => { - console.log('-------------error-----------------'); - }); - - client.addEventListener('close', (event) => { - console.log('----------client---close-----------------', event); - }); - - return new Response(null, { - status: 101, - webSocket: client, - }); - }, -}; diff --git a/libs/cf-worker-vless/tsconfig.json b/libs/cf-worker-vless/tsconfig.json deleted file mode 100644 index 07f5e7a..0000000 --- a/libs/cf-worker-vless/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "lib": ["esnext"], - "types": ["@cloudflare/workers-types"], - "paths": { - "vless-js": ["../vless-js/src/index.ts"] - } - } -} diff --git a/libs/cf-worker-vless/tsconfig.lib.json b/libs/cf-worker-vless/tsconfig.lib.json deleted file mode 100644 index 33eca2c..0000000 --- a/libs/cf-worker-vless/tsconfig.lib.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "declaration": true, - "types": ["node"] - }, - "include": ["src/**/*.ts"], - "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] -} diff --git a/libs/cf-worker-vless/tsconfig.spec.json b/libs/cf-worker-vless/tsconfig.spec.json deleted file mode 100644 index 9b2a121..0000000 --- a/libs/cf-worker-vless/tsconfig.spec.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/libs/edge-ui/.eslintrc.json b/libs/edge-ui/.eslintrc.json deleted file mode 100644 index a39ac5d..0000000 --- a/libs/edge-ui/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": ["plugin:@nx/react", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/libs/edge-ui/README.md b/libs/edge-ui/README.md deleted file mode 100644 index 4994342..0000000 --- a/libs/edge-ui/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# edge-ui - -This library was generated with [Nx](https://nx.dev). - -## Running unit tests - -Run `nx test edge-ui` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/libs/edge-ui/postcss.config.js b/libs/edge-ui/postcss.config.js deleted file mode 100644 index c72626d..0000000 --- a/libs/edge-ui/postcss.config.js +++ /dev/null @@ -1,15 +0,0 @@ -const { join } = require('path'); - -// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build -// option from your application's configuration (i.e. project.json). -// -// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries - -module.exports = { - plugins: { - tailwindcss: { - config: join(__dirname, 'tailwind.config.js'), - }, - autoprefixer: {}, - }, -}; diff --git a/libs/edge-ui/project.json b/libs/edge-ui/project.json deleted file mode 100644 index dfce800..0000000 --- a/libs/edge-ui/project.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "edge-ui", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/edge-ui/src", - "projectType": "library", - "tags": [], - "targets": { - "lint": { - "executor": "@nx/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/edge-ui/**/*.{ts,tsx,js,jsx}"] - } - }, - "test": { - "executor": "@nx/vite:test", - "outputs": ["{projectRoot}/coverage"], - "options": { - "passWithNoTests": true - } - } - } -} diff --git a/libs/edge-ui/src/index.ts b/libs/edge-ui/src/index.ts deleted file mode 100644 index eb924fc..0000000 --- a/libs/edge-ui/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './lib/app'; diff --git a/libs/edge-ui/src/lib/app.tsx b/libs/edge-ui/src/lib/app.tsx deleted file mode 100644 index b2ac347..0000000 --- a/libs/edge-ui/src/lib/app.tsx +++ /dev/null @@ -1,382 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { Transition } from '@headlessui/react'; -import { ExclamationTriangleIcon, XMarkIcon } from '@heroicons/react/20/solid'; -import QRCode from 'qrcode'; -import { Fragment, useEffect, useState } from 'react'; -import { validate as uuidValidate } from 'uuid'; -import { V2Option } from './model'; -export function EdgeApp() { - const [text, setText] = useState(''); - const [show, setShow] = useState(false); - const [v2Option, setV2Option] = useState({ - ws0Rtt: false, - }); - function handleShare(text: string) { - setText(text); - setShow(true); - } - function handleV2Option(option: V2Option) { - setV2Option(option); - } - - useEffect(() => { - if (show) { - console.log('useEffect---setShow'); - const timeoutID = setTimeout(() => { - setShow(false); - }, 1500); - return () => { - clearTimeout(timeoutID); - }; - } - }, [show]); - return ( - <> -
- -
- - - - {/* */} - -
-
- - - ); -} - -function V2Options({ - handleV2Option, -}: { - handleV2Option: (option: V2Option) => void; -}) { - const [ws0Rtt, setWs0Rtt] = useState(false); - return ( -
- Notifications -
-
-
- { - setWs0Rtt(!ws0Rtt); - handleV2Option({ - ws0Rtt: !ws0Rtt, - }); - }} - className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600" - /> -
-
- -

- Enable WS 0RTT -

-
-
-
-
- ); -} - -function SetUpAlert() { - return ( -
-
-
-
-
-

请注意!

-
-

- 如果遇到连不上网的情况, 请查看/参考具体客户端的   - - DNS 相关设置。 - -

-
-
-
-
- ); -} -function ShareNotifications({ - show, - setShow, -}: { - show: boolean; - setShow: (show: boolean) => void; -}) { - return ( - <> - {/* Global notification live region, render this permanently at the end of the document */} -
-
- {/* Notification panel, dynamically insert this into the live region when it needs to be displayed */} - -
-
-
-
-
-
-

- 分享成功! -

-

- 请不要随意泄露分享链接!! -

-
-
- -
-
-
-
-
-
-
- - ); -} - -function QRcodeImg({ text }: { text: string }) { - const [codeImg, setcodeImg] = useState(''); - const [copy, setCopy] = useState(false); - useEffect(() => { - (async () => { - if (text) { - const dataURL = await QRCode.toDataURL(text); - setcodeImg(dataURL); - } - })(); - }, [text]); - - async function copyText() { - await navigator.clipboard.writeText(text); - setCopy(true); - setTimeout(() => { - setCopy(false); - }, 1500); - } - - return ( -
- 二维码 -
- - {text} - -
- - - - -
-
-
- ); -} -function ShareAnything({ - handleShare, -}: { - handleShare: (text: string) => void; -}) { - const [text, setText] = useState(''); - return ( -
- -
-