diff --git a/.eslintignore b/.eslintignore index 6791fbf312a08b..1ccb8f831baa0b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,3 +6,4 @@ test/disabled test/tmp*/ tools/eslint node_modules +benchmark/tmp/ diff --git a/.eslintrc b/.eslintrc.yaml similarity index 93% rename from .eslintrc rename to .eslintrc.yaml index 16e4b66a93d477..713e2f1c93d08d 100644 --- a/.eslintrc +++ b/.eslintrc.yaml @@ -83,7 +83,12 @@ rules: computed-property-spacing: 2 eol-last: 2 func-call-spacing: 2 - indent: [2, 2, {SwitchCase: 1, MemberExpression: 1}] + func-name-matching: 2 + indent: [2, 2, {ArrayExpression: first, + CallExpression: {arguments: first}, + MemberExpression: 1, + ObjectExpression: first, + SwitchCase: 1}] key-spacing: [2, {mode: minimum}] keyword-spacing: 2 linebreak-style: [2, unix] @@ -119,11 +124,11 @@ rules: template-curly-spacing: 2 # Custom rules in tools/eslint-rules - align-function-arguments: 2 align-multiline-assignment: 2 assert-fail-single-argument: 2 assert-throws-arguments: [2, { requireTwo: false }] new-with-error: [2, Error, RangeError, TypeError, SyntaxError, ReferenceError] + timer-arguments: 2 # Global scoped method and vars globals: diff --git a/AUTHORS b/AUTHORS index f52fb4d2d72c28..6d4c9842d4774c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -935,7 +935,7 @@ Felix Becker Igor Klopov Tsarevich Dmitry Ojas Shirekar -Noah Rose +Noah Rose Ledesma Rafael Cepeda Chinedu Francis Nwafili Braydon Fuller diff --git a/BUILDING.md b/BUILDING.md index b5e9293d19c1fd..75ef93f8c73a13 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -109,7 +109,8 @@ Prerequisites: * One of: * [Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) * [Visual Studio 2015 Update 3](https://www.visualstudio.com/), all editions - including the Community edition. + including the Community edition (remember to select + "Common Tools for Visual C++ 2015" feature during installation). * Basic Unix tools required for some tests, [Git for Windows](http://git-scm.com/download/win) includes Git Bash and tools which can be included in the global `PATH`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 04f1eb449abf9c..f79d8fe3481bc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,8 @@ release. -6.10.0
+6.10.1
+6.10.0
6.9.5
6.9.4
6.9.3
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 32533304fecc67..4ce11257b707f2 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -4,6 +4,9 @@ * [Issues and Pull Requests](#issues-and-pull-requests) * [Accepting Modifications](#accepting-modifications) + - [Internal vs. Public API](#internal-vs-public-api) + - [Breaking Changes](#breaking-changes) + - [Deprecations](#deprecations) - [Involving the CTC](#involving-the-ctc) * [Landing Pull Requests](#landing-pull-requests) - [Technical HOWTO](#technical-howto) @@ -84,6 +87,206 @@ All pull requests that modify executable code should be subjected to continuous integration tests on the [project CI server](https://ci.nodejs.org/). +### Internal vs. Public API + +Due to the nature of the JavaScript language, it can often be difficult to +establish a clear distinction between which parts of the Node.js implementation +represent the "public" API Node.js users should assume to be stable and which +are considered part of the "internal" implementation detail of Node.js itself. +A general rule of thumb has been to base the determination off what +functionality is actually *documented* in the official Node.js API +documentation. However, it has been repeatedly demonstrated that either the +documentation does not completely cover implemented behavior or that Node.js +users have come to rely heavily on undocumented aspects of the Node.js +implementation. + +While there are numerous exceptions, the following general rules should be +followed to determine which aspects of the Node.js API are considered +"internal": + +- Any and all functionality exposed via `process.binding(...)` is considered to + be internal and *not* part of the Node.js Public API. +- Any and all functionality implemented in `lib/internal/**/*.js` that is not + re-exported by code in `lib/*.js`, or is not documented as part of the + Node.js Public API, is considered to be internal. +- Any object property or method whose key is a non-exported `Symbol` is + considered to be an internal property. +- Any object property or method whose key begins with the underscore `_` prefix, + and is not documented as part of the Node.js Public API, is considered to be + an internal property. +- Any object, property, method, argument, behavior, or event not documented in + the Node.js documentation is considered to be internal. +- Any native C/C++ APIs/ABIs exported by the Node.js `*.h` header files that + are hidden behind the `NODE_WANT_INTERNALS` flag are considered to be + internal. + +Exception to each of these points can be made if use or behavior of a given +internal API can be demonstrated to be sufficiently relied upon by the Node.js +ecosystem such that any changes would cause too much breakage. The threshold +for what qualifies as "too much breakage" is to be decided on a case-by-case +basis by the CTC. + +If it is determined that a currently undocumented object, property, method, +argument, or event *should* be documented, then a pull request adding the +documentation is required in order for it to be considered part of the "public" +API. + +Making a determination about whether something *should* be documented can be +difficult and will need to be handled on a case-by-case basis. For instance, if +one documented API cannot be used successfully without the use of a second +*currently undocumented* API, then the second API *should* be documented. If +using an API in a manner currently undocumented achieves a particular useful +result, a decision will need to be made whether or not that falls within the +supported scope of that API; and if it does, it should be documented. + +Breaking changes to internal elements are permitted in semver-patch or +semver-minor commits but Collaborators should take significant care when +making and reviewing such changes. Before landing such commits, an effort +must be made to determine the potential impact of the change in the ecosystem +by analyzing current use and by validating such changes through ecosystem +testing using the [Canary in the Goldmine](https://github.com/nodejs/citgm) +tool. If a change cannot be made without ecosystem breakage, then CTC review is +required before landing the change as anything less than semver-major. + +If a determination is made that a particular internal API (for instance, an +underscore `_` prefixed property) is sufficiently relied upon by the ecosystem +such that any changes may break user code, then serious consideration should be +given to providing an alternative Public API for that functionality before any +breaking changes are made. + +### Breaking Changes + +Backwards-incompatible changes may land on the master branch at any time after +sufficient review by collaborators and approval of at least two CTC members. + +Examples of breaking changes include, but are not necessarily limited to, +removal or redefinition of existing API arguments, changing return values +(except when return values do not currently exist), removing or modifying +existing properties on an options argument, adding or removing errors, +changing error messages in any way, altering expected timing of an event (e.g. +moving from sync to async responses or vice versa), and changing the +non-internal side effects of using a particular API. + +With a few notable exceptions outlined below, when backwards incompatible +changes to a *Public* API are necessary, the existing API *must* be deprecated +*first* and the new API either introduced in parallel or added after the next +major Node.js version following the deprecation as a replacement for the +deprecated API. In other words, as a general rule, existing *Public* APIs +*must not* change (in a backwards incompatible way) without a deprecation. + +Exception to this rule is given in the following cases: + +* Adding or removing errors thrown or reported by a Public API; +* Changing error messages; +* Altering the timing and non-internal side effects of the Public API. + +Such changes *must* be handled as semver-major changes but MAY be landed +without a [Deprecation cycle](#deprecation-cycle). + +From time-to-time, in particularly exceptional cases, the CTC may be asked to +consider and approve additional exceptions to this rule. + +Purely additive changes (e.g. adding new events to EventEmitter +implementations, adding new arguments to a method in a way that allows +existing code to continue working without modification, or adding new +properties to an options argument) are handled as semver-minor changes. + +Note that errors thrown, along with behaviors and APIs implemented by +dependencies of Node.js (e.g. those originating from V8) are generally not +under the control of Node.js and therefore *are not directly subject to this +policy*. However, care should still be taken when landing updates to +dependencies when it is known or expected that breaking changes to error +handling may have been made. Additional CI testing may be required. + +#### When breaking changes actually break things + +Breaking changes are difficult primarily because they change the fundamental +assumptions a user of Node.js has when writing their code and can cause +existing code to stop functioning as expected -- costing developers and users +time and energy to fix. + +Because breaking (semver-major) changes are permitted to land in master at any +time, it should be *understood and expected* that at least some subset of the +user ecosystem *may* be adversely affected *in the short term* when attempting +to build and use Node.js directly from master. This potential instability is +precisely why Node.js offers distinct Current and LTS release streams that +offer explicit stability guarantees. + +Specifically: + +* Breaking changes should *never* land in Current or LTS except when: + * Resolving critical security issues. + * Fixing a critical bug (e.g. fixing a memory leak) requires a breaking + change. + * There is CTC consensus that the change is required. +* If a breaking commit does accidentally land in a Current or LTS branch, an + attempt to fix the issue will be made before the next release; If no fix is + provided then the commit will be reverted. + +When any change is landed in master, and it is determined that the such +changes *do* break existing code, a decision may be made to revert those +changes either temporarily or permanently. However, the decision to revert or +not can often be based on many complex factors that are not easily codified. It +is also possible that the breaking commit can be labeled retroactively as a +semver-major change that will not be backported to Current or LTS branches. + +### Deprecations + +Deprecation refers to the identification of Public APIs that should no longer +be used and that may be removed or modified in non-backwards compatible ways in +a future major release of Node.js. Deprecation *may* be used with internal APIs +if there is expected impact on the user community. + +Node.js uses three fundamental Deprecation levels: + +* *Documentation-Only Deprecation* refers to elements of the Public API that are + being staged for deprecation in a future Node.js major release. An explicit + notice indicating the deprecated status is added to the API documentation + *but no functional changes are implemented in the code*. There will be no + runtime deprecation warning emitted for such deprecations. + +* *Runtime Deprecation* refers to the use of process warnings emitted at + runtime the first time that a deprecated API is used. A command-line + switch can be used to escalate such warnings into runtime errors that will + cause the Node.js process to exit. As with Documentation-Only Deprecation, + the documentation for the API must be updated to clearly indicate the + deprecated status. + +* *End-of-life* refers to APIs that have gone through Runtime Deprecation and + are ready to be removed from Node.js entirely. + +Documentation-Only Deprecations *may* be handled as semver-minor or +semver-major changes. Such deprecations have no impact on the successful +operation of running code and therefore should not be viewed as breaking +changes. + +Runtime Deprecations and End-of-life APIs (internal or public) *must* be +handled as semver-major changes unless there is CTC consensus to land the +deprecation as a semver-minor. + +All Documentation-Only and Runtime deprecations will be assigned a unique +identifier that can be used to persistently refer to the deprecation in +documentation, emitted process warnings, or errors thrown. Documentation for +these identifiers will be included in the Node.js API documentation and will +be immutable once assigned. Even if End-of-Life code is removed from Node.js, +the documentation for the assigned deprecation identifier must remain in the +Node.js API documentation. + + +A "Deprecation cycle" is one full Node.js major release during which an API +has been in one of the three Deprecation levels. (Note that Documentation-Only +Deprecations may land in a Node.js minor release but must not be upgraded to +a Runtime Deprecation until the next major release.) + +No API can be moved to End-of-life without first having gone through a +Runtime Deprecation cycle. + +A best effort will be made to communicate pending deprecations and associated +mitigations with the ecosystem as soon as possible (preferably *before* the pull +request adding the deprecation lands in master). All deprecations included in +a Node.js release should be listed prominently in the "Notable Changes" section +of the release notes. + ### Involving the CTC Collaborators may opt to elevate pull requests or issues to the CTC for @@ -120,6 +323,7 @@ information regarding the change process: for an issue, and/or the hash and commit message if the commit fixes a bug in a previous commit. Multiple `Fixes:` lines may be added if appropriate. +- A `Refs:` line referencing a URL for any relevant background. - A `Reviewed-By: Name ` line for yourself and any other Collaborators who have reviewed the change. - Useful for @mentions / contact list if something goes wrong in the PR. @@ -290,7 +494,7 @@ You can find more information [in the full LTS plan](https://github.com/nodejs/l #### How does LTS work? -Once a stable branch enters LTS, changes in that branch are limited to bug +Once a Current branch enters LTS, changes in that branch are limited to bug fixes, security updates, possible npm updates, documentation updates, and certain performance improvements that can be demonstrated to not break existing applications. Semver-minor changes are only permitted if required for bug fixes @@ -298,7 +502,7 @@ and then only on a case-by-case basis with LTS WG and possibly Core Technical Committee (CTC) review. Semver-major changes are permitted only if required for security related fixes. -Once a stable branch moves into Maintenance mode, only **critical** bugs, +Once a Current branch moves into Maintenance mode, only **critical** bugs, **critical** security fixes, and documentation updates will be permitted. #### Landing semver-minor commits in LTS @@ -318,9 +522,8 @@ CTC for further discussion. #### How are LTS Branches Managed? -There are currently three LTS branches: `v4.x`, `v0.10`, and `v0.12`. Each -of these is paired with a "staging" branch: `v4.x-staging`, `v0.10-staging`, -and `v0.12-staging`. +There are currently two LTS branches: `v6.x` and `v4.x`. Each of these is paired +with a "staging" branch: `v6.x-staging` and `v4.x-staging`. As commits land in `master`, they are cherry-picked back to each staging branch as appropriate. If the commit applies only to the LTS branch, the @@ -341,18 +544,14 @@ please feel free to include that information in the PR thread. Several LTS related issue and PR labels have been provided: +* `lts-watch-v6.x` - tells the LTS WG that the issue/PR needs to be considered + for landing in the `v6.x-staging` branch. * `lts-watch-v4.x` - tells the LTS WG that the issue/PR needs to be considered for landing in the `v4.x-staging` branch. -* `lts-watch-v0.10` - tells the LTS WG that the issue/PR needs to be considered - for landing in the `v0.10-staging` branch. -* `lts-watch-v0.12` - tells the LTS WG that the issue/PR needs to be considered - for landing in the `v0.12-staging` branch. +* `land-on-v6.x` - tells the release team that the commit should be landed + in a future v6.x release * `land-on-v4.x` - tells the release team that the commit should be landed in a future v4.x release -* `land-on-v0.10` - tells the release team that the commit should be landed - in a future v0.10 release -* `land-on-v0.12` - tells the release team that the commit should be landed - in a future v0.12 release Any collaborator can attach these labels to any PR/issue. As commits are landed into the staging branches, the `lts-watch-` label will be removed. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f198c82ee2f2f1..144fc393b8ac98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ For general help using Node.js, please file an issue at the [Node.js help repository](https://github.com/nodejs/help/issues). Discussion of non-technical topics including subjects like intellectual -property, trademark and high level project questions should move to the +property, trademark, and high level project questions should move to the [Technical Steering Committee (TSC)](https://github.com/nodejs/TSC/issues) instead. @@ -85,6 +85,9 @@ Create a branch and start hacking: $ git checkout -b my-branch -t origin/master ``` +Any text you write should follow the [Style Guide](doc/STYLE_GUIDE.md), +including comments and API documentation. + ### Step 3: Commit Make sure git knows your name and email address: @@ -109,8 +112,8 @@ changed and why. Follow these guidelines when writing one: lowercase with the exception of proper nouns, acronyms, and the ones that refer to code, like function/variable names. The description should be prefixed with the name of the changed subsystem and start with an - imperative verb, for example, "net: add localAddress and localPort - to Socket". + imperative verb. Example: "net: add localAddress and localPort + to Socket" 2. Keep the second line blank. 3. Wrap all other lines at 72 columns. @@ -121,11 +124,11 @@ subsystem: explain the commit in one line Body of commit message is a few lines of text, explaining things in more detail, possibly giving some background about the issue -being fixed, etc. etc. +being fixed, etc. The body of the commit message can be several paragraphs, and please do proper word-wrap and keep columns shorter than about -72 characters or so. That way `git log` will show things +72 characters or so. That way, `git log` will show things nicely even when it is indented. ``` @@ -136,10 +139,13 @@ Check the output of `git log --oneline files_that_you_changed` to find out what subsystem (or subsystems) your changes touch. If your patch fixes an open issue, you can add a reference to it at the end -of the log. Use the `Fixes:` prefix and the full issue URL. For example: +of the log. Use the `Fixes:` prefix and the full issue URL. For other references +use `Refs:`. For example: ```txt Fixes: https://github.com/nodejs/node/issues/1337 +Refs: http://eslint.org/docs/rules/space-in-parens.html +Refs: https://github.com/nodejs/node/pull/3615 ``` ### Step 4: Rebase @@ -167,19 +173,19 @@ $ ./configure && make -j4 test Windows: ```text - .\vcbuild nosign test +> vcbuild test ``` (See the [BUILDING.md](./BUILDING.md) for more details.) -Make sure the linter is happy and that all tests pass. Please, do not submit -patches that fail either check. +Make sure the linter does not report any issues and that all tests pass. Please +do not submit patches that fail either check. -Running `make test`/`.\vcbuild nosign test` will run the linter as well unless one or +Running `make test`/`vcbuild test` will run the linter as well unless one or more tests fail. If you want to run the linter without running tests, use -`make lint`/`.\vcbuild nosign jslint`. +`make lint`/`vcbuild lint`. If you are updating tests and just want to run a single test to check it, you can use this syntax to run it exactly as the test harness would: @@ -211,7 +217,7 @@ Pull requests are usually reviewed within a few days. ### Step 7: Discuss and update You will probably get feedback or requests for changes to your Pull Request. -This is a big part of the submission process, so don't be disheartened! +This is a big part of the submission process so don't be disheartened! To make changes to an existing Pull Request, make the changes to your branch. When you push that branch to your fork, GitHub will automatically update the @@ -249,7 +255,7 @@ If in doubt, you can always ask for guidance in the Pull Request or on Feel free to post a comment in the Pull Request to ping reviewers if you are awaiting an answer on something. If you encounter words or acronyms that -seem unfamiliar, check out this +seem unfamiliar, refer to this [glossary](https://sites.google.com/a/chromium.org/dev/glossary). Note that multiple commits often get squashed when they are landed (see the @@ -257,7 +263,7 @@ notes about [commit squashing](#commit-squashing)). ### Step 8: Landing -In order to get landed, a Pull Request needs to be reviewed and +In order to land, a Pull Request needs to be reviewed and [approved](#getting-approvals-for-your-pull-request) by at least one Node.js Collaborator and pass a [CI (Continuous Integration) test run](#ci-testing). @@ -277,8 +283,8 @@ your name on it. Congratulations and thanks for your contribution! ### Commit Squashing -When the commits in your Pull Request get landed, they will be squashed -into one commit per logical change, with metadata added to the commit +When the commits in your Pull Request land, they will be squashed +into one commit per logical change. Metadata will be added to the commit message (including links to the Pull Request, links to relevant issues, and the names of the reviewers). The commit history of your Pull Request, however, will stay intact on the Pull Request page. @@ -308,9 +314,9 @@ Every Pull Request needs to be tested to make sure that it works on the platforms that Node.js supports. This is done by running the code through the CI system. -Only a Collaborator can request a CI run. Usually one of them will do it +Only a Collaborator can start a CI run. Usually one of them will do it for you as approvals for the Pull Request come in. -If not, you can ask a Collaborator to request a CI run. +If not, you can ask a Collaborator to start a CI run. ### Waiting Until the Pull Request Gets Landed diff --git a/Makefile b/Makefile index 719b855559383a..a2b64e63b4a378 100644 --- a/Makefile +++ b/Makefile @@ -64,13 +64,18 @@ endif # to check for changes. .PHONY: $(NODE_EXE) $(NODE_G_EXE) +# The -r/-L check stops it recreating the link if it is already in place, +# otherwise $(NODE_EXE) being a .PHONY target means it is always re-run. +# Without the check there is a race condition between the link being deleted +# and recreated which can break the addons build when running test-ci +# See comments on the build-addons target for some more info $(NODE_EXE): config.gypi out/Makefile $(MAKE) -C out BUILDTYPE=Release V=$(V) - ln -fs out/Release/$(NODE_EXE) $@ + if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Release/$(NODE_EXE) $@; fi $(NODE_G_EXE): config.gypi out/Makefile $(MAKE) -C out BUILDTYPE=Debug V=$(V) - ln -fs out/Debug/$(NODE_EXE) $@ + if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Debug/$(NODE_EXE) $@; fi out/Makefile: common.gypi deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi $(PYTHON) tools/gyp_node.py -f make @@ -164,7 +169,7 @@ test/addons/.buildstamp: config.gypi \ # Cannot use $(wildcard test/addons/*/) here, it's evaluated before # embedded addons have been generated from the documentation. @for dirname in test/addons/*/; do \ - echo "\nBuilding addon $$PWD/$$dirname" ; \ + printf "\nBuilding addon $$PWD/$$dirname\n" ; \ env MAKEFLAGS="-j1" $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp \ --loglevel=$(LOGLEVEL) rebuild \ --python="$(PYTHON)" \ @@ -207,6 +212,11 @@ test-ci-js: $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ --mode=release --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_JS_SUITES) + # Clean up any leftover processes + PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \ + if [ "$${PS_OUT}" ]; then \ + echo $${PS_OUT} | $(XARGS) kill; exit 1; \ + fi test-ci: LOGLEVEL := info test-ci: | build-addons @@ -214,6 +224,11 @@ test-ci: | build-addons $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ --mode=release --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_NATIVE_SUITES) $(CI_JS_SUITES) + # Clean up any leftover processes + PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \ + if [ "$${PS_OUT}" ]; then \ + echo $${PS_OUT} | $(XARGS) kill; exit 1; \ + fi test-release: test-build $(PYTHON) tools/test.py --mode=release @@ -254,6 +269,11 @@ test-npm-publish: $(NODE_EXE) test-addons: test-build $(PYTHON) tools/test.py --mode=release addons +test-addons-clean: + $(RM) -rf test/addons/??_*/ + $(RM) -rf test/addons/*/build + $(RM) test/addons/.buildstamp test/addons/.docbuildstamp + test-timers: $(MAKE) --directory=tools faketime $(PYTHON) tools/test.py --mode=release timers @@ -293,6 +313,11 @@ test-v8 test-v8-intl test-v8-benchmarks test-v8-all: "$ git clone https://github.com/nodejs/node.git" endif +# Google Analytics ID used for tracking API docs page views, empty +# DOCS_ANALYTICS means no tracking scripts will be included in the +# generated .html files +DOCS_ANALYTICS ?= + apidoc_sources = $(wildcard doc/api/*.md) apidocs_html = $(apidoc_dirs) $(apiassets) $(addprefix out/,$(apidoc_sources:.md=.html)) apidocs_json = $(apidoc_dirs) $(apiassets) $(addprefix out/,$(apidoc_sources:.md=.json)) @@ -326,7 +351,8 @@ out/doc/api/%.json: doc/api/%.md [ -x $(NODE) ] && $(NODE) $(gen-json) || node $(gen-json) # check if ./node is actually set, else use user pre-installed binary -gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html --template=doc/template.html $< > $@ +gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html \ + --template=doc/template.html --analytics=$(DOCS_ANALYTICS) $< > $@ out/doc/api/%.html: doc/api/%.md @[ -e tools/doc/node_modules/js-yaml/package.json ] || \ [ -e tools/eslint/node_modules/js-yaml/package.json ] || \ @@ -491,7 +517,7 @@ PKGDIR=out/dist-osx release-only: @if [ "$(DISTTYPE)" != "nightly" ] && [ "$(DISTTYPE)" != "next-nightly" ] && \ `grep -q REPLACEME doc/api/*.md`; then \ - echo 'Please update Added: tags in the documentation first.' ; \ + echo 'Please update REPLACEME in Added: tags in doc/api/*.md (See doc/releases.md)' ; \ exit 1 ; \ fi @if [ "$(shell git status --porcelain | egrep -v '^\?\? ')" = "" ]; then \ @@ -580,7 +606,7 @@ ifeq ($(XZ), 0) ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).tar.xz.done" endif -doc-upload: tar +doc-upload: doc ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" chmod -R ug=rw-x+X,o=r+X out/doc/ scp -pr out/doc/ $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/ @@ -761,9 +787,11 @@ endif .PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean \ check uninstall install install-includes install-bin all staticlib \ - dynamiclib test test-all test-addons build-addons website-upload pkg \ - blog blogclean tar binary release-only bench-http-simple bench-idle \ - bench-all bench bench-misc bench-array bench-buffer bench-net \ - bench-http bench-fs bench-tls cctest run-ci test-v8 test-v8-intl \ - test-v8-benchmarks test-v8-all v8 lint-ci bench-ci jslint-ci doc-only \ - $(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci + dynamiclib test test-all test-addons test-addons-clean build-addons \ + website-upload pkg blog blogclean tar binary release-only \ + bench-http-simple bench-idle bench-all bench bench-misc bench-array \ + bench-buffer bench-net bench-http bench-fs bench-tls cctest run-ci \ + test-v8 test-v8-intl test-v8-benchmarks test-v8-all v8 lint-ci \ + bench-ci jslint-ci doc-only $(TARBALL)-headers test-ci test-ci-native \ + test-ci-js build-ci + diff --git a/README.md b/README.md index 3bc0bea7020e8b..7fe05e05e27ad0 100644 --- a/README.md +++ b/README.md @@ -155,56 +155,56 @@ more information about the governance of the Node.js project, see ### CTC (Core Technical Committee) * [addaleax](https://github.com/addaleax) - -**Anna Henningsen** <anna@addaleax.net> +**Anna Henningsen** <anna@addaleax.net> (she/her) * [bnoordhuis](https://github.com/bnoordhuis) - **Ben Noordhuis** <info@bnoordhuis.nl> * [ChALkeR](https://github.com/ChALkeR) - -**Сковорода Никита Андреевич** <chalkerx@gmail.com> -* [chrisdickinson](https://github.com/chrisdickinson) - -**Chris Dickinson** <christopher.s.dickinson@gmail.com> +**Сковорода Никита Андреевич** <chalkerx@gmail.com> (he/him) * [cjihrig](https://github.com/cjihrig) - **Colin Ihrig** <cjihrig@gmail.com> * [evanlucas](https://github.com/evanlucas) - -**Evan Lucas** <evanlucas@me.com> +**Evan Lucas** <evanlucas@me.com> (he/him) * [fishrock123](https://github.com/fishrock123) - **Jeremiah Senkpiel** <fishrock123@rocketmail.com> * [indutny](https://github.com/indutny) - **Fedor Indutny** <fedor.indutny@gmail.com> * [jasnell](https://github.com/jasnell) - -**James M Snell** <jasnell@gmail.com> +**James M Snell** <jasnell@gmail.com> (he/him) * [mhdawson](https://github.com/mhdawson) - -**Michael Dawson** <michael_dawson@ca.ibm.com> +**Michael Dawson** <michael_dawson@ca.ibm.com> (he/him) * [misterdjules](https://github.com/misterdjules) - **Julien Gilli** <jgilli@nodejs.org> * [mscdex](https://github.com/mscdex) - **Brian White** <mscdex@mscdex.net> +* [MylesBorins](https://github.com/MylesBorins) - +**Myles Borins** <myles.borins@gmail.com> (he/him) * [ofrobots](https://github.com/ofrobots) - **Ali Ijaz Sheikh** <ofrobots@google.com> * [rvagg](https://github.com/rvagg) - **Rod Vagg** <rod@vagg.org> * [shigeki](https://github.com/shigeki) - -**Shigeki Ohtsu** <ohtsu@iij.ad.jp> +**Shigeki Ohtsu** <ohtsu@iij.ad.jp> (he/him) * [targos](https://github.com/targos) - -**Michaël Zasso** <targos@protonmail.com> -* [TheAlphaNerd](https://github.com/TheAlphaNerd) - -**Myles Borins** <myles.borins@gmail.com> +**Michaël Zasso** <targos@protonmail.com> (he/him) * [thefourtheye](https://github.com/thefourtheye) - -**Sakthipriyan Vairamani** <thechargingvolcano@gmail.com> +**Sakthipriyan Vairamani** <thechargingvolcano@gmail.com> (he/him) * [trevnorris](https://github.com/trevnorris) - **Trevor Norris** <trev.norris@gmail.com> * [Trott](https://github.com/Trott) - -**Rich Trott** <rtrott@gmail.com> +**Rich Trott** <rtrott@gmail.com> (he/him) ### Collaborators +* [abouthiroppy](https://github.com/abouthiroppy) - +**Yuta Hiroto** <hello@about-hiroppy.com> (he/him) * [ak239](https://github.com/ak239) - **Aleksei Koziatinskii** <ak239spb@gmail.com> * [andrasq](https://github.com/andrasq) - **Andras** <andras@kinvey.com> * [AndreasMadsen](https://github.com/AndreasMadsen) - -**Andreas Madsen** <amwebdk@gmail.com> +**Andreas Madsen** <amwebdk@gmail.com> (he/him) * [bengl](https://github.com/bengl) - -**Bryan English** <bryan@bryanenglish.com> +**Bryan English** <bryan@bryanenglish.com> (he/him) * [benjamingr](https://github.com/benjamingr) - **Benjamin Gruenbaum** <benjamingr@gmail.com> * [bmeck](https://github.com/bmeck) - @@ -215,10 +215,14 @@ more information about the governance of the Node.js project, see **Bartosz Sosnowski** <bartosz@janeasystems.com> * [calvinmetcalf](https://github.com/calvinmetcalf) - **Calvin Metcalf** <calvin.metcalf@gmail.com> +* [chrisdickinson](https://github.com/chrisdickinson) - +**Chris Dickinson** <christopher.s.dickinson@gmail.com> * [claudiorodriguez](https://github.com/claudiorodriguez) - **Claudio Rodriguez** <cjrodr@yahoo.com> * [danbev](https://github.com/danbev) - **Daniel Bevenius** <daniel.bevenius@gmail.com> +* [edsadr](https://github.com/edsadr) - +**Adrian Estrada** <edsadr@gmail.com> (he/him) * [eljefedelrodeodeljefe](https://github.com/eljefedelrodeodeljefe) - **Robert Jefe Lindstaedt** <robert.lindstaedt@gmail.com> * [estliberitas](https://github.com/estliberitas) - @@ -232,7 +236,7 @@ more information about the governance of the Node.js project, see * [geek](https://github.com/geek) - **Wyatt Preul** <wpreul@gmail.com> * [gibfahn](https://github.com/gibfahn) - -**Gibson Fahnestock** <gibfahn@gmail.com> +**Gibson Fahnestock** <gibfahn@gmail.com> (he/him) * [iarna](https://github.com/iarna) - **Rebecca Turner** <me@re-becca.org> * [imyller](https://github.com/imyller) - @@ -240,7 +244,7 @@ more information about the governance of the Node.js project, see * [isaacs](https://github.com/isaacs) - **Isaac Z. Schlueter** <i@izs.me> * [italoacasas](https://github.com/italoacasas) - -**Italo A. Casas** <me@italoacasas.com> +**Italo A. Casas** <me@italoacasas.com> (he/him) * [iWuzHere](https://github.com/iWuzHere) - **Imran Iqbal** <imran@imraniqbal.org> * [JacksonTian](https://github.com/JacksonTian) - @@ -254,23 +258,23 @@ more information about the governance of the Node.js project, see * [joshgav](https://github.com/joshgav) - **Josh Gavant** <josh.gavant@outlook.com> * [joyeecheung](https://github.com/joyeecheung) - -**Joyee Cheung** <joyeec9h3@gmail.com> +**Joyee Cheung** <joyeec9h3@gmail.com> (she/her) * [julianduque](https://github.com/julianduque) - -**Julian Duque** <julianduquej@gmail.com> +**Julian Duque** <julianduquej@gmail.com> (he/him) * [JungMinu](https://github.com/JungMinu) - -**Minwoo Jung** <jmwsoft@gmail.com> +**Minwoo Jung** <minwoo@nodesource.com> (he/him) * [lance](https://github.com/lance) - **Lance Ball** <lball@redhat.com> * [lpinca](https://github.com/lpinca) - -**Luigi Pinca** <luigipinca@gmail.com> +**Luigi Pinca** <luigipinca@gmail.com> (he/him) * [lxe](https://github.com/lxe) - **Aleksey Smolenchuk** <lxe@lxe.co> * [matthewloring](https://github.com/matthewloring) - **Matthew Loring** <mattloring@google.com> * [mcollina](https://github.com/mcollina) - -**Matteo Collina** <matteo.collina@gmail.com> +**Matteo Collina** <matteo.collina@gmail.com> (he/him) * [micnic](https://github.com/micnic) - -**Nicu Micleușanu** <micnic90@gmail.com> +**Nicu Micleușanu** <micnic90@gmail.com> (he/him) * [mikeal](https://github.com/mikeal) - **Mikeal Rogers** <mikeal.rogers@gmail.com> * [monsanto](https://github.com/monsanto) - @@ -282,7 +286,7 @@ more information about the governance of the Node.js project, see * [orangemocha](https://github.com/orangemocha) - **Alexis Campailla** <orangemocha@nodejs.org> * [othiym23](https://github.com/othiym23) - -**Forrest L Norvell** <ogd@aoaioxxysz.net> +**Forrest L Norvell** <ogd@aoaioxxysz.net> (he/him) * [petkaantonov](https://github.com/petkaantonov) - **Petka Antonov** <petka_antonov@hotmail.com> * [phillipj](https://github.com/phillipj) - @@ -294,7 +298,7 @@ more information about the governance of the Node.js project, see * [princejwesley](https://github.com/princejwesley) - **Prince John Wesley** <princejohnwesley@gmail.com> * [qard](https://github.com/qard) - -**Stephen Belanger** <admin@stephenbelanger.com> +**Stephen Belanger** <admin@stephenbelanger.com> (he/him) * [rlidwka](https://github.com/rlidwka) - **Alex Kocharin** <alex@kocharin.ru> * [rmg](https://github.com/rmg) - @@ -324,9 +328,11 @@ more information about the governance of the Node.js project, see * [tellnes](https://github.com/tellnes) - **Christian Tellnes** <christian@tellnes.no> * [thekemkid](https://github.com/thekemkid) - -**Glen Keane** <glenkeane.94@gmail.com> +**Glen Keane** <glenkeane.94@gmail.com> (he/him) * [thlorenz](https://github.com/thlorenz) - **Thorsten Lorenz** <thlorenz@gmx.de> +* [TimothyGu](https://github.com/TimothyGu) - +**Timothy Gu** <timothygu99@gmail.com> (he/him) * [tunniclm](https://github.com/tunniclm) - **Mike Tunnicliffe** <m.j.tunnicliffe@gmail.com> * [vkurchatkin](https://github.com/vkurchatkin) - @@ -344,14 +350,14 @@ project. ### Release Team -Releases of Node.js and io.js will be signed with one of the following GPG keys: +Node.js releases are signed with one of the following GPG keys: -* **Chris Dickinson** <christopher.s.dickinson@gmail.com> -`9554F04D7259F04124DE6B476D5A82AC7E37093B` * **Colin Ihrig** <cjihrig@gmail.com> `94AE36675C464D64BAFA68DD7434390BDBE9B9C5` * **Evan Lucas** <evanlucas@me.com> `B9AE9905FFD7803F25714661B63B535A4C206CA9` +* **Italo A. Casas** <me@italoacasas.com> +`56730D5401028683275BD23C23EFEFE93C4CFFFE` * **James M Snell** <jasnell@keybase.io> `71DCFD284A79C3B38668286BC97EC7A07EDE3FC1` * **Jeremiah Senkpiel** <fishrock@keybase.io> @@ -364,21 +370,22 @@ Releases of Node.js and io.js will be signed with one of the following GPG keys: The full set of trusted release keys can be imported by running: ```shell -gpg --keyserver pool.sks-keyservers.net --recv-keys 9554F04D7259F04124DE6B476D5A82AC7E37093B gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 gpg --keyserver pool.sks-keyservers.net --recv-keys FD3A5288F042B6850C66B31F09FE44734EB7990E gpg --keyserver pool.sks-keyservers.net --recv-keys 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D gpg --keyserver pool.sks-keyservers.net --recv-keys C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 gpg --keyserver pool.sks-keyservers.net --recv-keys B9AE9905FFD7803F25714661B63B535A4C206CA9 +gpg --keyserver pool.sks-keyservers.net --recv-keys 56730D5401028683275BD23C23EFEFE93C4CFFFE ``` See the section above on [Verifying Binaries](#verifying-binaries) for details on what to do with these keys to verify that a downloaded file is official. -Previous releases of Node.js have been signed with one of the following GPG -keys: +Previous releases may also have been signed with one of the following GPG keys: +* **Chris Dickinson** <christopher.s.dickinson@gmail.com> +`9554F04D7259F04124DE6B476D5A82AC7E37093B` * **Isaac Z. Schlueter** <i@izs.me> `93C7E9E91B49E432C2F75674B0A78B0A6C481CF6` * **Julien Gilli** <jgilli@fastmail.fm> diff --git a/WORKING_GROUPS.md b/WORKING_GROUPS.md index 0126abeb54939a..6390946f5d1899 100644 --- a/WORKING_GROUPS.md +++ b/WORKING_GROUPS.md @@ -42,7 +42,6 @@ Top Level Working Group](https://github.com/nodejs/TSC/blob/master/WORKING_GROUP * [Benchmarking](#benchmarking) * [Post-mortem](#post-mortem) * [Intl](#intl) -* [HTTP](#http) * [Documentation](#documentation) * [Testing](#testing) @@ -189,21 +188,6 @@ Responsibilities include: * Publishing regular update summaries and other promotional content. -### [HTTP](https://github.com/nodejs/http) - -The HTTP Working Group is chartered for the support and improvement of the -HTTP implementation in Node.js. - -Responsibilities include: -* Addressing HTTP issues on the Node.js issue tracker. -* Authoring and editing HTTP documentation within the Node.js project. -* Reviewing changes to HTTP functionality within the Node.js project. -* Working with the ecosystem of HTTP related module developers to evolve the - HTTP implementation and APIs in core. -* Advising the CTC on all HTTP related issues and discussions. -* Messaging about the future of HTTP to give the community advance notice of - changes. - ### [Docker](https://github.com/nodejs/docker-iojs) The Docker Working Group's purpose is to build, maintain, and improve official diff --git a/benchmark/assert/deepequal-buffer.js b/benchmark/assert/deepequal-buffer.js new file mode 100644 index 00000000000000..2a7d9e3bed7c38 --- /dev/null +++ b/benchmark/assert/deepequal-buffer.js @@ -0,0 +1,40 @@ +'use strict'; +const common = require('../common.js'); +const assert = require('assert'); +const bench = common.createBenchmark(main, { + n: [1e3], + len: [1e2], + method: ['strict', 'nonstrict'] +}); + +function main(conf) { + const n = +conf.n; + const len = +conf.len; + var i; + + const data = Buffer.allocUnsafe(len); + const actual = Buffer.alloc(len); + const expected = Buffer.alloc(len); + data.copy(actual); + data.copy(expected); + + switch (conf.method) { + case 'strict': + bench.start(); + for (i = 0; i < n; ++i) { + // eslint-disable-next-line no-restricted-properties + assert.deepEqual(actual, expected); + } + bench.end(n); + break; + case 'nonstrict': + bench.start(); + for (i = 0; i < n; ++i) { + assert.deepStrictEqual(actual, expected); + } + bench.end(n); + break; + default: + throw new Error('Unsupported method'); + } +} diff --git a/benchmark/assert/deepequal-prims-and-objs-big-array.js b/benchmark/assert/deepequal-prims-and-objs-big-array.js index 1b4802c8ff4ac2..69eda8af087dfa 100644 --- a/benchmark/assert/deepequal-prims-and-objs-big-array.js +++ b/benchmark/assert/deepequal-prims-and-objs-big-array.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common.js'); -var assert = require('assert'); +const common = require('../common.js'); +const assert = require('assert'); const primValues = { 'null': null, @@ -13,29 +13,43 @@ const primValues = { 'new-array': new Array([1, 2, 3]) }; -var bench = common.createBenchmark(main, { +const bench = common.createBenchmark(main, { prim: Object.keys(primValues), - n: [25] + n: [25], + len: [1e5], + method: ['strict', 'nonstrict'] }); function main(conf) { - var prim = primValues[conf.prim]; - var n = +conf.n; - var primArray; - var primArrayCompare; - var x; + const prim = primValues[conf.prim]; + const n = +conf.n; + const len = +conf.len; + const actual = []; + const expected = []; + var i; - primArray = new Array(); - primArrayCompare = new Array(); - for (x = 0; x < (1e5); x++) { - primArray.push(prim); - primArrayCompare.push(prim); + for (var x = 0; x < len; x++) { + actual.push(prim); + expected.push(prim); } - bench.start(); - for (x = 0; x < n; x++) { - // eslint-disable-next-line no-restricted-properties - assert.deepEqual(primArray, primArrayCompare); + switch (conf.method) { + case 'strict': + bench.start(); + for (i = 0; i < n; ++i) { + // eslint-disable-next-line no-restricted-properties + assert.deepEqual(actual, expected); + } + bench.end(n); + break; + case 'nonstrict': + bench.start(); + for (i = 0; i < n; ++i) { + assert.deepStrictEqual(actual, expected); + } + bench.end(n); + break; + default: + throw new Error('Unsupported method'); } - bench.end(n); } diff --git a/benchmark/assert/deepequal-prims-and-objs-big-loop.js b/benchmark/assert/deepequal-prims-and-objs-big-loop.js index dea084bc984126..781c5ad754e723 100644 --- a/benchmark/assert/deepequal-prims-and-objs-big-loop.js +++ b/benchmark/assert/deepequal-prims-and-objs-big-loop.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common.js'); -var assert = require('assert'); +const common = require('../common.js'); +const assert = require('assert'); const primValues = { 'null': null, @@ -13,22 +13,37 @@ const primValues = { 'new-array': new Array([1, 2, 3]) }; -var bench = common.createBenchmark(main, { +const bench = common.createBenchmark(main, { prim: Object.keys(primValues), - n: [1e5] + n: [1e6], + method: ['strict', 'nonstrict'] }); function main(conf) { - var prim = primValues[conf.prim]; - var n = +conf.n; - var x; + const prim = primValues[conf.prim]; + const n = +conf.n; + const actual = prim; + const expected = prim; + var i; - bench.start(); - - for (x = 0; x < n; x++) { - // eslint-disable-next-line no-restricted-properties - assert.deepEqual(new Array([prim]), new Array([prim])); + // Creates new array to avoid loop invariant code motion + switch (conf.method) { + case 'strict': + bench.start(); + for (i = 0; i < n; ++i) { + // eslint-disable-next-line no-restricted-properties + assert.deepEqual([actual], [expected]); + } + bench.end(n); + break; + case 'nonstrict': + bench.start(); + for (i = 0; i < n; ++i) { + assert.deepStrictEqual([actual], [expected]); + } + bench.end(n); + break; + default: + throw new Error('Unsupported method'); } - - bench.end(n); } diff --git a/benchmark/assert/deepequal-typedarrays.js b/benchmark/assert/deepequal-typedarrays.js index 1954c57ee59eeb..037cfb2cf1ec3c 100644 --- a/benchmark/assert/deepequal-typedarrays.js +++ b/benchmark/assert/deepequal-typedarrays.js @@ -1,23 +1,41 @@ 'use strict'; -var common = require('../common.js'); -var assert = require('assert'); -var bench = common.createBenchmark(main, { +const common = require('../common.js'); +const assert = require('assert'); +const bench = common.createBenchmark(main, { type: ('Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array ' + 'Float32Array Float64Array Uint8ClampedArray').split(' '), - n: [1] + n: [1], + method: ['strict', 'nonstrict'], + len: [1e6] }); function main(conf) { - var type = conf.type; - var clazz = global[type]; - var n = +conf.n; + const type = conf.type; + const clazz = global[type]; + const n = +conf.n; + const len = +conf.len; - bench.start(); - var actual = new clazz(n * 1e6); - var expected = new clazz(n * 1e6); + const actual = new clazz(len); + const expected = new clazz(len); + var i; - // eslint-disable-next-line no-restricted-properties - assert.deepEqual(actual, expected); - - bench.end(n); + switch (conf.method) { + case 'strict': + bench.start(); + for (i = 0; i < n; ++i) { + // eslint-disable-next-line no-restricted-properties + assert.deepEqual(actual, expected); + } + bench.end(n); + break; + case 'nonstrict': + bench.start(); + for (i = 0; i < n; ++i) { + assert.deepStrictEqual(actual, expected); + } + bench.end(n); + break; + default: + throw new Error('Unsupported method'); + } } diff --git a/benchmark/buffers/buffer-compare-instance-method.js b/benchmark/buffers/buffer-compare-instance-method.js index 0becbeee23a7d7..bb07326f3de218 100644 --- a/benchmark/buffers/buffer-compare-instance-method.js +++ b/benchmark/buffers/buffer-compare-instance-method.js @@ -4,26 +4,80 @@ const v8 = require('v8'); const bench = common.createBenchmark(main, { size: [16, 512, 1024, 4096, 16386], + args: [1, 2, 3, 4, 5], millions: [1] }); function main(conf) { const iter = (conf.millions >>> 0) * 1e6; const size = (conf.size >>> 0); - const b0 = new Buffer(size).fill('a'); - const b1 = new Buffer(size).fill('a'); + const args = (conf.args >>> 0); + const b0 = Buffer.alloc(size, 'a'); + const b1 = Buffer.alloc(size, 'a'); + const b0Len = b0.length; + const b1Len = b1.length; + var i; b1[size - 1] = 'b'.charCodeAt(0); // Force optimization before starting the benchmark - b0.compare(b1); + switch (args) { + case 2: + b0.compare(b1, 0); + break; + case 3: + b0.compare(b1, 0, b1Len); + break; + case 4: + b0.compare(b1, 0, b1Len, 0); + break; + case 5: + b0.compare(b1, 0, b1Len, 0, b0Len); + break; + default: + b0.compare(b1); + } v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(b0.compare)'); - b0.compare(b1); - - bench.start(); - for (var i = 0; i < iter; i++) { - b0.compare(b1); + switch (args) { + case 2: + b0.compare(b1, 0); + bench.start(); + for (i = 0; i < iter; i++) { + b0.compare(b1, 0); + } + bench.end(iter / 1e6); + break; + case 3: + b0.compare(b1, 0, b1Len); + bench.start(); + for (i = 0; i < iter; i++) { + b0.compare(b1, 0, b1Len); + } + bench.end(iter / 1e6); + break; + case 4: + b0.compare(b1, 0, b1Len, 0); + bench.start(); + for (i = 0; i < iter; i++) { + b0.compare(b1, 0, b1Len, 0); + } + bench.end(iter / 1e6); + break; + case 5: + b0.compare(b1, 0, b1Len, 0, b0Len); + bench.start(); + for (i = 0; i < iter; i++) { + b0.compare(b1, 0, b1Len, 0, b0Len); + } + bench.end(iter / 1e6); + break; + default: + b0.compare(b1); + bench.start(); + for (i = 0; i < iter; i++) { + b0.compare(b1); + } + bench.end(iter / 1e6); } - bench.end(iter / 1e6); } diff --git a/benchmark/buffers/buffer-tojson.js b/benchmark/buffers/buffer-tojson.js new file mode 100644 index 00000000000000..1be59952c3fe60 --- /dev/null +++ b/benchmark/buffers/buffer-tojson.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [1e4], + len: [0, 10, 256, 4 * 1024] +}); + +function main(conf) { + var n = +conf.n; + var buf = Buffer.allocUnsafe(+conf.len); + + bench.start(); + for (var i = 0; i < n; ++i) + buf.toJSON(); + bench.end(n); +} diff --git a/benchmark/common.js b/benchmark/common.js index ac98b667820288..bdeaaa57364aa9 100644 --- a/benchmark/common.js +++ b/benchmark/common.js @@ -58,7 +58,7 @@ function runBenchmarks() { if (!test) return; - if (test.match(/^[\._]/)) + if (test.match(/^[._]/)) return process.nextTick(runBenchmarks); if (outputFormat == 'default') @@ -86,7 +86,7 @@ function Benchmark(fn, options) { this.fn = fn; this.options = options; this.config = parseOpts(options); - this._name = require.main.filename.split(/benchmark[\/\\]/).pop(); + this._name = require.main.filename.split(/benchmark[/\\]/).pop(); this._start = [0, 0]; this._started = false; @@ -101,7 +101,7 @@ function Benchmark(fn, options) { Benchmark.prototype.http = function(p, args, cb) { hasWrk(); var self = this; - var regexp = /Requests\/sec:[ \t]+([0-9\.]+)/; + var regexp = /Requests\/sec:[ \t]+([0-9.]+)/; var url = 'http://127.0.0.1:' + exports.PORT + p; args = args.concat(url); diff --git a/benchmark/dgram/bind-params.js b/benchmark/dgram/bind-params.js new file mode 100644 index 00000000000000..6f641f7f570667 --- /dev/null +++ b/benchmark/dgram/bind-params.js @@ -0,0 +1,38 @@ +'use strict'; + +const common = require('../common.js'); +const dgram = require('dgram'); + +const configs = { + n: [1e4], + port: ['true', 'false'], + address: ['true', 'false'], +}; + +const bench = common.createBenchmark(main, configs); + +function main(conf) { + const n = +conf.n; + const port = conf.port === 'true' ? 0 : undefined; + const address = conf.address === 'true' ? '0.0.0.0' : undefined; + + if (port !== undefined && address !== undefined) { + bench.start(); + for (let i = 0; i < n; i++) { + dgram.createSocket('udp4').bind(port, address).unref(); + } + bench.end(n); + } else if (port !== undefined) { + bench.start(); + for (let i = 0; i < n; i++) { + dgram.createSocket('udp4').bind(port).unref(); + } + bench.end(n); + } else if (port === undefined && address === undefined) { + bench.start(); + for (let i = 0; i < n; i++) { + dgram.createSocket('udp4').bind().unref(); + } + bench.end(n); + } +} diff --git a/benchmark/fs/bench-statSync.js b/benchmark/fs/bench-statSync.js index ba1e8168b4aaf5..4bc2ecd65a3624 100644 --- a/benchmark/fs/bench-statSync.js +++ b/benchmark/fs/bench-statSync.js @@ -5,17 +5,35 @@ const fs = require('fs'); const bench = common.createBenchmark(main, { n: [1e4], - kind: ['lstatSync', 'statSync'] + kind: ['fstatSync', 'lstatSync', 'statSync'] }); function main(conf) { const n = conf.n >>> 0; - const fn = fs[conf.kind]; - - bench.start(); - for (var i = 0; i < n; i++) { - fn(__filename); + var fn; + var i; + switch (conf.kind) { + case 'statSync': + case 'lstatSync': + fn = fs[conf.kind]; + bench.start(); + for (i = 0; i < n; i++) { + fn(__filename); + } + bench.end(n); + break; + case 'fstatSync': + fn = fs.fstatSync; + const fd = fs.openSync(__filename, 'r'); + bench.start(); + for (i = 0; i < n; i++) { + fn(fd); + } + bench.end(n); + fs.closeSync(fd); + break; + default: + throw new Error('Invalid kind argument'); } - bench.end(n); } diff --git a/benchmark/misc/object-property-bench.js b/benchmark/misc/object-property-bench.js new file mode 100644 index 00000000000000..8ac7683cd54d7e --- /dev/null +++ b/benchmark/misc/object-property-bench.js @@ -0,0 +1,81 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + method: ['property', 'string', 'variable', 'symbol'], + millions: [1000] +}); + +function runProperty(n) { + const object = {}; + var i = 0; + bench.start(); + for (; i < n; i++) { + object.p1 = 21; + object.p2 = 21; + object.p1 += object.p2; + } + bench.end(n / 1e6); +} + +function runString(n) { + const object = {}; + var i = 0; + bench.start(); + for (; i < n; i++) { + object['p1'] = 21; + object['p2'] = 21; + object['p1'] += object['p2']; + } + bench.end(n / 1e6); +} + +function runVariable(n) { + const object = {}; + const var1 = 'p1'; + const var2 = 'p2'; + var i = 0; + bench.start(); + for (; i < n; i++) { + object[var1] = 21; + object[var2] = 21; + object[var1] += object[var2]; + } + bench.end(n / 1e6); +} + +function runSymbol(n) { + const object = {}; + const symbol1 = Symbol('p1'); + const symbol2 = Symbol('p2'); + var i = 0; + bench.start(); + for (; i < n; i++) { + object[symbol1] = 21; + object[symbol2] = 21; + object[symbol1] += object[symbol2]; + } + bench.end(n / 1e6); +} + +function main(conf) { + const n = +conf.millions * 1e6; + + switch (conf.method) { + case 'property': + runProperty(n); + break; + case 'string': + runString(n); + break; + case 'variable': + runVariable(n); + break; + case 'symbol': + runSymbol(n); + break; + default: + throw new Error('Unexpected method'); + } +} diff --git a/benchmark/net/punycode.js b/benchmark/misc/punycode.js similarity index 100% rename from benchmark/net/punycode.js rename to benchmark/misc/punycode.js diff --git a/benchmark/net/net-c2s.js b/benchmark/net/net-c2s.js index 2c3bbe3c6a18cd..7c6a92471ab83b 100644 --- a/benchmark/net/net-c2s.js +++ b/benchmark/net/net-c2s.js @@ -65,8 +65,17 @@ Writer.prototype.emit = function() {}; Writer.prototype.prependListener = function() {}; +function flow() { + var dest = this.dest; + var res = dest.write(chunk, encoding); + if (!res) + dest.once('drain', this.flow); + else + process.nextTick(this.flow); +} + function Reader() { - this.flow = this.flow.bind(this); + this.flow = flow.bind(this); this.readable = true; } @@ -76,15 +85,6 @@ Reader.prototype.pipe = function(dest) { return dest; }; -Reader.prototype.flow = function() { - var dest = this.dest; - var res = dest.write(chunk, encoding); - if (!res) - dest.once('drain', this.flow); - else - process.nextTick(this.flow); -}; - function server() { var reader = new Reader(); diff --git a/benchmark/net/net-pipe.js b/benchmark/net/net-pipe.js index fd3a6d4f4334b8..b3cf1ba90e6b5e 100644 --- a/benchmark/net/net-pipe.js +++ b/benchmark/net/net-pipe.js @@ -65,8 +65,17 @@ Writer.prototype.emit = function() {}; Writer.prototype.prependListener = function() {}; +function flow() { + var dest = this.dest; + var res = dest.write(chunk, encoding); + if (!res) + dest.once('drain', this.flow); + else + process.nextTick(this.flow); +} + function Reader() { - this.flow = this.flow.bind(this); + this.flow = flow.bind(this); this.readable = true; } @@ -76,15 +85,6 @@ Reader.prototype.pipe = function(dest) { return dest; }; -Reader.prototype.flow = function() { - var dest = this.dest; - var res = dest.write(chunk, encoding); - if (!res) - dest.once('drain', this.flow); - else - process.nextTick(this.flow); -}; - function server() { var reader = new Reader(); diff --git a/benchmark/net/net-s2c.js b/benchmark/net/net-s2c.js index fc3f3e13894d3c..d9b3d8e6c972ab 100644 --- a/benchmark/net/net-s2c.js +++ b/benchmark/net/net-s2c.js @@ -65,8 +65,17 @@ Writer.prototype.emit = function() {}; Writer.prototype.prependListener = function() {}; +function flow() { + var dest = this.dest; + var res = dest.write(chunk, encoding); + if (!res) + dest.once('drain', this.flow); + else + process.nextTick(this.flow); +} + function Reader() { - this.flow = this.flow.bind(this); + this.flow = flow.bind(this); this.readable = true; } @@ -76,15 +85,6 @@ Reader.prototype.pipe = function(dest) { return dest; }; -Reader.prototype.flow = function() { - var dest = this.dest; - var res = dest.write(chunk, encoding); - if (!res) - dest.once('drain', this.flow); - else - process.nextTick(this.flow); -}; - function server() { var reader = new Reader(); diff --git a/benchmark/os/loadavg.js b/benchmark/os/loadavg.js new file mode 100644 index 00000000000000..6e3c57ed44b777 --- /dev/null +++ b/benchmark/os/loadavg.js @@ -0,0 +1,17 @@ +'use strict'; + +const common = require('../common.js'); +const loadavg = require('os').loadavg; + +const bench = common.createBenchmark(main, { + n: [5e6] +}); + +function main(conf) { + const n = +conf.n; + + bench.start(); + for (var i = 0; i < n; ++i) + loadavg(); + bench.end(n); +} diff --git a/benchmark/process/memoryUsage.js b/benchmark/process/memoryUsage.js new file mode 100644 index 00000000000000..d68ef339b4d10b --- /dev/null +++ b/benchmark/process/memoryUsage.js @@ -0,0 +1,16 @@ +'use strict'; + +var common = require('../common.js'); +var bench = common.createBenchmark(main, { + n: [1e5] +}); + +function main(conf) { + var n = +conf.n; + + bench.start(); + for (var i = 0; i < n; i++) { + process.memoryUsage(); + } + bench.end(n); +} diff --git a/benchmark/querystring/querystring-parse.js b/benchmark/querystring/querystring-parse.js index d78ef99f84f3d4..fe14d95a53f0a0 100644 --- a/benchmark/querystring/querystring-parse.js +++ b/benchmark/querystring/querystring-parse.js @@ -3,35 +3,26 @@ var common = require('../common.js'); var querystring = require('querystring'); var v8 = require('v8'); -var types = [ - 'noencode', - 'multicharsep', - 'encodemany', - 'encodelast', - 'multivalue', - 'multivaluemany', - 'manypairs' -]; +var inputs = { + noencode: 'foo=bar&baz=quux&xyzzy=thud', + multicharsep: 'foo=bar&&&&&&&&&&baz=quux&&&&&&&&&&xyzzy=thud', + encodefake: 'foo=%©ar&baz=%A©uux&xyzzy=%©ud', + encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d', + encodelast: 'foo=bar&baz=quux&xyzzy=thu%64', + multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz', + multivaluemany: 'foo=bar&foo=baz&foo=quux&quuy=quuz&foo=abc&foo=def&' + + 'foo=ghi&foo=jkl&foo=mno&foo=pqr&foo=stu&foo=vwxyz', + manypairs: 'a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z' +}; var bench = common.createBenchmark(main, { - type: types, + type: Object.keys(inputs), n: [1e6], }); function main(conf) { var type = conf.type; var n = conf.n | 0; - - var inputs = { - noencode: 'foo=bar&baz=quux&xyzzy=thud', - multicharsep: 'foo=bar&&&&&&&&&&baz=quux&&&&&&&&&&xyzzy=thud', - encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d', - encodelast: 'foo=bar&baz=quux&xyzzy=thu%64', - multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz', - multivaluemany: 'foo=bar&foo=baz&foo=quux&quuy=quuz&foo=abc&foo=def&' + - 'foo=ghi&foo=jkl&foo=mno&foo=pqr&foo=stu&foo=vwxyz', - manypairs: 'a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z' - }; var input = inputs[type]; // Force-optimize querystring.parse() so that the benchmark doesn't get diff --git a/benchmark/querystring/querystring-unescapebuffer.js b/benchmark/querystring/querystring-unescapebuffer.js new file mode 100644 index 00000000000000..fe48a6f149bc6a --- /dev/null +++ b/benchmark/querystring/querystring-unescapebuffer.js @@ -0,0 +1,23 @@ +'use strict'; +var common = require('../common.js'); +var querystring = require('querystring'); + +var bench = common.createBenchmark(main, { + input: [ + 'there is nothing to unescape here', + 'there%20are%20several%20spaces%20that%20need%20to%20be%20unescaped', + 'there%2Qare%0-fake%escaped values in%%%%this%9Hstring', + '%20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F%30%31%32%33%34%35%36%37' + ], + n: [10e6], +}); + +function main(conf) { + var input = conf.input; + var n = conf.n | 0; + + bench.start(); + for (var i = 0; i < n; i += 1) + querystring.unescapeBuffer(input); + bench.end(n); +} diff --git a/benchmark/misc/set-immediate-breadth-args.js b/benchmark/timers/set-immediate-breadth-args.js similarity index 100% rename from benchmark/misc/set-immediate-breadth-args.js rename to benchmark/timers/set-immediate-breadth-args.js diff --git a/benchmark/misc/set-immediate-breadth.js b/benchmark/timers/set-immediate-breadth.js similarity index 100% rename from benchmark/misc/set-immediate-breadth.js rename to benchmark/timers/set-immediate-breadth.js diff --git a/benchmark/misc/set-immediate-depth-args.js b/benchmark/timers/set-immediate-depth-args.js similarity index 100% rename from benchmark/misc/set-immediate-depth-args.js rename to benchmark/timers/set-immediate-depth-args.js diff --git a/benchmark/misc/set-immediate-depth.js b/benchmark/timers/set-immediate-depth.js similarity index 100% rename from benchmark/misc/set-immediate-depth.js rename to benchmark/timers/set-immediate-depth.js diff --git a/benchmark/timers/timers-cancel-pooled.js b/benchmark/timers/timers-cancel-pooled.js new file mode 100644 index 00000000000000..47c9fea2cb5b61 --- /dev/null +++ b/benchmark/timers/timers-cancel-pooled.js @@ -0,0 +1,32 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); + +var bench = common.createBenchmark(main, { + thousands: [500], +}); + +function main(conf) { + var iterations = +conf.thousands * 1e3; + + var timer = setTimeout(() => {}, 1); + for (var i = 0; i < iterations; i++) { + setTimeout(cb, 1); + } + var next = timer._idlePrev; + clearTimeout(timer); + + bench.start(); + + for (var j = 0; j < iterations; j++) { + timer = next; + next = timer._idlePrev; + clearTimeout(timer); + } + + bench.end(iterations / 1e3); +} + +function cb() { + assert(false, 'Timer should not call callback'); +} diff --git a/benchmark/timers/timers-cancel-unpooled.js b/benchmark/timers/timers-cancel-unpooled.js new file mode 100644 index 00000000000000..a040fad69e1c66 --- /dev/null +++ b/benchmark/timers/timers-cancel-unpooled.js @@ -0,0 +1,26 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); + +var bench = common.createBenchmark(main, { + thousands: [100], +}); + +function main(conf) { + var iterations = +conf.thousands * 1e3; + + var timersList = []; + for (var i = 0; i < iterations; i++) { + timersList.push(setTimeout(cb, i + 1)); + } + + bench.start(); + for (var j = 0; j < iterations + 1; j++) { + clearTimeout(timersList[j]); + } + bench.end(iterations / 1e3); +} + +function cb() { + assert(false, 'Timer ' + this._idleTimeout + ' should not call callback'); +} diff --git a/benchmark/timers/timers-insert-pooled.js b/benchmark/timers/timers-insert-pooled.js new file mode 100644 index 00000000000000..11c35319b11d69 --- /dev/null +++ b/benchmark/timers/timers-insert-pooled.js @@ -0,0 +1,18 @@ +'use strict'; +var common = require('../common.js'); + +var bench = common.createBenchmark(main, { + thousands: [500], +}); + +function main(conf) { + var iterations = +conf.thousands * 1e3; + + bench.start(); + + for (var i = 0; i < iterations; i++) { + setTimeout(() => {}, 1); + } + + bench.end(iterations / 1e3); +} diff --git a/benchmark/timers/timers-insert-unpooled.js b/benchmark/timers/timers-insert-unpooled.js new file mode 100644 index 00000000000000..91eabeb04e9d4f --- /dev/null +++ b/benchmark/timers/timers-insert-unpooled.js @@ -0,0 +1,27 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); + +var bench = common.createBenchmark(main, { + thousands: [100], +}); + +function main(conf) { + var iterations = +conf.thousands * 1e3; + + var timersList = []; + + bench.start(); + for (var i = 0; i < iterations; i++) { + timersList.push(setTimeout(cb, i + 1)); + } + bench.end(iterations / 1e3); + + for (var j = 0; j < iterations + 1; j++) { + clearTimeout(timersList[j]); + } +} + +function cb() { + assert(false, 'Timer ' + this._idleTimeout + ' should not call callback'); +} diff --git a/benchmark/timers/timers-timeout-pooled.js b/benchmark/timers/timers-timeout-pooled.js new file mode 100644 index 00000000000000..feaec23237f13d --- /dev/null +++ b/benchmark/timers/timers-timeout-pooled.js @@ -0,0 +1,23 @@ +'use strict'; +var common = require('../common.js'); + +var bench = common.createBenchmark(main, { + thousands: [500], +}); + +function main(conf) { + var iterations = +conf.thousands * 1e3; + var count = 0; + + for (var i = 0; i < iterations; i++) { + setTimeout(cb, 1); + } + + bench.start(); + + function cb() { + count++; + if (count === iterations) + bench.end(iterations / 1e3); + } +} diff --git a/benchmark/util/normalize-encoding.js b/benchmark/util/normalize-encoding.js new file mode 100644 index 00000000000000..8c4d03478104b0 --- /dev/null +++ b/benchmark/util/normalize-encoding.js @@ -0,0 +1,65 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); + +const groupedInputs = { + group_common: ['undefined', 'utf8', 'utf-8', 'base64', 'binary', 'latin1'], + group_upper: ['UTF-8', 'UTF8', 'UCS2', 'UTF-16LE', 'UTF16LE', 'BASE64'], + group_uncommon: [ 'foo', '1', 'false', 'undefined', '[]'], + group_misc: ['', 'utf16le', 'usc2', 'hex', 'HEX', 'BINARY'] +}; + +const inputs = [ + '', 'utf8', 'utf-8', 'UTF-8', + 'UTF8', 'Utf8', 'uTf-8', 'utF-8', 'ucs2', + 'UCS2', 'utf16le', 'utf-16le', 'UTF-16LE', 'UTF16LE', + 'binary', 'BINARY', 'latin1', 'base64', 'BASE64', + 'hex', 'HEX', 'foo', '1', 'false', 'undefined', '[]']; + +const bench = common.createBenchmark(main, { + input: inputs.concat(Object.keys(groupedInputs)), + n: [1e5] +}, { + flags: '--expose-internals' +}); + +function getInput(input) { + switch (input) { + case 'group_common': + return groupedInputs.group_common; + case 'group_upper': + return groupedInputs.group_upper; + case 'group_uncommon': + return groupedInputs.group_uncommon; + case 'group_misc': + return groupedInputs.group_misc; + case '1': + return [1]; + case 'false': + return [false]; + case 'undefined': + return [undefined]; + case '[]': + return [[]]; + default: + return [input]; + } +} + +function main(conf) { + const normalizeEncoding = require('internal/util').normalizeEncoding; + + const n = conf.n | 0; + const inputs = getInput(conf.input); + var noDead = ''; + + bench.start(); + for (var i = 0; i < n; i += 1) { + for (var j = 0; j < inputs.length; ++j) { + noDead = normalizeEncoding(inputs[j]); + } + } + bench.end(n); + assert.ok(noDead === undefined || noDead.length > 0); +} diff --git a/common.gypi b/common.gypi index 8a3179dae597f0..af9c6bafb0debe 100644 --- a/common.gypi +++ b/common.gypi @@ -185,6 +185,10 @@ 'BufferSecurityCheck': 'true', 'ExceptionHandling': 0, # /EHsc 'SuppressStartupBanner': 'true', + # Disable "warning C4267: conversion from 'size_t' to 'int', + # possible loss of data". Many originate from our dependencies + # and their sheer number drowns out other, more legitimate warnings. + 'DisableSpecificWarnings': ['4267'], 'WarnAsError': 'false', }, 'VCLibrarianTool': { diff --git a/configure b/configure index 821b8771bc8909..74229bf1120998 100755 --- a/configure +++ b/configure @@ -2,7 +2,16 @@ import sys if sys.version_info[0] != 2 or sys.version_info[1] not in (6, 7): - sys.stdout.write("Please use either Python 2.6 or 2.7\n") + sys.stderr.write('Please use either Python 2.6 or 2.7') + + from distutils.spawn import find_executable as which + python2 = which('python2') or which('python2.6') or which('python2.7') + + if python2: + sys.stderr.write(':\n\n') + sys.stderr.write(' ' + python2 + ' ' + ' '.join(sys.argv)) + + sys.stderr.write('\n') sys.exit(1) import errno @@ -469,6 +478,12 @@ parser.add_option('--without-bundled-v8', help='do not use V8 includes from the bundled deps folder. ' + '(This mode is not officially supported for regular applications)') +# Create compile_commands.json in out/Debug and out/Release. +parser.add_option('-C', + action='store_true', + dest='compile_commands_json', + help=optparse.SUPPRESS_HELP) + (options, args) = parser.parse_args() # Expand ~ in the install prefix now, it gets written to multiple files. @@ -1342,6 +1357,9 @@ elif flavor == 'win' and sys.platform != 'msys': else: gyp_args += ['-f', 'make-' + flavor] +if options.compile_commands_json: + gyp_args += ['-f', 'compile_commands_json'] + gyp_args += args if warn.warned: diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index e670d564e6cba5..4dcb3e573482a3 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 5 #define V8_MINOR_VERSION 1 #define V8_BUILD_NUMBER 281 -#define V8_PATCH_LEVEL 93 +#define V8_PATCH_LEVEL 95 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 8b7b7c2cc48c3b..c842b01587961d 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -3182,7 +3182,7 @@ class FunctionCallbackInfo { V8_INLINE Isolate* GetIsolate() const; V8_INLINE ReturnValue GetReturnValue() const; // This shouldn't be public, but the arm compiler needs it. - static const int kArgsLength = 7; + static const int kArgsLength = 8; protected: friend class internal::FunctionCallbackArguments; @@ -3194,6 +3194,7 @@ class FunctionCallbackInfo { static const int kDataIndex = 4; static const int kCalleeIndex = 5; static const int kContextSaveIndex = 6; + static const int kNewTargetIndex = 7; V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args, internal::Object** values, @@ -7902,7 +7903,6 @@ Local FunctionCallbackInfo::Holder() const { &implicit_args_[kHolderIndex])); } - template Local FunctionCallbackInfo::Data() const { return Local(reinterpret_cast(&implicit_args_[kDataIndex])); diff --git a/deps/v8/src/api-arguments.h b/deps/v8/src/api-arguments.h index 3bfe34dc894c18..136282b102f1c8 100644 --- a/deps/v8/src/api-arguments.h +++ b/deps/v8/src/api-arguments.h @@ -206,19 +206,22 @@ class FunctionCallbackArguments static const int kIsolateIndex = T::kIsolateIndex; static const int kCalleeIndex = T::kCalleeIndex; static const int kContextSaveIndex = T::kContextSaveIndex; + static const int kNewTargetIndex = T::kNewTargetIndex; FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data, internal::HeapObject* callee, - internal::Object* holder, internal::Object** argv, - int argc, bool is_construct_call) + internal::Object* holder, + internal::HeapObject* new_target, + internal::Object** argv, int argc) : Super(isolate), argv_(argv), argc_(argc), - is_construct_call_(is_construct_call) { + is_construct_call_(!new_target->IsUndefined()) { Object** values = begin(); values[T::kDataIndex] = data; values[T::kCalleeIndex] = callee; values[T::kHolderIndex] = holder; + values[T::kNewTargetIndex] = new_target; values[T::kContextSaveIndex] = isolate->heap()->the_hole_value(); values[T::kIsolateIndex] = reinterpret_cast(isolate); // Here the hole is set as default value. diff --git a/deps/v8/src/api-natives.cc b/deps/v8/src/api-natives.cc index adf4b6af576431..fa735e523be5b6 100644 --- a/deps/v8/src/api-natives.cc +++ b/deps/v8/src/api-natives.cc @@ -17,6 +17,7 @@ namespace { MaybeHandle InstantiateObject(Isolate* isolate, Handle data, + Handle new_target, bool is_hidden_prototype); MaybeHandle InstantiateFunction(Isolate* isolate, @@ -31,7 +32,7 @@ MaybeHandle Instantiate(Isolate* isolate, Handle data, Handle::cast(data), name); } else if (data->IsObjectTemplateInfo()) { return InstantiateObject(isolate, Handle::cast(data), - false); + Handle(), false); } else { return data; } @@ -288,11 +289,25 @@ void UncacheTemplateInstantiation(Isolate* isolate, uint32_t serial_number) { MaybeHandle InstantiateObject(Isolate* isolate, Handle info, + Handle new_target, bool is_hidden_prototype) { - // Fast path. - Handle result; + Handle constructor; uint32_t serial_number = static_cast(Smi::cast(info->serial_number())->value()); + if (!new_target.is_null()) { + if (new_target->IsJSFunction() && + JSFunction::cast(*new_target)->shared()->function_data() == + info->constructor() && + JSFunction::cast(*new_target)->context()->native_context() == + isolate->context()->native_context()) { + constructor = Handle::cast(new_target); + } else { + // Disable caching for subclass instantiation. + serial_number = 0; + } + } + // Fast path. + Handle result; if (serial_number) { // Probe cache. auto cache = isolate->template_instantiations_cache(); @@ -305,20 +320,27 @@ MaybeHandle InstantiateObject(Isolate* isolate, } // Enter a new scope. Recursion could otherwise create a lot of handles. HandleScope scope(isolate); - auto constructor = handle(info->constructor(), isolate); - Handle cons; - if (constructor->IsUndefined()) { - cons = isolate->object_function(); - } else { - auto cons_templ = Handle::cast(constructor); - ASSIGN_RETURN_ON_EXCEPTION( - isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction); + + if (constructor.is_null()) { + Handle cons(info->constructor(), isolate); + if (cons->IsUndefined()) { + constructor = isolate->object_function(); + } else { + auto cons_templ = Handle::cast(cons); + ASSIGN_RETURN_ON_EXCEPTION(isolate, constructor, + InstantiateFunction(isolate, cons_templ), + JSObject); + } + + if (new_target.is_null()) new_target = constructor; } - auto object = isolate->factory()->NewJSObject(cons); + + Handle object; + ASSIGN_RETURN_ON_EXCEPTION(isolate, object, + JSObject::New(constructor, new_target), JSObject); ASSIGN_RETURN_ON_EXCEPTION( isolate, result, - ConfigureInstance(isolate, object, info, is_hidden_prototype), - JSFunction); + ConfigureInstance(isolate, object, info, is_hidden_prototype), JSObject); // TODO(dcarney): is this necessary? JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); @@ -356,7 +378,7 @@ MaybeHandle InstantiateFunction(Isolate* isolate, isolate, prototype, InstantiateObject(isolate, Handle::cast(prototype_templ), - data->hidden_prototype()), + Handle(), data->hidden_prototype()), JSFunction); } auto parent = handle(data->parent_template(), isolate); @@ -448,12 +470,11 @@ MaybeHandle ApiNatives::InstantiateFunction( return ::v8::internal::InstantiateFunction(isolate, data); } - MaybeHandle ApiNatives::InstantiateObject( - Handle data) { + Handle data, Handle new_target) { Isolate* isolate = data->GetIsolate(); InvokeScope invoke_scope(isolate); - return ::v8::internal::InstantiateObject(isolate, data, false); + return ::v8::internal::InstantiateObject(isolate, data, new_target, false); } diff --git a/deps/v8/src/api-natives.h b/deps/v8/src/api-natives.h index 91f0b168d92830..66901fe965e715 100644 --- a/deps/v8/src/api-natives.h +++ b/deps/v8/src/api-natives.h @@ -23,7 +23,8 @@ class ApiNatives { Handle data); MUST_USE_RESULT static MaybeHandle InstantiateObject( - Handle data); + Handle data, + Handle new_target = Handle()); enum ApiInstanceType { JavaScriptObjectType, diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index 1fffcb67e596dd..d2af1cb49c651a 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -604,16 +604,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // r0: number of arguments // r1: constructor function // r3: new target - if (is_api_function) { - __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(r0); - __ InvokeFunction(r1, r3, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(r0); + __ InvokeFunction(r1, r3, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index 31e3e95f0329c1..93fe16edcdbe8c 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -5423,7 +5423,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); // context save __ push(context); diff --git a/deps/v8/src/arm64/builtins-arm64.cc b/deps/v8/src/arm64/builtins-arm64.cc index 44bfc1762d83cf..acaba1ef8c5164 100644 --- a/deps/v8/src/arm64/builtins-arm64.cc +++ b/deps/v8/src/arm64/builtins-arm64.cc @@ -605,16 +605,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // x0: number of arguments // x1: constructor function // x3: new target - if (is_api_function) { - __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(argc); - __ InvokeFunction(constructor, new_target, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(argc); + __ InvokeFunction(constructor, new_target, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/arm64/code-stubs-arm64.cc b/deps/v8/src/arm64/code-stubs-arm64.cc index ee4053515a6b20..800dfad0081ed4 100644 --- a/deps/v8/src/arm64/code-stubs-arm64.cc +++ b/deps/v8/src/arm64/code-stubs-arm64.cc @@ -5807,9 +5807,15 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); - // FunctionCallbackArguments: context, callee and call data. + // FunctionCallbackArguments + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); + + // context, callee and call data. __ Push(context, callee, call_data); if (!is_lazy()) { diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc index 1ad19946cb0acd..01f103101ced02 100644 --- a/deps/v8/src/builtins.cc +++ b/deps/v8/src/builtins.cc @@ -89,17 +89,6 @@ Handle BuiltinArguments::target() { return Arguments::at(Arguments::length() - 1); } -template <> -int BuiltinArguments::length() const { - return Arguments::length() - 1; -} - -template <> -Handle -BuiltinArguments::new_target() { - return Arguments::at(Arguments::length() - 1); -} - template <> int BuiltinArguments::length() const { @@ -4247,11 +4236,13 @@ BUILTIN(RestrictedStrictArgumentsPropertiesThrower) { namespace { -template MUST_USE_RESULT MaybeHandle HandleApiCallHelper( - Isolate* isolate, BuiltinArguments args) { + Isolate* isolate, + BuiltinArguments args) { HandleScope scope(isolate); Handle function = args.target(); + Handle new_target = args.new_target(); + bool is_construct = !new_target->IsUndefined(); Handle receiver; DCHECK(function->IsFunctionTemplateInfo() || @@ -4271,9 +4262,11 @@ MUST_USE_RESULT MaybeHandle HandleApiCallHelper( } Handle instance_template( ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); - ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, - ApiNatives::InstantiateObject(instance_template), - Object); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, receiver, + ApiNatives::InstantiateObject(instance_template, + Handle::cast(new_target)), + Object); args[0] = *receiver; DCHECK_EQ(*receiver, *args.receiver()); } else { @@ -4311,13 +4304,9 @@ MUST_USE_RESULT MaybeHandle HandleApiCallHelper( LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); DCHECK(raw_holder->IsJSObject()); - FunctionCallbackArguments custom(isolate, - data_obj, - *function, - raw_holder, - &args[0] - 1, - args.length() - 1, - is_construct); + FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, + *new_target, &args[0] - 1, + args.length() - 1); Handle result = custom.Call(callback); if (result.is_null()) result = isolate->factory()->undefined_value(); @@ -4338,19 +4327,11 @@ BUILTIN(HandleApiCall) { HandleScope scope(isolate); Handle result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, - HandleApiCallHelper(isolate, args)); + HandleApiCallHelper(isolate, args)); return *result; } -BUILTIN(HandleApiCallConstruct) { - HandleScope scope(isolate); - Handle result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, - HandleApiCallHelper(isolate, args)); - return *result; -} - Handle Builtins::CallFunction(ConvertReceiverMode mode, TailCallMode tail_call_mode) { switch (tail_call_mode) { @@ -4432,11 +4413,12 @@ Handle Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode) { namespace { class RelocatableArguments - : public BuiltinArguments, + : public BuiltinArguments, public Relocatable { public: RelocatableArguments(Isolate* isolate, int length, Object** arguments) - : BuiltinArguments(length, arguments), + : BuiltinArguments(length, + arguments), Relocatable(isolate) {} virtual inline void IterateInstance(ObjectVisitor* v) { @@ -4468,24 +4450,26 @@ MaybeHandle Builtins::InvokeApiFunction(Handle function, } } } - // Construct BuiltinArguments object: function, arguments reversed, receiver. + // Construct BuiltinArguments object: + // new target, function, arguments reversed, receiver. const int kBufferSize = 32; Object* small_argv[kBufferSize]; Object** argv; - if (argc + 2 <= kBufferSize) { + if (argc + 3 <= kBufferSize) { argv = small_argv; } else { - argv = new Object* [argc + 2]; + argv = new Object*[argc + 3]; } - argv[argc + 1] = *receiver; + argv[argc + 2] = *receiver; for (int i = 0; i < argc; ++i) { - argv[argc - i] = *args[i]; + argv[argc - i + 1] = *args[i]; } - argv[0] = *function; + argv[1] = *function; + argv[0] = isolate->heap()->undefined_value(); // new target MaybeHandle result; { - RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]); - result = HandleApiCallHelper(isolate, arguments); + RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); + result = HandleApiCallHelper(isolate, arguments); } if (argv != small_argv) { delete[] argv; @@ -4505,6 +4489,18 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( // Get the object called. JSObject* obj = JSObject::cast(*receiver); + // Set the new target. + HeapObject* new_target; + if (is_construct_call) { + // TODO(adamk): This should be passed through in args instead of + // being patched in here. We need to set a non-undefined value + // for v8::FunctionCallbackInfo::IsConstructCall() to get the + // right answer. + new_target = obj; + } else { + new_target = isolate->heap()->undefined_value(); + } + // Get the invocation callback from the function descriptor that was // used to create the called object. DCHECK(obj->map()->is_callable()); @@ -4527,13 +4523,9 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( HandleScope scope(isolate); LOG(isolate, ApiObjectAccess("call non-function", obj)); - FunctionCallbackArguments custom(isolate, - call_data->data(), - constructor, - obj, - &args[0] - 1, - args.length() - 1, - is_construct_call); + FunctionCallbackArguments custom(isolate, call_data->data(), constructor, + obj, new_target, &args[0] - 1, + args.length() - 1); Handle result_handle = custom.Call(callback); if (result_handle.is_null()) { result = isolate->heap()->undefined_value(); diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h index 221d06f30f845f..68788784584a87 100644 --- a/deps/v8/src/builtins.h +++ b/deps/v8/src/builtins.h @@ -166,8 +166,7 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) { V(SymbolConstructor, kNone) \ V(SymbolConstructor_ConstructStub, kTarget) \ \ - V(HandleApiCall, kTarget) \ - V(HandleApiCallConstruct, kTarget) \ + V(HandleApiCall, kTargetAndNewTarget) \ V(HandleApiCallAsFunction, kNone) \ V(HandleApiCallAsConstructor, kNone) \ \ diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 8bb53323abb3bf..4276d23e735fb0 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -1926,7 +1926,10 @@ void Compiler::PostInstantiation(Handle function, PretenureFlag pretenure) { Handle shared(function->shared()); - if (FLAG_always_opt && shared->allows_lazy_compilation()) { + if (FLAG_always_opt && + shared->allows_lazy_compilation() && + !shared->optimization_disabled() && + !shared->dont_crankshaft()) { function->MarkForOptimization(); } diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc index b7e33d9a74fce5..1c788e2f2bf66e 100644 --- a/deps/v8/src/ia32/builtins-ia32.cc +++ b/deps/v8/src/ia32/builtins-ia32.cc @@ -186,16 +186,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ j(greater_equal, &loop); // Call the function. - if (is_api_function) { - __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(eax); - __ InvokeFunction(edi, edx, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(eax); + __ InvokeFunction(edi, edx, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc index 53b35a3a841c66..510c2aed855025 100644 --- a/deps/v8/src/ia32/code-stubs-ia32.cc +++ b/deps/v8/src/ia32/code-stubs-ia32.cc @@ -5686,9 +5686,14 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); __ pop(return_address); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); + // context save. __ push(context); diff --git a/deps/v8/src/messages.h b/deps/v8/src/messages.h index 4aa0b73e7179c1..5ea0bc2686e84e 100644 --- a/deps/v8/src/messages.h +++ b/deps/v8/src/messages.h @@ -449,6 +449,8 @@ class CallSite { "Too many arguments in function call (only 65535 allowed)") \ T(TooManyParameters, \ "Too many parameters in function definition (only 65535 allowed)") \ + T(TooManySpreads, \ + "Literal containing too many nested spreads (up to 65534 allowed)") \ T(TooManyVariables, "Too many variables declared (only 4194303 allowed)") \ T(TypedArrayTooShort, \ "Derived TypedArray constructor created an array which was too small") \ diff --git a/deps/v8/src/mips/builtins-mips.cc b/deps/v8/src/mips/builtins-mips.cc index 9693a52697aa58..63fbfcf5413f4c 100644 --- a/deps/v8/src/mips/builtins-mips.cc +++ b/deps/v8/src/mips/builtins-mips.cc @@ -603,16 +603,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // a0: number of arguments // a1: constructor function // a3: new target - if (is_api_function) { - __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(a0); - __ InvokeFunction(a1, a3, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(a0); + __ InvokeFunction(a1, a3, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc index fd286fbb77bead..93a20acad9e0b9 100644 --- a/deps/v8/src/mips/code-stubs-mips.cc +++ b/deps/v8/src/mips/code-stubs-mips.cc @@ -5608,7 +5608,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); // Save context, callee and call data. __ Push(context, callee, call_data); diff --git a/deps/v8/src/mips64/builtins-mips64.cc b/deps/v8/src/mips64/builtins-mips64.cc index b55b77c51158bf..0e2df6962f7cfd 100644 --- a/deps/v8/src/mips64/builtins-mips64.cc +++ b/deps/v8/src/mips64/builtins-mips64.cc @@ -592,16 +592,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // a0: number of arguments // a1: constructor function // a3: new target - if (is_api_function) { - __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(a0); - __ InvokeFunction(a1, a3, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(a0); + __ InvokeFunction(a1, a3, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/mips64/code-stubs-mips64.cc b/deps/v8/src/mips64/code-stubs-mips64.cc index fdb6c81d2ee40b..30584f3f9eb79a 100644 --- a/deps/v8/src/mips64/code-stubs-mips64.cc +++ b/deps/v8/src/mips64/code-stubs-mips64.cc @@ -5636,7 +5636,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); // Save context, callee and call data. __ Push(context, callee, call_data); diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index fa45a091b12dfc..7dbc2a377c9f60 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -3069,9 +3069,16 @@ void MigrateFastToSlow(Handle object, Handle new_map, // Ensure that in-object space of slow-mode object does not contain random // garbage. int inobject_properties = new_map->GetInObjectProperties(); - for (int i = 0; i < inobject_properties; i++) { - FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); - object->RawFastPropertyAtPut(index, Smi::FromInt(0)); + if (inobject_properties) { + Heap* heap = isolate->heap(); + heap->ClearRecordedSlotRange( + object->address() + map->GetInObjectPropertyOffset(0), + object->address() + new_instance_size); + + for (int i = 0; i < inobject_properties; i++) { + FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); + object->RawFastPropertyAtPut(index, Smi::FromInt(0)); + } } isolate->counters()->props_to_dictionary()->Increment(); @@ -13080,50 +13087,51 @@ namespace { bool CanSubclassHaveInobjectProperties(InstanceType instance_type) { switch (instance_type) { - case JS_OBJECT_TYPE: - case JS_CONTEXT_EXTENSION_OBJECT_TYPE: - case JS_GENERATOR_OBJECT_TYPE: - case JS_MODULE_TYPE: - case JS_VALUE_TYPE: - case JS_DATE_TYPE: - case JS_ARRAY_TYPE: - case JS_MESSAGE_OBJECT_TYPE: case JS_ARRAY_BUFFER_TYPE: - case JS_TYPED_ARRAY_TYPE: + case JS_ARRAY_TYPE: + case JS_CONTEXT_EXTENSION_OBJECT_TYPE: case JS_DATA_VIEW_TYPE: - case JS_SET_TYPE: + case JS_DATE_TYPE: + case JS_FUNCTION_TYPE: + case JS_GENERATOR_OBJECT_TYPE: + case JS_MAP_ITERATOR_TYPE: case JS_MAP_TYPE: + case JS_MESSAGE_OBJECT_TYPE: + case JS_MODULE_TYPE: + case JS_OBJECT_TYPE: + case JS_PROMISE_TYPE: + case JS_REGEXP_TYPE: case JS_SET_ITERATOR_TYPE: - case JS_MAP_ITERATOR_TYPE: + case JS_SET_TYPE: + case JS_SPECIAL_API_OBJECT_TYPE: + case JS_TYPED_ARRAY_TYPE: + case JS_VALUE_TYPE: case JS_WEAK_MAP_TYPE: case JS_WEAK_SET_TYPE: - case JS_PROMISE_TYPE: - case JS_REGEXP_TYPE: - case JS_FUNCTION_TYPE: return true; - case JS_BOUND_FUNCTION_TYPE: - case JS_PROXY_TYPE: - case JS_GLOBAL_PROXY_TYPE: - case JS_GLOBAL_OBJECT_TYPE: + case BYTECODE_ARRAY_TYPE: + case BYTE_ARRAY_TYPE: + case CELL_TYPE: + case CODE_TYPE: + case FILLER_TYPE: case FIXED_ARRAY_TYPE: case FIXED_DOUBLE_ARRAY_TYPE: - case ODDBALL_TYPE: case FOREIGN_TYPE: - case MAP_TYPE: - case CODE_TYPE: - case CELL_TYPE: - case PROPERTY_CELL_TYPE: - case WEAK_CELL_TYPE: - case SYMBOL_TYPE: - case BYTECODE_ARRAY_TYPE: + case FREE_SPACE_TYPE: case HEAP_NUMBER_TYPE: + case JS_BOUND_FUNCTION_TYPE: + case JS_GLOBAL_OBJECT_TYPE: + case JS_GLOBAL_PROXY_TYPE: + case JS_PROXY_TYPE: + case MAP_TYPE: case MUTABLE_HEAP_NUMBER_TYPE: - case SIMD128_VALUE_TYPE: - case FILLER_TYPE: - case BYTE_ARRAY_TYPE: - case FREE_SPACE_TYPE: + case ODDBALL_TYPE: + case PROPERTY_CELL_TYPE: case SHARED_FUNCTION_INFO_TYPE: + case SIMD128_VALUE_TYPE: + case SYMBOL_TYPE: + case WEAK_CELL_TYPE: #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ case FIXED_##TYPE##_ARRAY_TYPE: diff --git a/deps/v8/src/parsing/expression-classifier.h b/deps/v8/src/parsing/expression-classifier.h index 71fa3d3e89b160..e3b0b8c487be5a 100644 --- a/deps/v8/src/parsing/expression-classifier.h +++ b/deps/v8/src/parsing/expression-classifier.h @@ -13,32 +13,52 @@ namespace v8 { namespace internal { +#define ERROR_CODES(T) \ + T(ExpressionProduction, 0) \ + T(FormalParameterInitializerProduction, 1) \ + T(BindingPatternProduction, 2) \ + T(AssignmentPatternProduction, 3) \ + T(DistinctFormalParametersProduction, 4) \ + T(StrictModeFormalParametersProduction, 5) \ + T(ArrowFormalParametersProduction, 6) \ + T(LetPatternProduction, 7) \ + T(CoverInitializedNameProduction, 8) + + template class ExpressionClassifier { public: + enum ErrorKind : unsigned { +#define DEFINE_ERROR_KIND(NAME, CODE) k##NAME = CODE, + ERROR_CODES(DEFINE_ERROR_KIND) +#undef DEFINE_ERROR_KIND + kUnusedError = 15 // Larger than error codes; should fit in 4 bits + }; + struct Error { - Error() + V8_INLINE Error() : location(Scanner::Location::invalid()), message(MessageTemplate::kNone), + kind(kUnusedError), type(kSyntaxError), arg(nullptr) {} + V8_INLINE explicit Error(Scanner::Location loc, + MessageTemplate::Template msg, ErrorKind k, + const char* a = nullptr, + ParseErrorType t = kSyntaxError) + : location(loc), message(msg), kind(k), type(t), arg(a) {} Scanner::Location location; - MessageTemplate::Template message : 30; + MessageTemplate::Template message : 26; + unsigned kind : 4; ParseErrorType type : 2; const char* arg; }; - enum TargetProduction { - ExpressionProduction = 1 << 0, - FormalParameterInitializerProduction = 1 << 1, - BindingPatternProduction = 1 << 2, - AssignmentPatternProduction = 1 << 3, - DistinctFormalParametersProduction = 1 << 4, - StrictModeFormalParametersProduction = 1 << 5, - ArrowFormalParametersProduction = 1 << 6, - LetPatternProduction = 1 << 7, - CoverInitializedNameProduction = 1 << 8, + enum TargetProduction : unsigned { +#define DEFINE_PRODUCTION(NAME, CODE) NAME = 1 << CODE, + ERROR_CODES(DEFINE_PRODUCTION) +#undef DEFINE_PRODUCTION ExpressionProductions = (ExpressionProduction | FormalParameterInitializerProduction), @@ -52,102 +72,121 @@ class ExpressionClassifier { ArrowFormalParametersProduction | CoverInitializedNameProduction) }; - enum FunctionProperties { NonSimpleParameter = 1 << 0 }; + enum FunctionProperties : unsigned { + NonSimpleParameter = 1 << 0 + }; explicit ExpressionClassifier(const Traits* t) : zone_(t->zone()), non_patterns_to_rewrite_(t->GetNonPatternList()), + reported_errors_(t->GetReportedErrorList()), + duplicate_finder_(nullptr), invalid_productions_(0), - function_properties_(0), - duplicate_finder_(nullptr) { + function_properties_(0) { + reported_errors_begin_ = reported_errors_end_ = reported_errors_->length(); non_pattern_begin_ = non_patterns_to_rewrite_->length(); } ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder) : zone_(t->zone()), non_patterns_to_rewrite_(t->GetNonPatternList()), + reported_errors_(t->GetReportedErrorList()), + duplicate_finder_(duplicate_finder), invalid_productions_(0), - function_properties_(0), - duplicate_finder_(duplicate_finder) { + function_properties_(0) { + reported_errors_begin_ = reported_errors_end_ = reported_errors_->length(); non_pattern_begin_ = non_patterns_to_rewrite_->length(); } ~ExpressionClassifier() { Discard(); } - bool is_valid(unsigned productions) const { + V8_INLINE bool is_valid(unsigned productions) const { return (invalid_productions_ & productions) == 0; } - DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } + V8_INLINE DuplicateFinder* duplicate_finder() const { + return duplicate_finder_; + } - bool is_valid_expression() const { return is_valid(ExpressionProduction); } + V8_INLINE bool is_valid_expression() const { + return is_valid(ExpressionProduction); + } - bool is_valid_formal_parameter_initializer() const { + V8_INLINE bool is_valid_formal_parameter_initializer() const { return is_valid(FormalParameterInitializerProduction); } - bool is_valid_binding_pattern() const { + V8_INLINE bool is_valid_binding_pattern() const { return is_valid(BindingPatternProduction); } - bool is_valid_assignment_pattern() const { + V8_INLINE bool is_valid_assignment_pattern() const { return is_valid(AssignmentPatternProduction); } - bool is_valid_arrow_formal_parameters() const { + V8_INLINE bool is_valid_arrow_formal_parameters() const { return is_valid(ArrowFormalParametersProduction); } - bool is_valid_formal_parameter_list_without_duplicates() const { + V8_INLINE bool is_valid_formal_parameter_list_without_duplicates() const { return is_valid(DistinctFormalParametersProduction); } // Note: callers should also check // is_valid_formal_parameter_list_without_duplicates(). - bool is_valid_strict_mode_formal_parameters() const { + V8_INLINE bool is_valid_strict_mode_formal_parameters() const { return is_valid(StrictModeFormalParametersProduction); } - bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); } + V8_INLINE bool is_valid_let_pattern() const { + return is_valid(LetPatternProduction); + } - const Error& expression_error() const { return expression_error_; } + V8_INLINE const Error& expression_error() const { + return reported_error(kExpressionProduction); + } - const Error& formal_parameter_initializer_error() const { - return formal_parameter_initializer_error_; + V8_INLINE const Error& formal_parameter_initializer_error() const { + return reported_error(kFormalParameterInitializerProduction); } - const Error& binding_pattern_error() const { return binding_pattern_error_; } + V8_INLINE const Error& binding_pattern_error() const { + return reported_error(kBindingPatternProduction); + } - const Error& assignment_pattern_error() const { - return assignment_pattern_error_; + V8_INLINE const Error& assignment_pattern_error() const { + return reported_error(kAssignmentPatternProduction); } - const Error& arrow_formal_parameters_error() const { - return arrow_formal_parameters_error_; + V8_INLINE const Error& arrow_formal_parameters_error() const { + return reported_error(kArrowFormalParametersProduction); } - const Error& duplicate_formal_parameter_error() const { - return duplicate_formal_parameter_error_; + V8_INLINE const Error& duplicate_formal_parameter_error() const { + return reported_error(kDistinctFormalParametersProduction); } - const Error& strict_mode_formal_parameter_error() const { - return strict_mode_formal_parameter_error_; + V8_INLINE const Error& strict_mode_formal_parameter_error() const { + return reported_error(kStrictModeFormalParametersProduction); } - const Error& let_pattern_error() const { return let_pattern_error_; } + V8_INLINE const Error& let_pattern_error() const { + return reported_error(kLetPatternProduction); + } - bool has_cover_initialized_name() const { + V8_INLINE bool has_cover_initialized_name() const { return !is_valid(CoverInitializedNameProduction); } - const Error& cover_initialized_name_error() const { - return cover_initialized_name_error_; + + V8_INLINE const Error& cover_initialized_name_error() const { + return reported_error(kCoverInitializedNameProduction); } - bool is_simple_parameter_list() const { + V8_INLINE bool is_simple_parameter_list() const { return !(function_properties_ & NonSimpleParameter); } - void RecordNonSimpleParameter() { + V8_INLINE void RecordNonSimpleParameter() { function_properties_ |= NonSimpleParameter; } @@ -156,9 +195,7 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_expression()) return; invalid_productions_ |= ExpressionProduction; - expression_error_.location = loc; - expression_error_.message = message; - expression_error_.arg = arg; + Add(Error(loc, message, kExpressionProduction, arg)); } void RecordExpressionError(const Scanner::Location& loc, @@ -166,10 +203,7 @@ class ExpressionClassifier { ParseErrorType type, const char* arg = nullptr) { if (!is_valid_expression()) return; invalid_productions_ |= ExpressionProduction; - expression_error_.location = loc; - expression_error_.message = message; - expression_error_.arg = arg; - expression_error_.type = type; + Add(Error(loc, message, kExpressionProduction, arg, type)); } void RecordFormalParameterInitializerError(const Scanner::Location& loc, @@ -177,9 +211,7 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_formal_parameter_initializer()) return; invalid_productions_ |= FormalParameterInitializerProduction; - formal_parameter_initializer_error_.location = loc; - formal_parameter_initializer_error_.message = message; - formal_parameter_initializer_error_.arg = arg; + Add(Error(loc, message, kFormalParameterInitializerProduction, arg)); } void RecordBindingPatternError(const Scanner::Location& loc, @@ -187,9 +219,7 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_binding_pattern()) return; invalid_productions_ |= BindingPatternProduction; - binding_pattern_error_.location = loc; - binding_pattern_error_.message = message; - binding_pattern_error_.arg = arg; + Add(Error(loc, message, kBindingPatternProduction, arg)); } void RecordAssignmentPatternError(const Scanner::Location& loc, @@ -197,9 +227,7 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_assignment_pattern()) return; invalid_productions_ |= AssignmentPatternProduction; - assignment_pattern_error_.location = loc; - assignment_pattern_error_.message = message; - assignment_pattern_error_.arg = arg; + Add(Error(loc, message, kAssignmentPatternProduction, arg)); } void RecordPatternError(const Scanner::Location& loc, @@ -214,17 +242,14 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_arrow_formal_parameters()) return; invalid_productions_ |= ArrowFormalParametersProduction; - arrow_formal_parameters_error_.location = loc; - arrow_formal_parameters_error_.message = message; - arrow_formal_parameters_error_.arg = arg; + Add(Error(loc, message, kArrowFormalParametersProduction, arg)); } void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { if (!is_valid_formal_parameter_list_without_duplicates()) return; invalid_productions_ |= DistinctFormalParametersProduction; - duplicate_formal_parameter_error_.location = loc; - duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe; - duplicate_formal_parameter_error_.arg = nullptr; + Add(Error(loc, MessageTemplate::kParamDupe, + kDistinctFormalParametersProduction)); } // Record a binding that would be invalid in strict mode. Confusingly this @@ -235,9 +260,7 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_strict_mode_formal_parameters()) return; invalid_productions_ |= StrictModeFormalParametersProduction; - strict_mode_formal_parameter_error_.location = loc; - strict_mode_formal_parameter_error_.message = message; - strict_mode_formal_parameter_error_.arg = arg; + Add(Error(loc, message, kStrictModeFormalParametersProduction, arg)); } void RecordLetPatternError(const Scanner::Location& loc, @@ -245,9 +268,7 @@ class ExpressionClassifier { const char* arg = nullptr) { if (!is_valid_let_pattern()) return; invalid_productions_ |= LetPatternProduction; - let_pattern_error_.location = loc; - let_pattern_error_.message = message; - let_pattern_error_.arg = arg; + Add(Error(loc, message, kLetPatternProduction, arg)); } void RecordCoverInitializedNameError(const Scanner::Location& loc, @@ -255,76 +276,102 @@ class ExpressionClassifier { const char* arg = nullptr) { if (has_cover_initialized_name()) return; invalid_productions_ |= CoverInitializedNameProduction; - cover_initialized_name_error_.location = loc; - cover_initialized_name_error_.message = message; - cover_initialized_name_error_.arg = arg; + Add(Error(loc, message, kCoverInitializedNameProduction, arg)); } void ForgiveCoverInitializedNameError() { + if (!(invalid_productions_ & CoverInitializedNameProduction)) return; + Error& e = reported_error(kCoverInitializedNameProduction); + e.kind = kUnusedError; invalid_productions_ &= ~CoverInitializedNameProduction; - cover_initialized_name_error_ = Error(); } void ForgiveAssignmentPatternError() { + if (!(invalid_productions_ & AssignmentPatternProduction)) return; + Error& e = reported_error(kAssignmentPatternProduction); + e.kind = kUnusedError; invalid_productions_ &= ~AssignmentPatternProduction; - assignment_pattern_error_ = Error(); } void Accumulate(ExpressionClassifier* inner, unsigned productions = StandardProductions, bool merge_non_patterns = true) { + DCHECK_EQ(inner->reported_errors_, reported_errors_); + DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_); + DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length()); if (merge_non_patterns) MergeNonPatterns(inner); // Propagate errors from inner, but don't overwrite already recorded // errors. unsigned non_arrow_inner_invalid_productions = inner->invalid_productions_ & ~ArrowFormalParametersProduction; - if (non_arrow_inner_invalid_productions == 0) return; - unsigned non_arrow_productions = - productions & ~ArrowFormalParametersProduction; - unsigned errors = - non_arrow_productions & non_arrow_inner_invalid_productions; - errors &= ~invalid_productions_; - if (errors != 0) { - invalid_productions_ |= errors; - if (errors & ExpressionProduction) - expression_error_ = inner->expression_error_; - if (errors & FormalParameterInitializerProduction) - formal_parameter_initializer_error_ = - inner->formal_parameter_initializer_error_; - if (errors & BindingPatternProduction) - binding_pattern_error_ = inner->binding_pattern_error_; - if (errors & AssignmentPatternProduction) - assignment_pattern_error_ = inner->assignment_pattern_error_; - if (errors & DistinctFormalParametersProduction) - duplicate_formal_parameter_error_ = - inner->duplicate_formal_parameter_error_; - if (errors & StrictModeFormalParametersProduction) - strict_mode_formal_parameter_error_ = - inner->strict_mode_formal_parameter_error_; - if (errors & LetPatternProduction) - let_pattern_error_ = inner->let_pattern_error_; - if (errors & CoverInitializedNameProduction) - cover_initialized_name_error_ = inner->cover_initialized_name_error_; - } - - // As an exception to the above, the result continues to be a valid arrow - // formal parameters if the inner expression is a valid binding pattern. - if (productions & ArrowFormalParametersProduction && - is_valid_arrow_formal_parameters()) { - // Also copy function properties if expecting an arrow function - // parameter. - function_properties_ |= inner->function_properties_; - - if (!inner->is_valid_binding_pattern()) { - invalid_productions_ |= ArrowFormalParametersProduction; - arrow_formal_parameters_error_ = inner->binding_pattern_error_; + if (non_arrow_inner_invalid_productions) { + unsigned errors = non_arrow_inner_invalid_productions & productions & + ~invalid_productions_; + // The result will continue to be a valid arrow formal parameters if the + // inner expression is a valid binding pattern. + bool copy_BP_to_AFP = false; + if (productions & ArrowFormalParametersProduction && + is_valid_arrow_formal_parameters()) { + // Also copy function properties if expecting an arrow function + // parameter. + function_properties_ |= inner->function_properties_; + if (!inner->is_valid_binding_pattern()) { + copy_BP_to_AFP = true; + invalid_productions_ |= ArrowFormalParametersProduction; + } + } + // Traverse the list of errors reported by the inner classifier + // to copy what's necessary. + if (errors != 0 || copy_BP_to_AFP) { + invalid_productions_ |= errors; + int binding_pattern_index = inner->reported_errors_end_; + for (int i = inner->reported_errors_begin_; + i < inner->reported_errors_end_; i++) { + int k = reported_errors_->at(i).kind; + if (errors & (1 << k)) Copy(i); + // Check if it's a BP error that has to be copied to an AFP error. + if (k == kBindingPatternProduction && copy_BP_to_AFP) { + if (reported_errors_end_ <= i) { + // If the BP error itself has not already been copied, + // copy it now and change it to an AFP error. + Copy(i); + reported_errors_->at(reported_errors_end_-1).kind = + kArrowFormalParametersProduction; + } else { + // Otherwise, if the BP error was already copied, keep its + // position and wait until the end of the traversal. + DCHECK_EQ(reported_errors_end_, i+1); + binding_pattern_index = i; + } + } + } + // Do we still have to copy the BP error to an AFP error? + if (binding_pattern_index < inner->reported_errors_end_) { + // If there's still unused space in the list of the inner + // classifier, copy it there, otherwise add it to the end + // of the list. + if (reported_errors_end_ < inner->reported_errors_end_) + Copy(binding_pattern_index); + else + Add(reported_errors_->at(binding_pattern_index)); + reported_errors_->at(reported_errors_end_-1).kind = + kArrowFormalParametersProduction; + } } } + reported_errors_->Rewind(reported_errors_end_); + inner->reported_errors_begin_ = inner->reported_errors_end_ = + reported_errors_end_; } V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } V8_INLINE void Discard() { + if (reported_errors_end_ == reported_errors_->length()) { + reported_errors_->Rewind(reported_errors_begin_); + reported_errors_end_ = reported_errors_begin_; + } + DCHECK_EQ(reported_errors_begin_, reported_errors_end_); DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); non_patterns_to_rewrite_->Rewind(non_pattern_begin_); } @@ -335,24 +382,70 @@ class ExpressionClassifier { } private: + V8_INLINE Error& reported_error(ErrorKind kind) const { + if (invalid_productions_ & (1 << kind)) { + for (int i = reported_errors_begin_; i < reported_errors_end_; i++) { + if (reported_errors_->at(i).kind == kind) + return reported_errors_->at(i); + } + UNREACHABLE(); + } + // We should only be looking for an error when we know that one has + // been reported. But we're not... So this is to make sure we have + // the same behaviour. + static Error none; + return none; + } + + // Adds e to the end of the list of reported errors for this classifier. + // It is expected that this classifier is the last one in the stack. + V8_INLINE void Add(const Error& e) { + DCHECK_EQ(reported_errors_end_, reported_errors_->length()); + reported_errors_->Add(e, zone_); + reported_errors_end_++; + } + + // Copies the error at position i of the list of reported errors, so that + // it becomes the last error reported for this classifier. Position i + // could be either after the existing errors of this classifier (i.e., + // in an inner classifier) or it could be an existing error (in case a + // copy is needed). + V8_INLINE void Copy(int i) { + DCHECK_LE(reported_errors_end_, i); + DCHECK_LT(i, reported_errors_->length()); + if (reported_errors_end_ != i) + reported_errors_->at(reported_errors_end_) = reported_errors_->at(i); + reported_errors_end_++; + } + Zone* zone_; ZoneList* non_patterns_to_rewrite_; - int non_pattern_begin_; - unsigned invalid_productions_; - unsigned function_properties_; - Error expression_error_; - Error formal_parameter_initializer_error_; - Error binding_pattern_error_; - Error assignment_pattern_error_; - Error arrow_formal_parameters_error_; - Error duplicate_formal_parameter_error_; - Error strict_mode_formal_parameter_error_; - Error let_pattern_error_; - Error cover_initialized_name_error_; + ZoneList* reported_errors_; DuplicateFinder* duplicate_finder_; + // The uint16_t for non_pattern_begin_ will not be enough in the case, + // e.g., of an array literal containing more than 64K inner array + // literals with spreads, as in: + // var N=65536; eval("var x=[];" + "[" + "[...x],".repeat(N) + "].length"); + // An implementation limit error in ParserBase::AddNonPatternForRewriting + // will be triggered in this case. + uint16_t non_pattern_begin_; + unsigned invalid_productions_ : 14; + unsigned function_properties_ : 2; + // The uint16_t for reported_errors_begin_ and reported_errors_end_ will + // not be enough in the case of a long series of expressions using nested + // classifiers, e.g., a long sequence of assignments, as in: + // literals with spreads, as in: + // var N=65536; eval("var x;" + "x=".repeat(N) + "42"); + // This should not be a problem, as such things currently fail with a + // stack overflow while parsing. + uint16_t reported_errors_begin_; + uint16_t reported_errors_end_; }; +#undef ERROR_CODES + + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index dde6b1dd863627..0eb19ceb83b13a 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -247,8 +247,8 @@ class ParserBase : public Traits { typename Traits::Type::Factory* factory() { return factory_; } - const List& destructuring_assignments_to_rewrite() - const { + const ZoneList& + destructuring_assignments_to_rewrite() const { return destructuring_assignments_to_rewrite_; } @@ -268,19 +268,26 @@ class ParserBase : public Traits { collect_expressions_in_tail_position_ = collect; } + ZoneList* GetReportedErrorList() { + return &reported_errors_; + } + ZoneList* non_patterns_to_rewrite() { return &non_patterns_to_rewrite_; } private: void AddDestructuringAssignment(DestructuringAssignment pair) { - destructuring_assignments_to_rewrite_.Add(pair); + destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone()); } V8_INLINE Scope* scope() { return *scope_stack_; } - void AddNonPatternForRewriting(ExpressionT expr) { + void AddNonPatternForRewriting(ExpressionT expr, bool* ok) { non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); + if (non_patterns_to_rewrite_.length() >= + std::numeric_limits::max()) + *ok = false; } // Used to assign an index to each literal that needs materialization in @@ -311,11 +318,13 @@ class ParserBase : public Traits { Scope** scope_stack_; Scope* outer_scope_; - List destructuring_assignments_to_rewrite_; + ZoneList destructuring_assignments_to_rewrite_; List expressions_in_tail_position_; bool collect_expressions_in_tail_position_; ZoneList non_patterns_to_rewrite_; + ZoneList reported_errors_; + typename Traits::Type::Factory* factory_; friend class ParserTraits; @@ -945,8 +954,10 @@ ParserBase::FunctionState::FunctionState( outer_function_state_(*function_state_stack), scope_stack_(scope_stack), outer_scope_(*scope_stack), + destructuring_assignments_to_rewrite_(16, scope->zone()), collect_expressions_in_tail_position_(true), non_patterns_to_rewrite_(0, scope->zone()), + reported_errors_(16, scope->zone()), factory_(factory) { *scope_stack_ = scope; *function_state_stack = this; @@ -1274,12 +1285,11 @@ ParserBase::ParsePrimaryExpression(ExpressionClassifier* classifier, // Parentheses are not valid on the LHS of a BindingPattern, so we use the // is_valid_binding_pattern() check to detect multiple levels of // parenthesization. - if (!classifier->is_valid_binding_pattern()) { - ArrowFormalParametersUnexpectedToken(classifier); - } + bool pattern_error = !classifier->is_valid_binding_pattern(); classifier->RecordPatternError(scanner()->peek_location(), MessageTemplate::kUnexpectedToken, Token::String(Token::LPAREN)); + if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier); Consume(Token::LPAREN); if (Check(Token::RPAREN)) { // ()=>x. The continuation that looks for the => is in @@ -1416,6 +1426,7 @@ typename ParserBase::ExpressionT ParserBase::ParseExpression( seen_rest = is_rest = true; } int pos = position(), expr_pos = peek_position(); + ExpressionClassifier binding_classifier(this); ExpressionT right = this->ParseAssignmentExpression( accept_IN, &binding_classifier, CHECK_OK); classifier->Accumulate(&binding_classifier, @@ -1501,7 +1512,15 @@ typename ParserBase::ExpressionT ParserBase::ParseArrayLiteral( literal_index, pos); if (first_spread_index >= 0) { result = factory()->NewRewritableExpression(result); - Traits::QueueNonPatternForRewriting(result); + Traits::QueueNonPatternForRewriting(result, ok); + if (!*ok) { + // If the non-pattern rewriting mechanism is used in the future for + // rewriting other things than spreads, this error message will have + // to change. Also, this error message will never appear while pre- + // parsing (this is OK, as it is an implementation limitation). + ReportMessage(MessageTemplate::kTooManySpreads); + return this->EmptyExpression(); + } } return result; } @@ -1907,9 +1926,7 @@ ParserBase::ParseAssignmentExpression(bool accept_IN, ExpressionT expression = this->ParseConditionalExpression( accept_IN, &arrow_formals_classifier, CHECK_OK); if (peek() == Token::ARROW) { - classifier->RecordPatternError(scanner()->peek_location(), - MessageTemplate::kUnexpectedToken, - Token::String(Token::ARROW)); + Scanner::Location arrow_loc = scanner()->peek_location(); ValidateArrowFormalParameters(&arrow_formals_classifier, expression, parenthesized_formals, CHECK_OK); // This reads strangely, but is correct: it checks whether any @@ -1944,6 +1961,10 @@ ParserBase::ParseAssignmentExpression(bool accept_IN, } expression = this->ParseArrowFunctionLiteral( accept_IN, parameters, arrow_formals_classifier, CHECK_OK); + arrow_formals_classifier.Discard(); + classifier->RecordPatternError(arrow_loc, + MessageTemplate::kUnexpectedToken, + Token::String(Token::ARROW)); if (fni_ != nullptr) fni_->Infer(); @@ -2113,8 +2134,8 @@ ParserBase::ParseConditionalExpression(bool accept_IN, this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); if (peek() != Token::CONDITIONAL) return expression; Traits::RewriteNonPattern(classifier, CHECK_OK); - ArrowFormalParametersUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier); + ArrowFormalParametersUnexpectedToken(classifier); Consume(Token::CONDITIONAL); // In parsing the first assignment expression in conditional // expressions we always accept the 'in' keyword; see ECMA-262, diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc index 48837f0ad62e27..bbb75de3ea3dab 100644 --- a/deps/v8/src/parsing/parser.cc +++ b/deps/v8/src/parsing/parser.cc @@ -2439,7 +2439,6 @@ Statement* Parser::ParseExpressionOrLabelledStatement( ReportUnexpectedToken(Next()); *ok = false; return nullptr; - default: break; } @@ -5405,13 +5404,19 @@ void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, } -Zone* ParserTraits::zone() const { - return parser_->function_state_->scope()->zone(); +ZoneList* ParserTraits::GetNonPatternList() const { + return parser_->function_state_->non_patterns_to_rewrite(); } -ZoneList* ParserTraits::GetNonPatternList() const { - return parser_->function_state_->non_patterns_to_rewrite(); +ZoneList* +ParserTraits::GetReportedErrorList() const { + return parser_->function_state_->GetReportedErrorList(); +} + + +Zone* ParserTraits::zone() const { + return parser_->function_state_->scope()->zone(); } @@ -5628,9 +5633,9 @@ void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { } -void ParserTraits::QueueNonPatternForRewriting(Expression* expr) { +void ParserTraits::QueueNonPatternForRewriting(Expression* expr, bool* ok) { DCHECK(expr->IsRewritableExpression()); - parser_->function_state_->AddNonPatternForRewriting(expr); + parser_->function_state_->AddNonPatternForRewriting(expr, ok); } diff --git a/deps/v8/src/parsing/parser.h b/deps/v8/src/parsing/parser.h index 5df11e77a01337..a62ffbe72b3032 100644 --- a/deps/v8/src/parsing/parser.h +++ b/deps/v8/src/parsing/parser.h @@ -646,7 +646,7 @@ class ParserTraits { V8_INLINE void QueueDestructuringAssignmentForRewriting( Expression* assignment); - V8_INLINE void QueueNonPatternForRewriting(Expression* expr); + V8_INLINE void QueueNonPatternForRewriting(Expression* expr, bool* ok); void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, const AstRawString* name); @@ -658,6 +658,8 @@ class ParserTraits { V8_INLINE void RewriteNonPattern(Type::ExpressionClassifier* classifier, bool* ok); + V8_INLINE ZoneList* + GetReportedErrorList() const; V8_INLINE Zone* zone() const; V8_INLINE ZoneList* GetNonPatternList() const; diff --git a/deps/v8/src/parsing/preparser.h b/deps/v8/src/parsing/preparser.h index f2f69517b25b42..1c6c7e6d6fed45 100644 --- a/deps/v8/src/parsing/preparser.h +++ b/deps/v8/src/parsing/preparser.h @@ -916,7 +916,7 @@ class PreParserTraits { } inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {} - inline void QueueNonPatternForRewriting(PreParserExpression) {} + inline void QueueNonPatternForRewriting(PreParserExpression, bool* ok) {} void SetFunctionNameFromPropertyName(PreParserExpression, PreParserIdentifier) {} @@ -926,6 +926,8 @@ class PreParserTraits { inline void RewriteNonPattern(Type::ExpressionClassifier* classifier, bool* ok); + V8_INLINE ZoneList* + GetReportedErrorList() const; V8_INLINE Zone* zone() const; V8_INLINE ZoneList* GetNonPatternList() const; @@ -1126,13 +1128,19 @@ void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, } -Zone* PreParserTraits::zone() const { - return pre_parser_->function_state_->scope()->zone(); +ZoneList* PreParserTraits::GetNonPatternList() const { + return pre_parser_->function_state_->non_patterns_to_rewrite(); } -ZoneList* PreParserTraits::GetNonPatternList() const { - return pre_parser_->function_state_->non_patterns_to_rewrite(); +ZoneList* +PreParserTraits::GetReportedErrorList() const { + return pre_parser_->function_state_->GetReportedErrorList(); +} + + +Zone* PreParserTraits::zone() const { + return pre_parser_->function_state_->scope()->zone(); } diff --git a/deps/v8/src/ppc/builtins-ppc.cc b/deps/v8/src/ppc/builtins-ppc.cc index 884afedb21b789..bc31d593e3847e 100644 --- a/deps/v8/src/ppc/builtins-ppc.cc +++ b/deps/v8/src/ppc/builtins-ppc.cc @@ -605,15 +605,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // r3: number of arguments // r4: constructor function // r6: new target - if (is_api_function) { - __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); - Handle code = masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(r3); - __ InvokeFunction(r4, r6, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + + ParameterCount actual(r3); + __ InvokeFunction(r4, r6, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/ppc/code-stubs-ppc.cc b/deps/v8/src/ppc/code-stubs-ppc.cc index 0671f990e8c5a6..98425fc6ad5416 100644 --- a/deps/v8/src/ppc/code-stubs-ppc.cc +++ b/deps/v8/src/ppc/code-stubs-ppc.cc @@ -5623,7 +5623,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); // context save __ push(context); diff --git a/deps/v8/src/s390/builtins-s390.cc b/deps/v8/src/s390/builtins-s390.cc index 12b52c123cfd8c..5c871beb5000df 100644 --- a/deps/v8/src/s390/builtins-s390.cc +++ b/deps/v8/src/s390/builtins-s390.cc @@ -596,15 +596,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // r2: number of arguments // r3: constructor function // r5: new target - if (is_api_function) { - __ LoadP(cp, FieldMemOperand(r3, JSFunction::kContextOffset)); - Handle code = masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(r2); - __ InvokeFunction(r3, r5, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + + ParameterCount actual(r2); + __ InvokeFunction(r3, r5, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/s390/code-stubs-s390.cc b/deps/v8/src/s390/code-stubs-s390.cc index 1c7d27b5caec91..81aae6446a1d7b 100644 --- a/deps/v8/src/s390/code-stubs-s390.cc +++ b/deps/v8/src/s390/code-stubs-s390.cc @@ -5533,7 +5533,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); // context save __ push(context); diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc index 316378348c20fd..be3563f87b8a9e 100644 --- a/deps/v8/src/x64/builtins-x64.cc +++ b/deps/v8/src/x64/builtins-x64.cc @@ -185,16 +185,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ j(greater_equal, &loop); // Call the function. - if (is_api_function) { - __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ Call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(rax); - __ InvokeFunction(rdi, rdx, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(rax); + __ InvokeFunction(rdi, rdx, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc index e737801f588f99..a96e31f6a23ca6 100644 --- a/deps/v8/src/x64/code-stubs-x64.cc +++ b/deps/v8/src/x64/code-stubs-x64.cc @@ -5404,10 +5404,14 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); __ PopReturnAddressTo(return_address); + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); + // context save __ Push(context); diff --git a/deps/v8/src/x87/builtins-x87.cc b/deps/v8/src/x87/builtins-x87.cc index 9e13172c852ef5..f4a6986e03e14b 100644 --- a/deps/v8/src/x87/builtins-x87.cc +++ b/deps/v8/src/x87/builtins-x87.cc @@ -186,16 +186,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ j(greater_equal, &loop); // Call the function. - if (is_api_function) { - __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); - Handle code = - masm->isolate()->builtins()->HandleApiCallConstruct(); - __ call(code, RelocInfo::CODE_TARGET); - } else { - ParameterCount actual(eax); - __ InvokeFunction(edi, edx, actual, CALL_FUNCTION, - CheckDebugStepCallWrapper()); - } + ParameterCount actual(eax); + __ InvokeFunction(edi, edx, actual, CALL_FUNCTION, + CheckDebugStepCallWrapper()); // Store offset of return address for deoptimizer. if (create_implicit_receiver && !is_api_function) { diff --git a/deps/v8/src/x87/code-stubs-x87.cc b/deps/v8/src/x87/code-stubs-x87.cc index 71adfd353110eb..4432bd98fab0b3 100644 --- a/deps/v8/src/x87/code-stubs-x87.cc +++ b/deps/v8/src/x87/code-stubs-x87.cc @@ -5354,9 +5354,14 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) { STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); STATIC_ASSERT(FCA::kIsolateIndex == 1); STATIC_ASSERT(FCA::kHolderIndex == 0); - STATIC_ASSERT(FCA::kArgsLength == 7); + STATIC_ASSERT(FCA::kNewTargetIndex == 7); + STATIC_ASSERT(FCA::kArgsLength == 8); __ pop(return_address); + + // new target + __ PushRoot(Heap::kUndefinedValueRootIndex); + // context save. __ push(context); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 220b0cd07784cb..e27f469e0c0aef 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -2142,6 +2142,95 @@ THREADED_TEST(TestObjectTemplateInheritedWithPrototype2) { Constructor_GetFunction_New); } +THREADED_TEST(TestObjectTemplateClassInheritance) { + LocalContext env; + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + + Local fun_A = v8::FunctionTemplate::New(isolate); + fun_A->SetClassName(v8_str("A")); + + Local templ_A = fun_A->InstanceTemplate(); + templ_A->SetNativeDataProperty(v8_str("nirk"), GetNirk); + templ_A->SetNativeDataProperty(v8_str("rino"), GetRino); + + Local fun_B = v8::FunctionTemplate::New(isolate); + v8::Local class_name = v8_str("B"); + fun_B->SetClassName(class_name); + fun_B->Inherit(fun_A); + + v8::Local subclass_name = v8_str("C"); + v8::Local b_proto; + v8::Local c_proto; + // Perform several iterations to make sure the cache doesn't break + // subclassing. + for (int i = 0; i < 3; i++) { + Local function_B = + fun_B->GetFunction(env.local()).ToLocalChecked(); + if (i == 0) { + CHECK(env->Global()->Set(env.local(), class_name, function_B).FromJust()); + CompileRun("class C extends B {}"); + b_proto = + CompileRun("B.prototype")->ToObject(env.local()).ToLocalChecked(); + c_proto = + CompileRun("C.prototype")->ToObject(env.local()).ToLocalChecked(); + CHECK(b_proto->Equals(env.local(), c_proto->GetPrototype()).FromJust()); + } + Local instance = + CompileRun("new C()")->ToObject(env.local()).ToLocalChecked(); + CHECK(c_proto->Equals(env.local(), instance->GetPrototype()).FromJust()); + + CHECK(subclass_name->StrictEquals(instance->GetConstructorName())); + CHECK(env->Global()->Set(env.local(), v8_str("o"), instance).FromJust()); + + CHECK_EQ(900, CompileRun("o.nirk")->IntegerValue(env.local()).FromJust()); + CHECK_EQ(560, CompileRun("o.rino")->IntegerValue(env.local()).FromJust()); + } +} + +static void NamedPropertyGetterWhichReturns42( + Local name, const v8::PropertyCallbackInfo& info) { + info.GetReturnValue().Set(v8_num(42)); +} + +THREADED_TEST(TestObjectTemplateReflectConstruct) { + LocalContext env; + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + + Local fun_B = v8::FunctionTemplate::New(isolate); + fun_B->InstanceTemplate()->SetHandler( + v8::NamedPropertyHandlerConfiguration(NamedPropertyGetterWhichReturns42)); + v8::Local class_name = v8_str("B"); + fun_B->SetClassName(class_name); + + v8::Local subclass_name = v8_str("C"); + v8::Local b_proto; + v8::Local c_proto; + // Perform several iterations to make sure the cache doesn't break + // subclassing. + for (int i = 0; i < 3; i++) { + Local function_B = + fun_B->GetFunction(env.local()).ToLocalChecked(); + if (i == 0) { + CHECK(env->Global()->Set(env.local(), class_name, function_B).FromJust()); + CompileRun("function C() {}"); + c_proto = + CompileRun("C.prototype")->ToObject(env.local()).ToLocalChecked(); + } + Local instance = CompileRun("Reflect.construct(B, [], C)") + ->ToObject(env.local()) + .ToLocalChecked(); + CHECK(c_proto->Equals(env.local(), instance->GetPrototype()).FromJust()); + + CHECK(subclass_name->StrictEquals(instance->GetConstructorName())); + CHECK(env->Global()->Set(env.local(), v8_str("o"), instance).FromJust()); + + CHECK_EQ(42, CompileRun("o.nirk")->IntegerValue(env.local()).FromJust()); + CHECK_EQ(42, CompileRun("o.rino")->IntegerValue(env.local()).FromJust()); + } +} + static void GetFlabby(const v8::FunctionCallbackInfo& args) { ApiTestFuzzer::Fuzz(); args.GetReturnValue().Set(v8_num(17.2)); @@ -18728,12 +18817,6 @@ TEST(SetterOnConstructorPrototype) { } -static void NamedPropertyGetterWhichReturns42( - Local name, const v8::PropertyCallbackInfo& info) { - info.GetReturnValue().Set(v8_num(42)); -} - - static void NamedPropertySetterWhichSetsYOnThisTo23( Local name, Local value, const v8::PropertyCallbackInfo& info) { diff --git a/deps/v8/test/mjsunit/regress/regress-666046.js b/deps/v8/test/mjsunit/regress/regress-666046.js new file mode 100644 index 00000000000000..b4615383e0bdae --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-666046.js @@ -0,0 +1,57 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-gc + +function P() { + this.a0 = {}; + this.a1 = {}; + this.a2 = {}; + this.a3 = {}; + this.a4 = {}; +} + +function A() { +} + +var proto = new P(); +A.prototype = proto; + +function foo(o) { + return o.a0; +} + +// Ensure |proto| is in old space. +gc(); +gc(); +gc(); + +// Ensure |proto| is marked as "should be fast". +var o = new A(); +foo(o); +foo(o); +foo(o); +assertTrue(%HasFastProperties(proto)); + +// Contruct a double value that looks like a tagged pointer. +var buffer = new ArrayBuffer(8); +var int32view = new Int32Array(buffer); +var float64view = new Float64Array(buffer); +int32view[0] = int32view[1] = 0x40000001; +var boom = float64view[0]; + + +// Write new space object. +proto.a4 = {a: 0}; +// Immediately delete the field. +delete proto.a4; + +// |proto| must sill be fast. +assertTrue(%HasFastProperties(proto)); + +// Add a double field instead of deleted a4 that looks like a tagged pointer. +proto.boom = boom; + +// Boom! +gc(); diff --git a/doc/STYLE_GUIDE.md b/doc/STYLE_GUIDE.md new file mode 100644 index 00000000000000..10f26421a4ceb5 --- /dev/null +++ b/doc/STYLE_GUIDE.md @@ -0,0 +1,63 @@ +# Style Guide + +* Documents are written in markdown files. +* Those files should be written in **`lowercase-with-dashes.md`.** + * Underscores in filenames are allowed only when they are present in the + topic the document will describe (e.g., `child_process`.) + * Filenames should be **lowercase**. + * Some files, such as top-level markdown files, are exceptions. + * Older files may use the `.markdown` extension. These may be ported to `.md` + at will. **Prefer `.md` for all new documents.** +* Documents should be word-wrapped at 80 characters. +* The formatting described in `.editorconfig` is preferred. + * A [plugin][] is available for some editors to automatically apply these rules. +* Mechanical issues, like spelling and grammar, should be identified by tools, + insofar as is possible. If not caught by a tool, they should be pointed out by + human reviewers. +* American English spelling is preferred. "Capitalize" vs. "Capitalise", + "color" vs. "colour", etc. +* Though controversial, the [Oxford comma][] is preferred for clarity's sake. +* Generally avoid personal pronouns in reference documentation ("I", "you", + "we".) + * Pronouns are acceptable in more colloquial documentation, like guides. + * Use **gender-neutral pronouns** and **mass nouns**. Non-comprehensive + examples: + * **OK**: "they", "their", "them", "folks", "people", "developers", "cats" + * **NOT OK**: "his", "hers", "him", "her", "guys", "dudes". +* When combining wrapping elements (parentheses and quotes), terminal + punctuation should be placed: + * Inside the wrapping element if the wrapping element contains a complete + clause — a subject, verb, and an object. + * Outside of the wrapping element if the wrapping element contains only a + fragment of a clause. +* Place end-of-sentence punctuation inside wrapping elements — periods go + inside parentheses and quotes, not after. +* Documents must start with a level-one heading. An example document will be + linked here eventually. +* Prefer affixing links to inlining links — prefer `[a link][]` to + `[a link](http://example.com)`. +* When documenting APIs, note the version the API was introduced in at + the end of the section. If an API has been deprecated, also note the first + version that the API appeared deprecated in. +* When using dashes, use emdashes ("—", Ctrl+Alt+"-" on OSX) surrounded by + spaces, per the New York Times usage. +* Including assets: + * If you wish to add an illustration or full program, add it to the + appropriate sub-directory in the `assets/` dir. + * Link to it like so: `[Asset](/assets/{subdir}/{filename})` for file-based + assets, and `![Asset](/assets/{subdir}/{filename})` for image-based assets. + * For illustrations, prefer SVG to other assets. When SVG is not feasible, + please keep a close eye on the filesize of the asset you're introducing. +* For code blocks: + * Use language aware fences. ("```js") + * Code need not be complete — treat code blocks as an illustration or aid to + your point, not as complete running programs. If a complete running program + is necessary, include it as an asset in `assets/code-examples` and link to + it. +* When using underscores, asterisks and backticks please use proper escaping (**\\\_**, **\\\*** and **\\\`** instead of **\_**, **\*** and **\`**) +* References to constructor functions should use PascalCase +* References to constructor instances should be camelCased +* References to methods should be used with parenthesis: `socket.end()` instead of `socket.end` + +[plugin]: http://editorconfig.org/#download +[Oxford comma]: https://en.wikipedia.org/wiki/Serial_comma diff --git a/doc/api/addons.md b/doc/api/addons.md index 44dc69915c428f..58f029fb20e98b 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -1,4 +1,4 @@ -# Addons +# C/C++ Addons Node.js Addons are dynamically-linked shared objects, written in C or C++, that can be loaded into Node.js using the [`require()`][require] function, and used @@ -1110,7 +1110,7 @@ const addon = require('./build/Release/addon'); [bindings]: https://github.com/TooTallNate/node-bindings [download]: https://github.com/nodejs/node-addon-examples -[Embedder's Guide]: https://developers.google.com/v8/embed +[Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide [examples]: https://github.com/nodejs/nan/tree/master/examples/ [installation instructions]: https://github.com/nodejs/node-gyp#installation [libuv]: https://github.com/libuv/libuv diff --git a/doc/api/assert.md b/doc/api/assert.md index 3db5f676886ca8..313b77cfbf149e 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -1,21 +1,16 @@ # Assert -> Stability: 3 - Locked +> Stability: 2 - Stable The `assert` module provides a simple set of assertion tests that can be used to -test invariants. The module is intended for internal use by Node.js, but can be -used in application code via `require('assert')`. However, `assert` is not a -testing framework, and is not intended to be used as a general purpose assertion -library. - -The API for the `assert` module is [Locked][]. This means that there will be no -additions or changes to any of the methods implemented and exposed by -the module. +test invariants. ## assert(value[, message]) +* `value` {any} +* `message` {any} An alias of [`assert.ok()`][] . @@ -38,6 +33,9 @@ assert(false, 'it\'s false'); +* `actual` {any} +* `expected` {any} +* `message` {any} Tests for deep equality between the `actual` and `expected` parameters. Primitive values are compared with the equal comparison operator ( `==` ). @@ -99,6 +97,9 @@ parameter is undefined, a default error message is assigned. +* `actual` {any} +* `expected` {any} +* `message` {any} Generally identical to `assert.deepEqual()` with two exceptions. First, primitive values are compared using the strict equality operator ( `===` ). @@ -123,6 +124,9 @@ parameter is undefined, a default error message is assigned. +* `block` {Function} +* `error` {RegExp|Function} +* `message` {any} Asserts that the function `block` does not throw an error. See [`assert.throws()`][] for more details. @@ -178,6 +182,9 @@ assert.doesNotThrow( +* `actual` {any} +* `expected` {any} +* `message` {any} Tests shallow, coercive equality between the `actual` and `expected` parameters using the equal comparison operator ( `==` ). @@ -204,6 +211,10 @@ parameter is undefined, a default error message is assigned. +* `actual` {any} +* `expected` {any} +* `message` {any} +* `operator` {String} Throws an `AssertionError`. If `message` is falsy, the error message is set as the values of `actual` and `expected` separated by the provided `operator`. @@ -223,6 +234,7 @@ assert.fail(1, 2, 'whoops', '>'); +* `value` {any} Throws `value` if `value` is truthy. This is useful when testing the `error` argument in callbacks. @@ -244,6 +256,9 @@ assert.ifError(new Error()); +* `actual` {any} +* `expected` {any} +* `message` {any} Tests for any deep inequality. Opposite of [`assert.deepEqual()`][]. @@ -288,6 +303,9 @@ parameter is undefined, a default error message is assigned. +* `actual` {any} +* `expected` {any} +* `message` {any} Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][]. @@ -309,6 +327,9 @@ the `message` parameter is undefined, a default error message is assigned. +* `actual` {any} +* `expected` {any} +* `message` {any} Tests shallow, coercive inequality with the not equal comparison operator ( `!=` ). @@ -334,6 +355,9 @@ parameter is undefined, a default error message is assigned. +* `actual` {any} +* `expected` {any} +* `message` {any} Tests strict inequality as determined by the strict not equal operator ( `!==` ). @@ -359,6 +383,8 @@ If the values are strictly equal, an `AssertionError` is thrown with a +* `value` {any} +* `message` {any} Tests if `value` is truthy. It is equivalent to `assert.equal(!!value, true, message)`. @@ -386,6 +412,9 @@ assert.ok(false, 'it\'s false'); +* `actual` {any} +* `expected` {any} +* `message` {any} Tests strict equality as determined by the strict equality operator ( `===` ). @@ -410,6 +439,9 @@ If the values are not strictly equal, an `AssertionError` is thrown with a +* `block` {Function} +* `error` {RegExp|Function} +* `message` {any} Expects the function `block` to throw an error. @@ -469,7 +501,6 @@ assert.throws(myFunction, 'missing foo', 'did not throw with expected message'); assert.throws(myFunction, /missing foo/, 'did not throw with expected message'); ``` -[Locked]: documentation.html#documentation_stability_index [`assert.deepEqual()`]: #assert_assert_deepequal_actual_expected_message [`assert.deepStrictEqual()`]: #assert_assert_deepstrictequal_actual_expected_message [`assert.ok()`]: #assert_assert_ok_value_message diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 566d4484c7125c..a33c214daeff29 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -282,7 +282,7 @@ const buf = Buffer.from([1, 2, 3]); // 1 // 2 // 3 -for (var b of buf) { +for (const b of buf) { console.log(b); } ``` @@ -404,14 +404,14 @@ are unknown and *could contain sensitive data*. Use Example: ```js -const buf = new Buffer(5); +const buf = new Buffer(10); -// Prints: (contents may vary): +// Prints: (contents may vary): console.log(buf); buf.fill(0); -// Prints: +// Prints: console.log(buf); ``` @@ -523,14 +523,14 @@ initialized*. The contents of the newly created `Buffer` are unknown and Example: ```js -const buf = Buffer.allocUnsafe(5); +const buf = Buffer.allocUnsafe(10); -// Prints: (contents may vary): +// Prints: (contents may vary): console.log(buf); buf.fill(0); -// Prints: +// Prints: console.log(buf); ``` @@ -618,6 +618,10 @@ Returns the actual byte length of a string. This is not the same as [`String.prototype.length`] since that returns the number of *characters* in a string. +*Note* that for `'base64'` and `'hex'`, this function assumes valid input. For +strings that contain non-Base64/Hex-encoded data (e.g. whitespace), the return +value might be greater than the length of a `Buffer` created from the string. + Example: ```js @@ -961,7 +965,7 @@ A `RangeError` will be thrown if: `targetStart < 0`, `sourceStart < 0`, added: v0.1.90 --> -* `target` {Buffer} A `Buffer` to copy into. +* `target` {Buffer|Uint8Array} A `Buffer` or [`Uint8Array`] to copy into. * `targetStart` {Integer} The offset within `target` at which to begin copying to. **Default:** `0` * `sourceStart` {Integer} The offset within `buf` at which to begin copying from. @@ -997,7 +1001,7 @@ overlapping region within the same `Buffer` ```js const buf = Buffer.allocUnsafe(26); -for (var i = 0 ; i < 26 ; i++) { +for (let i = 0 ; i < 26 ; i++) { // 97 is the decimal ASCII value for 'a' buf[i] = i + 97; } @@ -1030,7 +1034,7 @@ const buf = Buffer.from('buffer'); // [3, 102] // [4, 101] // [5, 114] -for (var pair of buf.entries()) { +for (const pair of buf.entries()) { console.log(pair); } ``` @@ -1124,7 +1128,7 @@ Examples: const buf = Buffer.from('this is a buffer'); // Prints: 0 -console.log(buf.indexOf('this'))); +console.log(buf.indexOf('this')); // Prints: 2 console.log(buf.indexOf('is')); @@ -1152,6 +1156,30 @@ console.log(utf16Buffer.indexOf('\u03a3', 0, 'ucs2')); console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2')); ``` +If `value` is not a string, number, or `Buffer`, this method will throw a +`TypeError`. If `value` is a number, it will be coerced to a valid byte value, +an integer between 0 and 255. + +If `byteOffset` is not a number, it will be coerced to a number. Any arguments +that coerce to `NaN` or 0, like `{}`, `[]`, `null` or `undefined`, will search +the whole buffer. This behavior matches [`String#indexOf()`]. + +```js +const b = Buffer.from('abcdef'); + +// Passing a value that's a number, but not a valid byte +// Prints: 2, equivalent to searching for 99 or 'c' +console.log(b.indexOf(99.9)); +console.log(b.indexOf(256 + 99)); + +// Passing a byteOffset that coerces to NaN or 0 +// Prints: 1, searching the whole buffer +console.log(b.indexOf('b', undefined)); +console.log(b.indexOf('b', {})); +console.log(b.indexOf('b', null)); +console.log(b.indexOf('b', [])); +``` + ### buf.includes(value[, byteOffset][, encoding]) * `value` {String | Buffer | Integer} What to search for -* `byteOffset` {Integer} Where to begin searching in `buf` (not inclusive). - **Default:** [`buf.length`] +* `byteOffset` {Integer} Where to begin searching in `buf`. + **Default:** [`buf.length`]` - 1` * `encoding` {String} If `value` is a string, this is its encoding. **Default:** `'utf8'` * Returns: {Integer} The index of the last occurrence of `value` in `buf` or `-1` @@ -1266,12 +1294,39 @@ console.log(buf.lastIndexOf('buffer', 4)); const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); // Prints: 6 -console.log(utf16Buffer.lastIndexOf('\u03a3', null, 'ucs2')); +console.log(utf16Buffer.lastIndexOf('\u03a3', undefined, 'ucs2')); // Prints: 4 console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2')); ``` +If `value` is not a string, number, or `Buffer`, this method will throw a +`TypeError`. If `value` is a number, it will be coerced to a valid byte value, +an integer between 0 and 255. + +If `byteOffset` is not a number, it will be coerced to a number. Any arguments +that coerce to `NaN`, like `{}` or `undefined`, will search the whole buffer. +This behavior matches [`String#lastIndexOf()`]. + +```js +const b = Buffer.from('abcdef'); + +// Passing a value that's a number, but not a valid byte +// Prints: 2, equivalent to searching for 99 or 'c' +console.log(b.lastIndexOf(99.9)); +console.log(b.lastIndexOf(256 + 99)); + +// Passing a byteOffset that coerces to NaN +// Prints: 1, searching the whole buffer +console.log(b.lastIndexOf('b', undefined)); +console.log(b.lastIndexOf('b', {})); + +// Passing a byteOffset that coerces to 0 +// Prints: -1, equivalent to passing 0 +console.log(b.lastIndexOf('b', null)); +console.log(b.lastIndexOf('b', [])); +``` + ### buf.length @@ -79,7 +69,7 @@ const Console = console.Console; Creates a new `Console` by passing one or two writable stream instances. `stdout` is a writable stream to print log or info output. `stderr` -is used for warning or error output. If `stderr` isn't passed, warning and error +is used for warning or error output. If `stderr` is not passed, warning and error output will be sent to `stdout`. ```js @@ -305,4 +295,5 @@ The `console.warn()` function is an alias for [`console.error()`][]. [`util.format()`]: util.html#util_util_format_format_args [`util.inspect()`]: util.html#util_util_inspect_object_options [customizing `util.inspect()` colors]: util.html#util_customizing_util_inspect_colors +[note on process I/O]: process.html#process_a_note_on_process_i_o [web-api-assert]: https://developer.mozilla.org/en-US/docs/Web/API/console/assert diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 0db2d8377cbe36..c6e24876e2e48c 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -26,7 +26,7 @@ It is possible for Node.js to be built without including support for the error being thrown. ```js -var crypto; +let crypto; try { crypto = require('crypto'); } catch (err) { @@ -132,9 +132,9 @@ Example: Using `Cipher` objects as streams: const crypto = require('crypto'); const cipher = crypto.createCipher('aes192', 'a password'); -var encrypted = ''; +let encrypted = ''; cipher.on('readable', () => { - var data = cipher.read(); + const data = cipher.read(); if (data) encrypted += data.toString('hex'); }); @@ -166,7 +166,7 @@ Example: Using the [`cipher.update()`][] and [`cipher.final()`][] methods: const crypto = require('crypto'); const cipher = crypto.createCipher('aes192', 'a password'); -var encrypted = cipher.update('some clear text data', 'utf8', 'hex'); +let encrypted = cipher.update('some clear text data', 'utf8', 'hex'); encrypted += cipher.final('hex'); console.log(encrypted); // Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504 @@ -265,9 +265,9 @@ Example: Using `Decipher` objects as streams: const crypto = require('crypto'); const decipher = crypto.createDecipher('aes192', 'a password'); -var decrypted = ''; +let decrypted = ''; decipher.on('readable', () => { - var data = decipher.read(); + const data = decipher.read(); if (data) decrypted += data.toString('utf8'); }); @@ -276,7 +276,7 @@ decipher.on('end', () => { // Prints: some clear text data }); -var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504'; +const encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504'; decipher.write(encrypted, 'hex'); decipher.end(); ``` @@ -300,8 +300,8 @@ Example: Using the [`decipher.update()`][] and [`decipher.final()`][] methods: const crypto = require('crypto'); const decipher = crypto.createDecipher('aes192', 'a password'); -var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504'; -var decrypted = decipher.update(encrypted, 'hex', 'utf8'); +const encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504'; +let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); console.log(decrypted); // Prints: some clear text data @@ -392,18 +392,18 @@ const assert = require('assert'); // Generate Alice's keys... const alice = crypto.createDiffieHellman(2048); -const alice_key = alice.generateKeys(); +const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator()); -const bob_key = bob.generateKeys(); +const bobKey = bob.generateKeys(); // Exchange and generate the secret... -const alice_secret = alice.computeSecret(bob_key); -const bob_secret = bob.computeSecret(alice_key); +const aliceSecret = alice.computeSecret(bobKey); +const bobSecret = bob.computeSecret(aliceKey); // OK -assert.equal(alice_secret.toString('hex'), bob_secret.toString('hex')); +assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex')); ``` ### diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding]) @@ -521,17 +521,17 @@ const assert = require('assert'); // Generate Alice's keys... const alice = crypto.createECDH('secp521r1'); -const alice_key = alice.generateKeys(); +const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = crypto.createECDH('secp521r1'); -const bob_key = bob.generateKeys(); +const bobKey = bob.generateKeys(); // Exchange and generate the secret... -const alice_secret = alice.computeSecret(bob_key); -const bob_secret = bob.computeSecret(alice_key); +const aliceSecret = alice.computeSecret(bobKey); +const bobSecret = bob.computeSecret(aliceKey); -assert(alice_secret, bob_secret); +assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex')); // OK ``` @@ -638,13 +638,14 @@ alice.setPrivateKey( ); // Bob uses a newly generated cryptographically strong -// pseudorandom key pair bob.generateKeys(); +// pseudorandom key pair +bob.generateKeys(); -const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); -const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); +const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); +const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); -// alice_secret and bob_secret should be the same shared secret value -console.log(alice_secret === bob_secret); +// aliceSecret and bobSecret should be the same shared secret value +console.log(aliceSecret === bobSecret); ``` ## Class: Hash @@ -670,7 +671,7 @@ const crypto = require('crypto'); const hash = crypto.createHash('sha256'); hash.on('readable', () => { - var data = hash.read(); + const data = hash.read(); if (data) console.log(data.toString('hex')); // Prints: @@ -753,7 +754,7 @@ const crypto = require('crypto'); const hmac = crypto.createHmac('sha256', 'a secret'); hmac.on('readable', () => { - var data = hmac.read(); + const data = hmac.read(); if (data) console.log(data.toString('hex')); // Prints: @@ -837,8 +838,8 @@ const sign = crypto.createSign('RSA-SHA256'); sign.write('some data to sign'); sign.end(); -const private_key = getPrivateKeySomehow(); -console.log(sign.sign(private_key, 'hex')); +const privateKey = getPrivateKeySomehow(); +console.log(sign.sign(privateKey, 'hex')); // Prints: the calculated signature ``` @@ -850,8 +851,8 @@ const sign = crypto.createSign('RSA-SHA256'); sign.update('some data to sign'); -const private_key = getPrivateKeySomehow(); -console.log(sign.sign(private_key, 'hex')); +const privateKey = getPrivateKeySomehow(); +console.log(sign.sign(privateKey, 'hex')); // Prints: the calculated signature ``` @@ -868,13 +869,14 @@ const sign = crypto.createSign('sha256'); sign.update('some data to sign'); -const private_key = '-----BEGIN EC PRIVATE KEY-----\n' + - 'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' + - 'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' + - 'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' + - '-----END EC PRIVATE KEY-----\n'; +const privateKey = +`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49 +AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2 +pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng== +-----END EC PRIVATE KEY-----`; -console.log(sign.sign(private_key).toString('hex')); +console.log(sign.sign(privateKey).toString('hex')); ``` ### sign.sign(private_key[, output_format]) @@ -937,9 +939,9 @@ const verify = crypto.createVerify('RSA-SHA256'); verify.write('some data to sign'); verify.end(); -const public_key = getPublicKeySomehow(); +const publicKey = getPublicKeySomehow(); const signature = getSignatureToVerify(); -console.log(verify.verify(public_key, signature)); +console.log(verify.verify(publicKey, signature)); // Prints: true or false ``` @@ -951,9 +953,9 @@ const verify = crypto.createVerify('RSA-SHA256'); verify.update('some data to sign'); -const public_key = getPublicKeySomehow(); +const publicKey = getPublicKeySomehow(); const signature = getSignatureToVerify(); -console.log(verify.verify(public_key, signature)); +console.log(verify.verify(publicKey, signature)); // Prints: true or false ``` @@ -1182,7 +1184,7 @@ const hash = crypto.createHash('sha256'); const input = fs.createReadStream(filename); input.on('readable', () => { - var data = input.read(); + const data = input.read(); if (data) hash.update(data); else { @@ -1216,7 +1218,7 @@ const hmac = crypto.createHmac('sha256', 'a secret'); const input = fs.createReadStream(filename); input.on('readable', () => { - var data = input.read(); + const data = input.read(); if (data) hmac.update(data); else { @@ -1268,7 +1270,7 @@ Example: ```js const curves = crypto.getCurves(); -console.log(curves); // ['secp256k1', 'secp384r1', ...] +console.log(curves); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...] ``` ### crypto.getDiffieHellman(group_name) @@ -1297,11 +1299,11 @@ const bob = crypto.getDiffieHellman('modp14'); alice.generateKeys(); bob.generateKeys(); -const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); -const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); +const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); +const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); -/* alice_secret and bob_secret should be the same */ -console.log(alice_secret == bob_secret); +/* aliceSecret and bobSecret should be the same */ +console.log(aliceSecret === bobSecret); ``` ### crypto.getHashes() @@ -1316,7 +1318,7 @@ Example: ```js const hashes = crypto.getHashes(); -console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] +console.log(hashes); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...] ``` ### crypto.pbkdf2(password, salt, iterations, keylen, digest, callback) @@ -1347,7 +1349,7 @@ Example: const crypto = require('crypto'); crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => { if (err) throw err; - console.log(key.toString('hex')); // 'c5e478d...1469e50' + console.log(key.toString('hex')); // '3745e48...aa39b34' }); ``` @@ -1380,7 +1382,7 @@ Example: ```js const crypto = require('crypto'); const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512'); -console.log(key.toString('hex')); // 'c5e478d...1469e50' +console.log(key.toString('hex')); // '3745e48...aa39b34' ``` An array of supported digest functions can be retrieved using @@ -1928,6 +1930,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. [`crypto.createHash()`]: #crypto_crypto_createhash_algorithm [`crypto.createHmac()`]: #crypto_crypto_createhmac_algorithm_key [`crypto.createSign()`]: #crypto_crypto_createsign_algorithm +[`crypto.createVerify()`]: #crypto_crypto_createverify_algorithm [`crypto.getCurves()`]: #crypto_crypto_getcurves [`crypto.getHashes()`]: #crypto_crypto_gethashes [`crypto.pbkdf2()`]: #crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback diff --git a/doc/api/debugger.md b/doc/api/debugger.md index c8a61d2ce742f8..7112b403fe35f3 100644 --- a/doc/api/debugger.md +++ b/doc/api/debugger.md @@ -117,7 +117,7 @@ script.js on line 1 It is also possible to set a breakpoint in a file (module) that -isn't loaded yet: +is not loaded yet: ```txt $ node debug test/fixtures/break-in-module/main.js diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 695ec3712eeddc..2e214beb2ff7d2 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -70,20 +70,14 @@ datagram messages. This occurs as soon as UDP sockets are created. added: v0.1.99 --> +The `'message'` event is emitted when a new datagram is available on a socket. +The event handler function is passed two arguments: `msg` and `rinfo`. * `msg` {Buffer} - The message * `rinfo` {Object} - Remote address information - -The `'message'` event is emitted when a new datagram is available on a socket. -The event handler function is passed two arguments: `msg` and `rinfo`. The -`msg` argument is a [`Buffer`][] and `rinfo` is an object with the sender's -address information provided by the `address`, `family` and `port` properties: - -```js -socket.on('message', (msg, rinfo) => { - console.log('Received %d bytes from %s:%d\n', - msg.length, rinfo.address, rinfo.port); -}); -``` + * `address` {String} The sender address + * `family` {String} The address family (`'IPv4'` or `'IPv6'`) + * `port` {Number} The sender port + * `size` {Number} The message size ### socket.addMembership(multicastAddress[, multicastInterface]) * `options` {Object} - Required. Supports the following properties: - * `port` {Number} - Required. + * `port` {Number} - Optional. * `address` {String} - Optional. * `exclusive` {Boolean} - Optional. * `callback` {Function} - Optional. -For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a -named `port` and optional `address` that are passed as properties of an -`options` object passed as the first argument. If `port` is not specified, the -operating system will attempt to bind to a random port. If `address` is not -specified, the operating system will attempt to listen on all addresses. Once -binding is complete, a `'listening'` event is emitted and the optional -`callback` function is called. +For UDP sockets, causes the `dgram.Socket` to listen for datagram +messages on a named `port` and optional `address` that are passed as +properties of an `options` object passed as the first argument. If +`port` is not specified or is `0`, the operating system will attempt +to bind to a random port. If `address` is not specified, the operating +system will attempt to listen on all addresses. Once binding is +complete, a `'listening'` event is emitted and the optional `callback` +function is called. + +Note that specifying both a `'listening'` event listener and passing a +`callback` to the `socket.bind()` method is not harmful but not very +useful. The `options` object may contain an additional `exclusive` property that is use when using `dgram.Socket` objects with the [`cluster`] module. When @@ -185,6 +185,12 @@ underlying socket handle allowing connection handling duties to be shared. When `exclusive` is `true`, however, the handle is not shared and attempted port sharing results in an error. +A bound datagram socket keeps the Node.js process running to receive +datagram messages. + +If binding fails, an `'error'` event is generated. In rare case (e.g. +attempting to bind with a closed socket), an [`Error`][] may be thrown. + An example socket listening on an exclusive port is shown below. ```js @@ -442,8 +448,8 @@ boolean `reuseAddr` field. When `reuseAddr` is `true` [`socket.bind()`][] will reuse the address, even if another process has already bound a socket on it. `reuseAddr` defaults to -`false`. An optional `callback` function can be passed specified which is added -as a listener for `'message'` events. +`false`. The optional `callback` function is added as a listener for `'message'` +events. Once the socket is created, calling [`socket.bind()`][] will instruct the socket to begin listening for datagram messages. When `address` and `port` are diff --git a/doc/api/dns.md b/doc/api/dns.md index 63caf8ed672d81..6d0b8999df9050 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -10,7 +10,7 @@ This category contains only one function: [`dns.lookup()`][]. **Developers looking to perform name resolution in the same way that other applications on the same operating system behave should use [`dns.lookup()`][].** -For example, looking up `nodejs.org`. +For example, looking up `iana.org`. ```js const dns = require('dns'); @@ -18,6 +18,7 @@ const dns = require('dns'); dns.lookup('nodejs.org', (err, addresses, family) => { console.log('addresses:', addresses); }); +// address: "192.0.43.8" family: IPv4 ``` 2) Functions that connect to an actual DNS server to perform name resolution, @@ -28,13 +29,13 @@ functions do not use the same set of configuration files used by developers who do not want to use the underlying operating system's facilities for name resolution, and instead want to _always_ perform DNS queries. -Below is an example that resolves `'nodejs.org'` then reverse resolves the IP +Below is an example that resolves `'archive.org'` then reverse resolves the IP addresses that are returned. ```js const dns = require('dns'); -dns.resolve4('nodejs.org', (err, addresses) => { +dns.resolve4('archive.org', (err, addresses) => { if (err) throw err; console.log(`addresses: ${JSON.stringify(addresses)}`); @@ -84,15 +85,7 @@ Alternatively, `options` can be an object containing these properties: * `all`: {Boolean} - When `true`, the callback returns all resolved addresses in an array, otherwise returns a single address. Defaults to `false`. -All properties are optional. An example usage of options is shown below. - -```js -{ - family: 4, - hints: dns.ADDRCONFIG | dns.V4MAPPED, - all: false -} -``` +All properties are optional. The `callback` function has arguments `(err, address, family)`. `address` is a string representation of an IPv4 or IPv6 address. `family` is either the @@ -115,6 +108,25 @@ important consequences on the behavior of any Node.js program. Please take some time to consult the [Implementation considerations section][] before using `dns.lookup()`. +Example usage: + +```js +const dns = require('dns'); +const options = { + family: 6, + hints: dns.ADDRCONFIG | dns.V4MAPPED, +}; +dns.lookup('example.com', options, (err, address, family) => + console.log('address: %j family: IPv%s', address, family)); +// address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6 + +// When options.all is true, the result will be an Array. +options.all = true; +dns.lookup('example.com', options, (err, addresses) => + console.log('addresses: %j', addresses)); +// addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}] +``` + ### Supported getaddrinfo flags The following flags can be passed as hints to [`dns.lookup()`][]. diff --git a/doc/api/documentation.md b/doc/api/documentation.md index 38ede72cf6c338..947010d951bdab 100644 --- a/doc/api/documentation.md +++ b/doc/api/documentation.md @@ -58,7 +58,7 @@ is a high priority, and will not be broken unless absolutely necessary. ```txt Stability: 3 - Locked -Only fixes related to security, performance, or bug fixes will be accepted. +Only bug fixes, security fixes, and performance improvements will be accepted. Please do not suggest API changes in this area; they will be refused. ``` diff --git a/doc/api/domain.md b/doc/api/domain.md index 86f5226d69e370..1cc25e0cf8d8fb 100644 --- a/doc/api/domain.md +++ b/doc/api/domain.md @@ -47,13 +47,13 @@ For example, this is not a good idea: ```js // XXX WARNING! BAD IDEA! -var d = require('domain').create(); +const d = require('domain').create(); d.on('error', (er) => { // The error won't crash the process, but what it does is worse! // Though we've prevented abrupt process restarting, we are leaking // resources like crazy if this ever happens. // This is no better than process.on('uncaughtException')! - console.log('error, but oh well', er.message); + console.log(`error, but oh well ${er.message}`); }); d.run(() => { require('http').createServer((req, res) => { @@ -104,9 +104,9 @@ if (cluster.isMaster) { // worker processes to serve requests. How it works, caveats, etc. const server = require('http').createServer((req, res) => { - var d = domain.create(); + const d = domain.create(); d.on('error', (er) => { - console.error('error', er.stack); + console.error(`error ${er.stack}`); // Note: we're in dangerous territory! // By definition, something unexpected occurred, @@ -115,7 +115,7 @@ if (cluster.isMaster) { try { // make sure we close down within 30 seconds - var killtimer = setTimeout(() => { + const killtimer = setTimeout(() => { process.exit(1); }, 30000); // But don't keep the process open just for that! @@ -135,7 +135,7 @@ if (cluster.isMaster) { res.end('Oops, there was a problem!\n'); } catch (er2) { // oh well, not much we can do at this point. - console.error('Error sending 500!', er2.stack); + console.error(`Error sending 500! ${er2.stack}`); } }); @@ -153,10 +153,10 @@ if (cluster.isMaster) { server.listen(PORT); } -// This part isn't important. Just an example routing thing. +// This part is not important. Just an example routing thing. // You'd put your fancy application logic here. function handleRequest(req, res) { - switch(req.url) { + switch (req.url) { case '/error': // We do some async stuff, and then... setTimeout(() => { @@ -239,7 +239,7 @@ serverDomain.run(() => { // req and res are also created in the scope of serverDomain // however, we'd prefer to have a separate domain for each request. // create it first thing, and add req and res to it. - var reqd = domain.create(); + const reqd = domain.create(); reqd.add(req); reqd.add(res); reqd.on('error', (er) => { @@ -247,8 +247,8 @@ serverDomain.run(() => { try { res.writeHead(500); res.end('Error occurred, sorry.'); - } catch (er) { - console.error('Error sending 500', er, req.url); + } catch (er2) { + console.error('Error sending 500', er2, req.url); } }); }).listen(1337); diff --git a/doc/api/errors.md b/doc/api/errors.md index 70588125a0f0c9..640935da35e460 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -195,6 +195,8 @@ will either be instances of, or inherit from, the `Error` class. ### new Error(message) +* `message` {String} + Creates a new `Error` object and sets the `error.message` property to the provided text message. If an object is passed as `message`, the text message is generated by calling `message.toString()`. The `error.stack` property will @@ -205,6 +207,9 @@ given by the property `Error.stackTraceLimit`, whichever is smaller. ### Error.captureStackTrace(targetObject[, constructorOpt]) +* `targetObject` {Object} +* `constructorOpt` {Function} + Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. @@ -238,6 +243,8 @@ new MyError().stack ### Error.stackTraceLimit +* {Number} + The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). @@ -250,10 +257,13 @@ not capture any frames. #### error.message -Returns the string description of error as set by calling `new Error(message)`. +* {String} + +The `error.message` property is the string description of the error as set by calling `new Error(message)`. The `message` passed to the constructor will also appear in the first line of the stack trace of the `Error`, however changing this property after the -`Error` object is created *may not* change the first line of the stack trace. +`Error` object is created *may not* change the first line of the stack trace +(for example, when `error.stack` is read before this property is changed). ```js const err = new Error('The message'); @@ -263,8 +273,10 @@ console.log(err.message); #### error.stack -Returns a string describing the point in the code at which the `Error` was -instantiated. +* {String} + +The `error.stack` property is a string describing the point in the code at which +the `Error` was instantiated. For example: @@ -450,18 +462,47 @@ added properties. #### error.code -Returns a string representing the error code, which is always `E` followed by -a sequence of capital letters, and may be referenced in `man 2 intro`. +* {String} + +The `error.code` property is a string representing the error code, which is always +`E` followed by a sequence of capital letters. #### error.errno -Returns a number corresponding to the **negated** error code, which may be -referenced in `man 2 intro`. For example, an `ENOENT` error has an `errno` of -`-2` because the error code for `ENOENT` is `2`. +* {String | Number} + +The `error.errno` property is a number or a string. +The number is a **negative** value which corresponds to the error code defined in +[`libuv Error handling`]. See uv-errno.h header file (`deps/uv/include/uv-errno.h` in +the Node.js source tree) for details. +In case of a string, it is the same as `error.code`. #### error.syscall -Returns a string describing the [syscall][] that failed. +* {String} + +The `error.syscall` property is a string describing the [syscall][] that failed. + +#### error.path + +* {String} + +When present (e.g. in `fs` or `child_process`), the `error.path` property is a string +containing a relevant invalid pathname. + +#### error.address + +* {String} + +When present (e.g. in `net` or `dgram`), the `error.address` property is a string +describing the address to which the connection failed. + +#### error.port + +* {Number} + +When present (e.g. in `net` or `dgram`), the `error.port` property is a number representing +the connection's port that is not available. ### Common System Errors @@ -528,6 +569,7 @@ found [here][online]. [`fs`]: fs.html [`http`]: http.html [`https`]: https.html +[`libuv Error handling`]: http://docs.libuv.org/en/v1.x/errors.html [`net`]: net.html [`process.on('uncaughtException')`]: process.html#process_event_uncaughtexception [domains]: domain.html diff --git a/doc/api/fs.md b/doc/api/fs.md index 490e1269d23848..5471c5f5e646f5 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1832,7 +1832,8 @@ added: v0.0.2 Write `buffer` to the file specified by `fd`. -`offset` and `length` determine the part of the buffer to be written. +`offset` determines the part of the buffer to be written, and `length` is +an integer specifying the number of bytes to write. `position` refers to the offset from the beginning of the file where this data should be written. If `typeof position !== 'number'`, the data will be written diff --git a/doc/api/globals.md b/doc/api/globals.md index f14a7833b2b2f0..a60cd4cc226fb2 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -32,7 +32,7 @@ added: v0.1.27 The directory name of the current module. This the same as the [`path.dirname()`][] of the [`__filename`][]. -`__dirname` isn't actually a global but rather local to each module. +`__dirname` is not actually a global but rather local to each module. Example: running `node example.js` from `/Users/mjr` @@ -60,7 +60,7 @@ command line. See [`__dirname`][] for the directory name of the current module. -`__filename` isn't actually a global but rather local to each module. +`__filename` is not actually a global but rather local to each module. Examples: @@ -132,7 +132,7 @@ A reference to the `module.exports` that is shorter to type. See [module system documentation][] for details on when to use `exports` and when to use `module.exports`. -`exports` isn't actually a global but rather local to each module. +`exports` is not actually a global but rather local to each module. See the [module system documentation][] for more information. @@ -163,7 +163,7 @@ A reference to the current module. In particular `module.exports` is used for defining what a module exports and makes available through `require()`. -`module` isn't actually a global but rather local to each module. +`module` is not actually a global but rather local to each module. See the [module system documentation][] for more information. @@ -187,7 +187,7 @@ added: v0.1.13 * {Function} -To require modules. See the [Modules][] section. `require` isn't actually a +To require modules. See the [Modules][] section. `require` is not actually a global but rather local to each module. ### require.cache diff --git a/doc/api/http.md b/doc/api/http.md index 7d165ea81b9473..6dc929d697e01e 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -48,26 +48,32 @@ list like the following: added: v0.3.4 --> -The HTTP Agent is used for pooling sockets used in HTTP client -requests. - -The HTTP Agent also defaults client requests to using -`Connection: keep-alive`. If no pending HTTP requests are waiting on a -socket to become free the socket is closed. This means that Node.js's -pool has the benefit of keep-alive when under load but still does not -require developers to manually close the HTTP clients using -KeepAlive. - -If you opt into using HTTP KeepAlive, you can create an Agent object -with that flag set to `true`. (See the [constructor options][].) -Then, the Agent will keep unused sockets in a pool for later use. They -will be explicitly marked so as to not keep the Node.js process running. -However, it is still a good idea to explicitly [`destroy()`][] KeepAlive -agents when they are no longer in use, so that the Sockets will be shut -down. - -Sockets are removed from the agent's pool when the socket emits either -a `'close'` event or a special `'agentRemove'` event. This means that if +An `Agent` is responsible for managing connection persistence +and reuse for HTTP clients. It maintains a queue of pending requests +for a given host and port, reusing a single socket connection for each +until the queue is empty, at which time the socket is either destroyed +or put into a pool where it is kept to be used again for requests to the +same host and port. Whether it is destroyed or pooled depends on the +`keepAlive` [option](#http_new_agent_options). + +Pooled connections have TCP Keep-Alive enabled for them, but servers may +still close idle connections, in which case they will be removed from the +pool and a new connection will be made when a new HTTP request is made for +that host and port. Servers may also refuse to allow multiple requests +over the same connection, in which case the connection will have to be +remade for every request and cannot be pooled. The `Agent` will still make +the requests to that server, but each one will occur over a new connection. + +When a connection is closed by the client or the server, it is removed +from the pool. Any unused sockets in the pool will be unrefed so as not +to keep the Node.js process running when there are no outstanding requests. +(see [socket.unref()]). + +It is good practice, to [`destroy()`][] an `Agent` instance when it is no +longer in use, because unused sockets consume OS resources. + +Sockets are removed from an agent's pool when the socket emits either +a `'close'` event or an `'agentRemove'` event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of: @@ -79,7 +85,11 @@ http.get(options, (res) => { }); ``` -Alternatively, you could just opt out of pooling entirely using +You may also use an agent for an individual request. By providing +`{agent: false}` as an option to the `http.get()` or `http.request()` +functions, a one-time use `Agent` with default options will be used +for the client connection. + `agent:false`: ```js @@ -100,11 +110,13 @@ added: v0.3.4 * `options` {Object} Set of configurable options to set on the agent. Can have the following fields: - * `keepAlive` {Boolean} Keep sockets around in a pool to be used by - other requests in the future. Default = `false` - * `keepAliveMsecs` {Integer} When using HTTP KeepAlive, how often - to send TCP KeepAlive packets over sockets being kept alive. - Default = `1000`. Only relevant if `keepAlive` is set to `true`. + * `keepAlive` {Boolean} Keep sockets around even when there are no + outstanding requests, so they can be used for future requests without + having to reestablish a TCP connection. Default = `false` + * `keepAliveMsecs` {Integer} When using the `keepAlive` option, specifies + the [initial delay](#net_socket_setkeepalive_enable_initialdelay) + for TCP Keep-Alive packets. Ignored when the + `keepAlive` option is `false` or `undefined`. Default = `1000`. * `maxSockets` {Number} Maximum number of sockets to allow per host. Default = `Infinity`. * `maxFreeSockets` {Number} Maximum number of sockets to leave open @@ -114,7 +126,7 @@ added: v0.3.4 The default [`http.globalAgent`][] that is used by [`http.request()`][] has all of these values set to their respective defaults. -To configure any of them, you must create your own [`http.Agent`][] object. +To configure any of them, you must create your own [`http.Agent`][] instance. ```js const http = require('http'); @@ -136,7 +148,7 @@ added: v0.11.4 Produces a socket/stream to be used for HTTP requests. By default, this function is the same as [`net.createConnection()`][]. However, -custom Agents may override this method in case greater flexibility is desired. +custom agents may override this method in case greater flexibility is desired. A socket/stream can be supplied in one of two ways: by returning the socket/stream from this function, or by passing the socket/stream to `callback`. @@ -151,7 +163,7 @@ added: v0.11.4 Destroy any sockets that are currently in use by the agent. It is usually not necessary to do this. However, if you are using an -agent with KeepAlive enabled, then it is best to explicitly shut down +agent with `keepAlive` enabled, then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, sockets may hang open for quite a long time before the server terminates them. @@ -164,7 +176,7 @@ added: v0.11.4 * {Object} An object which contains arrays of sockets currently awaiting use by -the Agent when HTTP KeepAlive is used. Do not modify. +the agent when `keepAlive` is enabled. Do not modify. ### agent.getName(options) + +If a request has been aborted, this value is the time when the request was +aborted, in milliseconds since 1 January 1970 00:00:00 UTC. + ### request.end([data][, encoding][, callback]) @@ -880,10 +880,11 @@ added: v0.1.13 * `code` {Integer} The exit code. Defaults to `0`. -The `process.exit()` method instructs Node.js to terminate the process as -quickly as possible with the specified exit `code`. If the `code` is omitted, -exit uses either the 'success' code `0` or the value of `process.exitCode` if -specified. +The `process.exit()` method instructs Node.js to terminate the process +synchronously with an exit status of `code`. If `code` is omitted, exit uses +either the 'success' code `0` or the value of `process.exitCode` if it has been +set. Node.js will not terminate until all the [`'exit'`] event listeners are +called. To exit with a 'failure' code: @@ -916,7 +917,7 @@ if (someConditionNotMet()) { ``` The reason this is problematic is because writes to `process.stdout` in Node.js -are sometimes *non-blocking* and may occur over multiple ticks of the Node.js +are sometimes *asynchronous* and may occur over multiple ticks of the Node.js event loop. Calling `process.exit()`, however, forces the process to exit *before* those additional writes to `stdout` can be performed. @@ -1511,23 +1512,11 @@ Android) * {Stream} -The `process.stderr` property returns a [Writable][] stream equivalent to or -associated with `stderr` (fd `2`). +The `process.stderr` property returns a [Writable][] stream connected to +`stderr` (fd `2`). -Note: `process.stderr` and `process.stdout` differ from other Node.js streams -in several ways: -1. They cannot be closed ([`end()`][] will throw). -2. They never emit the [`'finish'`][] event. -3. Writes _can_ block when output is redirected to a file. - - Note that disks are fast and operating systems normally employ write-back - caching so this is very uncommon. -4. Writes on UNIX **will** block by default if output is going to a TTY - (a terminal). -5. Windows functionality differs. Writes block except when output is going to a - TTY. - -To check if Node.js is being run in a TTY context, read the `isTTY` property -on `process.stderr`, `process.stdout`, or `process.stdin`: +Note: `process.stderr` differs from other Node.js streams in important ways, +see [note on process I/O][] for more information. ## process.stdin @@ -1565,40 +1554,52 @@ must call `process.stdin.resume()` to read from it. Note also that calling * {Stream} -The `process.stdout` property returns a [Writable][] stream equivalent to or -associated with `stdout` (fd `1`). +The `process.stdout` property returns a [Writable][] stream connected to +`stdout` (fd `2`). -For example: +For example, to copy process.stdin to process.stdout: ```js -console.log = (msg) => { - process.stdout.write(`${msg}\n`); -}; +process.stdin.pipe(process.stdout); ``` -Note: `process.stderr` and `process.stdout` differ from other Node.js streams -in several ways: -1. They cannot be closed ([`end()`][] will throw). -2. They never emit the [`'finish'`][] event. -3. Writes _can_ block when output is redirected to a file. - - Note that disks are fast and operating systems normally employ write-back - caching so this is very uncommon. -4. Writes on UNIX **will** block by default if output is going to a TTY - (a terminal). -5. Windows functionality differs. Writes block except when output is going to a - TTY. +Note: `process.stdout` differs from other Node.js streams in important ways, +see [note on process I/O][] for more information. + +### A note on process I/O -To check if Node.js is being run in a TTY context, read the `isTTY` property -on `process.stderr`, `process.stdout`, or `process.stdin`: +`process.stdout` and `process.stderr` differ from other Node.js streams in +important ways: -### TTY Terminals and `process.stdout` +1. They are used internally by [`console.log()`][] and [`console.error()`][], + respectively. +2. They cannot be closed ([`end()`][] will throw). +3. They will never emit the [`'finish'`][] event. +4. Writes may be synchronous depending on the what the stream is connected to + and whether the system is Windows or Unix: + - Files: *synchronous* on Windows and Linux + - TTYs (Terminals): *asynchronous* on Windows, *synchronous* on Unix + - Pipes (and sockets): *synchronous* on Windows, *asynchronous* on Unix -The `process.stderr` and `process.stdout` streams are blocking when outputting -to TTYs (terminals) on OS X as a workaround for the operating system's small, -1kb buffer size. This is to prevent interleaving between `stdout` and `stderr`. +These behaviours are partly for historical reasons, as changing them would +create backwards incompatibility, but they are also expected by some users. -To check if Node.js is being run in a [TTY][] context, check the `isTTY` -property on `process.stderr`, `process.stdout`, or `process.stdin`. +Synchronous writes avoid problems such as output written with `console.log()` or +`console.write()` being unexpectedly interleaved, or not written at all if +`process.exit()` is called before an asynchronous write completes. See +[`process.exit()`][] for more information. + +***Warning***: Synchronous writes block the event loop until the write has +completed. This can be near instantaneous in the case of output to a file, but +under high system load, pipes that are not being read at the receiving end, or +with slow terminals or file systems, its possible for the event loop to be +blocked often enough and long enough to have severe negative performance +impacts. This may not be a problem when writing to an interactive terminal +session, but consider this particularly careful when doing production logging to +the process output streams. + +To check if a stream is connected to a [TTY][] context, check the `isTTY` +property. For instance: ```console @@ -1606,7 +1607,6 @@ $ node -p "Boolean(process.stdin.isTTY)" true $ echo "foo" | node -p "Boolean(process.stdin.isTTY)" false - $ node -p "Boolean(process.stdout.isTTY)" true $ node -p "Boolean(process.stdout.isTTY)" | cat @@ -1687,9 +1687,9 @@ added: v0.2.0 * {Object} The `process.versions` property returns an object listing the version strings of -Node.js and its dependencies. In addition, `process.versions.modules` indicates -the current ABI version, which is increased whenever a C++ API changes. Node.js -will refuse to load native modules built for an older `modules` value. +Node.js and its dependencies. `process.versions.modules` indicates the current +ABI version, which is increased whenever a C++ API changes. Node.js will refuse +to load modules that were compiled against a different module ABI version. ```js console.log(process.versions); @@ -1758,6 +1758,7 @@ cases: the high-order bit, and then contain the value of the signal code. +[`'exit'`]: #process_event_exit [`'finish'`]: stream.html#stream_event_finish [`'message'`]: child_process.html#child_process_event_message [`'rejectionHandled'`]: #process_event_rejectionhandled @@ -1779,14 +1780,15 @@ cases: [`promise.catch()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch [`require.main`]: modules.html#modules_accessing_the_main_module [`setTimeout(fn, 0)`]: timers.html#timers_settimeout_callback_delay_args +[note on process I/O]: process.html#process_a_note_on_process_i_o [process_emit_warning]: #process_process_emitwarning_warning_name_ctor [process_warning]: #process_event_warning [Signal Events]: #process_signal_events [Stream compatibility]: stream.html#stream_compatibility_with_older_node_js_versions [TTY]: tty.html#tty_tty -[Writable]: stream.html -[Readable]: stream.html +[Writable]: stream.html#stream_writable_streams +[Readable]: stream.html#stream_readable_streams [Child Process]: child_process.html [Cluster]: cluster.html -[`process.exitCode`]: #processexitcode-1 +[`process.exitCode`]: #process_process_exitcode [LTS]: https://github.com/nodejs/LTS/ diff --git a/doc/api/punycode.md b/doc/api/punycode.md index 18809370145abd..a5d1908a8c40b6 100644 --- a/doc/api/punycode.md +++ b/doc/api/punycode.md @@ -1,4 +1,4 @@ -# punycode +# Punycode > Stability: 0 - Deprecated diff --git a/doc/api/readline.md b/doc/api/readline.md index 32fad5732c70df..bafb0071446e74 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -518,8 +518,8 @@ rl.on('line', (line) => { [`process.stdin`]: process.html#process_process_stdin [`process.stdout`]: process.html#process_process_stdout -[Writable]: stream.html -[Readable]: stream.html +[Writable]: stream.html#stream_writable_streams +[Readable]: stream.html#stream_readable_streams [TTY]: tty.html [`SIGTSTP`]: readline.html#readline_event_sigtstp [`SIGCONT`]: readline.html#readline_event_sigcont diff --git a/doc/api/repl.md b/doc/api/repl.md index b78a13544add4a..9ff416e004f4b3 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -371,7 +371,7 @@ within the action function for commands registered using the added: v0.1.91 --> -* `options` {Object} +* `options` {Object | String} * `prompt` {String} The input prompt to display. Defaults to `> `. * `input` {Readable} The Readable stream from which REPL input will be read. Defaults to `process.stdin`. @@ -413,6 +413,15 @@ added: v0.1.91 The `repl.start()` method creates and starts a `repl.REPLServer` instance. +If `options` is a string, then it specifies the input prompt: + +```js +const repl = require('repl'); + +// a Unix style prompt +repl.start('$ '); +``` + ## The Node.js REPL Node.js itself uses the `repl` module to provide its own interactive interface diff --git a/doc/api/stream.md b/doc/api/stream.md index 55c1bb39780d95..d9a2f47db4271f 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -347,6 +347,8 @@ buffer that would have an adverse impact on performance. In such situations, implementations that implement the `writable._writev()` method can perform buffered writes in a more optimized manner. +See also: [`writable.uncork()`][]. + ##### writable.end([chunk][, encoding][, callback]) + +The default curve name to use for ECDH key agreement in a tls server. The +default value is `'prime256v1'` (NIST P-256). Consult [RFC 4492] and +[FIPS.186-4] for more details. + + ## Deprecated APIs ### Class: CryptoStream @@ -1183,32 +1193,35 @@ secure_socket = tls.TLSSocket(socket, options); where `secure_socket` has the same API as `pair.cleartext`. -[OpenSSL cipher list format documentation]: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT [Chrome's 'modern cryptography' setting]: https://www.chromium.org/Home/chromium-security/education/tls#TOC-Cipher-Suites -[OpenSSL Options]: crypto.html#crypto_openssl_options -[modifying the default cipher suite]: #tls_modifying_the_default_tls_cipher_suite -[specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html -[`crypto.getCurves()`]: crypto.html#crypto_crypto_getcurves -[`tls.createServer()`]: #tls_tls_createserver_options_secureconnectionlistener -[`tls.createSecurePair()`]: #tls_tls_createsecurepair_context_isserver_requestcert_rejectunauthorized_options -[`tls.TLSSocket`]: #tls_class_tls_tlssocket -[`net.Server`]: net.html#net_class_net_server -[`net.Socket`]: net.html#net_class_net_socket -[`net.Server.address()`]: net.html#net_server_address -[`'secureConnect'`]: #tls_event_secureconnect -[`'secureConnection'`]: #tls_event_secureconnection -[Perfect Forward Secrecy]: #tls_perfect_forward_secrecy -[Stream]: stream.html#stream_stream -[SSL_METHODS]: https://www.openssl.org/docs/man1.0.2/ssl/ssl.html#DEALING-WITH-PROTOCOL-METHODS -[tls.Server]: #tls_class_tls_server -[SSL_CTX_set_timeout]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_timeout.html -[Forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy [DHE]: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange [ECDHE]: https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman -[asn1.js]: https://npmjs.org/package/asn1.js +[FIPS.186-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf +[Forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy [OCSP request]: https://en.wikipedia.org/wiki/OCSP_stapling -[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS +[OpenSSL Options]: crypto.html#crypto_openssl_options +[OpenSSL cipher list format documentation]: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT +[Perfect Forward Secrecy]: #tls_perfect_forward_secrecy +[RFC 4492]: https://www.rfc-editor.org/rfc/rfc4492.txt +[SSL_CTX_set_timeout]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_timeout.html +[SSL_METHODS]: https://www.openssl.org/docs/man1.0.2/ssl/ssl.html#DEALING-WITH-PROTOCOL-METHODS +[Stream]: stream.html#stream_stream [TLS Session Tickets]: https://www.ietf.org/rfc/rfc5077.txt +[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS +[`'secureConnect'`]: #tls_event_secureconnect +[`'secureConnection'`]: #tls_event_secureconnection +[`crypto.getCurves()`]: crypto.html#crypto_crypto_getcurves +[`net.Server.address()`]: net.html#net_server_address +[`net.Server`]: net.html#net_class_net_server +[`net.Socket`]: net.html#net_class_net_socket +[`tls.DEFAULT_ECDH_CURVE`]: #tls_tls_default_ecdh_curve [`tls.TLSSocket.getPeerCertificate()`]: #tls_tlssocket_getpeercertificate_detailed -[`tls.createSecureContext()`]: #tls_tls_createsecurecontext_options +[`tls.TLSSocket`]: #tls_class_tls_tlssocket [`tls.connect()`]: #tls_tls_connect_options_callback +[`tls.createSecureContext()`]: #tls_tls_createsecurecontext_options +[`tls.createSecurePair()`]: #tls_tls_createsecurepair_context_isserver_requestcert_rejectunauthorized_options +[`tls.createServer()`]: #tls_tls_createserver_options_secureconnectionlistener +[asn1.js]: https://npmjs.org/package/asn1.js +[modifying the default cipher suite]: #tls_modifying_the_default_tls_cipher_suite +[specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html +[tls.Server]: #tls_class_tls_server diff --git a/doc/api/util.md b/doc/api/util.md index a8fded6b2db042..3843f80ce75366 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1,4 +1,4 @@ -# util +# Util > Stability: 2 - Stable diff --git a/doc/api/vm.md b/doc/api/vm.md index a62923c2a1a317..ffa50be84612df 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -1,4 +1,4 @@ -# Executing JavaScript +# VM (Executing JavaScript) > Stability: 2 - Stable @@ -212,8 +212,24 @@ that sandbox][contextified] so that it can be used in calls to [`vm.runInContext()`][] or [`script.runInContext()`][]. Inside such scripts, the `sandbox` object will be the global object, retaining all of its existing properties but also having the built-in objects and functions any standard -[global object][] has. Outside of scripts run by the vm module, `sandbox` will -remain unchanged. +[global object][] has. Outside of scripts run by the vm module, global variables +will remain unchanged. + +```js +const util = require('util'); +const vm = require('vm'); + +var globalVar = 3; + +const sandbox = { globalVar: 1 }; +vm.createContext(sandbox); + +vm.runInContext('globalVar *= 2;', sandbox); + +console.log(util.inspect(sandbox)); // 2 + +console.log(util.inspect(globalVar)); // 3 +``` If `sandbox` is omitted (or passed explicitly as `undefined`), a new, empty [contextified][] sandbox object will be returned. @@ -423,9 +439,9 @@ let code = vm.runInThisContext(code)(require); ``` -*Note*: The `require()` in the above case shares the state with context it is -passed from. This may introduce risks when untrusted code is executed, e.g. -altering objects from the calling thread's context in unwanted ways. +*Note*: The `require()` in the above case shares the state with the context it +is passed from. This may introduce risks when untrusted code is executed, e.g. +altering objects in the context in unwanted ways. ## What does it mean to "contextify" an object? @@ -453,6 +469,6 @@ associating it with the `sandbox` object is what this document refers to as [`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedsandbox_options [`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options [`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval -[V8 Embedder's Guide]: https://developers.google.com/v8/embed#contexts +[V8 Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide#contexts [contextified]: #vm_what_does_it_mean_to_contextify_an_object [command line option]: cli.html diff --git a/doc/api/zlib.md b/doc/api/zlib.md index 1c0029242671bb..a2e1c7e730f0ee 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -388,6 +388,9 @@ Reset the compressor/decompressor to factory defaults. Only applicable to the inflate and deflate algorithms. ## zlib.constants + Provides an object enumerating Zlib-related constants. @@ -460,7 +463,7 @@ added: v0.6.0 added: v0.11.12 --> -Compress a Buffer or string with Deflate. +Compress a [Buffer][] or string with [Deflate][]. ### zlib.deflateRaw(buf[, options], callback) -Compress a Buffer or string with DeflateRaw. +Compress a [Buffer][] or string with [DeflateRaw][]. ### zlib.gunzip(buf[, options], callback) -Decompress a Buffer or string with Gunzip. +Decompress a [Buffer][] or string with [Gunzip][]. ### zlib.gzip(buf[, options], callback) -Compress a Buffer or string with Gzip. +Compress a [Buffer][] or string with [Gzip][]. ### zlib.inflate(buf[, options], callback) -Decompress a Buffer or string with Inflate. +Decompress a [Buffer][] or string with [Inflate][]. ### zlib.inflateRaw(buf[, options], callback) -Decompress a Buffer or string with InflateRaw. +Decompress a [Buffer][] or string with [InflateRaw][]. ### zlib.unzip(buf[, options], callback) -Decompress a Buffer or string with Unzip. +Decompress a [Buffer][] or string with [Unzip][]. [`Accept-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 [`Content-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11 diff --git a/doc/api_assets/dnt_helper.js b/doc/api_assets/dnt_helper.js new file mode 100644 index 00000000000000..f255d916c2df32 --- /dev/null +++ b/doc/api_assets/dnt_helper.js @@ -0,0 +1,49 @@ +/** + * http://schalkneethling.github.io/blog/2015/11/06/respect-user-choice-do-not-track/ + * https://github.com/schalkneethling/dnt-helper/blob/master/js/dnt-helper.js + * + * Returns true or false based on whether doNotTack is enabled. It also takes into account the + * anomalies, such as !bugzilla 887703, which effect versions of Fx 31 and lower. It also handles + * IE versions on Windows 7, 8 and 8.1, where the DNT implementation does not honor the spec. + * @see https://bugzilla.mozilla.org/show_bug.cgi?id=1217896 for more details + * @params {string} [dnt] - An optional mock doNotTrack string to ease unit testing. + * @params {string} [userAgent] - An optional mock userAgent string to ease unit testing. + * @returns {boolean} true if enabled else false + */ +function _dntEnabled(dnt, userAgent) { + + 'use strict'; + + // for old version of IE we need to use the msDoNotTrack property of navigator + // on newer versions, and newer platforms, this is doNotTrack but, on the window object + // Safari also exposes the property on the window object. + var dntStatus = dnt || navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack; + var ua = userAgent || navigator.userAgent; + + // List of Windows versions known to not implement DNT according to the standard. + var anomalousWinVersions = ['Windows NT 6.1', 'Windows NT 6.2', 'Windows NT 6.3']; + + var fxMatch = ua.match(/Firefox\/(\d+)/); + var ieRegEx = /MSIE|Trident/i; + var isIE = ieRegEx.test(ua); + // Matches from Windows up to the first occurance of ; un-greedily + // http://www.regexr.com/3c2el + var platform = ua.match(/Windows.+?(?=;)/g); + + // With old versions of IE, DNT did not exist so we simply return false; + if (isIE && typeof Array.prototype.indexOf !== 'function') { + return false; + } else if (fxMatch && parseInt(fxMatch[1], 10) < 32) { + // Can't say for sure if it is 1 or 0, due to Fx bug 887703 + dntStatus = 'Unspecified'; + } else if (isIE && platform && anomalousWinVersions.indexOf(platform.toString()) !== -1) { + // default is on, which does not honor the specification + dntStatus = 'Unspecified'; + } else { + // sets dntStatus to Disabled or Enabled based on the value returned by the browser. + // If dntStatus is undefined, it will be set to Unspecified + dntStatus = { '0': 'Disabled', '1': 'Enabled' }[dntStatus] || 'Unspecified'; + } + + return dntStatus === 'Enabled' ? true : false; +} diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index ca74b8aa6a0c70..549cf1b34f85af 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -7,6 +7,8 @@ +6.10.1
+6.10.0
6.9.5
6.9.4
6.9.3
@@ -44,6 +46,333 @@ [Node.js Long Term Support Plan](https://github.com/nodejs/LTS) and will be supported actively until April 2018 and maintained until April 2019. + +## 2017-03-21, Version 6.10.1 'Boron' (LTS), @MylesBorins + +This LTS release comes with 297 commits. This includes 124 which are test related, +79 which are doc related, 16 which are build / tool related and 4 commits which are updates to dependencies. + +### Notable changes + +* **performance**: The performance of several APIs has been improved. + - `Buffer.compare()` is up to 35% faster on average. (Brian White) [#10927](https://github.com/nodejs/node/pull/10927) + - `buffer.toJSON()` is up to 2859% faster on average. (Brian White) [#10895](https://github.com/nodejs/node/pull/10895) + - `fs.*statSync()` functions are now up to 9.3% faster on average. (Brian White) [#11522](https://github.com/nodejs/node/pull/11522) + - `os.loadavg` is up to 151% faster. (Brian White) [#11516](https://github.com/nodejs/node/pull/11516) + - `process.memoryUsage()` is up to 34% faster. (Brian White) [#11497](https://github.com/nodejs/node/pull/11497) + - `querystring.unescape()` for `Buffer`s is 15% faster on average. (Brian White) [#10837](https://github.com/nodejs/node/pull/10837) + - `querystring.stringify()` is up to 7.8% faster on average. (Brian White) [#10852](https://github.com/nodejs/node/pull/10852) + - `querystring.parse()` is up to 21% faster on average. (Brian White) [#10874](https://github.com/nodejs/node/pull/10874) +* **IPC**: Batched writes have been enabled for process IPC on platforms that support Unix Domain Sockets. (Alexey Orlenko) [#10677](https://github.com/nodejs/node/pull/10677) + - Performance gains may be up to 40% for some workloads. +* **child_process**: `spawnSync` now returns a null `status` when child is terminated by a signal. (cjihrig) [#11288](https://github.com/nodejs/node/pull/11288) + - This fixes the behavior to act like `spawn()` does. +* **http**: + - Control characters are now always rejected when using `http.request()`. (Ben Noordhuis) [#8923](https://github.com/nodejs/node/pull/8923) + - Debug messages have been added for cases when headers contain invalid values. (Evan Lucas) [#9195](https://github.com/nodejs/node/pull/9195) +* **node**: Heap statistics now support values larger than 4GB. (Ben Noordhuis) [#10186](https://github.com/nodejs/node/pull/10186) +* **timers**: Timer callbacks now always maintain order when interacting with domain error handling. (John Barboza) [#10522](https://github.com/nodejs/node/pull/10522) + +### Commits + +* [[`fb75bed078`](https://github.com/nodejs/node/commit/fb75bed078)] - **assert**: unlock the assert API (Rich Trott) [#11304](https://github.com/nodejs/node/pull/11304) +* [[`32b264c33b`](https://github.com/nodejs/node/commit/32b264c33b)] - **assert**: remove unneeded condition (Rich Trott) [#11314](https://github.com/nodejs/node/pull/11314) +* [[`a0c705ef79`](https://github.com/nodejs/node/commit/a0c705ef79)] - **assert**: apply minor refactoring (Rich Trott) [#11511](https://github.com/nodejs/node/pull/11511) +* [[`7ecfe4971a`](https://github.com/nodejs/node/commit/7ecfe4971a)] - **assert**: update comments (Kai Cataldo) [#10579](https://github.com/nodejs/node/pull/10579) +* [[`4d6fa8d040`](https://github.com/nodejs/node/commit/4d6fa8d040)] - **benchmark**: add more thorough timers benchmarks (Jeremiah Senkpiel) [#10925](https://github.com/nodejs/node/pull/10925) +* [[`406e623b13`](https://github.com/nodejs/node/commit/406e623b13)] - **benchmark**: add benchmark for object properties (Michaël Zasso) [#10949](https://github.com/nodejs/node/pull/10949) +* [[`7ee04c6015`](https://github.com/nodejs/node/commit/7ee04c6015)] - **benchmark**: don't lint autogenerated modules (Brian White) [#10756](https://github.com/nodejs/node/pull/10756) +* [[`d22d7cce7c`](https://github.com/nodejs/node/commit/d22d7cce7c)] - **benchmark**: move punycode benchmark out of net (Brian White) [#10446](https://github.com/nodejs/node/pull/10446) +* [[`6b361611c3`](https://github.com/nodejs/node/commit/6b361611c3)] - **benchmark**: move setImmediate benchmarks to timers (Joshua Colvin) [#11010](https://github.com/nodejs/node/pull/11010) +* [[`a469ce5826`](https://github.com/nodejs/node/commit/a469ce5826)] - **benchmark**: add assert.deep\[Strict\]Equal benchmarks (Joyee Cheung) [#11092](https://github.com/nodejs/node/pull/11092) +* [[`eca1e80722`](https://github.com/nodejs/node/commit/eca1e80722)] - **benchmark**: add dgram bind(+/- params) benchmark (Vse Mozhet Byt) [#11313](https://github.com/nodejs/node/pull/11313) +* [[`06c339dcce`](https://github.com/nodejs/node/commit/06c339dcce)] - **benchmark**: improve readability of net benchmarks (Brian White) [#10446](https://github.com/nodejs/node/pull/10446) +* [[`b4cf8c4036`](https://github.com/nodejs/node/commit/b4cf8c4036)] - **benchmark,lib,test**: adjust for linting (Rich Trott) [#10561](https://github.com/nodejs/node/pull/10561) +* [[`e397e6f94a`](https://github.com/nodejs/node/commit/e397e6f94a)] - **buffer**: improve compare() performance (Brian White) [#10927](https://github.com/nodejs/node/pull/10927) +* [[`2b52859535`](https://github.com/nodejs/node/commit/2b52859535)] - **buffer**: fix comments in bidirectionalIndexOf (dcposch@dcpos.ch) [#10162](https://github.com/nodejs/node/pull/10162) +* [[`f7879d98f8`](https://github.com/nodejs/node/commit/f7879d98f8)] - **buffer**: improve toJSON() performance (Brian White) [#10895](https://github.com/nodejs/node/pull/10895) +* [[`f83d035c50`](https://github.com/nodejs/node/commit/f83d035c50)] - **buffer**: convert offset & length to int properly (Sakthipriyan Vairamani (thefourtheye)) [#11176](https://github.com/nodejs/node/pull/11176) +* [[`cda593774f`](https://github.com/nodejs/node/commit/cda593774f)] - **build**: sort sources alphabetically (Daniel Bevenius) [#10892](https://github.com/nodejs/node/pull/10892) +* [[`2d31fd8bf7`](https://github.com/nodejs/node/commit/2d31fd8bf7)] - **build**: move source files from headers section (Daniel Bevenius) [#10850](https://github.com/nodejs/node/pull/10850) +* [[`b7c5295437`](https://github.com/nodejs/node/commit/b7c5295437)] - **build**: don't squash signal handlers with --shared (Stewart X Addison) [#10539](https://github.com/nodejs/node/pull/10539) +* [[`6772b1d81c`](https://github.com/nodejs/node/commit/6772b1d81c)] - **build**: disable C4267 conversion compiler warning (Ben Noordhuis) [#11205](https://github.com/nodejs/node/pull/11205) +* [[`93416e9b7a`](https://github.com/nodejs/node/commit/93416e9b7a)] - **build**: fix newlines in addon build output (Brian White) [#11466](https://github.com/nodejs/node/pull/11466) +* [[`2d5cb3b870`](https://github.com/nodejs/node/commit/2d5cb3b870)] - **build**: fail on CI if leftover processes (Rich Trott) [#11269](https://github.com/nodejs/node/pull/11269) +* [[`edcca78f10`](https://github.com/nodejs/node/commit/edcca78f10)] - **build**: add rule to clean addon tests build (Joyee Cheung) [#11519](https://github.com/nodejs/node/pull/11519) +* [[`0200a5a74e`](https://github.com/nodejs/node/commit/0200a5a74e)] - **build**: fix node_g target (Daniel Bevenius) [#10153](https://github.com/nodejs/node/pull/10153) +* [[`f44c0a5d7a`](https://github.com/nodejs/node/commit/f44c0a5d7a)] - **build**: Don't regenerate node symlink (sxa555) [#9827](https://github.com/nodejs/node/pull/9827) +* [[`947d07bd87`](https://github.com/nodejs/node/commit/947d07bd87)] - **child_process**: exit spawnSync with null on signal (cjihrig) [#11288](https://github.com/nodejs/node/pull/11288) +* [[`4179c7050f`](https://github.com/nodejs/node/commit/4179c7050f)] - **child_process**: move anonymous class to top level (Jackson Tian) [#11147](https://github.com/nodejs/node/pull/11147) +* [[`818cef848e`](https://github.com/nodejs/node/commit/818cef848e)] - **child_process**: remove empty if condition (cjihrig) [#11427](https://github.com/nodejs/node/pull/11427) +* [[`c371fdcf34`](https://github.com/nodejs/node/commit/c371fdcf34)] - **child_process**: refactor internal/child_process.js (Arseniy Maximov) [#11366](https://github.com/nodejs/node/pull/11366) +* [[`b662c117cb`](https://github.com/nodejs/node/commit/b662c117cb)] - **crypto**: return the retval of HMAC_Update (Travis Meisenheimer) [#10891](https://github.com/nodejs/node/pull/10891) +* [[`44510197dd`](https://github.com/nodejs/node/commit/44510197dd)] - **crypto**: freelist_max_len is gone in OpenSSL 1.1.0 (Adam Langley) [#10859](https://github.com/nodejs/node/pull/10859) +* [[`34614af53b`](https://github.com/nodejs/node/commit/34614af53b)] - **crypto**: add cert check issued by StartCom/WoSign (Shigeki Ohtsu) [#9469](https://github.com/nodejs/node/pull/9469) +* [[`b4b3bb4c5d`](https://github.com/nodejs/node/commit/b4b3bb4c5d)] - **crypto**: Remove expired certs from CNNIC whitelist (Shigeki Ohtsu) [#9469](https://github.com/nodejs/node/pull/9469) +* [[`1f44922e34`](https://github.com/nodejs/node/commit/1f44922e34)] - **crypto**: use CHECK_NE instead of ABORT or abort (Sam Roberts) [#10413](https://github.com/nodejs/node/pull/10413) +* [[`ccb6045f2d`](https://github.com/nodejs/node/commit/ccb6045f2d)] - **crypto,tls**: fix mutability of return values (Rich Trott) [#10795](https://github.com/nodejs/node/pull/10795) +* [[`3ab070d4e1`](https://github.com/nodejs/node/commit/3ab070d4e1)] - **deps**: backport dfb8d33 from V8 upstream (Michaël Zasso) [#11483](https://github.com/nodejs/node/pull/11483) +* [[`3fc6a2247f`](https://github.com/nodejs/node/commit/3fc6a2247f)] - **deps**: cherry-pick a814b8a from upstream V8 (ishell@chromium.org) [#10733](https://github.com/nodejs/node/pull/10733) +* [[`254cb1cb77`](https://github.com/nodejs/node/commit/254cb1cb77)] - **deps**: back-port 73ee7943 from v8 upstream (Ben Noordhuis) [#9293](https://github.com/nodejs/node/pull/9293) +* [[`e774de1685`](https://github.com/nodejs/node/commit/e774de1685)] - **deps**: back-port 306c412c from v8 upstream (Ben Noordhuis) [#9293](https://github.com/nodejs/node/pull/9293) +* [[`e5d1e273d7`](https://github.com/nodejs/node/commit/e5d1e273d7)] - **dgram**: fix possibly deoptimizing use of arguments (Vse Mozhet Byt) [#11242](https://github.com/nodejs/node/pull/11242) +* [[`c7257e716f`](https://github.com/nodejs/node/commit/c7257e716f)] - **dgram**: remove this aliases (cjihrig) [#11243](https://github.com/nodejs/node/pull/11243) +* [[`227cc1e810`](https://github.com/nodejs/node/commit/227cc1e810)] - **doc**: restrict the ES.Next features usage in tests (DavidCai) [#11452](https://github.com/nodejs/node/pull/11452) +* [[`23246768fb`](https://github.com/nodejs/node/commit/23246768fb)] - **doc**: add missing entry in v6 changelog table (Luigi Pinca) [#11534](https://github.com/nodejs/node/pull/11534) +* [[`ff9a86a73e`](https://github.com/nodejs/node/commit/ff9a86a73e)] - **doc**: remove Chris Dickinson from active releasers (Ben Noordhuis) [#11011](https://github.com/nodejs/node/pull/11011) +* [[`313d1a3009`](https://github.com/nodejs/node/commit/313d1a3009)] - **doc**: for style, remove "isn't" contraction (Sam Roberts) [#10981](https://github.com/nodejs/node/pull/10981) +* [[`ab7587ed6c`](https://github.com/nodejs/node/commit/ab7587ed6c)] - **doc**: update http.md for consistency and clarity (Lance Ball) [#10715](https://github.com/nodejs/node/pull/10715) +* [[`21a94ab78c`](https://github.com/nodejs/node/commit/21a94ab78c)] - **doc**: clarify Buffer.indexOf/lastIndexOf edge cases (dcposch@dcpos.ch) [#10162](https://github.com/nodejs/node/pull/10162) +* [[`8c487de736`](https://github.com/nodejs/node/commit/8c487de736)] - **doc**: document argument variant in the repl.md (Vse Mozhet Byt) [#10221](https://github.com/nodejs/node/pull/10221) +* [[`130710476b`](https://github.com/nodejs/node/commit/130710476b)] - **doc**: DEFAULT_ECDH_CURVE was added in 0.11.13 (Sam Roberts) [#10983](https://github.com/nodejs/node/pull/10983) +* [[`5118e05b15`](https://github.com/nodejs/node/commit/5118e05b15)] - **doc**: HTTP response getHeader doc fix (Faiz Halde) [#10817](https://github.com/nodejs/node/pull/10817) +* [[`243652abbe`](https://github.com/nodejs/node/commit/243652abbe)] - **doc**: remove duplicate properties bullet in readme (Javis Sullivan) [#10741](https://github.com/nodejs/node/pull/10741) +* [[`fa8a394e51`](https://github.com/nodejs/node/commit/fa8a394e51)] - **doc**: specify sorted requires in tests (Sam Roberts) [#10716](https://github.com/nodejs/node/pull/10716) +* [[`1660311056`](https://github.com/nodejs/node/commit/1660311056)] - **doc**: fix typo in http.md (Peter Mescalchin) [#10975](https://github.com/nodejs/node/pull/10975) +* [[`8936814a70`](https://github.com/nodejs/node/commit/8936814a70)] - **doc**: add who to CC list for dgram (cjihrig) [#11035](https://github.com/nodejs/node/pull/11035) +* [[`b934058128`](https://github.com/nodejs/node/commit/b934058128)] - **doc**: correct and complete dgram's Socket.bind docs (Alex Jordan) [#11025](https://github.com/nodejs/node/pull/11025) +* [[`faa55fbe09`](https://github.com/nodejs/node/commit/faa55fbe09)] - **doc**: edit CONTRIBUTING.md for clarity (Rich Trott) [#11045](https://github.com/nodejs/node/pull/11045) +* [[`c26258e1fd`](https://github.com/nodejs/node/commit/c26258e1fd)] - **doc**: fix confusing example in dns.md (Vse Mozhet Byt) [#11022](https://github.com/nodejs/node/pull/11022) +* [[`8bf7f9f202`](https://github.com/nodejs/node/commit/8bf7f9f202)] - **doc**: add personal pronouns option (Rich Trott) [#11089](https://github.com/nodejs/node/pull/11089) +* [[`7c22a52a74`](https://github.com/nodejs/node/commit/7c22a52a74)] - **doc**: clarify msg when doc/api/cli.md not updated (Stewart X Addison) [#10872](https://github.com/nodejs/node/pull/10872) +* [[`d404d8b673`](https://github.com/nodejs/node/commit/d404d8b673)] - **doc**: edit stability text for clarity and style (Rich Trott) [#11112](https://github.com/nodejs/node/pull/11112) +* [[`38938e1ba9`](https://github.com/nodejs/node/commit/38938e1ba9)] - **doc**: remove assertions about assert (Rich Trott) [#11113](https://github.com/nodejs/node/pull/11113) +* [[`89d30908f2`](https://github.com/nodejs/node/commit/89d30908f2)] - **doc**: fix "initial delay" link in http.md (Timo Tijhof) [#11108](https://github.com/nodejs/node/pull/11108) +* [[`c0072f8d71`](https://github.com/nodejs/node/commit/c0072f8d71)] - **doc**: typographical fixes in COLLABORATOR_GUIDE.md (Anna Henningsen) [#11163](https://github.com/nodejs/node/pull/11163) +* [[`207142d050`](https://github.com/nodejs/node/commit/207142d050)] - **doc**: add not-an-aardvark as ESLint contact (Rich Trott) [#11169](https://github.com/nodejs/node/pull/11169) +* [[`3746eee19d`](https://github.com/nodejs/node/commit/3746eee19d)] - **doc**: improve testing guide (Joyee Cheung) [#11150](https://github.com/nodejs/node/pull/11150) +* [[`6cadc7160f`](https://github.com/nodejs/node/commit/6cadc7160f)] - **doc**: remove extraneous paragraph from assert doc (Rich Trott) [#11174](https://github.com/nodejs/node/pull/11174) +* [[`d5d8a8d7b5`](https://github.com/nodejs/node/commit/d5d8a8d7b5)] - **doc**: fix typo in dgram doc (Rich Trott) [#11186](https://github.com/nodejs/node/pull/11186) +* [[`59a1d00906`](https://github.com/nodejs/node/commit/59a1d00906)] - **doc**: add and fix System Error properties (Daiki Arai) [#10986](https://github.com/nodejs/node/pull/10986) +* [[`72adba4317`](https://github.com/nodejs/node/commit/72adba4317)] - **doc**: add links between cork() and uncork() (Matteo Collina) [#11222](https://github.com/nodejs/node/pull/11222) +* [[`1cd526c253`](https://github.com/nodejs/node/commit/1cd526c253)] - **doc**: clarify the behavior of Buffer.byteLength (Nikolai Vavilov) [#11238](https://github.com/nodejs/node/pull/11238) +* [[`b1bda165ce`](https://github.com/nodejs/node/commit/b1bda165ce)] - **doc**: edit maxBuffer/Unicode paragraph for clarity (Rich Trott) [#11228](https://github.com/nodejs/node/pull/11228) +* [[`1150af00f7`](https://github.com/nodejs/node/commit/1150af00f7)] - **doc**: improve consistency in documentation titles (Vse Mozhet Byt) [#11230](https://github.com/nodejs/node/pull/11230) +* [[`ade39cdf9c`](https://github.com/nodejs/node/commit/ade39cdf9c)] - **doc**: drop "and io.js" from release section (Ben Noordhuis) [#11054](https://github.com/nodejs/node/pull/11054) +* [[`c79d9f95d1`](https://github.com/nodejs/node/commit/c79d9f95d1)] - **doc**: update email and add personal pronoun (JungMinu) [#11318](https://github.com/nodejs/node/pull/11318) +* [[`7df4ee8d49`](https://github.com/nodejs/node/commit/7df4ee8d49)] - **doc**: update link to V8 Embedder's guide (Franziska Hinkelmann) [#11336](https://github.com/nodejs/node/pull/11336) +* [[`8468d823a8`](https://github.com/nodejs/node/commit/8468d823a8)] - **doc**: update code examples in domain.md (Vse Mozhet Byt) [#11110](https://github.com/nodejs/node/pull/11110) +* [[`10a497cdcb`](https://github.com/nodejs/node/commit/10a497cdcb)] - **doc**: describe when stdout/err is sync (Sam Roberts) [#10884](https://github.com/nodejs/node/pull/10884) +* [[`53d5002ef9`](https://github.com/nodejs/node/commit/53d5002ef9)] - **doc**: dns examples implied string args were arrays (Sam Roberts) [#11350](https://github.com/nodejs/node/pull/11350) +* [[`42304de4f7`](https://github.com/nodejs/node/commit/42304de4f7)] - **doc**: change STYLE-GUIDE to STYLE_GUIDE (Dean Coakley) [#11460](https://github.com/nodejs/node/pull/11460) +* [[`13a9ba9523`](https://github.com/nodejs/node/commit/13a9ba9523)] - **doc**: add STYLE_GUIDE (moved from nodejs/docs) (Gibson Fahnestock) [#11321](https://github.com/nodejs/node/pull/11321) +* [[`0164d9263e`](https://github.com/nodejs/node/commit/0164d9263e)] - **doc**: improve test/README.md (Joyee Cheung) [#11237](https://github.com/nodejs/node/pull/11237) +* [[`e0868aa529`](https://github.com/nodejs/node/commit/e0868aa529)] - **doc**: add comment for net.Server's error event (QianJin2013) [#11136](https://github.com/nodejs/node/pull/11136) +* [[`9a684a1511`](https://github.com/nodejs/node/commit/9a684a1511)] - **doc**: note message event listeners ref IPC channels (Diego Rodríguez Baquero) [#11494](https://github.com/nodejs/node/pull/11494) +* [[`bfa3989584`](https://github.com/nodejs/node/commit/bfa3989584)] - **doc**: argument types for assert methods (Amelia Clarke) [#11548](https://github.com/nodejs/node/pull/11548) +* [[`fc41a1d34d`](https://github.com/nodejs/node/commit/fc41a1d34d)] - **doc**: document clientRequest.aborted (Zach Bjornson) [#11544](https://github.com/nodejs/node/pull/11544) +* [[`ff77425eba`](https://github.com/nodejs/node/commit/ff77425eba)] - **doc**: link to readable and writeable stream section (Sebastian Van Sande) [#11517](https://github.com/nodejs/node/pull/11517) +* [[`4850b503dd`](https://github.com/nodejs/node/commit/4850b503dd)] - **doc**: update TheAlphaNerd to MylesBorins (Myles Borins) [#10586](https://github.com/nodejs/node/pull/10586) +* [[`d04de226a1`](https://github.com/nodejs/node/commit/d04de226a1)] - **doc**: update examples in api/crypto.md (Vse Mozhet Byt) [#10909](https://github.com/nodejs/node/pull/10909) +* [[`a045af3b95`](https://github.com/nodejs/node/commit/a045af3b95)] - **doc**: update AUTHORS list to fix name (Noah Rose Ledesma) [#10945](https://github.com/nodejs/node/pull/10945) +* [[`d266759b99`](https://github.com/nodejs/node/commit/d266759b99)] - **doc**: add TimothyGu to collaborators (Timothy Gu) [#10954](https://github.com/nodejs/node/pull/10954) +* [[`42a5989b39`](https://github.com/nodejs/node/commit/42a5989b39)] - **doc**: mention moderation repo in onboarding doc (Anna Henningsen) [#10869](https://github.com/nodejs/node/pull/10869) +* [[`cdc981f6e1`](https://github.com/nodejs/node/commit/cdc981f6e1)] - **doc**: add edsadr to collaborators (Adrian Estrada) [#10883](https://github.com/nodejs/node/pull/10883) +* [[`787d4ec197`](https://github.com/nodejs/node/commit/787d4ec197)] - **doc**: clarifying variables in fs.write() (Jessica Quynh Tran) [#9792](https://github.com/nodejs/node/pull/9792) +* [[`f48c86ce48`](https://github.com/nodejs/node/commit/f48c86ce48)] - **doc**: add links for zlib convenience methods (Anna Henningsen) [#10829](https://github.com/nodejs/node/pull/10829) +* [[`1dbb366611`](https://github.com/nodejs/node/commit/1dbb366611)] - **doc**: add missing `added:` tag for `zlib.constants` (Anna Henningsen) [#10826](https://github.com/nodejs/node/pull/10826) +* [[`867b4d87dc`](https://github.com/nodejs/node/commit/867b4d87dc)] - **doc**: fix broken internal link in process.md (Anna Henningsen) [#10828](https://github.com/nodejs/node/pull/10828) +* [[`6d726c07aa`](https://github.com/nodejs/node/commit/6d726c07aa)] - **doc**: update writable.write return value (Nathan Phillip Brink) [#10582](https://github.com/nodejs/node/pull/10582) +* [[`1975f82168`](https://github.com/nodejs/node/commit/1975f82168)] - **doc**: edit writing-tests.md (Rich Trott) [#10585](https://github.com/nodejs/node/pull/10585) +* [[`494ee5163f`](https://github.com/nodejs/node/commit/494ee5163f)] - **doc**: fix misleading language in vm docs (Alexey Orlenko) [#10708](https://github.com/nodejs/node/pull/10708) +* [[`8e807f6552`](https://github.com/nodejs/node/commit/8e807f6552)] - **doc**: mention cc-ing nodejs/url team for reviews (Anna Henningsen) [#10652](https://github.com/nodejs/node/pull/10652) +* [[`f9bd4a5645`](https://github.com/nodejs/node/commit/f9bd4a5645)] - **doc**: sort require statements in tests (Sam Roberts) [#10616](https://github.com/nodejs/node/pull/10616) +* [[`032d73841d`](https://github.com/nodejs/node/commit/032d73841d)] - **doc**: handle backpressure when write() return false (Matteo Collina) [#10631](https://github.com/nodejs/node/pull/10631) +* [[`af991c7a98`](https://github.com/nodejs/node/commit/af991c7a98)] - **doc**: add test naming information to guide (Rich Trott) [#10584](https://github.com/nodejs/node/pull/10584) +* [[`b5fd61d77a`](https://github.com/nodejs/node/commit/b5fd61d77a)] - **doc**: fix missing negation in stream.md (Johannes Rieken) [#10712](https://github.com/nodejs/node/pull/10712) +* [[`7e5a59e6fc`](https://github.com/nodejs/node/commit/7e5a59e6fc)] - **doc**: "s/git apply/git am -3" in V8 guide (Myles Borins) [#10665](https://github.com/nodejs/node/pull/10665) +* [[`789bafd693`](https://github.com/nodejs/node/commit/789bafd693)] - **doc**: update LTS info for current releases (Evan Lucas) [#10720](https://github.com/nodejs/node/pull/10720) +* [[`fef978584a`](https://github.com/nodejs/node/commit/fef978584a)] - **doc**: update BUILDING.md (Lukasz Gasior) [#10669](https://github.com/nodejs/node/pull/10669) +* [[`f2ddc72b62`](https://github.com/nodejs/node/commit/f2ddc72b62)] - **doc**: document use of Refs: for references (Gibson Fahnestock) [#10670](https://github.com/nodejs/node/pull/10670) +* [[`0a1d15fba6`](https://github.com/nodejs/node/commit/0a1d15fba6)] - **doc**: clarify information about ABI version (Rich Trott) [#10419](https://github.com/nodejs/node/pull/10419) +* [[`22f3813b3e`](https://github.com/nodejs/node/commit/22f3813b3e)] - **doc**: clarify the statement in vm.createContext() (AnnaMag) [#10519](https://github.com/nodejs/node/pull/10519) +* [[`38d63e49eb`](https://github.com/nodejs/node/commit/38d63e49eb)] - **doc**: improve rinfo object documentation (Matt Crummey) [#10050](https://github.com/nodejs/node/pull/10050) +* [[`998fd1e7e1`](https://github.com/nodejs/node/commit/998fd1e7e1)] - **doc**: add tls.DEFAULT_ECDH_CURVE (Sam Roberts) [#10264](https://github.com/nodejs/node/pull/10264) +* [[`4995a819e0`](https://github.com/nodejs/node/commit/4995a819e0)] - **doc**: fix a wrong note in the buffer.md (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`6d3c2d6212`](https://github.com/nodejs/node/commit/6d3c2d6212)] - **doc**: fix examples in buffer.md to avoid confusion (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`020c90eb2d`](https://github.com/nodejs/node/commit/020c90eb2d)] - **doc**: remove a wrong remark in the buffer.md (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`8af811f90e`](https://github.com/nodejs/node/commit/8af811f90e)] - **doc**: fix copy-paste artifacts in the buffer.md (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`a2b40ad6a4`](https://github.com/nodejs/node/commit/a2b40ad6a4)] - **doc**: fix wrong function arguments in the buffer.md (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`e94abaec1c`](https://github.com/nodejs/node/commit/e94abaec1c)] - **doc**: fix a syntax error in the buffer.md (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`b36c315423`](https://github.com/nodejs/node/commit/b36c315423)] - **doc**: var =\> const/let in the buffer.md (Vse Mozhet Byt) [#9795](https://github.com/nodejs/node/pull/9795) +* [[`b503824b81`](https://github.com/nodejs/node/commit/b503824b81)] - **doc,test**: args to `buffer.copy` can be Uint8Arrays (Anna Henningsen) [#11486](https://github.com/nodejs/node/pull/11486) +* [[`c8d2ca7a78`](https://github.com/nodejs/node/commit/c8d2ca7a78)] - **fs**: improve performance for sync stat() functions (Brian White) [#11522](https://github.com/nodejs/node/pull/11522) +* [[`b4dc7a778f`](https://github.com/nodejs/node/commit/b4dc7a778f)] - **http**: make request.abort() destroy the socket (Luigi Pinca) [#10818](https://github.com/nodejs/node/pull/10818) +* [[`d777da27bc`](https://github.com/nodejs/node/commit/d777da27bc)] - **http**: reject control characters in http.request() (Ben Noordhuis) [#8923](https://github.com/nodejs/node/pull/8923) +* [[`bad0d9367e`](https://github.com/nodejs/node/commit/bad0d9367e)] - **http**: add debug message for invalid header value (Evan Lucas) [#9195](https://github.com/nodejs/node/pull/9195) +* [[`bde1a7e09e`](https://github.com/nodejs/node/commit/bde1a7e09e)] - **lib**: remove unnecessary parameter for assertCrypto() (Jackson Tian) [#10834](https://github.com/nodejs/node/pull/10834) +* [[`a2aa2f7de4`](https://github.com/nodejs/node/commit/a2aa2f7de4)] - **lib**: refactor bootstrap_node.js regular expression (Rich Trott) [#10749](https://github.com/nodejs/node/pull/10749) +* [[`797d9ee924`](https://github.com/nodejs/node/commit/797d9ee924)] - **lib**: refactor crypto cipher/hash/curve getters (Rich Trott) [#10682](https://github.com/nodejs/node/pull/10682) +* [[`69327f5e72`](https://github.com/nodejs/node/commit/69327f5e72)] - **lib**: rename kMaxCallbacksUntilQueueIsShortened (JungMinu) [#11473](https://github.com/nodejs/node/pull/11473) +* [[`a6b2dfa43c`](https://github.com/nodejs/node/commit/a6b2dfa43c)] - **lib**: add constant kMaxCallbacksUntilQueueIsShortened (Daniel Bevenius) [#11199](https://github.com/nodejs/node/pull/11199) +* [[`a3ad63b9b3`](https://github.com/nodejs/node/commit/a3ad63b9b3)] - **lib,src**: support values \> 4GB in heap statistics (Ben Noordhuis) [#10186](https://github.com/nodejs/node/pull/10186) +* [[`8b5dd35ae8`](https://github.com/nodejs/node/commit/8b5dd35ae8)] - **meta**: add explicit deprecation and semver-major policy (James M Snell) [#7964](https://github.com/nodejs/node/pull/7964) +* [[`4df850ba59`](https://github.com/nodejs/node/commit/4df850ba59)] - **meta**: remove Chris Dickinson from CTC (Chris Dickinson) [#11267](https://github.com/nodejs/node/pull/11267) +* [[`8863360a21`](https://github.com/nodejs/node/commit/8863360a21)] - **meta**: adding Italo A. Casas PGP Fingerprint (Italo A. Casas) [#11202](https://github.com/nodejs/node/pull/11202) +* [[`8287d03adf`](https://github.com/nodejs/node/commit/8287d03adf)] - **meta**: decharter the http working group (James M Snell) [#10604](https://github.com/nodejs/node/pull/10604) +* [[`742ec6213f`](https://github.com/nodejs/node/commit/742ec6213f)] - **net**: prefer === to == (Arseniy Maximov) [#11513](https://github.com/nodejs/node/pull/11513) +* [[`5bfa43d8f0`](https://github.com/nodejs/node/commit/5bfa43d8f0)] - **os**: improve loadavg() performance (Brian White) [#11516](https://github.com/nodejs/node/pull/11516) +* [[`b7088a9355`](https://github.com/nodejs/node/commit/b7088a9355)] - **process**: improve memoryUsage() performance (Brian White) [#11497](https://github.com/nodejs/node/pull/11497) +* [[`02e5f5c57e`](https://github.com/nodejs/node/commit/02e5f5c57e)] - **process**: fix typo in comments (levsthings) [#11503](https://github.com/nodejs/node/pull/11503) +* [[`db45bf850a`](https://github.com/nodejs/node/commit/db45bf850a)] - **querystring**: improve unescapeBuffer performance (Brian White) [#10837](https://github.com/nodejs/node/pull/10837) +* [[`32cdbca2dc`](https://github.com/nodejs/node/commit/32cdbca2dc)] - **querystring**: improve stringify() performance (Brian White) [#10852](https://github.com/nodejs/node/pull/10852) +* [[`23f3f20963`](https://github.com/nodejs/node/commit/23f3f20963)] - **querystring**: improve parse() performance (Brian White) [#10874](https://github.com/nodejs/node/pull/10874) +* [[`dc88b6572d`](https://github.com/nodejs/node/commit/dc88b6572d)] - **readline**: refactor construct Interface (Jackson Tian) [#4740](https://github.com/nodejs/node/pull/4740) +* [[`f7c6ad2df9`](https://github.com/nodejs/node/commit/f7c6ad2df9)] - **readline**: update 6 comparions to strict (Umair Ishaq) [#11078](https://github.com/nodejs/node/pull/11078) +* [[`b5a0d46c55`](https://github.com/nodejs/node/commit/b5a0d46c55)] - **src**: add NODE_NO_WARNINGS to --help output (cjihrig) [#10918](https://github.com/nodejs/node/pull/10918) +* [[`566e2fea48`](https://github.com/nodejs/node/commit/566e2fea48)] - **src**: remove unnecessary req_wrap_obj (Daniel Bevenius) [#10942](https://github.com/nodejs/node/pull/10942) +* [[`c7436df889`](https://github.com/nodejs/node/commit/c7436df889)] - **src**: add a missing space in node_os.cc (Alexey Orlenko) [#10931](https://github.com/nodejs/node/pull/10931) +* [[`4358c6096c`](https://github.com/nodejs/node/commit/4358c6096c)] - **src**: enable writev for pipe handles on Unix (Alexey Orlenko) [#10677](https://github.com/nodejs/node/pull/10677) +* [[`28102edbc8`](https://github.com/nodejs/node/commit/28102edbc8)] - **src**: unconsume stream fix in internal http impl (Roee Kasher) [#11015](https://github.com/nodejs/node/pull/11015) +* [[`587857e301`](https://github.com/nodejs/node/commit/587857e301)] - **src**: fix delete operator on vm context (Franziska Hinkelmann) [#11266](https://github.com/nodejs/node/pull/11266) +* [[`b7cbb8002c`](https://github.com/nodejs/node/commit/b7cbb8002c)] - **src**: support UTF-8 in compiled-in JS source files (Ben Noordhuis) [#11129](https://github.com/nodejs/node/pull/11129) +* [[`ce01372b68`](https://github.com/nodejs/node/commit/ce01372b68)] - **src**: remove unused typedef (Ben Noordhuis) [#11322](https://github.com/nodejs/node/pull/11322) +* [[`1dddfeccb2`](https://github.com/nodejs/node/commit/1dddfeccb2)] - **src**: remove usage of deprecated debug API (Yang Guo) [#11437](https://github.com/nodejs/node/pull/11437) +* [[`7f273c6f6e`](https://github.com/nodejs/node/commit/7f273c6f6e)] - **src**: update http-parser link (Daniel Bevenius) [#11477](https://github.com/nodejs/node/pull/11477) +* [[`214b514efe`](https://github.com/nodejs/node/commit/214b514efe)] - **src**: use ABORT() macro instead of abort() (Evan Lucas) [#9613](https://github.com/nodejs/node/pull/9613) +* [[`412f380903`](https://github.com/nodejs/node/commit/412f380903)] - **stream**: move legacy to lib/internal dir (yorkie) [#8197](https://github.com/nodejs/node/pull/8197) +* [[`336f1bd842`](https://github.com/nodejs/node/commit/336f1bd842)] - **test**: increase setMulticastLoopback() coverage (cjihrig) [#11277](https://github.com/nodejs/node/pull/11277) +* [[`b29165f249`](https://github.com/nodejs/node/commit/b29165f249)] - **test**: increase dgram ref()/unref() coverage (cjihrig) [#11240](https://github.com/nodejs/node/pull/11240) +* [[`22d4ed2484`](https://github.com/nodejs/node/commit/22d4ed2484)] - **test**: add an exception test to http-write-head (Yuta Hiroto) [#11034](https://github.com/nodejs/node/pull/11034) +* [[`9edd342e81`](https://github.com/nodejs/node/commit/9edd342e81)] - **test**: add known_issues test for #10223 (AnnaMag) [#11024](https://github.com/nodejs/node/pull/11024) +* [[`646f82520c`](https://github.com/nodejs/node/commit/646f82520c)] - **test**: guarantee test runs in test-readline-keys (Rich Trott) [#11023](https://github.com/nodejs/node/pull/11023) +* [[`d8eed12d31`](https://github.com/nodejs/node/commit/d8eed12d31)] - **test**: check error message in test-http-outgoing-proto (Alex Ling) [#10943](https://github.com/nodejs/node/pull/10943) +* [[`174bef182a`](https://github.com/nodejs/node/commit/174bef182a)] - **test**: increase coverage for stream's duplex (abouthiroppy) [#10963](https://github.com/nodejs/node/pull/10963) +* [[`8ff15a262d`](https://github.com/nodejs/node/commit/8ff15a262d)] - **test**: allow for slow hosts in spawnSync() test (Rich Trott) [#10998](https://github.com/nodejs/node/pull/10998) +* [[`62f6749cd6`](https://github.com/nodejs/node/commit/62f6749cd6)] - **test**: expand test coverage of fs.js (Vinícius do Carmo) [#10947](https://github.com/nodejs/node/pull/10947) +* [[`5cea2239d8`](https://github.com/nodejs/node/commit/5cea2239d8)] - **test**: expand test coverage of events.js (Vinícius do Carmo) [#10947](https://github.com/nodejs/node/pull/10947) +* [[`a1751864e2`](https://github.com/nodejs/node/commit/a1751864e2)] - **test**: check noAssert option in buf.write*() (larissayvette) [#10790](https://github.com/nodejs/node/pull/10790) +* [[`0b5f2b45f9`](https://github.com/nodejs/node/commit/0b5f2b45f9)] - **test**: expand test coverage of fs.js (Vinícius do Carmo) [#10972](https://github.com/nodejs/node/pull/10972) +* [[`d9362efb6c`](https://github.com/nodejs/node/commit/d9362efb6c)] - **test**: enhance test-timers (Rich Trott) [#10960](https://github.com/nodejs/node/pull/10960) +* [[`b9615b3abc`](https://github.com/nodejs/node/commit/b9615b3abc)] - **test**: increase coverage for exec() functions (cjihrig) [#10919](https://github.com/nodejs/node/pull/10919) +* [[`b45280671a`](https://github.com/nodejs/node/commit/b45280671a)] - **test**: add process.assert's test (abouthiroppy) [#10911](https://github.com/nodejs/node/pull/10911) +* [[`6584ea0715`](https://github.com/nodejs/node/commit/6584ea0715)] - **test**: update Buffer.lastIndexOf (dcposch@dcpos.ch) [#10162](https://github.com/nodejs/node/pull/10162) +* [[`0c60540014`](https://github.com/nodejs/node/commit/0c60540014)] - **test**: improve code in test-crypto-verify (Adrian Estrada) [#10845](https://github.com/nodejs/node/pull/10845) +* [[`2a52a68a96`](https://github.com/nodejs/node/commit/2a52a68a96)] - **test**: add dgram.Socket.prototype.bind's test (abouthiroppy) [#10894](https://github.com/nodejs/node/pull/10894) +* [[`2494d8ac68`](https://github.com/nodejs/node/commit/2494d8ac68)] - **test**: update V8 flag in test (Franziska Hinkelmann) [#10917](https://github.com/nodejs/node/pull/10917) +* [[`9ac22cdcaf`](https://github.com/nodejs/node/commit/9ac22cdcaf)] - **test**: increase coverage of string-decoder (abouthiroppy) [#10863](https://github.com/nodejs/node/pull/10863) +* [[`d766f5e0ad`](https://github.com/nodejs/node/commit/d766f5e0ad)] - **test**: improving coverage of dns-lookup (abouthiroppy) [#10844](https://github.com/nodejs/node/pull/10844) +* [[`8f984c3a8a`](https://github.com/nodejs/node/commit/8f984c3a8a)] - **test**: refactor test-fs-read-zero-length.js (abouthiroppy) [#10729](https://github.com/nodejs/node/pull/10729) +* [[`c0e24f9029`](https://github.com/nodejs/node/commit/c0e24f9029)] - **test**: improving coverage for dgram (abouthiroppy) [#10783](https://github.com/nodejs/node/pull/10783) +* [[`c91d873115`](https://github.com/nodejs/node/commit/c91d873115)] - **test**: improve code in test-console-instance (Adrian Estrada) [#10813](https://github.com/nodejs/node/pull/10813) +* [[`a434f451d9`](https://github.com/nodejs/node/commit/a434f451d9)] - **test**: improve code in test-domain-multi (Adrian Estrada) [#10798](https://github.com/nodejs/node/pull/10798) +* [[`b01db3a73f`](https://github.com/nodejs/node/commit/b01db3a73f)] - **test**: improve test-stream2-large-read-stall (stefan judis) [#10725](https://github.com/nodejs/node/pull/10725) +* [[`76f0556c4a`](https://github.com/nodejs/node/commit/76f0556c4a)] - **test**: improve code in test-http-host-headers (Adrian Estrada) [#10830](https://github.com/nodejs/node/pull/10830) +* [[`c740cb6667`](https://github.com/nodejs/node/commit/c740cb6667)] - **test**: add test case to test-http-response-statuscode.js (abouthiroppy) [#10808](https://github.com/nodejs/node/pull/10808) +* [[`872354563c`](https://github.com/nodejs/node/commit/872354563c)] - **test**: refactor cluster-preload.js (abouthiroppy) [#10701](https://github.com/nodejs/node/pull/10701) +* [[`04dc1cdfcb`](https://github.com/nodejs/node/commit/04dc1cdfcb)] - **test**: improve test-fs-write-file-sync (Adrian Estrada) [#10624](https://github.com/nodejs/node/pull/10624) +* [[`0d25d056a4`](https://github.com/nodejs/node/commit/0d25d056a4)] - **test**: test hmac binding robustness (Sam Roberts) [#10923](https://github.com/nodejs/node/pull/10923) +* [[`99a234c97e`](https://github.com/nodejs/node/commit/99a234c97e)] - **test**: refactor the code in test-fs-watch.js (sivaprasanna) [#10357](https://github.com/nodejs/node/pull/10357) +* [[`c13f01c94d`](https://github.com/nodejs/node/commit/c13f01c94d)] - **test**: reduce unmanaged parallelism in domain test (Joyee Cheung) [#10329](https://github.com/nodejs/node/pull/10329) +* [[`ed76b4a8e9`](https://github.com/nodejs/node/commit/ed76b4a8e9)] - **test**: add dgram.Socket.prototype.sendto's test (abouthiroppy) [#10901](https://github.com/nodejs/node/pull/10901) +* [[`5365501a2f`](https://github.com/nodejs/node/commit/5365501a2f)] - **test**: add regression test for V8 parse error (Michaël Zasso) [#11483](https://github.com/nodejs/node/pull/11483) +* [[`b5fb9f4098`](https://github.com/nodejs/node/commit/b5fb9f4098)] - **test**: increase timeout in break-on-uncaught (Sakthipriyan Vairamani (thefourtheye)) [#10822](https://github.com/nodejs/node/pull/10822) +* [[`443dd508d2`](https://github.com/nodejs/node/commit/443dd508d2)] - **test**: fix process.title expectation (Sakthipriyan Vairamani (thefourtheye)) [#10597](https://github.com/nodejs/node/pull/10597) +* [[`ae338daf06`](https://github.com/nodejs/node/commit/ae338daf06)] - **test**: refactor test-debugger-remote (Sakthipriyan Vairamani (thefourtheye)) [#10455](https://github.com/nodejs/node/pull/10455) +* [[`34e0bc6d16`](https://github.com/nodejs/node/commit/34e0bc6d16)] - **test**: fix and improve debugger-client test (Sakthipriyan Vairamani (thefourtheye)) [#10371](https://github.com/nodejs/node/pull/10371) +* [[`da874590a6`](https://github.com/nodejs/node/commit/da874590a6)] - **test**: improve test-assert (richnologies) [#10916](https://github.com/nodejs/node/pull/10916) +* [[`a15ecd269d`](https://github.com/nodejs/node/commit/a15ecd269d)] - **test**: increase coverage for punycode's decode (abouthiroppy) [#10940](https://github.com/nodejs/node/pull/10940) +* [[`98e32db207`](https://github.com/nodejs/node/commit/98e32db207)] - **test**: check fd 0,1,2 are used, not access mode (John Barboza) [#10339](https://github.com/nodejs/node/pull/10339) +* [[`e59697c695`](https://github.com/nodejs/node/commit/e59697c695)] - **test**: fix flaky test-regress-GH-897 (Rich Trott) [#10903](https://github.com/nodejs/node/pull/10903) +* [[`a08c7f6d87`](https://github.com/nodejs/node/commit/a08c7f6d87)] - **test**: don't connect to :: (use localhost instead) (Gibson Fahnestock) [#10854](https://github.com/nodejs/node/pull/10854) +* [[`ca53866333`](https://github.com/nodejs/node/commit/ca53866333)] - **test**: add message verification on assert.throws (Travis Meisenheimer) [#10890](https://github.com/nodejs/node/pull/10890) +* [[`38b123c918`](https://github.com/nodejs/node/commit/38b123c918)] - **test**: refactor test-repl-tab-complete (Rich Trott) [#10879](https://github.com/nodejs/node/pull/10879) +* [[`68fc4d3a1c`](https://github.com/nodejs/node/commit/68fc4d3a1c)] - **test**: simplify array initialization (Rich Trott) [#10860](https://github.com/nodejs/node/pull/10860) +* [[`a26d752e77`](https://github.com/nodejs/node/commit/a26d752e77)] - **test**: add http-common's test (abouthiroppy) [#10832](https://github.com/nodejs/node/pull/10832) +* [[`80e2ff9bff`](https://github.com/nodejs/node/commit/80e2ff9bff)] - **test**: tests for _readableStream.awaitDrain (Mark) [#8914](https://github.com/nodejs/node/pull/8914) +* [[`e4e9f675d2`](https://github.com/nodejs/node/commit/e4e9f675d2)] - **test**: improve the code in test-process-cpuUsage (Adrian Estrada) [#10714](https://github.com/nodejs/node/pull/10714) +* [[`73c0c46cf2`](https://github.com/nodejs/node/commit/73c0c46cf2)] - **test**: increase test-crypto.js strictness (Rich Trott) [#10784](https://github.com/nodejs/node/pull/10784) +* [[`e316fafbd4`](https://github.com/nodejs/node/commit/e316fafbd4)] - **test**: delete duplicate test of noAssert in readUInt* (larissayvette) [#10791](https://github.com/nodejs/node/pull/10791) +* [[`896fb63173`](https://github.com/nodejs/node/commit/896fb63173)] - **test**: add http_incoming's matchKnownFields test (abouthiroppy) [#10811](https://github.com/nodejs/node/pull/10811) +* [[`c086bdc2de`](https://github.com/nodejs/node/commit/c086bdc2de)] - **test**: check error msg test-writeint.js (Irene Li) [#10755](https://github.com/nodejs/node/pull/10755) +* [[`2eb0c25aa1`](https://github.com/nodejs/node/commit/2eb0c25aa1)] - **test**: no unused args test-fs-watch-file.js (istinson) [#10758](https://github.com/nodejs/node/pull/10758) +* [[`2f026f6668`](https://github.com/nodejs/node/commit/2f026f6668)] - **test**: improve tests in pummel/test-exec (Chase Starr) [#10757](https://github.com/nodejs/node/pull/10757) +* [[`93877c87cc`](https://github.com/nodejs/node/commit/93877c87cc)] - **test**: fix temp-dir option in tools/test.py (Gibson Fahnestock) [#10723](https://github.com/nodejs/node/pull/10723) +* [[`0f3677dd5d`](https://github.com/nodejs/node/commit/0f3677dd5d)] - **test**: use realpath for NODE_TEST_DIR in common.js (Gibson Fahnestock) [#10723](https://github.com/nodejs/node/pull/10723) +* [[`5d0cc617bb`](https://github.com/nodejs/node/commit/5d0cc617bb)] - **test**: move resource intensive test to sequential (Rich Trott) [#10744](https://github.com/nodejs/node/pull/10744) +* [[`cd4bb067ad`](https://github.com/nodejs/node/commit/cd4bb067ad)] - **test**: add test for noAssert option in buf.read*() (larissayvette) [#10713](https://github.com/nodejs/node/pull/10713) +* [[`5b55689b2c`](https://github.com/nodejs/node/commit/5b55689b2c)] - **test**: refactor test-crypto-padding-aes256 (adelmann) [#10622](https://github.com/nodejs/node/pull/10622) +* [[`119e512db3`](https://github.com/nodejs/node/commit/119e512db3)] - **test**: refactor the code of test-keep-alive.js (sivaprasanna) [#10684](https://github.com/nodejs/node/pull/10684) +* [[`ef3d889ee7`](https://github.com/nodejs/node/commit/ef3d889ee7)] - **test**: validate 'expected' argument to mustCall() (Nathan Friedly) [#10692](https://github.com/nodejs/node/pull/10692) +* [[`21704a3b6b`](https://github.com/nodejs/node/commit/21704a3b6b)] - **test**: fix misplaced ) in http response statuscode test (Nathan Friedly) [#10692](https://github.com/nodejs/node/pull/10692) +* [[`8565a06b09`](https://github.com/nodejs/node/commit/8565a06b09)] - **test**: refactor test-doctool-html.js (abouthiroppy) [#10696](https://github.com/nodejs/node/pull/10696) +* [[`168f3e4bf8`](https://github.com/nodejs/node/commit/168f3e4bf8)] - **test**: improve the code in test-process-hrtime (Adrian Estrada) [#10667](https://github.com/nodejs/node/pull/10667) +* [[`9acc86f578`](https://github.com/nodejs/node/commit/9acc86f578)] - **test**: refactor test-watch-file.js (sivaprasanna) [#10679](https://github.com/nodejs/node/pull/10679) +* [[`86e39367d6`](https://github.com/nodejs/node/commit/86e39367d6)] - **test**: improve zlib-from-gzip-with-trailing-garbage (Michael Lefkowitz) [#10674](https://github.com/nodejs/node/pull/10674) +* [[`3135455cd9`](https://github.com/nodejs/node/commit/3135455cd9)] - **test**: refactor the code in test-child-process-spawn-loop.js (sivaprasanna) [#10605](https://github.com/nodejs/node/pull/10605) +* [[`f43a8765a2`](https://github.com/nodejs/node/commit/f43a8765a2)] - **test**: allow testing uid and gid separately (cjihrig) [#10647](https://github.com/nodejs/node/pull/10647) +* [[`2f1d231c0d`](https://github.com/nodejs/node/commit/2f1d231c0d)] - **test**: improve test-http-chunked-304 (Adrian Estrada) [#10462](https://github.com/nodejs/node/pull/10462) +* [[`ec8a9962ce`](https://github.com/nodejs/node/commit/ec8a9962ce)] - **test**: improve test-fs-readfile-zero-byte-liar (Adrian Estrada) [#10570](https://github.com/nodejs/node/pull/10570) +* [[`12746af524`](https://github.com/nodejs/node/commit/12746af524)] - **test**: refactor test-fs-utimes (Junshu Okamoto) [#9290](https://github.com/nodejs/node/pull/9290) +* [[`e81b1cc1ae`](https://github.com/nodejs/node/commit/e81b1cc1ae)] - **test**: provide duration/interval to timers (Rich Trott) [#9472](https://github.com/nodejs/node/pull/9472) +* [[`17a63e15e6`](https://github.com/nodejs/node/commit/17a63e15e6)] - **test**: improve test-event-emitter-modify-in-emit (Adrian Estrada) [#10600](https://github.com/nodejs/node/pull/10600) +* [[`50ee4e6dad`](https://github.com/nodejs/node/commit/50ee4e6dad)] - **test**: require handler to be run in sigwinch test (Rich Trott) [#11068](https://github.com/nodejs/node/pull/11068) +* [[`8cce29587c`](https://github.com/nodejs/node/commit/8cce29587c)] - **test**: add 2nd argument to throws in test-assert (Marlena Compton) [#11061](https://github.com/nodejs/node/pull/11061) +* [[`b14d7b3aa1`](https://github.com/nodejs/node/commit/b14d7b3aa1)] - **test**: improve error messages in test-npm-install (Gonen Dukas) [#11027](https://github.com/nodejs/node/pull/11027) +* [[`87488ba2ff`](https://github.com/nodejs/node/commit/87488ba2ff)] - **test**: add path.join's test (Yuta Hiroto) [#11063](https://github.com/nodejs/node/pull/11063) +* [[`232664a10d`](https://github.com/nodejs/node/commit/232664a10d)] - **test**: fix timing sensitivity in debugger test (Ali Ijaz Sheikh) [#11008](https://github.com/nodejs/node/pull/11008) +* [[`c16160418b`](https://github.com/nodejs/node/commit/c16160418b)] - **test**: improve coverage on removeListeners functions (matsuda-koushi) [#11140](https://github.com/nodejs/node/pull/11140) +* [[`898276b1b4`](https://github.com/nodejs/node/commit/898276b1b4)] - **test**: simplify output handling in repl tests (Rich Trott) [#11124](https://github.com/nodejs/node/pull/11124) +* [[`3248cdb2e6`](https://github.com/nodejs/node/commit/3248cdb2e6)] - **test**: improve crypto.setEngine coverage to check for errors (Sebastian Van Sande) [#11143](https://github.com/nodejs/node/pull/11143) +* [[`28111f9eb2`](https://github.com/nodejs/node/commit/28111f9eb2)] - **test**: increase specificity in dgram test (Rich Trott) [#11187](https://github.com/nodejs/node/pull/11187) +* [[`c5e8ccab63`](https://github.com/nodejs/node/commit/c5e8ccab63)] - **test**: remove obsolete comment from dgram test (ALJCepeda) [#8689](https://github.com/nodejs/node/pull/8689) +* [[`7aebc6907c`](https://github.com/nodejs/node/commit/7aebc6907c)] - **test**: improve checks in test-path-parse-format (cjihrig) [#11223](https://github.com/nodejs/node/pull/11223) +* [[`baec432c93`](https://github.com/nodejs/node/commit/baec432c93)] - **test**: add coverage for string array dgram send() (cjihrig) [#11247](https://github.com/nodejs/node/pull/11247) +* [[`6694c26420`](https://github.com/nodejs/node/commit/6694c26420)] - **test**: adapt test-debugger-pid to localized Windows (Vse Mozhet Byt) [#11270](https://github.com/nodejs/node/pull/11270) +* [[`2db4c3c453`](https://github.com/nodejs/node/commit/2db4c3c453)] - **test**: add vm module edge cases (Franziska Hinkelmann) [#11265](https://github.com/nodejs/node/pull/11265) +* [[`759604912a`](https://github.com/nodejs/node/commit/759604912a)] - **test**: refactor test-dgram-setBroadcast.js (cjihrig) [#11252](https://github.com/nodejs/node/pull/11252) +* [[`3185fa1249`](https://github.com/nodejs/node/commit/3185fa1249)] - **test**: querystring.escape with multibyte characters (Daijiro Wachi) [#11251](https://github.com/nodejs/node/pull/11251) +* [[`460a3e1f7a`](https://github.com/nodejs/node/commit/460a3e1f7a)] - **test**: improve test-assert.js (jobala) [#11193](https://github.com/nodejs/node/pull/11193) +* [[`1adfca4b5e`](https://github.com/nodejs/node/commit/1adfca4b5e)] - **test**: refactor test-repl-sigint (Rich Trott) [#11309](https://github.com/nodejs/node/pull/11309) +* [[`c539325d89`](https://github.com/nodejs/node/commit/c539325d89)] - **test**: improve punycode test coverage (Sebastian Van Sande) [#11144](https://github.com/nodejs/node/pull/11144) +* [[`8db3c770be`](https://github.com/nodejs/node/commit/8db3c770be)] - **test**: refactor test-repl-sigint-nested-eval (Rich Trott) [#11303](https://github.com/nodejs/node/pull/11303) +* [[`874ef9d312`](https://github.com/nodejs/node/commit/874ef9d312)] - **test**: add coverage for dgram _createSocketHandle() (cjihrig) [#11291](https://github.com/nodejs/node/pull/11291) +* [[`92f6919532`](https://github.com/nodejs/node/commit/92f6919532)] - **test**: improve crypto coverage (Akito Ito) [#11280](https://github.com/nodejs/node/pull/11280) +* [[`d9deb1fb62`](https://github.com/nodejs/node/commit/d9deb1fb62)] - **test**: improve message in net-connect-local-error (Rich Trott) [#11393](https://github.com/nodejs/node/pull/11393) +* [[`6677c113aa`](https://github.com/nodejs/node/commit/6677c113aa)] - **test**: refactor test-dgram-membership (Rich Trott) [#11388](https://github.com/nodejs/node/pull/11388) +* [[`e7b7d7279c`](https://github.com/nodejs/node/commit/e7b7d7279c)] - **test**: cases to querystring related to empty string (Daijiro Wachi) [#11329](https://github.com/nodejs/node/pull/11329) +* [[`5a92fc25a1`](https://github.com/nodejs/node/commit/5a92fc25a1)] - **test**: consolidate buffer.read() in a file (larissayvette) [#11297](https://github.com/nodejs/node/pull/11297) +* [[`607158ab6e`](https://github.com/nodejs/node/commit/607158ab6e)] - **test**: improve crypto coverage (樋口 彰) [#11279](https://github.com/nodejs/node/pull/11279) +* [[`27f302d94f`](https://github.com/nodejs/node/commit/27f302d94f)] - **test**: remove unused args and comparison fix (Alexander) [#11396](https://github.com/nodejs/node/pull/11396) +* [[`8da156d68f`](https://github.com/nodejs/node/commit/8da156d68f)] - **test**: add coverage for utf8CheckIncomplete() (xiaoyu) [#11419](https://github.com/nodejs/node/pull/11419) +* [[`0ddad76813`](https://github.com/nodejs/node/commit/0ddad76813)] - **test**: fix over-dependence on native promise impl (Ali Ijaz Sheikh) [#11437](https://github.com/nodejs/node/pull/11437) +* [[`34444580f6`](https://github.com/nodejs/node/commit/34444580f6)] - **test**: add test cases for path (Yuta Hiroto) [#11453](https://github.com/nodejs/node/pull/11453) +* [[`4bcf1a0387`](https://github.com/nodejs/node/commit/4bcf1a0387)] - **test**: refactor test-http-response-splitting (Arseniy Maximov) [#11429](https://github.com/nodejs/node/pull/11429) +* [[`7836807178`](https://github.com/nodejs/node/commit/7836807178)] - **test**: add error checking in callback (Rich Trott) [#11446](https://github.com/nodejs/node/pull/11446) +* [[`13b7856444`](https://github.com/nodejs/node/commit/13b7856444)] - **test**: improve coverage in test-crypto.dh (Eric Christie) [#11253](https://github.com/nodejs/node/pull/11253) +* [[`b2f7e7a5ad`](https://github.com/nodejs/node/commit/b2f7e7a5ad)] - **test**: add regex check to test-module-loading (Tarang Hirani) [#11413](https://github.com/nodejs/node/pull/11413) +* [[`6bf936644e`](https://github.com/nodejs/node/commit/6bf936644e)] - **test**: increase coverage of vm (DavidCai) [#11377](https://github.com/nodejs/node/pull/11377) +* [[`6202f14583`](https://github.com/nodejs/node/commit/6202f14583)] - **test**: throw check in test-zlib-write-after-close (Jason Wilson) [#11482](https://github.com/nodejs/node/pull/11482) +* [[`f8884dd1b5`](https://github.com/nodejs/node/commit/f8884dd1b5)] - **test**: add cases for unescape & unescapeBuffer (Daijiro Wachi) [#11326](https://github.com/nodejs/node/pull/11326) +* [[`05909d045b`](https://github.com/nodejs/node/commit/05909d045b)] - **test**: fix flaky test-vm-timeout-rethrow (Kunal Pathak) [#11530](https://github.com/nodejs/node/pull/11530) +* [[`6e5f6e3c02`](https://github.com/nodejs/node/commit/6e5f6e3c02)] - **test**: favor assertions over console logging (Rich Trott) [#11547](https://github.com/nodejs/node/pull/11547) +* [[`2c4aa39021`](https://github.com/nodejs/node/commit/2c4aa39021)] - **test**: mark test-tty-wrap as flaky for AIX (Michael Dawson) [#10618](https://github.com/nodejs/node/pull/10618) +* [[`cb03e74037`](https://github.com/nodejs/node/commit/cb03e74037)] - **test**: improve test-fs-null-bytes (Adrian Estrada) [#10521](https://github.com/nodejs/node/pull/10521) +* [[`69b55f35f7`](https://github.com/nodejs/node/commit/69b55f35f7)] - **test**: refactor test-https-truncate (Rich Trott) [#10225](https://github.com/nodejs/node/pull/10225) +* [[`ada7166dfd`](https://github.com/nodejs/node/commit/ada7166dfd)] - **test**: simplify test-http-client-unescaped-path (Rod Vagg) [#9649](https://github.com/nodejs/node/pull/9649) +* [[`1b85989fb2`](https://github.com/nodejs/node/commit/1b85989fb2)] - **test**: move long-running test to sequential (Rich Trott) [#11176](https://github.com/nodejs/node/pull/11176) +* [[`87760cc346`](https://github.com/nodejs/node/commit/87760cc346)] - **test**: add new.target add-on regression test (Ben Noordhuis) [#9689](https://github.com/nodejs/node/pull/9689) +* [[`73283060ad`](https://github.com/nodejs/node/commit/73283060ad)] - **test,repl**: add coverage for repl .clear+useGlobal (Rich Trott) [#10777](https://github.com/nodejs/node/pull/10777) +* [[`4a87aee532`](https://github.com/nodejs/node/commit/4a87aee532)] - **test,util**: remove lint workarounds (Rich Trott) [#10785](https://github.com/nodejs/node/pull/10785) +* [[`3e9ce770f7`](https://github.com/nodejs/node/commit/3e9ce770f7)] - **test-console**: streamline arrow fn and refine regex (John Maguire) [#11039](https://github.com/nodejs/node/pull/11039) +* [[`b90a141cc7`](https://github.com/nodejs/node/commit/b90a141cc7)] - **timer**: remove duplicated word in comment (asafdav2) [#11323](https://github.com/nodejs/node/pull/11323) +* [[`d71ebb90ec`](https://github.com/nodejs/node/commit/d71ebb90ec)] - **timer,domain**: maintain order of timer callbacks (John Barboza) [#10522](https://github.com/nodejs/node/pull/10522) +* [[`2a168917cb`](https://github.com/nodejs/node/commit/2a168917cb)] - **tls**: do not crash on STARTTLS when OCSP requested (Fedor Indutny) [#10706](https://github.com/nodejs/node/pull/10706) +* [[`f33684ac5f`](https://github.com/nodejs/node/commit/f33684ac5f)] - **tools**: remove custom align-function-arguments rule (Rich Trott) [#10561](https://github.com/nodejs/node/pull/10561) +* [[`fb2f449acc`](https://github.com/nodejs/node/commit/fb2f449acc)] - **tools**: update ESLint to current version (Rich Trott) [#10561](https://github.com/nodejs/node/pull/10561) +* [[`83a3aef873`](https://github.com/nodejs/node/commit/83a3aef873)] - **tools**: rename eslintrc to an undeprecated format (Sakthipriyan Vairamani) [#7699](https://github.com/nodejs/node/pull/7699) +* [[`e4f7f5c630`](https://github.com/nodejs/node/commit/e4f7f5c630)] - **tools**: add lint rule to enforce timer arguments (Rich Trott) [#9472](https://github.com/nodejs/node/pull/9472) +* [[`a13bb54466`](https://github.com/nodejs/node/commit/a13bb54466)] - **tools**: add compile_commands.json gyp generator (Ben Noordhuis) [#7986](https://github.com/nodejs/node/pull/7986) +* [[`b38d8d6e06`](https://github.com/nodejs/node/commit/b38d8d6e06)] - **tools**: suggest python2 command in configure (Roman Reiss) [#11375](https://github.com/nodejs/node/pull/11375) +* [[`291346ea51`](https://github.com/nodejs/node/commit/291346ea51)] - **tools,doc**: add Google Analytics tracking. (Phillip Johnsen) [#6601](https://github.com/nodejs/node/pull/6601) +* [[`1ed47d3f33`](https://github.com/nodejs/node/commit/1ed47d3f33)] - **tty**: avoid oob warning in TTYWrap::GetWindowSize() (Dmitry Tsvettsikh) [#11454](https://github.com/nodejs/node/pull/11454) +* [[`9e6fcbb34c`](https://github.com/nodejs/node/commit/9e6fcbb34c)] - **url**: fix surrogate handling in encodeAuth() (Timothy Gu) [#11387](https://github.com/nodejs/node/pull/11387) +* [[`53213004eb`](https://github.com/nodejs/node/commit/53213004eb)] - **util**: improve readability of normalizeEncoding (Joyee Cheung) [#10439](https://github.com/nodejs/node/pull/10439) +* [[`e54b433c8d`](https://github.com/nodejs/node/commit/e54b433c8d)] - **util**: use ES2015+ Object.is to check negative zero (Shinnosuke Watanabe) [#11332](https://github.com/nodejs/node/pull/11332) +* [[`2e15d48447`](https://github.com/nodejs/node/commit/2e15d48447)] - **v8**: drop v8::FunctionCallbackInfo\::NewTarget() (Ben Noordhuis) [#9293](https://github.com/nodejs/node/pull/9293) +* [[`fd1ffe4f5a`](https://github.com/nodejs/node/commit/fd1ffe4f5a)] - **v8**: fix --always-opt bug (Ben Noordhuis) [#9293](https://github.com/nodejs/node/pull/9293) +* [[`a55af77fc5`](https://github.com/nodejs/node/commit/a55af77fc5)] - **vm**: refactor vm module (James M Snell) [#11392](https://github.com/nodejs/node/pull/11392) + ## 2017-02-21, Version 6.10.0 'Boron' (LTS), @MylesBorins diff --git a/doc/guides/maintaining-V8.md b/doc/guides/maintaining-V8.md index 19ee61fe20c5d7..4bfed3790f5185 100644 --- a/doc/guides/maintaining-V8.md +++ b/doc/guides/maintaining-V8.md @@ -177,8 +177,8 @@ https://crbug.com/v8/5199. From the bug we can see that it was merged by V8 into `v6.x` uses V8 5.1, the fix needed to cherry-picked. To cherry-pick, here's an example workflow: -* Download and apply the commit linked-to in the issue (in this case a51f429). `curl -L https://github.com/v8/v8/commit/a51f429.patch | git apply --directory=deps/v8`. If the branches have diverged significantly, this may not apply cleanly. It may help to try to cherry-pick the merge to the oldest branch that was done upstream in V8. In this example, this would be the patch from the merge to 5.2. The hope is that this would be closer to the V8 5.1, and has a better chance of applying cleanly. If you're stuck, feel free to ping @ofrobots for help. -* Modify the commit message to match the format we use for V8 backports. You may want to add extra description if necessary to indicate the impact of the fix on Node.js. In this case the original issue was descriptive enough. Example: +* Download and apply the commit linked-to in the issue (in this case a51f429). `curl -L https://github.com/v8/v8/commit/a51f429.patch | git am -3 --directory=deps/v8`. If the branches have diverged significantly, this may not apply cleanly. It may help to try to cherry-pick the merge to the oldest branch that was done upstream in V8. In this example, this would be the patch from the merge to 5.2. The hope is that this would be closer to the V8 5.1, and has a better chance of applying cleanly. If you're stuck, feel free to ping @ofrobots for help. +* Modify the commit message to match the format we use for V8 backports and replace yourself as the author. `git commit --amend --reset-author`. You may want to add extra description if necessary to indicate the impact of the fix on Node.js. In this case the original issue was descriptive enough. Example: ``` deps: cherry-pick a51f429 from V8 upstream diff --git a/doc/guides/writing-tests.md b/doc/guides/writing-tests.md index d628e3f6f5873c..4f226bfdb2580c 100644 --- a/doc/guides/writing-tests.md +++ b/doc/guides/writing-tests.md @@ -2,26 +2,25 @@ ## What is a test? -A test must be a node script that exercises a specific functionality provided -by node and checks that it behaves as expected. It should exit with code `0` on success, -otherwise it will fail. A test will fail if: +Most tests in Node.js core are JavaScript programs that exercise a functionality +provided by Node.js and check that it behaves as expected. Tests should exit +with code `0` on success. A test will fail if: - It exits by setting `process.exitCode` to a non-zero number. - - This is most often done by having an assertion throw an uncaught - Error. + - This is usually done by having an assertion throw an uncaught Error. - Occasionally, using `process.exit(code)` may be appropriate. - It never exits. In this case, the test runner will terminate the test because it sets a maximum time limit. -Tests can be added for multiple reasons: +Add tests when: -- When adding new functionality. -- When fixing regressions and bugs. -- When expanding test coverage. +- Adding new functionality. +- Fixing regressions and bugs. +- Expanding test coverage. ## Test structure -Let's analyze this very basic test from the Node.js test suite: +Let's analyze this basic test from the Node.js test suite: ```javascript 1 'use strict'; @@ -30,8 +29,8 @@ Let's analyze this very basic test from the Node.js test suite: 4 // This test ensures that the http-parser can handle UTF-8 characters 5 // in the http header. 6 -7 const http = require('http'); -8 const assert = require('assert'); +7 const assert = require('assert'); +8 const http = require('http'); 9 10 const server = http.createServer(common.mustCall((req, res) => { 11 res.end('ok'); @@ -47,7 +46,7 @@ Let's analyze this very basic test from the Node.js test suite: 21 }); ``` -**Lines 1-2** +### **Lines 1-2** ```javascript 'use strict'; @@ -60,17 +59,18 @@ the nature of the test requires that the test run without it. The second line loads the `common` module. The `common` module is a helper module that provides useful tools for the tests. -Even if no functions or other properties exported by `common` are used in a -test, the `common` module should still be included. This is because the `common` -module includes code that will cause tests to fail if variables are leaked into -the global space. In situations where no functions or other properties exported -by `common` are used, it can be included without assigning it to an identifier: +Even if a test uses no functions or other properties exported by `common`, +the test should still include the `common` module before any other modules. This +is because the `common` module includes code that will cause a test to fail if +the test leaks variables into the global space. In situations where a test uses +no functions or other properties exported by `common`, include it without +assigning it to an identifier: ```javascript require('../common'); ``` -**Lines 4-5** +### **Lines 4-5** ```javascript // This test ensures that the http-parser can handle UTF-8 characters @@ -80,32 +80,35 @@ require('../common'); A test should start with a comment containing a brief description of what it is designed to test. -**Lines 7-8** +### **Lines 7-8** ```javascript -const http = require('http'); const assert = require('assert'); +const http = require('http'); ``` -These modules are required for the test to run. Except for special cases, these -modules should only include core modules. -The `assert` module is used by most of the tests to check that the assumptions -for the test are met. +The test checks functionality in the `http` module. + +Most tests use the `assert` module to confirm expectations of the test. + +The require statements are sorted in +[ASCII](http://man7.org/linux/man-pages/man7/ascii.7.html) order (digits, upper +case, `_`, lower case). -**Lines 10-21** +### **Lines 10-21** -This is the body of the test. This test is quite simple, it just tests that an +This is the body of the test. This test is simple, it just tests that an HTTP server accepts `non-ASCII` characters in the headers of an incoming request. Interesting things to notice: -- If the test doesn't depend on a specific port number then always use 0 instead - of an arbitrary value, as it allows tests to be run in parallel safely, as the - operating system will assign a random port. If the test requires a specific - port, for example if the test checks that assigning a specific port works as - expected, then it is ok to assign a specific port number. +- If the test doesn't depend on a specific port number, then always use 0 + instead of an arbitrary value, as it allows tests to run in parallel safely, + as the operating system will assign a random port. If the test requires a + specific port, for example if the test checks that assigning a specific port + works as expected, then it is ok to assign a specific port number. - The use of `common.mustCall` to check that some callbacks/listeners are called. -- The HTTP server is closed once all the checks have run. This way, the test can +- The HTTP server closes once all the checks have run. This way, the test can exit gracefully. Remember that for a test to succeed, it must exit with a status code of 0. @@ -113,20 +116,20 @@ request. Interesting things to notice: ### Timers -The use of timers is discouraged, unless timers are being tested. There are -multiple reasons for this. Mainly, they are a source of flakiness. For a thorough +Avoid timers unless the test is specifically testing timers. There are multiple +reasons for this. Mainly, they are a source of flakiness. For a thorough explanation go [here](https://github.com/nodejs/testing/issues/27). -In the event a timer is needed, it's recommended using the -`common.platformTimeout()` method, that allows setting specific timeouts +In the event a test needs a timer, consider using the +`common.platformTimeout()` method. It allows setting specific timeouts depending on the platform. For example: ```javascript const timer = setTimeout(fail, common.platformTimeout(4000)); ``` -will create a 4-seconds timeout, except for some platforms where the delay will -be multiplied for some factor. +will create a 4-second timeout on most platforms but a longer timeout on slower +platforms. ### The *common* API @@ -191,9 +194,9 @@ var server = http.createServer(common.mustCall(function(req, res) { ### Flags Some tests will require running Node.js with specific command line flags set. To -accomplish this, a `// Flags: ` comment should be added in the preamble of the +accomplish this, add a `// Flags: ` comment in the preamble of the test followed by the flags. For example, to allow a test to require some of the -`internal/*` modules, the `--expose-internals` flag should be added. +`internal/*` modules, add the `--expose-internals` flag. A test that would require `internal/freelist` could start like this: ```javascript @@ -205,3 +208,74 @@ require('../common'); const assert = require('assert'); const freelist = require('internal/freelist'); ``` + +### Assertions + +When writing assertions, prefer the strict versions: + +* `assert.strictEqual()` over `assert.equal()` +* `assert.deepStrictEqual()` over `assert.deepEqual()` + +When using `assert.throws()`, if possible, provide the full error message: + +```js +assert.throws( + () => { + throw new Error('Wrong value'); + }, + /^Error: Wrong value$/ // Instead of something like /Wrong value/ +); +``` + +### ES.Next features + +For performance considerations, we only use a selected subset of ES.Next +features in JavaScript code in the `lib` directory. However, when writing +tests, for the ease of backporting, it is encouraged to use those ES.Next +features that can be used directly without a flag in [all maintained branches] +(https://github.com/nodejs/lts), you can check [node.green](http://node.green) +for all available features in each release. + +For example: + +* `let` and `const` over `var` +* Template literals over string concatenation +* Arrow functions when appropriate + +## Naming Test Files + +Test files are named using kebab casing. The first component of the name is +`test`. The second is the module or subsystem being tested. The third is usually +the method or event name being tested. Subsequent components of the name add +more information about what is being tested. + +For example, a test for the `beforeExit` event on the `process` object might be +named `test-process-before-exit.js`. If the test specifically checked that arrow +functions worked correctly with the `beforeExit` event, then it might be named +`test-process-before-exit-arrow-functions.js`. + +## Imported Tests + +### Web Platform Tests + +Some of the tests for the WHATWG URL implementation (named +`test-whatwg-url-*.js`) are imported from the +[Web Platform Tests Project](https://github.com/w3c/web-platform-tests/tree/master/url). +These imported tests will be wrapped like this: + +```js +/* eslint-disable */ +/* WPT Refs: + https://github.com/w3c/web-platform-tests/blob/8791bed/url/urlsearchparams-stringifier.html + License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html +*/ + +// Test code + +/* eslint-enable */ +``` + +If you want to improve tests that have been imported this way, please send +a PR to the upstream project first. When your proposed change is merged in +the upstream project, send another PR here to update Node.js accordingly. +Be sure to update the hash in the URL following `WPT Refs:`. diff --git a/doc/onboarding-extras.md b/doc/onboarding-extras.md index a952bae866cd95..80691ddd0dd58b 100644 --- a/doc/onboarding-extras.md +++ b/doc/onboarding-extras.md @@ -11,8 +11,10 @@ | `lib/child_process` | @bnoordhuis, @cjihrig | | `lib/cluster` | @bnoordhuis, @cjihrig, @mcollina | | `lib/{crypto,tls,https}` | @nodejs/crypto | +| `lib/dgram` | @cjihrig, @mcollina | | `lib/domains` | @misterdjules | | `lib/fs`, `src/{fs|file}` | @nodejs/fs | +| `lib/internal/url`, `src/node_url` | @nodejs/url | | `lib/{_}http{*}` | @nodejs/http | | `lib/net` | @bnoordhuis, @indutny, @nodejs/streams | | `lib/{_}stream{s|*}` | @nodejs/streams | @@ -23,10 +25,10 @@ | `src/async-wrap.*` | @trevnorris | | `src/node_crypto.*` | @nodejs/crypto | | `test/*` | @nodejs/testing | -| `tools/eslint`, `.eslintrc` | @silverwind, @trott | +| `tools/eslint`, `.eslintrc` | @not-an-aardvark, @silverwind, @trott | | async_hooks | @nodejs/diagnostics | | upgrading V8 | @nodejs/v8, @nodejs/post-mortem | -| upgrading npm | @fishrock123, @thealphanerd | +| upgrading npm | @fishrock123, @MylesBorins | | upgrading c-ares | @jbergstroem | | upgrading http-parser | @jbergstroem, @nodejs/http | | upgrading libuv | @saghul | diff --git a/doc/onboarding.md b/doc/onboarding.md index dbe3dfd569b7ae..4fd207637b90ec 100644 --- a/doc/onboarding.md +++ b/doc/onboarding.md @@ -71,6 +71,10 @@ onboarding session. * [**See "Who to CC in issues"**](./onboarding-extras.md#who-to-cc-in-issues) * will also come more naturally over time + * When a discussion gets heated, you can request that other collaborators keep an eye on it by opening an issue at the private [nodejs/moderation](https://github.com/nodejs/moderation) repository. + * This is a repository to which all members of the `nodejs` GitHub organization (not just Collaborators on Node.js core) have access. Its contents should not be shared externally. + * You can find the full moderation policy [here](https://github.com/nodejs/TSC/blob/master/Moderation-Policy.md). + ## Reviewing PRs * The primary goal is for the codebase to improve. * Secondary (but not far off) is for the person submitting code to succeed. @@ -135,6 +139,7 @@ onboarding session. * Example: [https://github.com/nodejs/node/commit/7b09aade8468e1c930f36b9c81e6ac2ed5bc8732](https://github.com/nodejs/node/commit/7b09aade8468e1c930f36b9c81e6ac2ed5bc8732) * For raw commit message: `git log 7b09aade8468e1c930f36b9c81e6ac2ed5bc8732 -1` * Collaborators are in alphabetical order by GitHub username. + * Optionally, include your personal pronouns. * Label your pull request with the `doc` subsystem label. * Run CI on your PR. * After a `LGTM` or two, land the PR. diff --git a/doc/template.html b/doc/template.html index af680645d15080..572197beff44fe 100644 --- a/doc/template.html +++ b/doc/template.html @@ -45,5 +45,6 @@

Table of Contents

+ diff --git a/lib/.eslintrc b/lib/.eslintrc.yaml similarity index 100% rename from lib/.eslintrc rename to lib/.eslintrc.yaml diff --git a/lib/_http_client.js b/lib/_http_client.js index 4ca03eae6796ac..b1f95469bc11d1 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -43,13 +43,12 @@ function ClientRequest(options, cb) { if (self.agent && self.agent.protocol) expectedProtocol = self.agent.protocol; - if (options.path && / /.test(options.path)) { + if (options.path && /[\u0000-\u0020]/.test(options.path)) { // The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/ // with an additional rule for ignoring percentage-escaped characters // but that's a) hard to capture in a regular expression that performs - // well, and b) possibly too restrictive for real-world usage. That's - // why it only scans for spaces because those are guaranteed to create - // an invalid request. + // well, and b) possibly too restrictive for real-world usage. + // Restrict the filter to control characters and spaces. throw new TypeError('Request path contains unescaped characters'); } else if (protocol !== expectedProtocol) { throw new Error('Protocol "' + protocol + '" not supported. ' + @@ -581,7 +580,11 @@ ClientRequest.prototype.onSocket = function(socket) { function onSocketNT(req, socket) { if (req.aborted) { // If we were aborted while waiting for a socket, skip the whole thing. - socket.emit('free'); + if (req.socketPath || !req.agent) { + socket.destroy(); + } else { + socket.emit('free'); + } } else { tickOnSocket(req, socket); } diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index a7467168c5899f..2b0b158721f562 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -315,6 +315,7 @@ function storeHeader(self, state, field, value) { 'Header name must be a valid HTTP Token ["' + field + '"]'); } if (common._checkInvalidHeaderChar(value) === true) { + debug('Header "%s" contains invalid characters', field); throw new TypeError('The header content contains invalid characters'); } state.messageHeader += field + ': ' + escapeHeaderValue(value) + CRLF; @@ -355,6 +356,7 @@ OutgoingMessage.prototype.setHeader = function(name, value) { if (this._header) throw new Error('Can\'t set headers after they are sent.'); if (common._checkInvalidHeaderChar(value) === true) { + debug('Header "%s" contains invalid characters', name); throw new TypeError('The header content contains invalid characters'); } if (this._headers === null) @@ -532,6 +534,7 @@ OutgoingMessage.prototype.addTrailers = function(headers) { 'Trailer name must be a valid HTTP Token ["' + field + '"]'); } if (common._checkInvalidHeaderChar(value) === true) { + debug('Trailer "%s" contains invalid characters', field); throw new TypeError('The header content contains invalid characters'); } this._trailer += field + ': ' + escapeHeaderValue(value) + CRLF; diff --git a/lib/_http_server.js b/lib/_http_server.js index fc88e8938c7f40..d036a410f6f40f 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -345,9 +345,11 @@ function connectionListener(socket) { // Override on to unconsume on `data`, `readable` listeners socket.on = socketOnWrap; + // We only consume the socket if it has never been consumed before. var external = socket._handle._externalStream; - if (external) { + if (!socket._handle._consumed && external) { parser._consumed = true; + socket._handle._consumed = true; parser.consume(external); } external = null; diff --git a/lib/_tls_common.js b/lib/_tls_common.js index 9cb70453860484..e161a484866f01 100644 --- a/lib/_tls_common.js +++ b/lib/_tls_common.js @@ -140,7 +140,9 @@ exports.createSecureContext = function createSecureContext(options, context) { } } - // Do not keep read/write buffers in free list + // Do not keep read/write buffers in free list for OpenSSL < 1.1.0. (For + // OpenSSL 1.1.0, buffers are malloced and freed without the use of a + // freelist.) if (options.singleUse) { c.singleUse = true; c.context.setFreeListLength(0); diff --git a/lib/_tls_legacy.js b/lib/_tls_legacy.js index f974b0cfc05575..e765b2507e7502 100644 --- a/lib/_tls_legacy.js +++ b/lib/_tls_legacy.js @@ -1,6 +1,6 @@ 'use strict'; -require('internal/util').assertCrypto(exports); +require('internal/util').assertCrypto(); const assert = require('assert'); const EventEmitter = require('events'); diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index cf40618aa32b3d..a4e3d6bd08b95e 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -1,6 +1,6 @@ 'use strict'; -require('internal/util').assertCrypto(exports); +require('internal/util').assertCrypto(); const assert = require('assert'); const crypto = require('crypto'); @@ -114,6 +114,13 @@ function requestOCSP(self, hello, ctx, cb) { if (!ctx) ctx = self.server._sharedCreds; + + // TLS socket is using a `net.Server` instead of a tls.TLSServer. + // Some TLS properties like `server._sharedCreds` will not be present + if (!ctx) + return cb(null); + + // TODO(indutny): eventually disallow raw `SecureContext` if (ctx.context) ctx = ctx.context; diff --git a/lib/assert.js b/lib/assert.js index 0458bb09816872..f18cc45fc3fe2f 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -1,7 +1,3 @@ -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// // Originally from narwhal.js (http://narwhaljs.org) // Copyright (c) 2009 Thomas Robinson <280north.com> // @@ -30,16 +26,16 @@ const util = require('util'); const Buffer = require('buffer').Buffer; const pToString = (obj) => Object.prototype.toString.call(obj); -// 1. The assert module provides functions that throw +// The assert module provides functions that throw // AssertionError's when particular conditions are not met. The // assert module must conform to the following interface. const assert = module.exports = ok; -// 2. The AssertionError is defined in assert. +// The AssertionError is defined in assert. // new assert.AssertionError({ message: message, // actual: actual, -// expected: expected }) +// expected: expected }); assert.AssertionError = function AssertionError(options) { this.name = 'AssertionError'; @@ -75,7 +71,7 @@ function getMessage(self) { // other keys to the AssertionError's constructor - they will be // ignored. -// 3. All of the following functions must throw an AssertionError +// All of the following functions must throw an AssertionError // when a corresponding condition is not met, with a message that // may be undefined if not provided. All assertion methods provide // both the actual and expected values to the assertion error for @@ -94,7 +90,7 @@ function fail(actual, expected, message, operator, stackStartFunction) { // EXTENSION! allows for well behaved errors defined elsewhere. assert.fail = fail; -// 4. Pure assertion tests whether a value is truthy, as determined +// Pure assertion tests whether a value is truthy, as determined // by !!guard. // assert.ok(guard, message_opt); // This statement is equivalent to assert.equal(true, !!guard, @@ -106,7 +102,7 @@ function ok(value, message) { } assert.ok = ok; -// 5. The equality assertion tests shallow, coercive equality with +// The equality assertion tests shallow, coercive equality with // ==. // assert.equal(actual, expected, message_opt); @@ -114,8 +110,9 @@ assert.equal = function equal(actual, expected, message) { if (actual != expected) fail(actual, expected, message, '==', assert.equal); }; -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); +// The non-equality assertion tests for whether two objects are not +// equal with !=. +// assert.notEqual(actual, expected, message_opt); assert.notEqual = function notEqual(actual, expected, message) { if (actual == expected) { @@ -123,7 +120,7 @@ assert.notEqual = function notEqual(actual, expected, message) { } }; -// 7. The equivalence assertion tests a deep equality relation. +// The equivalence assertion tests a deep equality relation. // assert.deepEqual(actual, expected, message_opt); /* eslint-disable no-restricted-properties */ @@ -141,18 +138,22 @@ assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { }; function _deepEqual(actual, expected, strict, memos) { - // 7.1. All identical values are equivalent, as determined by ===. + // All identical values are equivalent, as determined by ===. if (actual === expected) { return true; + + // If both values are instances of buffers, equivalence is + // determined by comparing the values and ensuring the result + // === 0. } else if (actual instanceof Buffer && expected instanceof Buffer) { return compare(actual, expected) === 0; - // 7.2. If the expected value is a Date object, the actual value is + // If the expected value is a Date object, the actual value is // equivalent if it is also a Date object that refers to the same time. } else if (util.isDate(actual) && util.isDate(expected)) { return actual.getTime() === expected.getTime(); - // 7.3 If the expected value is a RegExp object, the actual value is + // If the expected value is a RegExp object, the actual value is // equivalent if it is also a RegExp object with the same source and // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). } else if (util.isRegExp(actual) && util.isRegExp(expected)) { @@ -162,18 +163,18 @@ function _deepEqual(actual, expected, strict, memos) { actual.lastIndex === expected.lastIndex && actual.ignoreCase === expected.ignoreCase; - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. + // If both values are primitives, equivalence is determined by + // == or, if checking for strict equivalence, ===. } else if ((actual === null || typeof actual !== 'object') && (expected === null || typeof expected !== 'object')) { return strict ? actual === expected : actual == expected; // If both values are instances of typed arrays, wrap their underlying - // ArrayBuffers in a Buffer each to increase performance + // ArrayBuffers in a Buffer to increase performance. // This optimization requires the arrays to have the same type as checked by - // Object.prototype.toString (aka pToString). Never perform binary - // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their - // bit patterns are not identical. + // Object.prototype.toString (pToString). Never perform binary + // comparisons for Float*Arrays, though, since +0 === -0 is true despite the + // two values' bit patterns not being identical. } else if (ArrayBuffer.isView(actual) && ArrayBuffer.isView(expected) && pToString(actual) === pToString(expected) && !(actual instanceof Float32Array || @@ -185,7 +186,7 @@ function _deepEqual(actual, expected, strict, memos) { expected.byteOffset, expected.byteLength)) === 0; - // 7.5 For all other Object pairs, including Array objects, equivalence is + // For all other Object pairs, including Array objects, equivalence is // determined by having the same number of owned properties (as verified // with Object.prototype.hasOwnProperty.call), the same set of keys // (although not necessarily the same order), equivalent values for every @@ -209,13 +210,14 @@ function _deepEqual(actual, expected, strict, memos) { } function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; + return Object.prototype.toString.call(object) === '[object Arguments]'; } function objEquiv(a, b, strict, actualVisitedObjects) { if (a === null || a === undefined || b === null || b === undefined) return false; - // if one is a primitive, the other must be same + + // If one is a primitive, the other must be the same. if (util.isPrimitive(a) || util.isPrimitive(b)) return a === b; if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) @@ -227,20 +229,23 @@ function objEquiv(a, b, strict, actualVisitedObjects) { const ka = Object.keys(a); const kb = Object.keys(b); var key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) + + // The pair must have the same number of owned properties (keys + // incorporates hasOwnProperty). if (ka.length !== kb.length) return false; - //the same set of keys (although not necessarily the same order), + + // The pair must have the same set of keys (although not + // necessarily in the same order). ka.sort(); kb.sort(); - //~~~cheap key test + // Cheap key test: for (i = ka.length - 1; i >= 0; i--) { if (ka[i] !== kb[i]) return false; } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test + // The pair must have equivalent values for every corresponding key. + // Possibly expensive deep test: for (i = ka.length - 1; i >= 0; i--) { key = ka[i]; if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) @@ -249,7 +254,7 @@ function objEquiv(a, b, strict, actualVisitedObjects) { return true; } -// 8. The non-equivalence assertion tests for any deep inequality. +// The non-equivalence assertion tests for any deep inequality. // assert.notDeepEqual(actual, expected, message_opt); assert.notDeepEqual = function notDeepEqual(actual, expected, message) { @@ -266,7 +271,7 @@ function notDeepStrictEqual(actual, expected, message) { } -// 9. The strict equality assertion tests strict equality, as determined by ===. +// The strict equality assertion tests strict equality, as determined by ===. // assert.strictEqual(actual, expected, message_opt); assert.strictEqual = function strictEqual(actual, expected, message) { @@ -275,8 +280,9 @@ assert.strictEqual = function strictEqual(actual, expected, message) { } }; -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); +// The strict non-equality assertion tests for strict inequality, as +// determined by !==. +// assert.notStrictEqual(actual, expected, message_opt); assert.notStrictEqual = function notStrictEqual(actual, expected, message) { if (actual === expected) { @@ -285,11 +291,12 @@ assert.notStrictEqual = function notStrictEqual(actual, expected, message) { }; function expectedException(actual, expected) { - if (!actual || !expected) { + // actual is guaranteed to be an Error object, but we need to check expected. + if (!expected) { return false; } - if (Object.prototype.toString.call(expected) == '[object RegExp]') { + if (Object.prototype.toString.call(expected) === '[object RegExp]') { return expected.test(actual); } @@ -298,7 +305,7 @@ function expectedException(actual, expected) { return true; } } catch (e) { - // Ignore. The instanceof check doesn't work for arrow functions. + // Ignore. The instanceof check doesn't work for arrow functions. } if (Error.isPrototypeOf(expected)) { @@ -356,7 +363,7 @@ function _throws(shouldThrow, block, expected, message) { } } -// 11. Expected to throw an error: +// Expected to throw an error. // assert.throws(block, Error_opt, message_opt); assert.throws = function(block, /*optional*/error, /*optional*/message) { diff --git a/lib/buffer.js b/lib/buffer.js index b1c0fc702ec1d5..7c29af3353d474 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -2,6 +2,7 @@ 'use strict'; const binding = process.binding('buffer'); +const { compare: compare_, compareOffset } = binding; const { isArrayBuffer, isSharedArrayBuffer } = process.binding('util'); const bindingObj = {}; const internalUtil = require('internal/util'); @@ -216,7 +217,7 @@ function fromArrayLike(obj) { } function fromArrayBuffer(obj, byteOffset, length) { - byteOffset >>>= 0; + byteOffset = internalUtil.toInteger(byteOffset); const maxLength = obj.byteLength - byteOffset; @@ -226,7 +227,7 @@ function fromArrayBuffer(obj, byteOffset, length) { if (length === undefined) { length = maxLength; } else { - length >>>= 0; + length = internalUtil.toLength(length); if (length > maxLength) throw new RangeError("'length' is out of bounds"); } @@ -529,36 +530,43 @@ Buffer.prototype.compare = function compare(target, if (!(target instanceof Buffer)) throw new TypeError('Argument must be a Buffer'); + if (arguments.length === 1) + return compare_(this, target); if (start === undefined) start = 0; + else if (start < 0) + throw new RangeError('out of range index'); + else + start >>>= 0; + if (end === undefined) end = target.length; + else if (end > target.length) + throw new RangeError('out of range index'); + else + end >>>= 0; + if (thisStart === undefined) thisStart = 0; + else if (thisStart < 0) + throw new RangeError('out of range index'); + else + thisStart >>>= 0; + if (thisEnd === undefined) thisEnd = this.length; - - if (start < 0 || - end > target.length || - thisStart < 0 || - thisEnd > this.length) { + else if (thisEnd > this.length) throw new RangeError('out of range index'); - } + else + thisEnd >>>= 0; - if (thisStart >= thisEnd && start >= end) - return 0; if (thisStart >= thisEnd) - return -1; - if (start >= end) + return (start >= end ? 0 : -1); + else if (start >= end) return 1; - start >>>= 0; - end >>>= 0; - thisStart >>>= 0; - thisEnd >>>= 0; - - return binding.compareOffset(this, target, start, thisStart, end, thisEnd); + return compareOffset(this, target, start, thisStart, end, thisEnd); }; @@ -580,9 +588,10 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { } else if (byteOffset < -0x80000000) { byteOffset = -0x80000000; } - byteOffset = +byteOffset; // Coerce to Number. - if (isNaN(byteOffset)) { - // If the offset is undefined, null, NaN, "foo", etc, search whole buffer. + // Coerce to Number. Values like null and [] become 0. + byteOffset = +byteOffset; + // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer. + if (Number.isNaN(byteOffset)) { byteOffset = dir ? 0 : (buffer.length - 1); } dir = !!dir; // Cast to bool. @@ -785,10 +794,14 @@ Buffer.prototype.write = function(string, offset, length, encoding) { Buffer.prototype.toJSON = function() { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this, 0) - }; + if (this.length) { + const data = []; + for (var i = 0; i < this.length; ++i) + data[i] = this[i]; + return { type: 'Buffer', data }; + } else { + return { type: 'Buffer', data: [] }; + } }; diff --git a/lib/child_process.js b/lib/child_process.js index ad8842e520c3be..5e37c81a1e0c33 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -191,9 +191,7 @@ exports.execFile = function(file /*, args, options, callback*/) { stderr = Buffer.concat(_stderr); } - if (ex) { - // Will be handled later - } else if (code === 0 && signal === null) { + if (!ex && code === 0 && signal === null) { callback(null, stdout, stderr); return; } diff --git a/lib/crypto.js b/lib/crypto.js index aa5a7d0cc97579..72602ff1a43555 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -4,7 +4,7 @@ 'use strict'; const internalUtil = require('internal/util'); -internalUtil.assertCrypto(exports); +internalUtil.assertCrypto(); exports.DEFAULT_ENCODING = 'buffer'; @@ -633,17 +633,17 @@ exports.randomBytes = exports.pseudoRandomBytes = randomBytes; exports.rng = exports.prng = randomBytes; -exports.getCiphers = internalUtil.cachedResult(() => { - return internalUtil.filterDuplicateStrings(getCiphers()); -}); +exports.getCiphers = internalUtil.cachedResult( + () => internalUtil.filterDuplicateStrings(getCiphers()) +); -exports.getHashes = internalUtil.cachedResult(() => { - return internalUtil.filterDuplicateStrings(getHashes()); -}); +exports.getHashes = internalUtil.cachedResult( + () => internalUtil.filterDuplicateStrings(getHashes()) +); -exports.getCurves = internalUtil.cachedResult(() => { - return internalUtil.filterDuplicateStrings(getCurves()); -}); +exports.getCurves = internalUtil.cachedResult( + () => internalUtil.filterDuplicateStrings(getCurves()) +); Object.defineProperty(exports, 'fips', { get: getFipsCrypto, diff --git a/lib/dgram.js b/lib/dgram.js index 31be3ce881ed22..97c2de5fc47ef7 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -134,24 +134,23 @@ function replaceHandle(self, newHandle) { self._handle = newHandle; } -Socket.prototype.bind = function(port_ /*, address, callback*/) { - var self = this; +Socket.prototype.bind = function(port_, address_ /*, callback*/) { let port = port_; - self._healthCheck(); + this._healthCheck(); if (this._bindState != BIND_STATE_UNBOUND) throw new Error('Socket is already bound'); this._bindState = BIND_STATE_BINDING; - if (typeof arguments[arguments.length - 1] === 'function') - self.once('listening', arguments[arguments.length - 1]); + if (arguments.length && typeof arguments[arguments.length - 1] === 'function') + this.once('listening', arguments[arguments.length - 1]); if (port instanceof UDP) { - replaceHandle(self, port); - startListening(self); - return self; + replaceHandle(this, port); + startListening(this); + return this; } var address; @@ -162,22 +161,22 @@ Socket.prototype.bind = function(port_ /*, address, callback*/) { exclusive = !!port.exclusive; port = port.port; } else { - address = typeof arguments[1] === 'function' ? '' : arguments[1]; + address = typeof address_ === 'function' ? '' : address_; exclusive = false; } // defaulting address for bind to all interfaces - if (!address && self._handle.lookup === lookup4) { + if (!address && this._handle.lookup === lookup4) { address = '0.0.0.0'; - } else if (!address && self._handle.lookup === lookup6) { + } else if (!address && this._handle.lookup === lookup6) { address = '::'; } // resolve address first - self._handle.lookup(address, function(err, ip) { + this._handle.lookup(address, (err, ip) => { if (err) { - self._bindState = BIND_STATE_UNBOUND; - self.emit('error', err); + this._bindState = BIND_STATE_UNBOUND; + this.emit('error', err); return; } @@ -185,51 +184,50 @@ Socket.prototype.bind = function(port_ /*, address, callback*/) { cluster = require('cluster'); var flags = 0; - if (self._reuseAddr) + if (this._reuseAddr) flags |= UV_UDP_REUSEADDR; if (cluster.isWorker && !exclusive) { - function onHandle(err, handle) { + const onHandle = (err, handle) => { if (err) { var ex = exceptionWithHostPort(err, 'bind', ip, port); - self.emit('error', ex); - self._bindState = BIND_STATE_UNBOUND; + this.emit('error', ex); + this._bindState = BIND_STATE_UNBOUND; return; } - if (!self._handle) + if (!this._handle) // handle has been closed in the mean time. return handle.close(); - replaceHandle(self, handle); - startListening(self); - } - cluster._getServer(self, { + replaceHandle(this, handle); + startListening(this); + }; + cluster._getServer(this, { address: ip, port: port, - addressType: self.type, + addressType: this.type, fd: -1, flags: flags }, onHandle); - } else { - if (!self._handle) + if (!this._handle) return; // handle has been closed in the mean time - const err = self._handle.bind(ip, port || 0, flags); + const err = this._handle.bind(ip, port || 0, flags); if (err) { var ex = exceptionWithHostPort(err, 'bind', ip, port); - self.emit('error', ex); - self._bindState = BIND_STATE_UNBOUND; + this.emit('error', ex); + this._bindState = BIND_STATE_UNBOUND; // Todo: close? return; } - startListening(self); + startListening(this); } }); - return self; + return this; }; @@ -315,7 +313,6 @@ Socket.prototype.send = function(buffer, port, address, callback) { - const self = this; let list; if (address || (port && typeof port !== 'function')) { @@ -347,24 +344,26 @@ Socket.prototype.send = function(buffer, if (typeof callback !== 'function') callback = undefined; - self._healthCheck(); + this._healthCheck(); - if (self._bindState == BIND_STATE_UNBOUND) - self.bind({port: 0, exclusive: true}, null); + if (this._bindState === BIND_STATE_UNBOUND) + this.bind({port: 0, exclusive: true}, null); if (list.length === 0) list.push(Buffer.alloc(0)); // If the socket hasn't been bound yet, push the outbound packet onto the // send queue and send after binding is complete. - if (self._bindState != BIND_STATE_BOUND) { - enqueue(self, self.send.bind(self, list, port, address, callback)); + if (this._bindState !== BIND_STATE_BOUND) { + enqueue(this, this.send.bind(this, list, port, address, callback)); return; } - self._handle.lookup(address, function afterDns(ex, ip) { - doSend(ex, self, ip, list, address, port, callback); - }); + const afterDns = (ex, ip) => { + doSend(ex, this, ip, list, address, port, callback); + }; + + this._handle.lookup(address, afterDns); }; diff --git a/lib/fs.js b/lib/fs.js index 9140393ba68c3a..bcebdb34c9b8b6 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -74,7 +74,7 @@ try { printDeprecation('fs: re-evaluating native module sources is not ' + 'supported. If you are using the graceful-fs module, ' + 'please update it to a more recent version.', - false); + false); } function throwOptionsError(options) { @@ -147,7 +147,7 @@ function isFd(path) { } // Static method to set the stats properties on a Stats object. -fs.Stats = function( +function Stats( dev, mode, nlink, @@ -176,7 +176,8 @@ fs.Stats = function( this.mtime = new Date(mtim_msec); this.ctime = new Date(ctim_msec); this.birthtime = new Date(birthtim_msec); -}; +} +fs.Stats = Stats; // Create a C++ binding to the function which creates a Stats object. binding.FSInitialize(fs.Stats); @@ -261,7 +262,7 @@ fs.exists = function(path, callback) { fs.existsSync = function(path) { try { nullCheck(path); - binding.stat(pathModule._makeLong(path)); + binding.stat(pathModule._makeLong(path), statValues); return true; } catch (e) { return false; @@ -973,18 +974,31 @@ fs.stat = function(path, callback) { binding.stat(pathModule._makeLong(path), req); }; +const statValues = new Float64Array(14); +function statsFromValues() { + return new Stats(statValues[0], statValues[1], statValues[2], statValues[3], + statValues[4], statValues[5], + statValues[6] < 0 ? undefined : statValues[6], statValues[7], + statValues[8], statValues[9] < 0 ? undefined : statValues[9], + statValues[10], statValues[11], statValues[12], + statValues[13]); +} + fs.fstatSync = function(fd) { - return binding.fstat(fd); + binding.fstat(fd, statValues); + return statsFromValues(); }; fs.lstatSync = function(path) { nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); + binding.lstat(pathModule._makeLong(path), statValues); + return statsFromValues(); }; fs.statSync = function(path) { nullCheck(path); - return binding.stat(pathModule._makeLong(path)); + binding.stat(pathModule._makeLong(path), statValues); + return statsFromValues(); }; fs.readlink = function(path, options, callback) { diff --git a/lib/https.js b/lib/https.js index b8969b68452451..4ecd2e8db63412 100644 --- a/lib/https.js +++ b/lib/https.js @@ -1,6 +1,6 @@ 'use strict'; -require('internal/util').assertCrypto(exports); +require('internal/util').assertCrypto(); const tls = require('tls'); const url = require('url'); diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 100b5063da1e60..023e85c1d0721e 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -48,6 +48,7 @@ _process.setup_hrtime(); _process.setup_cpuUsage(); + _process.setupMemoryUsage(); _process.setupConfig(NativeModule._source); NativeModule.require('internal/process/warning').setup(); NativeModule.require('internal/process/next_tick').setup(); @@ -367,9 +368,7 @@ } function isDebugBreak() { - return process.execArgv.some((arg) => { - return arg.match(/^--debug-brk(=[0-9]*)?$/); - }); + return process.execArgv.some((arg) => /^--debug-brk(=[0-9]+)?$/.test(arg)); } function run(entryFunction) { diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index f79657048cc489..a03b6cefd5c69b 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -230,12 +230,16 @@ util.inherits(ChildProcess, EventEmitter); function flushStdio(subprocess) { - if (subprocess.stdio == null) return; - subprocess.stdio.forEach(function(stream, fd, stdio) { + const stdio = subprocess.stdio; + + if (stdio == null) return; + + for (var i = 0; i < stdio.length; i++) { + const stream = stdio[i]; if (!stream || !stream.readable || stream._readableState.readableListening) - return; + continue; stream.resume(); - }); + } } @@ -268,6 +272,7 @@ ChildProcess.prototype.spawn = function(options) { const self = this; var ipc; var ipcFd; + var i; // If no `stdio` option was given - use default var stdio = options.stdio || 'pipe'; @@ -302,11 +307,12 @@ ChildProcess.prototype.spawn = function(options) { if (err !== uv.UV_ENOENT) return err; } else if (err) { // Close all opened fds on error - stdio.forEach(function(stdio) { - if (stdio.type === 'pipe') { - stdio.handle.close(); + for (i = 0; i < stdio.length; i++) { + const stream = stdio[i]; + if (stream.type === 'pipe') { + stream.handle.close(); } - }); + } this._handle.close(); this._handle = null; @@ -315,27 +321,29 @@ ChildProcess.prototype.spawn = function(options) { this.pid = this._handle.pid; - stdio.forEach(function(stdio, i) { - if (stdio.type === 'ignore') return; + for (i = 0; i < stdio.length; i++) { + const stream = stdio[i]; + if (stream.type === 'ignore') continue; - if (stdio.ipc) { + if (stream.ipc) { self._closesNeeded++; - return; + continue; } - if (stdio.handle) { + if (stream.handle) { // when i === 0 - we're dealing with stdin // (which is the only one writable pipe) - stdio.socket = createSocket(self.pid !== 0 ? stdio.handle : null, i > 0); + stream.socket = createSocket(self.pid !== 0 ? + stream.handle : null, i > 0); if (i > 0 && self.pid !== 0) { self._closesNeeded++; - stdio.socket.on('close', function() { + stream.socket.on('close', function() { maybeClose(self); }); } } - }); + } this.stdin = stdio.length >= 1 && stdio[0].socket !== undefined ? stdio[0].socket : null; @@ -407,30 +415,31 @@ ChildProcess.prototype.unref = function() { if (this._handle) this._handle.unref(); }; +class Control extends EventEmitter { + constructor(channel) { + super(); + this.channel = channel; + this.refs = 0; + } + ref() { + if (++this.refs === 1) { + this.channel.ref(); + } + } + unref() { + if (--this.refs === 0) { + this.channel.unref(); + this.emit('unref'); + } + } +} function setupChannel(target, channel) { target._channel = channel; target._handleQueue = null; target._pendingHandle = null; - const control = new class extends EventEmitter { - constructor() { - super(); - this.channel = channel; - this.refs = 0; - } - ref() { - if (++this.refs === 1) { - this.channel.ref(); - } - } - unref() { - if (--this.refs === 0) { - this.channel.unref(); - this.emit('unref'); - } - } - }(); + const control = new Control(channel); var decoder = new StringDecoder('utf8'); var jsonBuffer = ''; @@ -783,11 +792,11 @@ function _validateStdio(stdio, sync) { } // Defaults - if (stdio === null || stdio === undefined) { + if (stdio == null) { stdio = i < 3 ? 'pipe' : 'ignore'; } - if (stdio === null || stdio === 'ignore') { + if (stdio === 'ignore') { acc.push({type: 'ignore'}); } else if (stdio === 'pipe' || typeof stdio === 'number' && stdio < 0) { var a = { @@ -873,7 +882,7 @@ function getSocketList(type, slave, key) { function maybeClose(subprocess) { subprocess._closesGot++; - if (subprocess._closesGot == subprocess._closesNeeded) { + if (subprocess._closesGot === subprocess._closesNeeded) { subprocess.emit('close', subprocess.exitCode, subprocess.signalCode); } } diff --git a/lib/internal/module.js b/lib/internal/module.js index a12af12f3e3d7e..2f38618daac5f7 100644 --- a/lib/internal/module.js +++ b/lib/internal/module.js @@ -51,10 +51,12 @@ function stripBOM(content) { return content; } -exports.builtinLibs = ['assert', 'buffer', 'child_process', 'cluster', - 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net', - 'os', 'path', 'punycode', 'querystring', 'readline', 'repl', 'stream', - 'string_decoder', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib']; +exports.builtinLibs = [ + 'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns', + 'domain', 'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'punycode', + 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'tls', 'tty', + 'url', 'util', 'v8', 'vm', 'zlib' +]; function addBuiltinLibsToObject(object) { // Make built-in modules available directly (loaded lazily). diff --git a/lib/internal/process.js b/lib/internal/process.js index 8afb89dccac84b..c8a58504fcf307 100644 --- a/lib/internal/process.js +++ b/lib/internal/process.js @@ -11,6 +11,7 @@ function lazyConstants() { exports.setup_cpuUsage = setup_cpuUsage; exports.setup_hrtime = setup_hrtime; +exports.setupMemoryUsage = setupMemoryUsage; exports.setupConfig = setupConfig; exports.setupKillAndExit = setupKillAndExit; exports.setupSignalHandlers = setupSignalHandlers; @@ -73,7 +74,9 @@ function setup_cpuUsage() { }; } - +// The 3 entries filled in by the original process.hrtime contains +// the upper/lower 32 bits of the second part of the value, +// and the remaining nanoseconds of the value. function setup_hrtime() { const _hrtime = process.hrtime; const hrValues = new Uint32Array(3); @@ -98,6 +101,20 @@ function setup_hrtime() { }; } +function setupMemoryUsage() { + const memoryUsage_ = process.memoryUsage; + const memValues = new Float64Array(4); + + process.memoryUsage = function memoryUsage() { + memoryUsage_(memValues); + return { + rss: memValues[0], + heapTotal: memValues[1], + heapUsed: memValues[2], + external: memValues[3] + }; + }; +} function setupConfig(_source) { // NativeModule._source @@ -124,6 +141,7 @@ function setupConfig(_source) { Intl.hasOwnProperty('v8BreakIterator') && !process.icu_data_dir) { const des = Object.getOwnPropertyDescriptor(Intl, 'v8BreakIterator'); + // eslint-disable-next-line func-name-matching des.value = function v8BreakIterator() { throw new Error('v8BreakIterator: full ICU data not installed. ' + 'See https://github.com/nodejs/node/wiki/Intl'); diff --git a/lib/internal/process/next_tick.js b/lib/internal/process/next_tick.js index f27ef622a96e6a..ad635aaf494b33 100644 --- a/lib/internal/process/next_tick.js +++ b/lib/internal/process/next_tick.js @@ -1,5 +1,11 @@ 'use strict'; +// This value is used to prevent the nextTickQueue from becoming too +// large and cause the process to run out of memory. When this value +// is reached the nextTimeQueue array will be shortend (see tickDone +// for details). +const kMaxCallbacksPerLoop = 1e4; + exports.setup = setupNextTick; function setupNextTick() { @@ -96,7 +102,7 @@ function setupNextTick() { // callback invocation with small numbers of arguments to avoid the // performance hit associated with using `fn.apply()` _combinedTickCallback(args, callback); - if (1e4 < tickInfo[kIndex]) + if (kMaxCallbacksPerLoop < tickInfo[kIndex]) tickDone(); } tickDone(); @@ -120,7 +126,7 @@ function setupNextTick() { // callback invocation with small numbers of arguments to avoid the // performance hit associated with using `fn.apply()` _combinedTickCallback(args, callback); - if (1e4 < tickInfo[kIndex]) + if (kMaxCallbacksPerLoop < tickInfo[kIndex]) tickDone(); if (domain) domain.exit(); diff --git a/lib/internal/streams/legacy.js b/lib/internal/streams/legacy.js new file mode 100644 index 00000000000000..3242b15eabdb0d --- /dev/null +++ b/lib/internal/streams/legacy.js @@ -0,0 +1,93 @@ +'use strict'; + +const EE = require('events'); +const util = require('util'); + +function Stream() { + EE.call(this); +} +util.inherits(Stream, EE); + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + +module.exports = Stream; diff --git a/lib/internal/util.js b/lib/internal/util.js index ab17d78204039d..58aa011c08c6b9 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -101,7 +101,7 @@ exports.objectToString = function objectToString(o) { }; const noCrypto = !process.versions.openssl; -exports.assertCrypto = function(exports) { +exports.assertCrypto = function() { if (noCrypto) throw new Error('Node.js is not compiled with openssl crypto support'); }; @@ -109,20 +109,14 @@ exports.assertCrypto = function(exports) { // Filters duplicate strings. Used to support functions in crypto and tls // modules. Implemented specifically to maintain existing behaviors in each. exports.filterDuplicateStrings = function filterDuplicateStrings(items, low) { - if (!Array.isArray(items)) - return []; - const len = items.length; - if (len <= 1) - return items; const map = new Map(); - for (var i = 0; i < len; i++) { + for (var i = 0; i < items.length; i++) { const item = items[i]; const key = item.toLowerCase(); if (low) { map.set(key, key); } else { - if (!map.has(key) || map.get(key) <= item) - map.set(key, item); + map.set(key, item); } } return Array.from(map.values()).sort(); @@ -133,15 +127,21 @@ exports.cachedResult = function cachedResult(fn) { return () => { if (result === undefined) result = fn(); - return result; + return result.slice(); }; }; exports.kIsEncodingSymbol = Symbol('node.isEncoding'); + +// The loop should only run at most twice, retrying with lowercased enc +// if there is no match in the first pass. +// We use a loop instead of branching to retry with a helper +// function in order to avoid the performance hit. +// Return undefined if there is no match. exports.normalizeEncoding = function normalizeEncoding(enc) { if (!enc) return 'utf8'; - var low; - for (;;) { + var retried; + while (true) { switch (enc) { case 'utf8': case 'utf-8': @@ -159,9 +159,27 @@ exports.normalizeEncoding = function normalizeEncoding(enc) { case 'hex': return enc; default: - if (low) return; // undefined + if (retried) return; // undefined enc = ('' + enc).toLowerCase(); - low = true; + retried = true; } } }; + +/* + * Implementation of ToInteger as per ECMAScript Specification + * Refer: http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger + */ +const toInteger = exports.toInteger = function toInteger(argument) { + const number = +argument; + return Number.isNaN(number) ? 0 : Math.trunc(number); +}; + +/* + * Implementation of ToLength as per ECMAScript Specification + * Refer: http://www.ecma-international.org/ecma-262/6.0/#sec-tolength + */ +exports.toLength = function toLength(argument) { + const len = toInteger(argument); + return len <= 0 ? 0 : Math.min(len, Number.MAX_SAFE_INTEGER); +}; diff --git a/lib/net.js b/lib/net.js index 616c299b12c240..44b95073cf1445 100644 --- a/lib/net.js +++ b/lib/net.js @@ -143,6 +143,9 @@ function Socket(options) { } else if (options.fd !== undefined) { this._handle = createHandle(options.fd); this._handle.open(options.fd); + // options.fd can be string (since it user-defined), + // so changing this to === would be semver-major + // See: https://github.com/nodejs/node/pull/11513 if ((options.fd == 1 || options.fd == 2) && (this._handle instanceof Pipe) && process.platform === 'win32') { @@ -1066,7 +1069,7 @@ function afterConnect(status, handle, req, readable, writable) { self.connecting = false; self._sockname = null; - if (status == 0) { + if (status === 0) { self.readable = readable; self.writable = writable; self._unrefTimer(); diff --git a/lib/os.js b/lib/os.js index 206e9941625965..72f307a8a3043d 100644 --- a/lib/os.js +++ b/lib/os.js @@ -1,12 +1,12 @@ 'use strict'; const binding = process.binding('os'); +const getLoadAvg = binding.getLoadAvg; const constants = process.binding('constants').os; const internalUtil = require('internal/util'); const isWindows = process.platform === 'win32'; exports.hostname = binding.getHostname; -exports.loadavg = binding.getLoadAvg; exports.uptime = binding.getUptime; exports.freemem = binding.getFreeMem; exports.totalmem = binding.getTotalMem; @@ -17,6 +17,12 @@ exports.networkInterfaces = binding.getInterfaceAddresses; exports.homedir = binding.getHomeDirectory; exports.userInfo = binding.getUserInfo; +const avgValues = new Float64Array(3); +exports.loadavg = function loadavg() { + getLoadAvg(avgValues); + return [avgValues[0], avgValues[1], avgValues[2]]; +}; + Object.defineProperty(exports, 'constants', { configurable: false, enumerable: true, diff --git a/lib/querystring.js b/lib/querystring.js index ff1b47fb51c614..5ccb5fa77b320f 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -1,8 +1,19 @@ -// Query String Utilities - 'use strict'; -const QueryString = exports; +const QueryString = module.exports = { + unescapeBuffer, + // `unescape()` is a JS global, so we need to use a different local name + unescape: qsUnescape, + + // `escape()` is a JS global, so we need to use a different local name + escape: qsEscape, + + stringify, + encode: stringify, + + parse, + decode: parse +}; const Buffer = require('buffer').Buffer; // This constructor is used to store parsed query string values. Instantiating @@ -11,15 +22,41 @@ const Buffer = require('buffer').Buffer; function ParsedQueryString() {} ParsedQueryString.prototype = Object.create(null); - +const unhexTable = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32 - 47 + +0, +1, +2, +3, +4, +5, +6, +7, +8, +9, -1, -1, -1, -1, -1, -1, // 48 - 63 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64 - 79 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80 - 95 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96 - 111 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112 - 127 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 ... + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // ... 255 +]; // a safe fast alternative to decodeURIComponent -QueryString.unescapeBuffer = function(s, decodeSpaces) { +function unescapeBuffer(s, decodeSpaces) { var out = Buffer.allocUnsafe(s.length); var state = 0; - var n, m, hexchar; + var n, m, hexchar, c; - for (var inIndex = 0, outIndex = 0; inIndex <= s.length; inIndex++) { - var c = inIndex < s.length ? s.charCodeAt(inIndex) : NaN; + for (var inIndex = 0, outIndex = 0; ; inIndex++) { + if (inIndex < s.length) { + c = s.charCodeAt(inIndex); + } else { + if (state > 0) { + out[outIndex++] = 37/*%*/; + if (state === 2) + out[outIndex++] = hexchar; + } + break; + } switch (state) { case 0: // Any character switch (c) { @@ -40,13 +77,8 @@ QueryString.unescapeBuffer = function(s, decodeSpaces) { case 1: // First hex digit hexchar = c; - if (c >= 48/*0*/ && c <= 57/*9*/) { - n = c - 48/*0*/; - } else if (c >= 65/*A*/ && c <= 70/*F*/) { - n = c - 65/*A*/ + 10; - } else if (c >= 97/*a*/ && c <= 102/*f*/) { - n = c - 97/*a*/ + 10; - } else { + n = unhexTable[c]; + if (!(n >= 0)) { out[outIndex++] = 37/*%*/; out[outIndex++] = c; state = 0; @@ -57,13 +89,8 @@ QueryString.unescapeBuffer = function(s, decodeSpaces) { case 2: // Second hex digit state = 0; - if (c >= 48/*0*/ && c <= 57/*9*/) { - m = c - 48/*0*/; - } else if (c >= 65/*A*/ && c <= 70/*F*/) { - m = c - 65/*A*/ + 10; - } else if (c >= 97/*a*/ && c <= 102/*f*/) { - m = c - 97/*a*/ + 10; - } else { + m = unhexTable[c]; + if (!(m >= 0)) { out[outIndex++] = 37/*%*/; out[outIndex++] = hexchar; out[outIndex++] = c; @@ -76,8 +103,8 @@ QueryString.unescapeBuffer = function(s, decodeSpaces) { // TODO support returning arbitrary buffers. - return out.slice(0, outIndex - 1); -}; + return out.slice(0, outIndex); +} function qsUnescape(s, decodeSpaces) { @@ -87,15 +114,31 @@ function qsUnescape(s, decodeSpaces) { return QueryString.unescapeBuffer(s, decodeSpaces).toString(); } } -QueryString.unescape = qsUnescape; -var hexTable = new Array(256); +const hexTable = []; for (var i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); -QueryString.escape = function(str) { - // replaces encodeURIComponent - // http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3.4 + +// These characters do not need escaping when generating query strings: +// ! - . _ ~ +// ' ( ) * +// digits +// alpha (uppercase) +// alpha (lowercase) +const noEscape = [ + 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, 0, 0, 0, 0, 1, 1, 1, 1, 0, 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, 0, 1, // 80 - 95 + 0, 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, 0, 0, 1, 0 // 112 - 127 +]; +// QueryString.escape() replaces encodeURIComponent() +// http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3.4 +function qsEscape(str) { if (typeof str !== 'string') { if (typeof str === 'object') str = String(str); @@ -108,30 +151,20 @@ QueryString.escape = function(str) { for (var i = 0; i < str.length; ++i) { var c = str.charCodeAt(i); - // These characters do not need escaping (in order): - // ! - . _ ~ - // ' ( ) * - // digits - // alpha (uppercase) - // alpha (lowercase) - if (c === 0x21 || c === 0x2D || c === 0x2E || c === 0x5F || c === 0x7E || - (c >= 0x27 && c <= 0x2A) || - (c >= 0x30 && c <= 0x39) || - (c >= 0x41 && c <= 0x5A) || - (c >= 0x61 && c <= 0x7A)) { - continue; - } - - if (i - lastPos > 0) - out += str.slice(lastPos, i); - - // Other ASCII characters + // ASCII if (c < 0x80) { + if (noEscape[c] === 1) + continue; + if (lastPos < i) + out += str.slice(lastPos, i); lastPos = i + 1; out += hexTable[c]; continue; } + if (lastPos < i) + out += str.slice(lastPos, i); + // Multi-byte characters ... if (c < 0x800) { lastPos = i + 1; @@ -164,9 +197,9 @@ QueryString.escape = function(str) { if (lastPos < str.length) return out + str.slice(lastPos); return out; -}; +} -var stringifyPrimitive = function(v) { +function stringifyPrimitive(v) { if (typeof v === 'string') return v; if (typeof v === 'number' && isFinite(v)) @@ -174,10 +207,10 @@ var stringifyPrimitive = function(v) { if (typeof v === 'boolean') return v ? 'true' : 'false'; return ''; -}; +} -QueryString.stringify = QueryString.encode = function(obj, sep, eq, options) { +function stringify(obj, sep, eq, options) { sep = sep || '&'; eq = eq || '='; @@ -215,34 +248,43 @@ QueryString.stringify = QueryString.encode = function(obj, sep, eq, options) { return fields; } return ''; -}; +} -// Parse a key/val string. -QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; +function charCodes(str) { + if (str.length === 0) return []; + if (str.length === 1) return [str.charCodeAt(0)]; + const ret = []; + for (var i = 0; i < str.length; ++i) + ret[ret.length] = str.charCodeAt(i); + return ret; +} +const defSepCodes = [38]; // & +const defEqCodes = [61]; // = +// Parse a key/val string. +function parse(qs, sep, eq, options) { const obj = new ParsedQueryString(); if (typeof qs !== 'string' || qs.length === 0) { return obj; } - if (typeof sep !== 'string') - sep += ''; + var sepCodes = (!sep ? defSepCodes : charCodes(sep + '')); + var eqCodes = (!eq ? defEqCodes : charCodes(eq + '')); + const sepLen = sepCodes.length; + const eqLen = eqCodes.length; - const eqLen = eq.length; - const sepLen = sep.length; - - var maxKeys = 1000; + var pairs = 1000; if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; + // -1 is used in place of a value like Infinity for meaning + // "unlimited pairs" because of additional checks V8 (at least as of v5.4) + // has to do when using variables that contain values like Infinity. Since + // `pairs` is always decremented and checked explicitly for 0, -1 works + // effectively the same as Infinity, while providing a significant + // performance boost. + pairs = (options.maxKeys > 0 ? options.maxKeys : -1); } - var pairs = Infinity; - if (maxKeys > 0) - pairs = maxKeys; - var decode = QueryString.unescape; if (options && typeof options.decodeURIComponent === 'function') { decode = options.decodeURIComponent; @@ -262,7 +304,7 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { const code = qs.charCodeAt(i); // Try matching key/value pair separator (e.g. '&') - if (code === sep.charCodeAt(sepIdx)) { + if (code === sepCodes[sepIdx]) { if (++sepIdx === sepLen) { // Key/value pair separator match! const end = i - sepIdx + 1; @@ -284,10 +326,10 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { keys[keys.length] = key; } else { const curValue = obj[key]; - // `instanceof Array` is used instead of Array.isArray() because it - // is ~15-20% faster with v8 4.7 and is safe to use because we are - // using it with values being created within this function - if (curValue instanceof Array) + // A simple Array-specific property check is enough here to + // distinguish from a string value and is faster and still safe since + // we are generating all of the values being assigned. + if (curValue.pop) curValue[curValue.length] = value; else obj[key] = [curValue, value]; @@ -322,7 +364,7 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { // Try matching key/value separator (e.g. '=') if we haven't already if (eqIdx < eqLen) { - if (code === eq.charCodeAt(eqIdx)) { + if (code === eqCodes[eqIdx]) { if (++eqIdx === eqLen) { // Key/value separator match! const end = i - eqIdx + 1; @@ -354,12 +396,12 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { if (code === 43/*+*/) { if (eqIdx < eqLen) { - if (i - lastPos > 0) + if (lastPos < i) key += qs.slice(lastPos, i); key += '%20'; keyEncoded = true; } else { - if (i - lastPos > 0) + if (lastPos < i) value += qs.slice(lastPos, i); value += '%20'; valEncoded = true; @@ -369,7 +411,7 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { } // Check if we have leftover key or value data - if (pairs > 0 && (lastPos < qs.length || eqIdx > 0)) { + if (pairs !== 0 && (lastPos < qs.length || eqIdx > 0)) { if (lastPos < qs.length) { if (eqIdx < eqLen) key += qs.slice(lastPos); @@ -387,10 +429,10 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { keys[keys.length] = key; } else { const curValue = obj[key]; - // `instanceof Array` is used instead of Array.isArray() because it - // is ~15-20% faster with v8 4.7 and is safe to use because we are - // using it with values being created within this function - if (curValue instanceof Array) + // A simple Array-specific property check is enough here to + // distinguish from a string value and is faster and still safe since + // we are generating all of the values being assigned. + if (curValue.pop) curValue[curValue.length] = value; else obj[key] = [curValue, value]; @@ -398,11 +440,12 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { } return obj; -}; +} // v8 does not optimize functions with try-catch blocks, so we isolate them here -// to minimize the damage +// to minimize the damage (Note: no longer true as of V8 5.4 -- but still will +// not be inlined). function decodeStr(s, decoder) { try { return decoder(s); diff --git a/lib/readline.js b/lib/readline.js index c973c92260ff98..bb186e6dd366a1 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -24,22 +24,13 @@ const stripVTControlCharacters = internalReadline.stripVTControlCharacters; exports.createInterface = function(input, output, completer, terminal) { - var rl; - if (arguments.length === 1) { - rl = new Interface(input); - } else { - rl = new Interface(input, output, completer, terminal); - } - return rl; + return new Interface(input, output, completer, terminal); }; function Interface(input, output, completer, terminal) { if (!(this instanceof Interface)) { - // call the constructor preserving original number of arguments - const self = Object.create(Interface.prototype); - Interface.apply(self, arguments); - return self; + return new Interface(input, output, completer, terminal); } this._sawReturnAt = 0; @@ -51,7 +42,7 @@ function Interface(input, output, completer, terminal) { let crlfDelay; let prompt = '> '; - if (arguments.length === 1) { + if (input && input.input) { // an options object was given output = input.output; completer = input.completer; @@ -458,7 +449,7 @@ Interface.prototype._tabComplete = function() { // this = Interface instance function handleGroup(self, group, width, maxColumns) { - if (group.length == 0) { + if (group.length === 0) { return; } var minRows = Math.ceil(group.length / maxColumns); @@ -483,14 +474,14 @@ function handleGroup(self, group, width, maxColumns) { } function commonPrefix(strings) { - if (!strings || strings.length == 0) { + if (!strings || strings.length === 0) { return ''; } var sorted = strings.slice().sort(); var min = sorted[0]; var max = sorted[sorted.length - 1]; for (var i = 0, len = min.length; i < len; i++) { - if (min[i] != max[i]) { + if (min[i] !== max[i]) { return min.slice(0, i); } } @@ -703,7 +694,7 @@ Interface.prototype._ttyWrite = function(s, key) { key = key || {}; // Ignore escape key - Fixes #2876 - if (key.name == 'escape') return; + if (key.name === 'escape') return; if (key.ctrl && key.shift) { /* Control and shift pressed */ @@ -784,7 +775,7 @@ Interface.prototype._ttyWrite = function(s, key) { break; case 'z': - if (process.platform == 'win32') break; + if (process.platform === 'win32') break; if (this.listenerCount('SIGTSTP') > 0) { this.emit('SIGTSTP'); } else { @@ -995,7 +986,7 @@ function emitKeypressEvents(stream, iface) { } function onNewListener(event) { - if (event == 'keypress') { + if (event === 'keypress') { stream.on('data', onData); stream.removeListener('newListener', onNewListener); } @@ -1111,17 +1102,20 @@ function codePointAt(str, index) { } return code; } -exports.codePointAt = internalUtil.deprecate(codePointAt, - 'readline.codePointAt is deprecated. ' + - 'Use String.prototype.codePointAt instead.'); +exports.codePointAt = internalUtil.deprecate( + codePointAt, + 'readline.codePointAt is deprecated. ' + + 'Use String.prototype.codePointAt instead.'); -exports.getStringWidth = internalUtil.deprecate(getStringWidth, - 'getStringWidth is deprecated and will be removed.'); +exports.getStringWidth = internalUtil.deprecate( + getStringWidth, + 'getStringWidth is deprecated and will be removed.'); -exports.isFullWidthCodePoint = internalUtil.deprecate(isFullWidthCodePoint, - 'isFullWidthCodePoint is deprecated and will be removed.'); +exports.isFullWidthCodePoint = internalUtil.deprecate( + isFullWidthCodePoint, + 'isFullWidthCodePoint is deprecated and will be removed.'); exports.stripVTControlCharacters = internalUtil.deprecate( diff --git a/lib/repl.js b/lib/repl.js index 8b00998be86968..52bb1b6b53986c 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -39,13 +39,13 @@ const debug = util.debuglog('repl'); const parentModule = module; const replMap = new WeakMap(); -const GLOBAL_OBJECT_PROPERTIES = ['NaN', 'Infinity', 'undefined', - 'eval', 'parseInt', 'parseFloat', 'isNaN', 'isFinite', 'decodeURI', - 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', - 'Object', 'Function', 'Array', 'String', 'Boolean', 'Number', - 'Date', 'RegExp', 'Error', 'EvalError', 'RangeError', - 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', - 'Math', 'JSON']; +const GLOBAL_OBJECT_PROPERTIES = [ + 'NaN', 'Infinity', 'undefined', 'eval', 'parseInt', 'parseFloat', 'isNaN', + 'isFinite', 'decodeURI', 'decodeURIComponent', 'encodeURI', + 'encodeURIComponent', 'Object', 'Function', 'Array', 'String', 'Boolean', + 'Number', 'Date', 'RegExp', 'Error', 'EvalError', 'RangeError', + 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Math', 'JSON' +]; const GLOBAL_OBJECT_PROPERTY_MAP = {}; GLOBAL_OBJECT_PROPERTIES.forEach((p) => GLOBAL_OBJECT_PROPERTY_MAP[p] = p); @@ -722,9 +722,7 @@ REPLServer.prototype.createContext = function() { Object.defineProperty(context, '_', { configurable: true, - get: () => { - return this.last; - }, + get: () => this.last, set: (value) => { this.last = value; if (!this.underscoreAssigned) { @@ -1217,12 +1215,13 @@ function addStandardGlobals(completionGroups, filter) { // Common keywords. Exclude for completion on the empty string, b/c // they just get in the way. if (filter) { - completionGroups.push(['break', 'case', 'catch', 'const', - 'continue', 'debugger', 'default', 'delete', 'do', 'else', - 'export', 'false', 'finally', 'for', 'function', 'if', - 'import', 'in', 'instanceof', 'let', 'new', 'null', 'return', - 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'undefined', - 'var', 'void', 'while', 'with', 'yield']); + completionGroups.push([ + 'break', 'case', 'catch', 'const', 'continue', 'debugger', 'default', + 'delete', 'do', 'else', 'export', 'false', 'finally', 'for', 'function', + 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null', 'return', + 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'undefined', 'var', + 'void', 'while', 'with', 'yield' + ]); } } @@ -1266,9 +1265,10 @@ function defineDefaultCommands(repl) { help: 'Print this help message', action: function() { const names = Object.keys(this.commands).sort(); - const longestNameLength = names.reduce((max, name) => { - return Math.max(max, name.length); - }, 0); + const longestNameLength = names.reduce( + (max, name) => Math.max(max, name.length), + 0 + ); names.forEach((name) => { const cmd = this.commands[name]; const spaces = ' '.repeat(longestNameLength - name.length + 3); diff --git a/lib/stream.js b/lib/stream.js index 047fbceb4bdb30..a6b25a212508ab 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -1,11 +1,9 @@ 'use strict'; -module.exports = Stream; +// Note: export Stream before Readable/Writable/Duplex/... +// to avoid a cross-reference(require) issues +const Stream = module.exports = require('internal/streams/legacy'); -const EE = require('events'); -const util = require('util'); - -util.inherits(Stream, EE); Stream.Readable = require('_stream_readable'); Stream.Writable = require('_stream_writable'); Stream.Duplex = require('_stream_duplex'); @@ -14,94 +12,3 @@ Stream.PassThrough = require('_stream_passthrough'); // Backwards-compat with node 0.4.x Stream.Stream = Stream; - - -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. - -function Stream() { - EE.call(this); -} - -Stream.prototype.pipe = function(dest, options) { - var source = this; - - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } - - source.on('data', ondata); - - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } - - dest.on('drain', ondrain); - - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); - } - - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - - dest.end(); - } - - - function onclose() { - if (didOnEnd) return; - didOnEnd = true; - - if (typeof dest.destroy === 'function') dest.destroy(); - } - - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } - } - - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); - - source.removeListener('end', onend); - source.removeListener('close', onclose); - - source.removeListener('error', onerror); - dest.removeListener('error', onerror); - - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); - - dest.removeListener('close', cleanup); - } - - source.on('end', cleanup); - source.on('close', cleanup); - - dest.on('close', cleanup); - - dest.emit('pipe', source); - - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; diff --git a/lib/timers.js b/lib/timers.js index 6d456da36faf67..0784f7f1e11247 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -15,7 +15,7 @@ const TIMEOUT_MAX = 2147483647; // 2^31-1 // // Timers are crucial to Node.js. Internally, any TCP I/O connection creates a // timer so that we can time out of connections. Additionally, many user -// user libraries and applications also use timers. As such there may be a +// libraries and applications also use timers. As such there may be a // significantly large amount of timeouts scheduled at any given time. // Therefore, it is very important that the timers implementation is performant // and efficient. @@ -156,12 +156,19 @@ function TimersList(msecs, unrefed) { this._timer = new TimerWrap(); this._unrefed = unrefed; this.msecs = msecs; + this.nextTick = false; } function listOnTimeout() { var list = this._list; var msecs = list.msecs; + if (list.nextTick) { + list.nextTick = false; + process.nextTick(listOnTimeoutNT, list); + return; + } + debug('timeout callback %d', msecs); var now = TimerWrap.now(); @@ -239,6 +246,14 @@ function tryOnTimeout(timer, list) { } finally { if (!threw) return; + // Postpone all later list events to next tick. We need to do this + // so that the events are called in the order they were created. + const lists = list._unrefed === true ? unrefedLists : refedLists; + for (var key in lists) { + if (key > list.msecs) { + lists[key].nextTick = true; + } + } // We need to continue processing after domain error handling // is complete, but not by using whatever domain was left over // when the timeout threw its exception. diff --git a/lib/tls.js b/lib/tls.js index 32c0319754be2a..bb4719d9b02c93 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -1,7 +1,7 @@ 'use strict'; const internalUtil = require('internal/util'); -internalUtil.assertCrypto(exports); +internalUtil.assertCrypto(); const net = require('net'); const url = require('url'); @@ -22,9 +22,9 @@ exports.DEFAULT_CIPHERS = exports.DEFAULT_ECDH_CURVE = 'prime256v1'; -exports.getCiphers = internalUtil.cachedResult(() => { - return internalUtil.filterDuplicateStrings(binding.getSSLCiphers(), true); -}); +exports.getCiphers = internalUtil.cachedResult( + () => internalUtil.filterDuplicateStrings(binding.getSSLCiphers(), true) +); // Convert protocols array into valid OpenSSL protocols list // ("\x06spdy/2\x08http/1.1\x08http/1.0") diff --git a/lib/tty.js b/lib/tty.js index 576144e4013064..f9b8a34e95d97a 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -55,7 +55,7 @@ function WriteStream(fd) { // Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671 this._handle.setBlocking(process.env.NODE_TTY_UNSAFE_ASYNC !== '1'); - var winSize = []; + var winSize = new Array(2); var err = this._handle.getWindowSize(winSize); if (!err) { this.columns = winSize[0]; @@ -72,7 +72,7 @@ WriteStream.prototype.isTTY = true; WriteStream.prototype._refreshSize = function() { var oldCols = this.columns; var oldRows = this.rows; - var winSize = []; + var winSize = new Array(2); var err = this._handle.getWindowSize(winSize); if (err) { this.emit('error', errnoException(err, 'getWindowSize')); diff --git a/lib/url.js b/lib/url.js index 1437443e758d3b..59821b67ca3bfc 100644 --- a/lib/url.js +++ b/lib/url.js @@ -41,7 +41,7 @@ const portPattern = /:[0-9]*$/; const hostPattern = /^\/\/[^@/]+@[^@/]+/; // Special case for a simple path URL -const simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/; +const simplePathPattern = /^(\/\/?(?!\/)[^?\s]*)(\?[^\s]*)?$/; const hostnameMaxLen = 255; // protocols that can allow "unsafe" and "unwise" chars. @@ -948,6 +948,24 @@ function spliceOne(list, index) { var hexTable = new Array(256); for (var i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); + +// These characters do not need escaping: +// ! - . _ ~ +// ' ( ) * : +// digits +// alpha (uppercase) +// alpha (lowercase) +const noEscapeAuth = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, // 0x20 - 0x2F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 0x4F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 0x50 - 0x5F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 // 0x70 - 0x7F +]; + function encodeAuth(str) { // faster encodeURIComponent alternative for encoding auth uri components var out = ''; @@ -955,37 +973,28 @@ function encodeAuth(str) { for (var i = 0; i < str.length; ++i) { var c = str.charCodeAt(i); - // These characters do not need escaping: - // ! - . _ ~ - // ' ( ) * : - // digits - // alpha (uppercase) - // alpha (lowercase) - if (c === 0x21 || c === 0x2D || c === 0x2E || c === 0x5F || c === 0x7E || - (c >= 0x27 && c <= 0x2A) || - (c >= 0x30 && c <= 0x3A) || - (c >= 0x41 && c <= 0x5A) || - (c >= 0x61 && c <= 0x7A)) { - continue; - } - - if (i - lastPos > 0) - out += str.slice(lastPos, i); - - lastPos = i + 1; - - // Other ASCII characters + // ASCII if (c < 0x80) { + if (noEscapeAuth[c] === 1) + continue; + if (lastPos < i) + out += str.slice(lastPos, i); + lastPos = i + 1; out += hexTable[c]; continue; } + if (lastPos < i) + out += str.slice(lastPos, i); + // Multi-byte characters ... if (c < 0x800) { + lastPos = i + 1; out += hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]; continue; } if (c < 0xD800 || c >= 0xE000) { + lastPos = i + 1; out += hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; @@ -998,6 +1007,7 @@ function encodeAuth(str) { c2 = str.charCodeAt(i) & 0x3FF; else c2 = 0; + lastPos = i + 1; c = 0x10000 + (((c & 0x3FF) << 10) | c2); out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + diff --git a/lib/util.js b/lib/util.js index 95c69248e07282..b96c5121ed9610 100644 --- a/lib/util.js +++ b/lib/util.js @@ -27,16 +27,13 @@ var simdFormatters; if (typeof global.SIMD === 'object' && global.SIMD !== null) { simdFormatters = new Map(); - const make = (extractLane, count) => { - return (ctx, value, recurseTimes, visibleKeys, keys) => { + const make = + (extractLane, count) => (ctx, value, recurseTimes, visibleKeys, keys) => { const output = new Array(count); for (var i = 0; i < count; i += 1) output[i] = formatPrimitive(ctx, extractLane(value, i)); return output; }; - }; - - const SIMD = global.SIMD; // Pacify eslint. const countPerType = { Bool16x8: 8, @@ -52,7 +49,7 @@ if (typeof global.SIMD === 'object' && global.SIMD !== null) { }; for (const key in countPerType) { - const type = SIMD[key]; + const type = global.SIMD[key]; simdFormatters.set(type, make(type.extractLane, countPerType[key])); } } @@ -403,7 +400,7 @@ function formatValue(ctx, value, recurseTimes) { if (keys.length === 0) { if (typeof value === 'function') { return ctx.stylize(`[Function${value.name ? `: ${value.name}` : ''}]`, - 'special'); + 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); @@ -598,9 +595,8 @@ function formatValue(ctx, value, recurseTimes) { function formatNumber(ctx, value) { - // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, - // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . - if (value === 0 && 1 / value < 0) + // Format -0 as '-0'. Strict equality won't distinguish 0 from -0. + if (Object.is(value, -0)) return ctx.stylize('-0', 'number'); return ctx.stylize('' + value, 'number'); } @@ -663,7 +659,7 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { for (var i = 0; i < maxLength; ++i) { if (hasOwnProperty(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); + String(i), true)); } else { output.push(''); } @@ -674,7 +670,7 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { keys.forEach(function(key) { if (typeof key === 'symbol' || !key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); + key, true)); } }); return output; diff --git a/lib/v8.js b/lib/v8.js index e78a2480ff04e7..c1ca09dda8bb07 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -18,7 +18,7 @@ const v8binding = process.binding('v8'); // Properties for heap statistics buffer extraction. const heapStatisticsBuffer = - new Uint32Array(v8binding.heapStatisticsArrayBuffer); + new Float64Array(v8binding.heapStatisticsArrayBuffer); const kTotalHeapSizeIndex = v8binding.kTotalHeapSizeIndex; const kTotalHeapSizeExecutableIndex = v8binding.kTotalHeapSizeExecutableIndex; const kTotalPhysicalSizeIndex = v8binding.kTotalPhysicalSizeIndex; @@ -28,7 +28,7 @@ const kHeapSizeLimitIndex = v8binding.kHeapSizeLimitIndex; // Properties for heap space statistics buffer extraction. const heapSpaceStatisticsBuffer = - new Uint32Array(v8binding.heapSpaceStatisticsArrayBuffer); + new Float64Array(v8binding.heapSpaceStatisticsArrayBuffer); const kHeapSpaces = v8binding.kHeapSpaces; const kNumberOfHeapSpaces = kHeapSpaces.length; const kHeapSpaceStatisticsPropertiesCount = diff --git a/lib/vm.js b/lib/vm.js index 73359c1b6825b0..785148c2d22e8c 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -37,17 +37,11 @@ Script.prototype.runInContext = function(contextifiedSandbox, options) { }; Script.prototype.runInNewContext = function(sandbox, options) { - var context = exports.createContext(sandbox); + var context = createContext(sandbox); return this.runInContext(context, options); }; -exports.Script = Script; - -exports.createScript = function(code, options) { - return new Script(code, options); -}; - -exports.createContext = function(sandbox) { +function createContext(sandbox) { if (sandbox === undefined) { sandbox = {}; } else if (binding.isContext(sandbox)) { @@ -56,28 +50,11 @@ exports.createContext = function(sandbox) { binding.makeContext(sandbox); return sandbox; -}; - -exports.runInDebugContext = function(code) { - return binding.runInDebugContext(code); -}; - -exports.runInContext = function(code, contextifiedSandbox, options) { - var script = new Script(code, options); - return script.runInContext(contextifiedSandbox, options); -}; - -exports.runInNewContext = function(code, sandbox, options) { - var script = new Script(code, options); - return script.runInNewContext(sandbox, options); -}; - -exports.runInThisContext = function(code, options) { - var script = new Script(code, options); - return script.runInThisContext(options); -}; +} -exports.isContext = binding.isContext; +function createScript(code, options) { + return new Script(code, options); +} // Remove all SIGINT listeners and re-attach them after the wrapped function // has executed, so that caught SIGINT are handled by the listeners again. @@ -102,3 +79,31 @@ function sigintHandlersWrap(fn) { } } } + +function runInDebugContext(code) { + return binding.runInDebugContext(code); +} + +function runInContext(code, contextifiedSandbox, options) { + return createScript(code, options) + .runInContext(contextifiedSandbox, options); +} + +function runInNewContext(code, sandbox, options) { + return createScript(code, options).runInNewContext(sandbox, options); +} + +function runInThisContext(code, options) { + return createScript(code, options).runInThisContext(options); +} + +module.exports = { + Script, + createContext, + createScript, + runInDebugContext, + runInContext, + runInNewContext, + runInThisContext, + isContext: binding.isContext +}; diff --git a/node.gyp b/node.gyp index e23ce40758cfda..73054dcda920fc 100644 --- a/node.gyp +++ b/node.gyp @@ -93,6 +93,7 @@ 'lib/internal/v8_prof_processor.js', 'lib/internal/streams/lazy_transform.js', 'lib/internal/streams/BufferList.js', + 'lib/internal/streams/legacy.js', 'deps/v8/tools/splaytree.js', 'deps/v8/tools/codemap.js', 'deps/v8/tools/consarray.js', @@ -133,17 +134,17 @@ 'src', 'tools/msvs/genfiles', 'deps/uv/src/ares', - '<(SHARED_INTERMEDIATE_DIR)', # for node_natives.h + '<(SHARED_INTERMEDIATE_DIR)', ], 'sources': [ - 'src/debug-agent.cc', 'src/async-wrap.cc', - 'src/env.cc', - 'src/fs_event_wrap.cc', 'src/cares_wrap.cc', 'src/connection_wrap.cc', 'src/connect_wrap.cc', + 'src/debug-agent.cc', + 'src/env.cc', + 'src/fs_event_wrap.cc', 'src/handle_wrap.cc', 'src/js_stream.cc', 'src/node.cc', @@ -153,7 +154,6 @@ 'src/node_contextify.cc', 'src/node_file.cc', 'src/node_http_parser.cc', - 'src/node_javascript.cc', 'src/node_main.cc', 'src/node_os.cc', 'src/node_revert.cc', @@ -164,16 +164,18 @@ 'src/node_zlib.cc', 'src/node_i18n.cc', 'src/pipe_wrap.cc', + 'src/process_wrap.cc', 'src/signal_wrap.cc', 'src/spawn_sync.cc', 'src/string_bytes.cc', + 'src/string_search.cc', 'src/stream_base.cc', 'src/stream_wrap.cc', 'src/tcp_wrap.cc', 'src/timer_wrap.cc', 'src/tty_wrap.cc', - 'src/process_wrap.cc', 'src/udp_wrap.cc', + 'src/util.cc', 'src/uv.cc', # headers to make for a more pleasant IDE experience 'src/async-wrap.h', @@ -214,16 +216,14 @@ 'src/tree.h', 'src/util.h', 'src/util-inl.h', - 'src/util.cc', - 'src/string_search.cc', 'deps/http_parser/http_parser.h', 'deps/v8/include/v8.h', 'deps/v8/include/v8-debug.h', - '<(SHARED_INTERMEDIATE_DIR)/node_natives.h', # javascript files to make for an even more pleasant IDE experience '<@(library_files)', # node.gyp is added to the project by default. 'common.gypi', + '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc', ], 'defines': [ @@ -697,12 +697,13 @@ 'actions': [ { 'action_name': 'node_js2c', + 'process_outputs_as_sources': 1, 'inputs': [ '<@(library_files)', './config.gypi', ], 'outputs': [ - '<(SHARED_INTERMEDIATE_DIR)/node_natives.h', + '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc', ], 'conditions': [ [ 'node_use_dtrace=="false" and node_use_etw=="false"', { diff --git a/src/CNNICHashWhitelist.inc b/src/CNNICHashWhitelist.inc index e3c6a618fd7729..ed4149f1c51346 100644 --- a/src/CNNICHashWhitelist.inc +++ b/src/CNNICHashWhitelist.inc @@ -16,102 +16,22 @@ struct WhitelistedCNNICHash { }; static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { - { - { 0x00, 0x5B, 0xF9, 0x8E, 0xED, 0x61, 0x2B, 0x50, 0xEC, 0xDA, 0x7B, 0xFF, 0x56, 0xA2, 0xDF, 0xF4, - 0x67, 0xA8, 0xAD, 0xD7, 0xEE, 0xC0, 0xAB, 0x30, 0x57, 0x54, 0xD7, 0x66, 0xBE, 0xBB, 0x5F, 0xE8 }, - }, - { - { 0x00, 0x87, 0x75, 0xB8, 0xEA, 0xD0, 0xFE, 0x16, 0x26, 0x9C, 0x9A, 0x9A, 0xB2, 0x83, 0x39, 0x55, - 0x49, 0xCA, 0x67, 0xC2, 0xA3, 0xAA, 0xE8, 0x2F, 0x1A, 0x6B, 0x4D, 0x3A, 0xBC, 0xCA, 0xDC, 0x27 }, - }, { { 0x00, 0xC5, 0x9F, 0x5E, 0xF3, 0xB4, 0x6D, 0xBC, 0xA0, 0xA8, 0xBB, 0xA5, 0x0A, 0x72, 0xD4, 0xE1, 0x83, 0x9A, 0x94, 0xFB, 0x1A, 0x58, 0x5A, 0xD7, 0x2A, 0x7A, 0xAC, 0x3C, 0x72, 0x56, 0x1F, 0xC0 }, }, - { - { 0x00, 0xC6, 0x81, 0x13, 0x16, 0xBD, 0x9C, 0x91, 0x98, 0x6E, 0xA9, 0x7E, 0x2C, 0x30, 0xAB, 0xEF, - 0xA0, 0xD5, 0x68, 0x04, 0x89, 0x0D, 0x65, 0x8D, 0xFF, 0x08, 0x59, 0x11, 0x6E, 0xB4, 0xC2, 0x32 }, - }, - { - { 0x00, 0xCB, 0x92, 0x51, 0xAF, 0xFA, 0x0E, 0x4C, 0xA0, 0xA5, 0x61, 0x1F, 0x1A, 0x79, 0x15, 0x05, - 0xD2, 0xAB, 0xF8, 0x9D, 0xD0, 0x48, 0x53, 0x29, 0x16, 0xF0, 0x5F, 0xD8, 0x74, 0xF2, 0x5D, 0xCD }, - }, - { - { 0x00, 0xDE, 0xFF, 0x68, 0x2E, 0x35, 0x10, 0x22, 0xCC, 0x3B, 0xBB, 0x4E, 0xB5, 0x88, 0x0A, 0x97, - 0x27, 0x88, 0x0A, 0xF3, 0x52, 0xFB, 0xBE, 0x2F, 0x91, 0x24, 0xBE, 0x92, 0x88, 0x4B, 0x18, 0xFD }, - }, - { - { 0x00, 0xF7, 0x28, 0x14, 0x8C, 0x8C, 0x28, 0x90, 0x7F, 0xAC, 0xF3, 0x89, 0xC0, 0xE9, 0xB9, 0xBC, - 0x6F, 0xD1, 0xB8, 0xDE, 0xE0, 0xE8, 0x5B, 0x65, 0xFE, 0x39, 0x39, 0x8B, 0xEE, 0x95, 0xDC, 0x59 }, - }, - { - { 0x00, 0xF8, 0x4A, 0x82, 0x67, 0xB3, 0xDA, 0xEE, 0x1E, 0x16, 0x90, 0x75, 0x1C, 0x86, 0xBD, 0x78, - 0x94, 0x08, 0x65, 0x94, 0x3E, 0xEE, 0x52, 0xE9, 0x7D, 0x98, 0x50, 0x1A, 0xC8, 0xE1, 0x58, 0x94 }, - }, - { - { 0x01, 0x1D, 0x7D, 0xC8, 0x19, 0x01, 0xAB, 0xCA, 0xE0, 0xF4, 0x74, 0x4C, 0x17, 0xB8, 0xF7, 0x87, - 0xF3, 0x97, 0x41, 0x3A, 0x42, 0x3D, 0xC0, 0x82, 0xC4, 0xB3, 0x80, 0x23, 0xDE, 0x42, 0x00, 0x75 }, - }, - { - { 0x01, 0x5F, 0x9B, 0x68, 0xD6, 0x4B, 0x86, 0x0D, 0x5E, 0xD0, 0x40, 0x50, 0x66, 0xA3, 0xF2, 0xFD, - 0x9D, 0x6D, 0xDE, 0x3A, 0x9B, 0x35, 0x73, 0x17, 0x34, 0x10, 0xE6, 0xCE, 0x63, 0x9B, 0x77, 0x91 }, - }, - { - { 0x01, 0xD6, 0x0A, 0xE5, 0x22, 0x20, 0x8E, 0xC6, 0xF5, 0x04, 0xD5, 0x91, 0xF9, 0x7A, 0x99, 0xA5, - 0xEF, 0x25, 0x25, 0x98, 0x71, 0xE4, 0x77, 0x42, 0xD4, 0x71, 0xE2, 0x6F, 0xF0, 0x75, 0xE9, 0xE9 }, - }, - { - { 0x01, 0xF1, 0x14, 0x28, 0x67, 0x99, 0xEA, 0x8B, 0x24, 0x08, 0xE3, 0xDA, 0xBE, 0x90, 0xF3, 0xAD, - 0xEA, 0x20, 0x46, 0x32, 0xAA, 0x3B, 0x82, 0xD2, 0xE5, 0x5A, 0x8D, 0xCF, 0x5B, 0x7E, 0xD7, 0xAD }, - }, - { - { 0x01, 0xFC, 0xEB, 0xF0, 0x6A, 0xF4, 0x9D, 0x87, 0x8A, 0xF9, 0xBD, 0x57, 0xE1, 0x2D, 0xBE, 0xA7, - 0xEB, 0x80, 0x12, 0x0F, 0x7C, 0x10, 0xCD, 0x1A, 0x1A, 0x98, 0x89, 0x8E, 0xD8, 0xE7, 0xEC, 0x4C }, - }, { { 0x02, 0x01, 0x4E, 0x80, 0xF5, 0xC4, 0xF3, 0x8B, 0xA9, 0xD9, 0x04, 0x79, 0x1A, 0x63, 0xF6, 0x4D, 0x05, 0xF9, 0xE2, 0x03, 0xA1, 0xF1, 0x2B, 0x06, 0xD6, 0x55, 0x94, 0x01, 0x41, 0x0E, 0x73, 0x36 }, }, - { - { 0x02, 0x08, 0x22, 0xAB, 0x1B, 0x8C, 0xC0, 0xD8, 0x22, 0x03, 0x60, 0xA1, 0xAF, 0x8B, 0xB4, 0xD9, - 0xBE, 0x60, 0xE8, 0x43, 0x9E, 0x2B, 0xA3, 0x07, 0x8D, 0x61, 0xF4, 0x01, 0xE1, 0x5B, 0x41, 0xBC }, - }, { { 0x02, 0x35, 0x38, 0xE2, 0x48, 0x15, 0x28, 0x75, 0x29, 0x2F, 0x2C, 0x83, 0x9A, 0xB3, 0x2B, 0xC7, 0x35, 0x1E, 0x2B, 0x29, 0x99, 0x1D, 0x66, 0xAE, 0xA6, 0x16, 0xCB, 0x0B, 0x26, 0xA5, 0xE3, 0x75 }, }, - { - { 0x02, 0x61, 0x53, 0xE5, 0x91, 0xCD, 0x82, 0xF7, 0xBD, 0xCE, 0x99, 0xB3, 0xBA, 0x10, 0xA8, 0xD6, - 0x90, 0x24, 0xC6, 0x36, 0xD3, 0x5D, 0xAB, 0x1A, 0x95, 0x6C, 0x7D, 0x7A, 0xEF, 0x80, 0x3A, 0xDE }, - }, - { - { 0x02, 0xC4, 0x8C, 0x3A, 0xDC, 0xF9, 0x9F, 0x28, 0xF4, 0x79, 0xB8, 0xF6, 0x79, 0x88, 0x77, 0x78, - 0xB9, 0x3A, 0x06, 0xAF, 0xF1, 0x6E, 0x35, 0x8F, 0x40, 0x9B, 0xC6, 0xFE, 0x54, 0x03, 0x04, 0xC6 }, - }, { { 0x02, 0xEC, 0x35, 0xF5, 0x83, 0x4C, 0xD2, 0xC3, 0x43, 0x33, 0x39, 0x9A, 0xEA, 0x6B, 0xDA, 0x84, 0x68, 0xAB, 0x8D, 0x74, 0xEF, 0x6C, 0xA5, 0x2D, 0x33, 0x7A, 0x30, 0x69, 0x4C, 0x3F, 0x95, 0xA4 }, }, - { - { 0x03, 0x2A, 0x7E, 0x55, 0xFE, 0xC3, 0x74, 0xC6, 0xD7, 0x9C, 0xFF, 0xDB, 0x46, 0x7C, 0x5C, 0xCD, - 0x56, 0xF5, 0x49, 0x0A, 0xAE, 0x9A, 0xF1, 0xBC, 0xCC, 0x7E, 0x54, 0xDA, 0xFA, 0x6D, 0x8A, 0x3F }, - }, - { - { 0x03, 0x33, 0xB3, 0x91, 0x64, 0xD6, 0x25, 0xF0, 0x1D, 0x50, 0x83, 0xDE, 0x2F, 0xB1, 0xE2, 0x5D, - 0x89, 0x34, 0x29, 0x69, 0x0F, 0xA5, 0xD7, 0x7D, 0x84, 0x90, 0x1E, 0xD1, 0x9B, 0x22, 0x1D, 0xF3 }, - }, - { - { 0x03, 0x83, 0xF9, 0xC1, 0xF5, 0xC8, 0x4C, 0x02, 0x64, 0xE6, 0x3B, 0x2A, 0x96, 0x21, 0x21, 0x37, - 0x58, 0x70, 0x0D, 0x1A, 0xFB, 0x61, 0xF8, 0x00, 0x1F, 0x3E, 0xFF, 0x81, 0x44, 0xE6, 0xFE, 0x73 }, - }, - { - { 0x03, 0xD9, 0x9F, 0x24, 0xF8, 0x64, 0x4B, 0x80, 0x4D, 0x8E, 0x3B, 0xC9, 0xC8, 0x7C, 0x02, 0x4E, - 0x4B, 0xB7, 0x0D, 0xC6, 0x30, 0x1B, 0xCD, 0xE3, 0x24, 0x12, 0xB4, 0xCE, 0x8C, 0x0C, 0x14, 0x58 }, - }, - { - { 0x03, 0xDE, 0x42, 0xAF, 0x1F, 0x30, 0x9F, 0x95, 0xF6, 0xC8, 0x91, 0x03, 0xEA, 0x98, 0x7E, 0x84, - 0xD3, 0x18, 0x6B, 0x60, 0x65, 0xF9, 0x60, 0x7A, 0x06, 0x6A, 0x30, 0x2B, 0x58, 0x05, 0xEB, 0x3B }, - }, { { 0x03, 0xE0, 0x6E, 0x0B, 0x7A, 0x2C, 0xBA, 0xE4, 0xB6, 0x8B, 0xCE, 0x5F, 0x83, 0xE7, 0xA9, 0x31, 0x6E, 0xD7, 0x82, 0x3E, 0x8D, 0x94, 0x85, 0x38, 0xF1, 0x94, 0x3F, 0xA4, 0x27, 0xD7, 0x91, 0x0E }, @@ -124,62 +44,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x04, 0x18, 0xD5, 0x3E, 0xBC, 0x8E, 0x71, 0x41, 0x25, 0x1B, 0x4D, 0xC8, 0xFA, 0x7B, 0x2B, 0xD8, 0xFD, 0x3A, 0x1C, 0x65, 0x2A, 0xA1, 0x16, 0xE7, 0xFC, 0x70, 0x0B, 0x2A, 0xB5, 0x1A, 0x2A, 0x1A }, }, - { - { 0x04, 0x3E, 0xD7, 0xFF, 0x71, 0xBD, 0x65, 0xAE, 0x28, 0x35, 0xB0, 0xCB, 0x38, 0x74, 0x8D, 0x0B, - 0x08, 0x5F, 0x86, 0xF7, 0x5F, 0x2A, 0x96, 0xC8, 0xD4, 0x64, 0x00, 0x89, 0xBC, 0x58, 0x3D, 0x7B }, - }, - { - { 0x04, 0x49, 0x38, 0x0A, 0x30, 0xBD, 0x6D, 0xBD, 0x55, 0xDF, 0xE2, 0x54, 0xC8, 0x20, 0xA0, 0x77, - 0xFF, 0x11, 0xCA, 0xFC, 0x83, 0xB5, 0x0E, 0x0A, 0x13, 0xF1, 0x3D, 0x59, 0xD3, 0xCA, 0x6C, 0xAF }, - }, - { - { 0x04, 0x6F, 0xDA, 0x46, 0xF0, 0xC4, 0x7B, 0x4A, 0x4D, 0x90, 0x31, 0x03, 0x7B, 0x33, 0xDB, 0xAC, - 0x99, 0x86, 0x1B, 0x7F, 0x0F, 0x85, 0x1D, 0x15, 0x1A, 0x83, 0x29, 0xF8, 0x42, 0x1B, 0x41, 0x5E }, - }, - { - { 0x04, 0x71, 0x57, 0x2C, 0x03, 0x03, 0x7D, 0xEE, 0x2B, 0x40, 0x09, 0x6E, 0xE8, 0xAA, 0x37, 0x82, - 0xC6, 0xFA, 0x81, 0x42, 0xCC, 0xA2, 0x68, 0x19, 0x09, 0xDA, 0xE8, 0xC4, 0x66, 0xD0, 0x58, 0x4E }, - }, - { - { 0x04, 0x80, 0x71, 0x3A, 0x76, 0x91, 0x7E, 0xB1, 0x7F, 0xB5, 0x4C, 0x93, 0xEE, 0xD3, 0xFD, 0x8A, - 0x98, 0x2B, 0xD9, 0x06, 0x9C, 0x69, 0xAB, 0xEA, 0xDE, 0xB2, 0x5A, 0x76, 0xD9, 0xA5, 0x90, 0x65 }, - }, - { - { 0x04, 0x8A, 0x21, 0x7A, 0xD4, 0x4E, 0x00, 0xCA, 0xD1, 0xEB, 0xEE, 0x67, 0x23, 0x51, 0xD2, 0x89, - 0x10, 0xAF, 0x69, 0xED, 0x4D, 0x45, 0x5A, 0xEF, 0x42, 0x76, 0x23, 0xF7, 0xD7, 0xAD, 0xDE, 0xC7 }, - }, - { - { 0x04, 0xA6, 0x4D, 0xD4, 0x31, 0x97, 0xC6, 0x2C, 0x2C, 0xD3, 0xB6, 0x0B, 0xDF, 0x30, 0x5B, 0x3E, - 0x81, 0xE5, 0xF5, 0x00, 0x2C, 0x15, 0x78, 0x59, 0xFB, 0xB7, 0xB4, 0x85, 0x45, 0xE6, 0x49, 0x11 }, - }, - { - { 0x04, 0xDE, 0x66, 0x05, 0x94, 0x63, 0xAF, 0xD2, 0xC1, 0x1E, 0x9E, 0x4F, 0xD6, 0xAE, 0x55, 0x07, - 0xEF, 0x68, 0xEF, 0x91, 0x54, 0x0C, 0x41, 0x0C, 0x32, 0xA8, 0xF0, 0x24, 0x62, 0x5F, 0x6B, 0xB0 }, - }, - { - { 0x05, 0x2E, 0xEB, 0x25, 0xB7, 0x24, 0xBA, 0x44, 0xF4, 0x81, 0xBE, 0x5C, 0x80, 0xFD, 0xB5, 0x5F, - 0x36, 0xB8, 0xD9, 0xBC, 0xE6, 0x45, 0xB2, 0x2F, 0xA1, 0x35, 0xC7, 0xD9, 0x74, 0xCB, 0xF6, 0xFE }, - }, - { - { 0x05, 0x4F, 0xF2, 0x4D, 0xD5, 0x0D, 0x49, 0x84, 0x68, 0x3B, 0x8B, 0xB0, 0x1A, 0xDE, 0xE5, 0xA8, - 0x73, 0x1F, 0x7C, 0x24, 0xCD, 0x11, 0x6F, 0x5A, 0xC6, 0x75, 0xE0, 0x17, 0x33, 0xCA, 0xD1, 0x83 }, - }, - { - { 0x05, 0x64, 0x05, 0x92, 0x8F, 0xDC, 0x6D, 0xFC, 0x08, 0xCD, 0x89, 0x88, 0x63, 0x0E, 0xE2, 0xD8, - 0x23, 0x5A, 0x62, 0xFC, 0xD1, 0xDB, 0xC9, 0x12, 0xA6, 0x52, 0xA3, 0xFD, 0xAC, 0xD4, 0xF3, 0x51 }, - }, - { - { 0x05, 0x69, 0xC6, 0xC6, 0x2A, 0x75, 0xA3, 0x9B, 0x82, 0x4F, 0x48, 0x77, 0xC8, 0x8E, 0xC0, 0x08, - 0x9C, 0x09, 0x42, 0x58, 0x1E, 0x38, 0x77, 0xFF, 0xF9, 0x19, 0x50, 0xEA, 0x0F, 0x9D, 0xD4, 0xFE }, - }, - { - { 0x05, 0xA7, 0xAF, 0xA3, 0x20, 0x08, 0xFE, 0x48, 0x46, 0x29, 0x67, 0xE7, 0xF8, 0x79, 0x9F, 0x72, - 0x48, 0x71, 0x80, 0xEC, 0x0F, 0x68, 0xBA, 0xF7, 0x96, 0x7A, 0x87, 0xFA, 0x0A, 0x75, 0xCF, 0xAA }, - }, - { - { 0x06, 0x17, 0xF8, 0xBC, 0x10, 0x4C, 0x24, 0x0A, 0x8E, 0x33, 0x42, 0x82, 0x00, 0x29, 0x1D, 0xB3, - 0xA6, 0xA0, 0x67, 0x70, 0x90, 0xCB, 0x02, 0x39, 0x9F, 0xFD, 0x88, 0x75, 0xB9, 0x05, 0xB1, 0x1F }, - }, { { 0x06, 0xD4, 0x08, 0xFF, 0xA9, 0x93, 0xAF, 0x04, 0x45, 0x9C, 0x45, 0x67, 0x1A, 0xAB, 0xD8, 0x7E, 0xF9, 0x2B, 0x85, 0x6B, 0x1B, 0x42, 0xC6, 0x7E, 0x00, 0x5E, 0xB4, 0xD2, 0x71, 0x58, 0xA8, 0x42 }, @@ -188,22 +52,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x07, 0x19, 0x4F, 0x47, 0xF4, 0xCE, 0xD0, 0x96, 0xD1, 0x06, 0x8D, 0x34, 0x49, 0x3B, 0x67, 0x37, 0x14, 0x45, 0x16, 0x93, 0xA6, 0xA2, 0x71, 0x2F, 0x70, 0x8F, 0x59, 0x36, 0x12, 0x11, 0xC6, 0x21 }, }, - { - { 0x07, 0x3C, 0xA3, 0x1D, 0x60, 0x08, 0x54, 0xA8, 0x29, 0x9A, 0xFF, 0x74, 0xE9, 0x8A, 0xC1, 0xED, - 0x48, 0x2A, 0xCA, 0x06, 0x8E, 0xC5, 0x90, 0x61, 0x54, 0xEA, 0x24, 0x7B, 0x6C, 0x27, 0x6E, 0xE9 }, - }, - { - { 0x07, 0x76, 0x08, 0x6A, 0x5A, 0x31, 0x72, 0x42, 0xA2, 0x50, 0x4C, 0x45, 0x3C, 0x89, 0xFF, 0xD3, - 0xC4, 0xF3, 0xA3, 0x6C, 0x46, 0xBE, 0xB3, 0xF5, 0xF3, 0x55, 0xDB, 0x47, 0x6D, 0xD7, 0x7C, 0x19 }, - }, { { 0x07, 0x8F, 0xEE, 0x58, 0x8A, 0x2C, 0x55, 0xC8, 0xE2, 0xC1, 0x78, 0x71, 0xAA, 0xB6, 0xE4, 0x00, 0xB3, 0xFD, 0xBC, 0xDC, 0xF3, 0x91, 0x46, 0xA0, 0x89, 0x37, 0xF9, 0xAC, 0x06, 0xA1, 0xB8, 0xBD }, }, - { - { 0x07, 0xA9, 0x5C, 0x81, 0xED, 0x15, 0x9E, 0x44, 0xA0, 0x41, 0x2B, 0xDE, 0xB1, 0x31, 0xA1, 0x1F, - 0x26, 0xE3, 0x4E, 0x51, 0x67, 0xEC, 0xF2, 0x11, 0x78, 0xF3, 0xEF, 0xBF, 0xB3, 0xA2, 0xBB, 0x72 }, - }, { { 0x07, 0xE9, 0x60, 0x9E, 0x05, 0xDC, 0x0A, 0x1E, 0x52, 0x15, 0x06, 0x49, 0xEB, 0xF4, 0x1F, 0x6D, 0xE3, 0x86, 0x7C, 0x9C, 0x25, 0xFE, 0x17, 0x7B, 0xAB, 0xCF, 0xD9, 0xB3, 0x70, 0x46, 0x13, 0x8B }, @@ -216,58 +68,22 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x08, 0xC2, 0xD3, 0x17, 0xA8, 0x4A, 0x3C, 0xBE, 0x38, 0xDE, 0x64, 0xA2, 0x4D, 0xD4, 0x27, 0x91, 0x09, 0xE2, 0xBC, 0x02, 0x2B, 0x93, 0xB1, 0x05, 0xA8, 0x94, 0xA5, 0x1A, 0xDC, 0x3E, 0xE5, 0xCC }, }, - { - { 0x08, 0xC7, 0xB0, 0x23, 0xA9, 0x9A, 0x63, 0x74, 0x13, 0xDE, 0x2C, 0x9D, 0x88, 0x09, 0x82, 0x33, - 0x8D, 0x09, 0x36, 0xF1, 0x21, 0x25, 0x1E, 0x75, 0x58, 0x59, 0x12, 0x62, 0x92, 0xF9, 0x6B, 0x1A }, - }, - { - { 0x09, 0x06, 0x86, 0xA8, 0x02, 0xD8, 0x42, 0x73, 0x06, 0x33, 0x5B, 0xC4, 0x63, 0x5F, 0x95, 0x8F, - 0x90, 0xB2, 0x76, 0xEB, 0x7B, 0x1A, 0x62, 0x7C, 0xBE, 0xA7, 0xF8, 0xA1, 0xD2, 0x44, 0xEE, 0x8A }, - }, - { - { 0x09, 0x1F, 0x0A, 0xDD, 0x81, 0x63, 0xC3, 0x11, 0xB3, 0xDF, 0x6C, 0x8A, 0xBA, 0x7B, 0xD3, 0x35, - 0x0C, 0x52, 0xC4, 0xFC, 0xAE, 0xC1, 0x67, 0x62, 0xF6, 0x64, 0xC4, 0xCB, 0xDC, 0xC5, 0x77, 0xC8 }, - }, - { - { 0x09, 0x35, 0x58, 0xED, 0xE2, 0x67, 0x67, 0x32, 0x63, 0x49, 0xE7, 0xBE, 0xBC, 0x8C, 0x77, 0x02, - 0x94, 0xC4, 0x42, 0xA7, 0x2E, 0x6C, 0x98, 0x0E, 0xA0, 0x4E, 0xFA, 0x90, 0x07, 0x30, 0x81, 0x3E }, - }, { { 0x09, 0x9F, 0x3E, 0x71, 0xB5, 0x00, 0xD1, 0x5B, 0x03, 0x7B, 0x93, 0xAA, 0x5F, 0xB4, 0x16, 0x19, 0x0A, 0xD1, 0xDF, 0x86, 0x73, 0xAB, 0x31, 0xA8, 0xF6, 0xD9, 0x7F, 0x59, 0x5E, 0x8E, 0x16, 0xE9 }, }, - { - { 0x09, 0xA2, 0xC1, 0x4E, 0x5D, 0x62, 0xC3, 0x4A, 0xA7, 0x06, 0xFF, 0xAB, 0xD2, 0x1E, 0x7A, 0xD2, - 0x25, 0xF6, 0x25, 0xF7, 0x1F, 0xF8, 0x9D, 0xB3, 0x9B, 0x32, 0x2A, 0xCB, 0x0C, 0x84, 0x57, 0x4F }, - }, - { - { 0x09, 0xA5, 0x9E, 0x8B, 0x56, 0xFD, 0x2B, 0xA0, 0xAC, 0x68, 0x5C, 0xB6, 0xF7, 0x51, 0xA0, 0x2F, - 0x83, 0x5C, 0x68, 0x50, 0x81, 0xA2, 0xD5, 0xDC, 0x02, 0xB0, 0x4E, 0x9B, 0x3B, 0xC7, 0xC8, 0xBC }, - }, { { 0x09, 0xEB, 0xDD, 0x1B, 0x7F, 0xFA, 0x4E, 0xD7, 0x4B, 0xEB, 0xAE, 0x96, 0xBA, 0x10, 0x65, 0xDC, 0x7D, 0xA1, 0xC5, 0xD3, 0x18, 0x3C, 0xC5, 0x94, 0x19, 0xE9, 0x78, 0x36, 0xAF, 0x7F, 0x6D, 0x70 }, }, - { - { 0x09, 0xFC, 0x8C, 0xAD, 0x2C, 0xE7, 0x52, 0x3C, 0xDB, 0xED, 0x70, 0x5F, 0xDA, 0x4B, 0x22, 0x8C, - 0xD4, 0xBB, 0xA3, 0xB7, 0xF9, 0xF2, 0x50, 0xEA, 0x6B, 0xE2, 0x3C, 0x17, 0x00, 0xA5, 0x1C, 0xE5 }, - }, { { 0x0A, 0x01, 0x88, 0x81, 0x2C, 0x9D, 0xE8, 0x8A, 0x2F, 0x0A, 0x5C, 0x4C, 0x57, 0xE6, 0xF9, 0xA8, 0x15, 0x69, 0xE9, 0xC7, 0x09, 0xC0, 0x95, 0x40, 0x80, 0xE5, 0xE4, 0xE6, 0x62, 0x85, 0x6D, 0xF8 }, }, - { - { 0x0A, 0x35, 0xB0, 0xDA, 0x94, 0xB8, 0xA4, 0xB4, 0xAE, 0xB6, 0x32, 0xB0, 0x90, 0xC8, 0xA3, 0xC0, - 0x81, 0x9B, 0xC6, 0x74, 0x99, 0xF8, 0x92, 0x8B, 0xF6, 0x8E, 0xB2, 0xFF, 0x4E, 0xD4, 0x29, 0x51 }, - }, { { 0x0A, 0x42, 0x19, 0x7E, 0x48, 0x70, 0xB2, 0x34, 0x20, 0xF5, 0x51, 0x9F, 0xB8, 0x39, 0xB6, 0xCC, 0x83, 0x03, 0x52, 0x9A, 0xA9, 0x06, 0x9A, 0xD1, 0xA0, 0x90, 0x86, 0xCF, 0x6C, 0xBA, 0x07, 0xC2 }, }, - { - { 0x0A, 0xB1, 0xB1, 0x53, 0x74, 0x59, 0x75, 0x6C, 0xD4, 0x1C, 0x02, 0x6D, 0x46, 0x83, 0x64, 0x3A, - 0xC1, 0x6C, 0xF9, 0xCB, 0x1C, 0x28, 0xBD, 0x27, 0x8A, 0x18, 0x53, 0x52, 0x30, 0xD6, 0xE4, 0x93 }, - }, { { 0x0B, 0x03, 0xE1, 0x27, 0xC2, 0xE3, 0x3E, 0xAD, 0xBC, 0xB0, 0x99, 0x80, 0x46, 0xCC, 0x9B, 0xA7, 0x33, 0x46, 0x3E, 0x0C, 0xA6, 0x43, 0x52, 0x27, 0x81, 0xB0, 0x3D, 0x81, 0x53, 0x97, 0xEB, 0x4F }, @@ -276,62 +92,22 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x0B, 0x1E, 0x1E, 0x73, 0x43, 0xA0, 0xE9, 0x1C, 0x2A, 0x27, 0xDD, 0x2A, 0x4D, 0x7E, 0x6B, 0xF1, 0xE8, 0x04, 0x4B, 0x58, 0xCE, 0x1A, 0xE8, 0x1E, 0x27, 0xD8, 0x14, 0xFD, 0x2D, 0xC0, 0x18, 0x93 }, }, - { - { 0x0B, 0x23, 0x83, 0x47, 0x04, 0xD5, 0x51, 0xF9, 0x14, 0xD0, 0xAE, 0xD0, 0x6A, 0x5F, 0x1A, 0x72, - 0x48, 0x11, 0xDB, 0x55, 0x18, 0x00, 0x4C, 0xB2, 0xC3, 0x8C, 0xF9, 0x71, 0x49, 0x64, 0xDB, 0x21 }, - }, - { - { 0x0B, 0x28, 0x58, 0xC0, 0x3B, 0xA3, 0xF1, 0x10, 0x18, 0x68, 0x8E, 0xC6, 0x2F, 0x1C, 0x17, 0x30, - 0xDC, 0xA2, 0x20, 0x48, 0x57, 0xCE, 0x5F, 0xAD, 0xB6, 0x6C, 0xE6, 0x6B, 0xDA, 0xB1, 0x70, 0x3D }, - }, - { - { 0x0B, 0x3D, 0x17, 0x8D, 0x8A, 0x68, 0x43, 0x73, 0x19, 0x35, 0x9F, 0xA3, 0x54, 0x28, 0x65, 0xAD, - 0xE1, 0x20, 0x02, 0x9A, 0xBE, 0x5B, 0x02, 0xBA, 0xFF, 0xBE, 0x98, 0x8B, 0x2A, 0x14, 0x46, 0x3D }, - }, - { - { 0x0B, 0x45, 0xC6, 0x0D, 0xE2, 0x72, 0x59, 0xC9, 0x59, 0x56, 0x71, 0xCE, 0xA0, 0xBE, 0x71, 0x1E, - 0x0F, 0x64, 0x49, 0xEE, 0xC6, 0x19, 0x88, 0x3A, 0x6C, 0x39, 0x3D, 0xCE, 0x51, 0x85, 0xA7, 0xAC }, - }, { { 0x0B, 0x48, 0xD5, 0x5C, 0xAC, 0x84, 0xFD, 0xEE, 0x15, 0xD8, 0x1A, 0xFF, 0x99, 0x07, 0xBB, 0x9A, 0x57, 0x11, 0xA9, 0x5C, 0xE2, 0x3A, 0x8D, 0x4D, 0x5E, 0x88, 0x62, 0xBF, 0x15, 0xA7, 0x6A, 0x75 }, }, - { - { 0x0B, 0x85, 0xEA, 0x41, 0xE5, 0x44, 0x13, 0x86, 0xC9, 0x44, 0xE8, 0x1D, 0x47, 0xEC, 0x0F, 0x42, - 0x0B, 0x54, 0xE5, 0x11, 0x14, 0x38, 0xCB, 0x5A, 0x1C, 0xBD, 0x53, 0xC7, 0x8E, 0x7E, 0xD2, 0xA6 }, - }, { { 0x0B, 0xFE, 0xA1, 0x38, 0x31, 0x67, 0x3E, 0xC9, 0x69, 0xD0, 0x5F, 0xD8, 0x67, 0xB6, 0x69, 0xF2, 0x71, 0x24, 0xAF, 0xEB, 0x7C, 0x60, 0x8C, 0xFE, 0x54, 0xCF, 0x46, 0x33, 0x06, 0xCC, 0x99, 0x2E }, }, - { - { 0x0C, 0x02, 0xA0, 0x08, 0xA4, 0x98, 0xD9, 0x82, 0x26, 0x80, 0xEC, 0x09, 0x73, 0x3B, 0x15, 0xCF, - 0xE2, 0x66, 0x30, 0xDA, 0x43, 0x94, 0x65, 0x82, 0xE5, 0xDA, 0xCA, 0x43, 0x89, 0x9D, 0x5F, 0x6F }, - }, - { - { 0x0C, 0x14, 0xF5, 0x4B, 0x4A, 0xE1, 0xD2, 0xBC, 0xA2, 0x83, 0x40, 0x09, 0x0E, 0x37, 0x37, 0x6C, - 0xFD, 0xE7, 0x78, 0x4A, 0xA7, 0x20, 0xB3, 0x55, 0x9C, 0x42, 0xD8, 0xC9, 0x4F, 0x44, 0xCB, 0x04 }, - }, - { - { 0x0C, 0xA8, 0x11, 0xFE, 0xDB, 0x74, 0xBE, 0xAD, 0x8B, 0xB6, 0xA9, 0xEF, 0x22, 0xE7, 0x3A, 0x5F, - 0x5F, 0x3F, 0x38, 0x53, 0xFD, 0xE6, 0xDB, 0xE3, 0xF6, 0xA2, 0xD8, 0xEF, 0x7F, 0x62, 0x27, 0x3A }, - }, { { 0x0C, 0xB9, 0x31, 0x93, 0xF1, 0x65, 0x26, 0xE1, 0xD1, 0x65, 0x52, 0x11, 0x7B, 0xA2, 0x1A, 0xAC, 0xB9, 0xF1, 0xD7, 0xA8, 0x93, 0x56, 0xA3, 0x5D, 0xE4, 0xF6, 0x65, 0xE9, 0x39, 0x90, 0x79, 0x38 }, }, - { - { 0x0D, 0x01, 0xD9, 0x55, 0x23, 0x47, 0x90, 0x24, 0x17, 0x4E, 0x8D, 0xC1, 0x05, 0x00, 0x90, 0x39, - 0xE7, 0x3C, 0x0B, 0xC6, 0x34, 0x66, 0x54, 0x6D, 0x91, 0xFA, 0xCD, 0x29, 0xAA, 0x39, 0x13, 0xC6 }, - }, { { 0x0D, 0x16, 0x1B, 0xB9, 0xCA, 0x0D, 0x20, 0xE4, 0x67, 0x35, 0x89, 0x67, 0x22, 0x78, 0xB0, 0xA3, 0xC5, 0xE2, 0x69, 0x30, 0xA4, 0xDC, 0x3A, 0x82, 0x16, 0x85, 0x43, 0x24, 0x27, 0xC7, 0x31, 0x5A }, }, - { - { 0x0D, 0x18, 0x5D, 0x97, 0x79, 0xAC, 0xFE, 0x41, 0x89, 0x12, 0xB5, 0x9E, 0xF7, 0xCD, 0x42, 0x8B, - 0xD4, 0xBC, 0x7F, 0x2B, 0xCD, 0xED, 0x9E, 0xAD, 0xAB, 0x55, 0xF0, 0x66, 0xE2, 0x9E, 0xDF, 0x4F }, - }, { { 0x0D, 0x66, 0x45, 0x6B, 0x0B, 0xF4, 0xAA, 0x54, 0x16, 0xE4, 0x4D, 0x9F, 0xDB, 0x40, 0x38, 0x3D, 0x34, 0x3D, 0x7B, 0x3F, 0x6A, 0xFE, 0x69, 0xAA, 0x08, 0x95, 0xBB, 0x1A, 0xB5, 0xE0, 0x61, 0xA0 }, @@ -340,30 +116,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x0D, 0x71, 0xC8, 0xCA, 0x16, 0x56, 0x59, 0xEF, 0xAF, 0x69, 0x65, 0x29, 0x28, 0x9A, 0xAE, 0x25, 0xD9, 0xC4, 0x2A, 0x1B, 0xBB, 0x03, 0x5A, 0x2B, 0x8C, 0x61, 0x14, 0x7E, 0x1B, 0x8B, 0x90, 0x52 }, }, - { - { 0x0D, 0xAB, 0xAE, 0xCB, 0x0D, 0x12, 0x9B, 0xC6, 0x36, 0xE8, 0x4A, 0x4B, 0x23, 0x93, 0x46, 0x03, - 0x06, 0xAB, 0x49, 0xBD, 0x03, 0xE2, 0x22, 0xEE, 0x79, 0x2A, 0x36, 0x9E, 0x6E, 0x4F, 0x70, 0x72 }, - }, - { - { 0x0D, 0xE7, 0xAB, 0x16, 0xC8, 0xC2, 0xAB, 0x33, 0x4A, 0x01, 0x65, 0x96, 0x97, 0x41, 0x5A, 0x9E, - 0x28, 0x02, 0xEE, 0xDC, 0x41, 0xAC, 0xF7, 0x46, 0x92, 0x41, 0xE2, 0xD3, 0x9B, 0x97, 0x9D, 0x81 }, - }, - { - { 0x0E, 0x23, 0x35, 0x4D, 0xE8, 0xD0, 0xE4, 0x79, 0xCA, 0x89, 0xA3, 0x0F, 0xD3, 0xEF, 0x7E, 0x20, - 0xBF, 0xC2, 0x80, 0x39, 0x8D, 0x4C, 0xDC, 0x28, 0x18, 0x79, 0xDA, 0x66, 0xEA, 0xD3, 0x73, 0xD0 }, - }, - { - { 0x0E, 0x4F, 0xD8, 0x53, 0xD6, 0x0F, 0xD7, 0x69, 0x90, 0xD7, 0x77, 0xAF, 0x09, 0x79, 0xD4, 0x65, - 0x16, 0xBD, 0xC9, 0x09, 0xA8, 0xD9, 0xD5, 0xEF, 0x70, 0x15, 0x59, 0xBF, 0x74, 0x62, 0xC4, 0xAF }, - }, - { - { 0x0E, 0x56, 0x71, 0x6D, 0xD3, 0xC1, 0x83, 0xAA, 0x5D, 0xE0, 0xD3, 0x96, 0x89, 0x88, 0x94, 0xF0, - 0x03, 0xAA, 0xFF, 0x06, 0x2E, 0x15, 0x82, 0x33, 0xEF, 0xFB, 0x5B, 0xC9, 0xE8, 0x33, 0x71, 0x4B }, - }, - { - { 0x0E, 0x67, 0x06, 0x78, 0x44, 0xAA, 0xC4, 0xC8, 0xC3, 0x56, 0xE7, 0xAA, 0xB8, 0x6B, 0x58, 0xB0, - 0x14, 0x21, 0x03, 0x87, 0xD2, 0xC1, 0x55, 0xDE, 0x71, 0x94, 0x08, 0x65, 0x12, 0xCF, 0x09, 0xDE }, - }, { { 0x0E, 0xFD, 0x68, 0x73, 0xD6, 0x0E, 0x77, 0x96, 0x2D, 0xF6, 0x00, 0x16, 0xDC, 0x3B, 0xAF, 0x9C, 0xA7, 0x1E, 0x7D, 0x86, 0x19, 0xE7, 0xEB, 0xAA, 0x3A, 0xF2, 0xDC, 0xB5, 0xBA, 0x24, 0xDE, 0xC2 }, @@ -372,86 +124,14 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x0E, 0xFF, 0x3C, 0xFF, 0xDA, 0x4A, 0x3E, 0x87, 0x23, 0x4A, 0x86, 0xC7, 0x0D, 0x49, 0x8C, 0x62, 0x60, 0x7F, 0x37, 0x44, 0xEA, 0x71, 0xF1, 0x83, 0x1D, 0xCF, 0xCA, 0xF3, 0xAF, 0x15, 0x56, 0x9C }, }, - { - { 0x0F, 0x07, 0xAA, 0xD7, 0xAC, 0x55, 0x6F, 0x85, 0x86, 0xCB, 0xF3, 0x47, 0x8F, 0x2E, 0xC0, 0xB5, - 0x29, 0xCA, 0x46, 0x5B, 0x19, 0x3F, 0xC2, 0xA6, 0xE1, 0x93, 0x28, 0x3A, 0xD8, 0xD7, 0xA5, 0x50 }, - }, - { - { 0x0F, 0x2C, 0x25, 0x7A, 0xFB, 0xE8, 0x25, 0x5D, 0x2D, 0x6F, 0x4D, 0x52, 0xC4, 0xE5, 0x31, 0x59, - 0xB7, 0xBA, 0x96, 0xF9, 0xBA, 0x07, 0xFA, 0x6D, 0x8C, 0xE1, 0xD0, 0xAC, 0x03, 0x3C, 0x17, 0xF7 }, - }, - { - { 0x0F, 0x43, 0xFC, 0x12, 0x47, 0x01, 0xFE, 0x29, 0xB7, 0x14, 0xF3, 0x05, 0xE2, 0x61, 0xB6, 0x32, - 0x04, 0x82, 0xC0, 0x09, 0x6F, 0xFE, 0xAD, 0x35, 0xE1, 0xF8, 0xE6, 0x32, 0xC6, 0x4D, 0x7B, 0x20 }, - }, - { - { 0x0F, 0x57, 0xED, 0x67, 0x2B, 0xAC, 0x50, 0x14, 0x89, 0xE4, 0xF4, 0xAB, 0x4B, 0x1D, 0xB1, 0x75, - 0x81, 0xFE, 0xB8, 0x76, 0x0F, 0xFB, 0xC0, 0x8A, 0x82, 0x83, 0xE0, 0xF8, 0x41, 0xAE, 0x01, 0x3C }, - }, - { - { 0x10, 0x14, 0xB6, 0xDB, 0xF3, 0xC9, 0x11, 0xEB, 0x21, 0x6F, 0xE6, 0xEC, 0xE6, 0x8C, 0xA9, 0x37, - 0x92, 0xCC, 0xCB, 0xD3, 0xC3, 0x9C, 0xBF, 0x83, 0xE8, 0x93, 0xD4, 0x4D, 0x5E, 0x4F, 0x00, 0xDB }, - }, - { - { 0x10, 0x7F, 0xA4, 0x31, 0x4E, 0x09, 0x74, 0x84, 0x8A, 0x9C, 0x14, 0xE0, 0x62, 0x10, 0x44, 0x7B, - 0x0A, 0xDF, 0xB8, 0x26, 0xB3, 0xE5, 0xBF, 0x88, 0x76, 0x93, 0x1F, 0xF4, 0x80, 0x74, 0x02, 0x01 }, - }, { { 0x10, 0x83, 0x6D, 0xA0, 0xCD, 0x6A, 0xC0, 0x95, 0xDD, 0x7A, 0xC3, 0x4D, 0x99, 0x01, 0x90, 0x9A, 0x8E, 0xF8, 0x4D, 0x6E, 0xE0, 0x5B, 0x83, 0x43, 0x03, 0xD4, 0x7F, 0xC0, 0xA5, 0xF9, 0x14, 0xFA }, }, - { - { 0x10, 0xCF, 0x15, 0xBB, 0x1E, 0xA3, 0x0B, 0xB4, 0xA2, 0xE5, 0x39, 0x1C, 0x39, 0xAF, 0xA3, 0xA9, - 0x96, 0xC8, 0x53, 0x22, 0xB1, 0x1F, 0xDE, 0xD5, 0xFB, 0x84, 0x80, 0x35, 0x5C, 0x78, 0x3E, 0xAD }, - }, - { - { 0x10, 0xDC, 0x64, 0x9C, 0x0A, 0x35, 0x20, 0x69, 0x0B, 0x49, 0xA8, 0x97, 0xEA, 0xB4, 0x97, 0xF4, - 0x38, 0x81, 0x0D, 0x28, 0x4F, 0xCB, 0xF2, 0x22, 0xA1, 0xDE, 0x45, 0x27, 0x1D, 0x1C, 0xCF, 0x17 }, - }, - { - { 0x11, 0x59, 0xD3, 0x5C, 0x9C, 0x09, 0xEF, 0x77, 0xCB, 0xEA, 0x92, 0x2E, 0xF5, 0xBB, 0xB0, 0x36, - 0x51, 0x11, 0x65, 0x52, 0x7A, 0xCF, 0x44, 0xAA, 0xB5, 0xDE, 0x87, 0x5E, 0x2F, 0x51, 0xA2, 0xDD }, - }, - { - { 0x11, 0x65, 0x97, 0x60, 0x44, 0x7F, 0xB6, 0x8D, 0x4F, 0xBB, 0x37, 0x6E, 0x3B, 0x66, 0xB1, 0x94, - 0xDA, 0x3E, 0xE0, 0x42, 0x5A, 0x0B, 0xC2, 0x13, 0x88, 0x06, 0xB2, 0x78, 0x43, 0x79, 0xD3, 0xB8 }, - }, - { - { 0x11, 0x6A, 0x75, 0xFA, 0x6F, 0x84, 0x56, 0x46, 0x7A, 0x45, 0xF1, 0x4D, 0xA4, 0xB7, 0xCF, 0x3E, - 0x37, 0xE6, 0xA7, 0xCF, 0x07, 0x5B, 0x23, 0x35, 0xB2, 0x01, 0x1D, 0x93, 0x8B, 0x0F, 0x09, 0xA0 }, - }, { { 0x11, 0xA4, 0x02, 0x7B, 0x45, 0xFC, 0x9A, 0x6F, 0x40, 0x21, 0x25, 0xC3, 0xCA, 0x22, 0x68, 0xE0, 0x15, 0xA3, 0x1B, 0xA4, 0xFD, 0xB0, 0x05, 0x9D, 0x66, 0x6B, 0x73, 0xC8, 0x51, 0xD5, 0x35, 0x92 }, }, - { - { 0x11, 0xB7, 0x69, 0xDE, 0xDE, 0x8B, 0xD6, 0x15, 0xFC, 0x71, 0x20, 0x0B, 0x20, 0xB9, 0xA3, 0x1D, - 0x70, 0x93, 0x15, 0x16, 0xEC, 0x54, 0x42, 0xC3, 0xDD, 0xC9, 0xC8, 0xD1, 0x90, 0x21, 0x9D, 0xE1 }, - }, - { - { 0x11, 0xD3, 0x0D, 0xD7, 0x81, 0x07, 0x21, 0x88, 0x84, 0xB6, 0x55, 0xD8, 0x62, 0xAB, 0x05, 0x0E, - 0xAC, 0x0F, 0x5E, 0x33, 0x8E, 0xB1, 0x18, 0x44, 0x4B, 0x36, 0x0C, 0x8A, 0x3E, 0x05, 0x09, 0x9D }, - }, - { - { 0x11, 0xDE, 0x20, 0x2A, 0x3E, 0x34, 0x13, 0xA2, 0x33, 0x3E, 0xC1, 0x67, 0x8E, 0xBB, 0x50, 0x6D, - 0xD9, 0x55, 0x7C, 0x06, 0x81, 0xCE, 0x5F, 0xED, 0xCD, 0x25, 0xAA, 0xD1, 0x2C, 0x46, 0x67, 0xD6 }, - }, - { - { 0x11, 0xE7, 0x54, 0xF7, 0x95, 0x9E, 0x25, 0xB0, 0x18, 0x52, 0xA0, 0x46, 0xB1, 0xD2, 0xC2, 0xF6, - 0x48, 0x93, 0x53, 0x7A, 0x47, 0x4D, 0x14, 0x1D, 0x6E, 0x50, 0x50, 0x1E, 0x33, 0x9D, 0x89, 0x19 }, - }, - { - { 0x11, 0xF6, 0x34, 0xE0, 0x59, 0xEA, 0xBB, 0x99, 0xD6, 0x48, 0xD4, 0xFF, 0x6C, 0xD4, 0x29, 0x8E, - 0xD2, 0x0A, 0xA8, 0x2C, 0xCC, 0xDE, 0x8E, 0x81, 0x09, 0x80, 0x16, 0xE2, 0xAC, 0x72, 0xD4, 0x16 }, - }, - { - { 0x12, 0x0D, 0x2B, 0x28, 0x15, 0xC5, 0xEF, 0x5C, 0x28, 0x71, 0xA1, 0x93, 0x4D, 0xD4, 0x3D, 0x49, - 0x9E, 0x4E, 0xE6, 0xB6, 0x30, 0x00, 0xAE, 0x1A, 0xBE, 0xF7, 0x6D, 0x0D, 0x85, 0x51, 0xEF, 0xC6 }, - }, - { - { 0x12, 0x50, 0x6D, 0x3D, 0xE8, 0xC3, 0x19, 0xCC, 0x5B, 0x07, 0x90, 0x67, 0x7B, 0x90, 0x86, 0x36, - 0xE0, 0x86, 0x5B, 0x5F, 0xA1, 0x95, 0xDC, 0x87, 0xAF, 0x26, 0xF2, 0xAA, 0x05, 0xC2, 0x9F, 0xAD }, - }, { { 0x12, 0x6B, 0x1B, 0xA6, 0x38, 0xC7, 0xE6, 0x99, 0xBC, 0xBC, 0x54, 0xF5, 0x79, 0xAC, 0xD3, 0x9F, 0xE6, 0x1D, 0x08, 0x22, 0x5F, 0xE5, 0xB1, 0xF9, 0x01, 0x88, 0xB2, 0x3F, 0xD8, 0x43, 0x3E, 0x8E }, @@ -464,22 +144,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x13, 0x6A, 0x40, 0x09, 0x81, 0xB1, 0xA3, 0xE0, 0x5F, 0xDC, 0xAC, 0x20, 0xA2, 0x36, 0xF8, 0x6E, 0x94, 0xE5, 0xEE, 0x58, 0x59, 0xD8, 0xFD, 0x45, 0xE9, 0xE9, 0xC5, 0xA6, 0xC5, 0xC0, 0xA4, 0x13 }, }, - { - { 0x13, 0xBD, 0x07, 0x7B, 0x8A, 0x9F, 0x46, 0xFF, 0x8F, 0x2F, 0xFD, 0x23, 0x6E, 0x53, 0xA7, 0x2C, - 0x3B, 0x87, 0xF3, 0x4C, 0xC9, 0xDB, 0xB5, 0x81, 0x7E, 0x4D, 0xBA, 0x1B, 0xD3, 0xBC, 0x9E, 0x5F }, - }, - { - { 0x13, 0xCF, 0x4A, 0xC3, 0x21, 0x48, 0xB9, 0xC5, 0x61, 0x8A, 0x7D, 0xA6, 0x2F, 0x1C, 0xB8, 0x41, - 0x56, 0x68, 0xD5, 0x9F, 0xD3, 0xB3, 0x04, 0x1F, 0x50, 0x23, 0x20, 0xE5, 0x8E, 0x95, 0x1B, 0xC0 }, - }, - { - { 0x13, 0xE0, 0x1B, 0xE5, 0x72, 0xDC, 0x11, 0xFA, 0xC3, 0xB4, 0x7A, 0xE6, 0x8F, 0x92, 0xDC, 0x00, - 0xF1, 0x00, 0xBF, 0x77, 0x53, 0x7B, 0x89, 0x47, 0xF4, 0xC1, 0x1C, 0x25, 0xA0, 0xB6, 0xF9, 0xF6 }, - }, - { - { 0x13, 0xF7, 0xAC, 0xE5, 0xF5, 0x11, 0xC1, 0xF9, 0x43, 0x88, 0xE5, 0xC8, 0xA7, 0x25, 0x8A, 0x61, - 0x86, 0x14, 0xB0, 0x1C, 0xEA, 0xDC, 0xB0, 0x0A, 0x94, 0xB3, 0xCC, 0x7A, 0xE7, 0x01, 0xBE, 0xAE }, - }, { { 0x14, 0x21, 0x28, 0xA6, 0x65, 0x1C, 0xDC, 0x18, 0x70, 0xC2, 0x67, 0x5E, 0xC0, 0xB0, 0xEF, 0x32, 0xB5, 0xD4, 0xC1, 0x55, 0x35, 0x8E, 0x7E, 0xD9, 0x5A, 0x98, 0xE8, 0x3B, 0x1A, 0xD8, 0xBE, 0x4D }, @@ -488,18 +152,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x14, 0x47, 0x25, 0xA6, 0x79, 0x1C, 0x60, 0x0C, 0x4C, 0x2C, 0xF3, 0x94, 0x3F, 0x3E, 0xCF, 0x40, 0xD6, 0x31, 0xD7, 0x60, 0xE4, 0x51, 0xEF, 0x28, 0x29, 0xAF, 0xFB, 0xEE, 0x74, 0x80, 0xAD, 0x17 }, }, - { - { 0x14, 0x60, 0x80, 0x7B, 0x0D, 0x93, 0xDD, 0x79, 0xF4, 0xA3, 0xB9, 0x07, 0x45, 0xE9, 0xA7, 0x15, - 0x29, 0xF1, 0xEC, 0x26, 0x63, 0x30, 0x41, 0x57, 0x4A, 0x81, 0x80, 0xE0, 0xCE, 0x42, 0x81, 0xDF }, - }, - { - { 0x14, 0xB0, 0x98, 0x34, 0xE2, 0xA5, 0xBC, 0x61, 0x9A, 0x79, 0xA5, 0xD2, 0xCE, 0x48, 0x78, 0xFA, - 0xBC, 0xA0, 0x6D, 0x76, 0xC2, 0x37, 0x65, 0xFD, 0x45, 0x86, 0x3C, 0x22, 0xFE, 0xCE, 0x30, 0x38 }, - }, - { - { 0x14, 0xF3, 0xB4, 0x17, 0x3B, 0x9F, 0x8C, 0x81, 0x90, 0x39, 0x74, 0xE6, 0x4C, 0x68, 0xDF, 0xAE, - 0xB6, 0xB7, 0xD8, 0x4B, 0x94, 0x2A, 0xAE, 0x78, 0x89, 0x03, 0xA1, 0x54, 0x01, 0x08, 0x57, 0xE7 }, - }, { { 0x15, 0x27, 0x2A, 0xBC, 0x1F, 0x0C, 0x4D, 0x1D, 0x1A, 0x92, 0x08, 0x73, 0x55, 0xA1, 0xE0, 0x42, 0x6C, 0x2B, 0xB5, 0xB4, 0x37, 0x30, 0x00, 0xB8, 0x2C, 0x2C, 0xCA, 0xB7, 0xFA, 0xD6, 0xFA, 0x20 }, @@ -516,118 +168,22 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x15, 0x5D, 0x88, 0x6E, 0x99, 0x1D, 0x40, 0x0A, 0xBF, 0x2F, 0x83, 0xC2, 0x80, 0xD1, 0x24, 0x6D, 0xCE, 0x02, 0xA6, 0x28, 0x31, 0x26, 0xC6, 0x17, 0xE4, 0x17, 0xD2, 0xB7, 0xEA, 0xC1, 0x19, 0x24 }, }, - { - { 0x15, 0x75, 0x93, 0x18, 0x80, 0x19, 0x6D, 0xE8, 0x0D, 0x97, 0xFE, 0xF1, 0x85, 0xD2, 0x7A, 0xF6, - 0xAD, 0x6B, 0x5B, 0x04, 0x0D, 0x87, 0x6C, 0xDF, 0x4A, 0x39, 0xB5, 0xB7, 0x8E, 0x96, 0xB7, 0xD5 }, - }, - { - { 0x15, 0xB0, 0xD9, 0xBE, 0xD6, 0x2B, 0xD8, 0x96, 0x11, 0x59, 0xFE, 0x7E, 0x88, 0x92, 0xF8, 0xE8, - 0xEB, 0xB0, 0xCE, 0x81, 0xE6, 0x8D, 0xEA, 0xDD, 0x29, 0x0F, 0xDD, 0xCE, 0xD0, 0x9D, 0xE7, 0xF1 }, - }, - { - { 0x15, 0xC0, 0x27, 0x02, 0x53, 0x4E, 0xB0, 0x57, 0x23, 0x9F, 0xD7, 0x85, 0x8A, 0xE3, 0x42, 0x23, - 0xBC, 0x57, 0x78, 0xA8, 0xB7, 0x1F, 0x92, 0x50, 0xD5, 0xD3, 0x3B, 0x31, 0x3C, 0x30, 0x2A, 0x67 }, - }, - { - { 0x15, 0xC1, 0x73, 0xD2, 0xF3, 0x73, 0xC2, 0x27, 0xDC, 0xFF, 0x4E, 0xCC, 0x68, 0xE8, 0x56, 0x7C, - 0xDA, 0xE3, 0x5D, 0xDF, 0x1E, 0xF4, 0x55, 0xCE, 0x53, 0x4A, 0x15, 0x90, 0x28, 0x79, 0xF4, 0xFE }, - }, - { - { 0x15, 0xCF, 0x2F, 0x78, 0xE6, 0x79, 0x62, 0x2C, 0x06, 0x78, 0xDC, 0x5B, 0xA8, 0x03, 0x84, 0x7A, - 0xBD, 0xB5, 0xEA, 0x64, 0x31, 0x65, 0x3E, 0xC2, 0x5F, 0xDC, 0x8D, 0x2B, 0xB3, 0x3D, 0x12, 0x23 }, - }, - { - { 0x15, 0xEA, 0x55, 0xF0, 0x2C, 0x49, 0x02, 0xEC, 0x77, 0x72, 0x64, 0xE0, 0x81, 0x71, 0x41, 0x24, - 0x7C, 0x52, 0x00, 0xE1, 0x16, 0x56, 0xFD, 0xC2, 0x72, 0x9D, 0x59, 0x5C, 0x37, 0x79, 0x95, 0x6C }, - }, - { - { 0x16, 0x21, 0xEC, 0x14, 0xE0, 0xB4, 0x13, 0xFA, 0xB7, 0xD0, 0x27, 0x5A, 0x9A, 0xC3, 0xC3, 0xC9, - 0x85, 0x13, 0xFE, 0x18, 0xA2, 0x02, 0x86, 0xF6, 0x56, 0x59, 0x36, 0x9C, 0x8D, 0x34, 0x68, 0xDA }, - }, - { - { 0x16, 0x9A, 0xFA, 0x4C, 0x7D, 0x97, 0x78, 0xC7, 0x1D, 0xB5, 0x84, 0x6C, 0xCA, 0x8E, 0xB7, 0x19, - 0x12, 0x3D, 0x4B, 0x06, 0xB3, 0xFF, 0x98, 0x66, 0xD7, 0x4D, 0x6E, 0x18, 0x7C, 0x1E, 0xF9, 0x70 }, - }, - { - { 0x16, 0xE7, 0x66, 0x47, 0xB3, 0x97, 0xEB, 0x4E, 0xFD, 0x9A, 0x79, 0xF2, 0xFB, 0xBA, 0x9A, 0xCA, - 0x46, 0xCE, 0xAD, 0x95, 0x43, 0x05, 0xFE, 0xE5, 0xB1, 0x3B, 0x5D, 0x53, 0xDB, 0x7C, 0x1D, 0xB1 }, - }, - { - { 0x17, 0x29, 0xB3, 0x34, 0x7A, 0x7D, 0x93, 0x73, 0x17, 0xE3, 0xDA, 0x5C, 0xC7, 0xF7, 0xB0, 0xD8, - 0xFD, 0x97, 0x72, 0x24, 0x7A, 0x57, 0x99, 0x93, 0x9A, 0x44, 0xD3, 0xA9, 0x7A, 0x50, 0xB9, 0xD9 }, - }, - { - { 0x17, 0x46, 0x68, 0x4E, 0x66, 0x21, 0x77, 0x68, 0x70, 0xDE, 0x55, 0x65, 0xDF, 0xD3, 0x3A, 0x30, - 0x92, 0x77, 0x18, 0x59, 0x6C, 0x01, 0x30, 0xF8, 0x77, 0x4B, 0xE9, 0x9C, 0xD2, 0xA2, 0x51, 0x06 }, - }, - { - { 0x17, 0x59, 0x7E, 0x00, 0x45, 0x6C, 0x38, 0x32, 0xE1, 0x85, 0x1C, 0x30, 0x0C, 0xD5, 0x52, 0xC2, - 0xE7, 0x73, 0x35, 0x8C, 0xF0, 0xF6, 0x88, 0x58, 0xF3, 0x4F, 0xCA, 0x34, 0x45, 0xC6, 0x4D, 0xB7 }, - }, - { - { 0x17, 0x5A, 0x97, 0x05, 0x5C, 0x9E, 0x03, 0x88, 0x2A, 0xCD, 0x35, 0x40, 0x58, 0xE2, 0x43, 0xE3, - 0x3A, 0x84, 0x76, 0xEF, 0x83, 0xB4, 0xB2, 0x08, 0xFC, 0xF6, 0x64, 0xE8, 0x4F, 0x05, 0x08, 0xB5 }, - }, - { - { 0x17, 0x99, 0x63, 0xD2, 0x28, 0x4D, 0xEC, 0x64, 0xAC, 0x6C, 0xE5, 0x60, 0x0B, 0xE9, 0x9A, 0xC4, - 0xF0, 0x4D, 0xD3, 0x20, 0x35, 0xE4, 0xF1, 0x24, 0x28, 0xEC, 0x9E, 0x51, 0xED, 0xF6, 0xB0, 0x6C }, - }, - { - { 0x17, 0xD1, 0xF6, 0xE5, 0x1C, 0xB3, 0xAF, 0x91, 0x23, 0xD4, 0xFC, 0xB3, 0x84, 0x18, 0x39, 0x4D, - 0xE3, 0xE6, 0xC3, 0x33, 0x3F, 0x80, 0x20, 0xD5, 0x13, 0x48, 0xDE, 0xBA, 0xCC, 0x74, 0x70, 0x14 }, - }, - { - { 0x17, 0xF7, 0x25, 0xAC, 0x12, 0xCE, 0xA5, 0xE0, 0x86, 0x6F, 0xCC, 0x3E, 0x83, 0x4E, 0x9C, 0xB6, - 0x34, 0x14, 0x5C, 0xED, 0xC5, 0x6B, 0x61, 0x3D, 0x2A, 0x1F, 0xE1, 0x3C, 0xF4, 0x0E, 0xDF, 0xD4 }, - }, - { - { 0x18, 0x04, 0xF7, 0x1E, 0x2C, 0x7A, 0xDC, 0x93, 0x38, 0xCA, 0x1B, 0x71, 0xDF, 0x81, 0xF8, 0x3E, - 0x59, 0xD4, 0xF4, 0x1C, 0xAF, 0x1D, 0x9F, 0x17, 0xD7, 0x87, 0x22, 0x4B, 0x0A, 0xF6, 0x46, 0xF3 }, - }, { { 0x18, 0x1E, 0xBB, 0x29, 0x8D, 0x20, 0x68, 0x5C, 0x48, 0xF7, 0x53, 0x89, 0x80, 0xC5, 0x63, 0xC8, 0xF7, 0x48, 0x95, 0x4C, 0xF2, 0x64, 0x41, 0x9A, 0x72, 0xFC, 0xC6, 0x34, 0x0A, 0x10, 0x23, 0x80 }, }, - { - { 0x18, 0x41, 0x69, 0xC5, 0x5C, 0xA2, 0xE2, 0x44, 0xF5, 0xF3, 0x3E, 0x5E, 0x9B, 0x82, 0x89, 0x2B, - 0x88, 0x5F, 0xD0, 0x2B, 0x0C, 0xEA, 0xFF, 0x5E, 0xB7, 0xEC, 0x05, 0x30, 0x72, 0xE9, 0xF3, 0x39 }, - }, { { 0x19, 0x77, 0x3E, 0xE9, 0xE9, 0x35, 0x6B, 0x88, 0x11, 0xD6, 0x56, 0x79, 0x9C, 0x53, 0x16, 0x0B, 0x61, 0x73, 0xFA, 0x8A, 0x81, 0x47, 0x97, 0xDB, 0xCD, 0x55, 0xB2, 0x27, 0x38, 0x70, 0x60, 0x3E }, }, - { - { 0x19, 0xD5, 0x67, 0x31, 0x19, 0x02, 0xA4, 0xA2, 0x61, 0xF8, 0xA8, 0x3D, 0x0C, 0xFE, 0x10, 0x1D, - 0x9C, 0x5C, 0x1F, 0x68, 0x0F, 0xF8, 0xF4, 0xEC, 0x0D, 0xF2, 0x3D, 0x84, 0x41, 0x92, 0xFB, 0x3B }, - }, { { 0x1A, 0x9E, 0xC6, 0x8C, 0xED, 0xB6, 0xBD, 0x94, 0x0C, 0x95, 0x34, 0xE6, 0x84, 0xBB, 0x04, 0x9F, 0xF1, 0xE2, 0x3B, 0x66, 0xA1, 0x33, 0x01, 0x2F, 0xC3, 0x99, 0xEB, 0x4F, 0xB5, 0xD3, 0xAA, 0x35 }, }, - { - { 0x1A, 0xCD, 0x0A, 0x9E, 0x5E, 0x20, 0x22, 0xBE, 0xE5, 0xA4, 0xFC, 0x2E, 0x7F, 0x69, 0xF8, 0x82, - 0x3E, 0xDC, 0x26, 0x5B, 0x97, 0x6A, 0x7F, 0x61, 0x41, 0x16, 0x03, 0x98, 0x6B, 0x90, 0x24, 0xF8 }, - }, - { - { 0x1A, 0xFA, 0xB3, 0x15, 0x5B, 0x57, 0x17, 0xC0, 0x89, 0x82, 0xF9, 0x0C, 0x88, 0xA7, 0xAA, 0xC3, - 0x6B, 0xEB, 0x00, 0x03, 0xFA, 0xC4, 0x9B, 0xCA, 0x74, 0xA1, 0xCC, 0x52, 0x09, 0xB7, 0x04, 0x39 }, - }, - { - { 0x1B, 0x56, 0xBA, 0x1E, 0xFF, 0xAC, 0x97, 0x36, 0x60, 0x74, 0xCE, 0x07, 0x24, 0xE7, 0x04, 0x59, - 0xDF, 0x99, 0x82, 0x1C, 0x3F, 0xAF, 0x20, 0xDE, 0x5C, 0x05, 0x30, 0x52, 0x52, 0xBE, 0x64, 0x3A }, - }, - { - { 0x1B, 0x69, 0xC0, 0xDD, 0xB0, 0x9B, 0xC2, 0xF0, 0xE9, 0x65, 0x7F, 0xFA, 0x94, 0x83, 0x96, 0xAF, - 0xC0, 0xCB, 0x45, 0xC0, 0x19, 0x7E, 0xC0, 0x85, 0x78, 0xC5, 0x61, 0x83, 0xEE, 0xEF, 0x59, 0x7B }, - }, { { 0x1B, 0x7B, 0xF8, 0xD9, 0xE8, 0x29, 0x3C, 0x53, 0xDD, 0x59, 0xEC, 0x97, 0xFE, 0x16, 0xF0, 0xEA, 0xB4, 0x68, 0x5B, 0x95, 0xCE, 0x14, 0xD2, 0x62, 0x3E, 0x70, 0x94, 0x2C, 0xFF, 0x25, 0xE7, 0x30 }, }, - { - { 0x1B, 0xD6, 0xA6, 0xF7, 0x63, 0xD2, 0xF6, 0xD8, 0xBC, 0xEC, 0x91, 0xA6, 0x22, 0xAA, 0x37, 0x00, - 0xD7, 0xA4, 0x2D, 0x18, 0x8C, 0x5B, 0xD8, 0x64, 0x16, 0x57, 0x6F, 0xFD, 0x32, 0x50, 0x7C, 0x92 }, - }, { { 0x1B, 0xD7, 0xB3, 0x62, 0xBC, 0x14, 0x66, 0xFA, 0xC0, 0x5E, 0xC5, 0x9E, 0x12, 0xE8, 0x1B, 0xE7, 0x35, 0x38, 0xC4, 0x97, 0x28, 0xF5, 0xAD, 0xBA, 0x2D, 0x81, 0xFC, 0xDB, 0xC4, 0x65, 0x7C, 0x1B }, @@ -644,46 +200,14 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x1C, 0x04, 0x82, 0x0F, 0x7B, 0x4A, 0x2F, 0x1E, 0x38, 0x5D, 0xE1, 0xDE, 0x16, 0xB2, 0x22, 0x6E, 0x88, 0x3D, 0x9C, 0x34, 0x66, 0x3E, 0x1B, 0x64, 0xE8, 0x5B, 0x98, 0x0E, 0xAF, 0xF0, 0xB9, 0xD3 }, }, - { - { 0x1C, 0x74, 0xBA, 0x75, 0xE5, 0x1B, 0x48, 0x29, 0x54, 0xC3, 0x8B, 0xF4, 0xD5, 0x1E, 0xFC, 0x70, - 0xA0, 0xA0, 0x4D, 0x41, 0x3A, 0xC1, 0xFF, 0x8E, 0xB9, 0x90, 0x39, 0x9D, 0x1F, 0x1A, 0xA9, 0xC4 }, - }, - { - { 0x1C, 0x76, 0xBB, 0xCA, 0x37, 0x71, 0x77, 0x5B, 0xB9, 0xB0, 0xC3, 0x33, 0x71, 0x70, 0x32, 0x69, - 0x06, 0x16, 0x77, 0xCA, 0x7B, 0x18, 0x99, 0xEF, 0x8C, 0x77, 0xE4, 0x15, 0x22, 0x2B, 0x56, 0xB6 }, - }, - { - { 0x1D, 0x36, 0x08, 0xAC, 0x22, 0xF0, 0x09, 0x40, 0xEE, 0x08, 0x4A, 0x8B, 0x2F, 0xD7, 0x95, 0x89, - 0x72, 0x57, 0x79, 0x4E, 0x3E, 0x00, 0xC2, 0xD2, 0x67, 0x10, 0xD2, 0xEA, 0x02, 0x79, 0xAC, 0xB5 }, - }, - { - { 0x1D, 0x57, 0xA3, 0xC0, 0x97, 0x74, 0x07, 0xE1, 0x57, 0xDF, 0x71, 0x97, 0x48, 0x91, 0x16, 0xE5, - 0xFC, 0x17, 0xED, 0x2A, 0x90, 0xFE, 0xD9, 0x6B, 0x3D, 0x4D, 0x5A, 0x4E, 0x0A, 0x80, 0xE1, 0xFB }, - }, - { - { 0x1D, 0x72, 0xE5, 0x91, 0x26, 0xFD, 0x8B, 0x78, 0x8E, 0xA5, 0x39, 0x63, 0xAD, 0x02, 0x07, 0x6B, - 0x3B, 0x04, 0x0E, 0xE8, 0xCD, 0x4C, 0xB8, 0xBD, 0xCD, 0xF3, 0xE5, 0xA9, 0x9F, 0x63, 0x70, 0x02 }, - }, { { 0x1D, 0x9E, 0xC0, 0x06, 0xA5, 0x26, 0xFA, 0xB5, 0xCE, 0x2E, 0x71, 0xFD, 0xFC, 0x07, 0xC0, 0x11, 0xF7, 0x65, 0x7B, 0xF8, 0x5F, 0x5D, 0x03, 0x52, 0xB8, 0xCB, 0x21, 0x8D, 0x4F, 0xCB, 0xC4, 0x43 }, }, - { - { 0x1E, 0x50, 0x62, 0x19, 0x88, 0xA0, 0x25, 0x0F, 0x2A, 0xDE, 0x2A, 0x16, 0xFC, 0xD8, 0x38, 0x46, - 0xDB, 0xD7, 0xA9, 0x0B, 0x2A, 0x71, 0xC8, 0x0A, 0x1D, 0xB1, 0x94, 0x6B, 0x89, 0x89, 0x1C, 0x46 }, - }, { { 0x1E, 0x78, 0xF8, 0x08, 0x84, 0xE3, 0x2A, 0x2E, 0xA5, 0xAD, 0x1E, 0xE8, 0x35, 0x88, 0xAC, 0xDB, 0x18, 0x4A, 0x4A, 0x6E, 0x87, 0x56, 0x5B, 0xF5, 0x03, 0xB5, 0x69, 0x7A, 0xBF, 0xAE, 0x64, 0xA4 }, }, - { - { 0x1E, 0xFE, 0x6A, 0x78, 0x51, 0x41, 0x33, 0x39, 0x7B, 0x05, 0x9C, 0xE1, 0x3A, 0x4F, 0xC9, 0x88, - 0xAE, 0x38, 0x4E, 0x21, 0x12, 0x7F, 0x13, 0xA1, 0x0E, 0x96, 0x7B, 0x9A, 0xA2, 0xAC, 0xF8, 0x81 }, - }, - { - { 0x1F, 0x00, 0x4B, 0x82, 0x0C, 0xF6, 0x8B, 0x00, 0x7B, 0xB5, 0x72, 0xA0, 0xED, 0x42, 0x9C, 0x79, - 0x8F, 0x79, 0x44, 0x4F, 0x6F, 0x13, 0x29, 0x32, 0xEE, 0x5F, 0x8E, 0x28, 0xA4, 0x0A, 0xB9, 0x86 }, - }, { { 0x1F, 0x11, 0x85, 0xA5, 0x21, 0xE2, 0x8E, 0x95, 0x17, 0x1C, 0xF3, 0x86, 0x07, 0x8A, 0x76, 0x4A, 0x9A, 0x3E, 0x71, 0xC2, 0x59, 0xBC, 0xDC, 0x5F, 0x8E, 0x66, 0xE1, 0xB5, 0x20, 0x55, 0xA2, 0x6D }, @@ -692,122 +216,42 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x1F, 0x23, 0xD7, 0xA6, 0x38, 0x17, 0x1F, 0x6D, 0x09, 0x99, 0x64, 0xE0, 0xFA, 0x01, 0x72, 0x1C, 0x06, 0xCC, 0xEB, 0x8E, 0xA2, 0x98, 0xBF, 0xD0, 0x04, 0x8E, 0x13, 0x8D, 0x98, 0xFC, 0x36, 0x24 }, }, - { - { 0x1F, 0x68, 0x40, 0x10, 0xC1, 0x92, 0xAB, 0xFA, 0x85, 0xA7, 0x9B, 0xBA, 0x45, 0xCE, 0x76, 0x4B, - 0x2D, 0xA8, 0x1F, 0x99, 0x1F, 0x5F, 0x01, 0xD9, 0xEB, 0x7E, 0x3C, 0x99, 0x9B, 0x78, 0x75, 0x0E }, - }, - { - { 0x1F, 0x7D, 0x37, 0x52, 0x93, 0x22, 0x7D, 0x04, 0x97, 0x5B, 0x78, 0x97, 0xDC, 0x17, 0x25, 0x39, - 0x64, 0xDC, 0xD7, 0xD0, 0x06, 0x7E, 0x84, 0xC6, 0xD8, 0x47, 0x9D, 0xFA, 0x27, 0x6E, 0xBE, 0xD0 }, - }, - { - { 0x1F, 0x88, 0x42, 0x37, 0xFD, 0x5C, 0xE3, 0xD9, 0xBC, 0x02, 0x4D, 0x1B, 0x26, 0xAB, 0xCB, 0x94, - 0x07, 0xA4, 0x35, 0x13, 0x78, 0xE0, 0xBD, 0x89, 0xDB, 0x67, 0xBE, 0xF8, 0xEF, 0xC8, 0xA5, 0x6E }, - }, { { 0x1F, 0xC7, 0xF8, 0x10, 0x4E, 0x27, 0xFF, 0x2A, 0x45, 0x56, 0xF9, 0x1E, 0x05, 0x42, 0x17, 0xC5, 0x8F, 0x69, 0x3F, 0x70, 0x36, 0x25, 0x9E, 0x39, 0x80, 0xB5, 0x59, 0x5B, 0x04, 0x3D, 0x11, 0x92 }, }, - { - { 0x1F, 0xD4, 0xB6, 0xA0, 0xDE, 0x45, 0x04, 0x2B, 0xCA, 0x14, 0xE3, 0x4A, 0x83, 0x78, 0x7C, 0x59, - 0x95, 0x5D, 0x82, 0xA0, 0x1C, 0xE3, 0x20, 0x05, 0xAC, 0x48, 0x83, 0x72, 0xA8, 0xFD, 0x41, 0xA6 }, - }, { { 0x20, 0x0B, 0x49, 0xBD, 0xD6, 0x35, 0x02, 0x57, 0xCC, 0xD4, 0xE6, 0xAD, 0xE1, 0xCB, 0x75, 0x13, 0x8D, 0xD6, 0xD9, 0x06, 0xFE, 0xF3, 0x49, 0xC0, 0xC9, 0x86, 0xA5, 0x1B, 0x29, 0xB9, 0xE5, 0x2D }, }, { - { 0x20, 0x15, 0x60, 0x8B, 0x8E, 0x86, 0xBA, 0x63, 0x12, 0x01, 0xC2, 0x12, 0x20, 0x99, 0x57, 0xAF, - 0xCB, 0x6E, 0xDF, 0x27, 0x22, 0xC6, 0x1B, 0x00, 0xE2, 0xFC, 0x92, 0x46, 0xA8, 0xD5, 0x20, 0x4E }, + { 0x21, 0x09, 0xF3, 0x10, 0x7D, 0x97, 0xF8, 0x70, 0x48, 0x70, 0x8E, 0xC8, 0x7C, 0xA2, 0xDC, 0x31, + 0x8B, 0x2F, 0x2B, 0x57, 0x47, 0xC3, 0x38, 0xBD, 0x9C, 0x6D, 0xBC, 0xD6, 0x0F, 0xD6, 0xBE, 0xA2 }, }, { - { 0x20, 0x7A, 0xE5, 0xE6, 0x56, 0xB3, 0xB1, 0x26, 0x39, 0x41, 0x83, 0x54, 0x5D, 0xF9, 0x9C, 0xC8, - 0x36, 0x53, 0x7A, 0x16, 0x88, 0x58, 0xD8, 0xCE, 0xB4, 0x5A, 0x6A, 0x52, 0x65, 0x86, 0xCA, 0xAE }, + { 0x21, 0x78, 0xE8, 0x28, 0x3A, 0x73, 0x39, 0x6E, 0x08, 0xC0, 0xA1, 0x1A, 0x88, 0x72, 0xFA, 0x4A, + 0x9F, 0xCC, 0x05, 0x67, 0x0C, 0xEE, 0xFF, 0xB8, 0x95, 0x83, 0x8E, 0xB6, 0x59, 0xDE, 0x38, 0xDB }, }, { - { 0x20, 0x8A, 0x46, 0xD9, 0x07, 0xE6, 0xB4, 0x09, 0x0E, 0x31, 0x02, 0xE1, 0xC7, 0xF1, 0x81, 0x57, - 0x21, 0x6C, 0xFC, 0x9A, 0xB9, 0xD5, 0x0F, 0x47, 0x83, 0x25, 0x8D, 0x79, 0x35, 0x01, 0x34, 0xBD }, + { 0x22, 0x01, 0x71, 0xF7, 0x0E, 0x1F, 0xC3, 0xC4, 0xF7, 0x8D, 0xA6, 0xC8, 0xB1, 0xD7, 0x2C, 0x3B, + 0xA8, 0x31, 0x9A, 0x46, 0xF8, 0x19, 0x2D, 0x1E, 0x19, 0xB9, 0xE2, 0x9A, 0xBA, 0x18, 0xEE, 0x87 }, }, { - { 0x20, 0xF1, 0x85, 0xBC, 0x7F, 0xA7, 0x61, 0x16, 0x6E, 0xA3, 0xA9, 0x98, 0x8F, 0xB1, 0x0B, 0x24, - 0xC7, 0x01, 0xEF, 0xDD, 0xAB, 0xE4, 0x74, 0x05, 0x63, 0x43, 0xA1, 0x36, 0x11, 0xD5, 0x4D, 0x7D }, + { 0x23, 0x19, 0xCB, 0x3D, 0x58, 0xC6, 0xD5, 0x53, 0x62, 0x5D, 0xE5, 0xF4, 0x25, 0x2B, 0xF0, 0x29, + 0xAB, 0x83, 0x05, 0xEB, 0xF2, 0x2F, 0xA2, 0x3E, 0x99, 0x73, 0x04, 0x66, 0xDE, 0x24, 0xD6, 0xC3 }, }, { - { 0x21, 0x03, 0x9F, 0x99, 0x3D, 0xAE, 0x79, 0x03, 0xA0, 0xA7, 0xAA, 0x93, 0x5B, 0x96, 0x70, 0x1A, - 0xDD, 0x7E, 0xC5, 0xCA, 0x99, 0xE1, 0x7E, 0x65, 0x1C, 0x21, 0x29, 0x5B, 0x3B, 0x65, 0x70, 0x49 }, - }, - { - { 0x21, 0x05, 0xA5, 0xB7, 0x80, 0x1C, 0xE4, 0x55, 0xA2, 0xA9, 0x31, 0xA2, 0x23, 0xBB, 0x8B, 0xF4, - 0x11, 0x28, 0x16, 0x03, 0x70, 0xFD, 0x25, 0xFC, 0x11, 0x23, 0xAB, 0x57, 0x9E, 0x06, 0x29, 0x23 }, - }, - { - { 0x21, 0x09, 0xF3, 0x10, 0x7D, 0x97, 0xF8, 0x70, 0x48, 0x70, 0x8E, 0xC8, 0x7C, 0xA2, 0xDC, 0x31, - 0x8B, 0x2F, 0x2B, 0x57, 0x47, 0xC3, 0x38, 0xBD, 0x9C, 0x6D, 0xBC, 0xD6, 0x0F, 0xD6, 0xBE, 0xA2 }, - }, - { - { 0x21, 0x4A, 0xBC, 0x84, 0x5D, 0x66, 0x68, 0x76, 0xC4, 0x78, 0x12, 0x84, 0x14, 0x16, 0xC6, 0xFB, - 0xFF, 0x4A, 0x38, 0x32, 0x20, 0x61, 0xB6, 0x5D, 0x9C, 0x5F, 0x6B, 0x74, 0x98, 0x2B, 0xC6, 0xEA }, - }, - { - { 0x21, 0x62, 0xAB, 0xC2, 0x7D, 0x0C, 0x3D, 0xA0, 0xF6, 0xAF, 0xF9, 0x76, 0x95, 0xFB, 0x3D, 0x47, - 0x7F, 0x4C, 0x63, 0x34, 0xFF, 0xB3, 0xE5, 0xBC, 0xD0, 0xE3, 0x05, 0x49, 0xD5, 0xFE, 0xEB, 0x47 }, - }, - { - { 0x21, 0x78, 0xE8, 0x28, 0x3A, 0x73, 0x39, 0x6E, 0x08, 0xC0, 0xA1, 0x1A, 0x88, 0x72, 0xFA, 0x4A, - 0x9F, 0xCC, 0x05, 0x67, 0x0C, 0xEE, 0xFF, 0xB8, 0x95, 0x83, 0x8E, 0xB6, 0x59, 0xDE, 0x38, 0xDB }, - }, - { - { 0x21, 0x82, 0x84, 0x4F, 0xB2, 0x8F, 0xB4, 0x71, 0x78, 0xEB, 0x38, 0x1C, 0xDB, 0xF1, 0x18, 0x06, - 0x3D, 0x6A, 0x9E, 0x43, 0xCC, 0x04, 0xE4, 0x8A, 0xEF, 0x84, 0xCE, 0x9C, 0xCE, 0x58, 0x4A, 0x5C }, - }, - { - { 0x22, 0x01, 0x71, 0xF7, 0x0E, 0x1F, 0xC3, 0xC4, 0xF7, 0x8D, 0xA6, 0xC8, 0xB1, 0xD7, 0x2C, 0x3B, - 0xA8, 0x31, 0x9A, 0x46, 0xF8, 0x19, 0x2D, 0x1E, 0x19, 0xB9, 0xE2, 0x9A, 0xBA, 0x18, 0xEE, 0x87 }, - }, - { - { 0x22, 0x2E, 0xC2, 0x75, 0xE6, 0x8A, 0x31, 0x7D, 0x60, 0x80, 0x67, 0x9D, 0xDF, 0x56, 0x78, 0x6A, - 0xBD, 0x2B, 0x11, 0xF2, 0x5A, 0x17, 0x15, 0x33, 0xCF, 0xBD, 0x59, 0xEE, 0x0D, 0xFA, 0x4E, 0xE4 }, - }, - { - { 0x22, 0x7A, 0x2B, 0xFF, 0xAB, 0xDE, 0xE1, 0x8C, 0x2C, 0x54, 0xE6, 0xE9, 0xB5, 0x8A, 0xBD, 0xBF, - 0x93, 0x07, 0xA4, 0x06, 0x2E, 0xDA, 0x97, 0xD4, 0xF6, 0xC4, 0x48, 0x1B, 0xB6, 0xEC, 0xA9, 0xE4 }, - }, - { - { 0x23, 0x19, 0xCB, 0x3D, 0x58, 0xC6, 0xD5, 0x53, 0x62, 0x5D, 0xE5, 0xF4, 0x25, 0x2B, 0xF0, 0x29, - 0xAB, 0x83, 0x05, 0xEB, 0xF2, 0x2F, 0xA2, 0x3E, 0x99, 0x73, 0x04, 0x66, 0xDE, 0x24, 0xD6, 0xC3 }, - }, - { - { 0x23, 0x3F, 0xC6, 0xF9, 0x15, 0x1F, 0x05, 0x00, 0xBB, 0x38, 0xAD, 0x20, 0x7A, 0xF2, 0x42, 0x21, - 0x3A, 0x6A, 0x51, 0xCE, 0xB3, 0x8C, 0x73, 0x0F, 0xF1, 0xBF, 0xA1, 0x0A, 0x82, 0x4A, 0x71, 0xC7 }, - }, - { - { 0x23, 0x86, 0x51, 0xAB, 0x70, 0xB7, 0x11, 0xA0, 0x65, 0x55, 0x4E, 0x5D, 0x63, 0x6A, 0x34, 0x2C, - 0x8A, 0x6B, 0xFE, 0x46, 0x0E, 0x4E, 0x7B, 0x4C, 0x9E, 0xAF, 0xB4, 0x75, 0xD5, 0x68, 0x51, 0xD8 }, - }, - { - { 0x23, 0x8A, 0x80, 0xCC, 0x9B, 0x58, 0x9A, 0xDC, 0x89, 0xB7, 0xA8, 0xF3, 0x4D, 0xDF, 0x12, 0x48, - 0x73, 0x4B, 0x9F, 0x7F, 0x78, 0x20, 0xB6, 0x04, 0x07, 0x66, 0xC5, 0x41, 0x3A, 0xD2, 0xBD, 0xEF }, + { 0x23, 0x8A, 0x80, 0xCC, 0x9B, 0x58, 0x9A, 0xDC, 0x89, 0xB7, 0xA8, 0xF3, 0x4D, 0xDF, 0x12, 0x48, + 0x73, 0x4B, 0x9F, 0x7F, 0x78, 0x20, 0xB6, 0x04, 0x07, 0x66, 0xC5, 0x41, 0x3A, 0xD2, 0xBD, 0xEF }, }, { { 0x23, 0x9C, 0x79, 0x5F, 0x0C, 0x55, 0xA5, 0x53, 0x16, 0x2A, 0x9C, 0xA0, 0x6E, 0x88, 0x01, 0xE1, 0x19, 0xBD, 0xFF, 0x54, 0x35, 0x4A, 0x3F, 0x68, 0x43, 0xCF, 0x2A, 0x2F, 0xA6, 0x01, 0x75, 0x8E }, }, - { - { 0x23, 0xF0, 0xDD, 0xD8, 0x9B, 0x42, 0x82, 0xA6, 0x7F, 0xD0, 0x57, 0x56, 0xFD, 0xC5, 0xD1, 0x8C, - 0x1E, 0x5D, 0xCC, 0xEF, 0xCF, 0x42, 0x65, 0x06, 0x6D, 0xFB, 0x4A, 0xBD, 0x30, 0xD9, 0xE9, 0x77 }, - }, - { - { 0x23, 0xF7, 0xE4, 0xA3, 0x5B, 0xCC, 0xE7, 0x40, 0x36, 0xD9, 0xC8, 0x6F, 0x7F, 0x61, 0x1D, 0x85, - 0xF3, 0x7C, 0xB6, 0x2C, 0x43, 0x24, 0x7D, 0x13, 0x52, 0x22, 0x4E, 0xC3, 0xDC, 0x89, 0xED, 0x37 }, - }, { { 0x24, 0x62, 0x52, 0x48, 0x32, 0xC1, 0x54, 0xD8, 0x4D, 0xF5, 0x8E, 0xD7, 0x75, 0x22, 0x3B, 0xBE, 0x25, 0x7D, 0xEA, 0xF7, 0x0E, 0xF9, 0xD2, 0x08, 0x61, 0x4E, 0xC0, 0xF5, 0x97, 0x7F, 0x6D, 0x58 }, }, - { - { 0x24, 0x63, 0xCB, 0x2E, 0x47, 0x55, 0x71, 0xA8, 0x68, 0x74, 0xEE, 0x45, 0xAE, 0x27, 0x0B, 0x40, - 0x08, 0xD8, 0xBA, 0xF3, 0x65, 0x32, 0x57, 0x0E, 0x28, 0xE2, 0x47, 0xFF, 0x88, 0x7F, 0x86, 0x83 }, - }, { { 0x24, 0x6D, 0x0C, 0x31, 0x48, 0x72, 0x75, 0x59, 0xF9, 0x9A, 0xD0, 0xC1, 0x50, 0x37, 0x70, 0x06, 0xB7, 0xA1, 0x7A, 0x60, 0x3A, 0x47, 0x3B, 0x6A, 0xAC, 0xD2, 0x4E, 0x16, 0xC6, 0xC5, 0x1B, 0x42 }, @@ -816,50 +260,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x25, 0x1B, 0xB7, 0xC5, 0x42, 0x33, 0xDA, 0x44, 0xBF, 0x53, 0xB5, 0x8A, 0xF2, 0x9A, 0xE1, 0x74, 0xB9, 0x78, 0xBA, 0xDB, 0x89, 0xA9, 0x50, 0xAB, 0x3E, 0x5F, 0x9B, 0x4D, 0x0D, 0xCD, 0xBC, 0x62 }, }, - { - { 0x25, 0x1D, 0x5D, 0x22, 0x2F, 0x1E, 0x67, 0x1D, 0x72, 0x1E, 0x1C, 0x26, 0x39, 0xB3, 0xB6, 0xD2, - 0x30, 0xB5, 0xC6, 0xB3, 0x0C, 0x8E, 0x34, 0xC8, 0x08, 0x75, 0x38, 0x8C, 0xCF, 0x23, 0xFB, 0x38 }, - }, - { - { 0x25, 0x50, 0x90, 0x44, 0x10, 0xAE, 0x84, 0xA6, 0xF8, 0xAD, 0xF5, 0x40, 0x46, 0x38, 0x7E, 0xBC, - 0x92, 0x6F, 0x0B, 0x2F, 0x66, 0x94, 0x61, 0xD7, 0xE6, 0x1A, 0xEE, 0x8D, 0xCE, 0xB8, 0x71, 0x3B }, - }, - { - { 0x25, 0x5A, 0x49, 0x8B, 0xEB, 0x7C, 0x89, 0x42, 0x74, 0xE5, 0xE3, 0xD4, 0x3B, 0x27, 0xAD, 0x66, - 0x62, 0x0B, 0x90, 0xCB, 0x91, 0x62, 0xC4, 0x68, 0x5F, 0xA2, 0x6D, 0x85, 0xF5, 0xA4, 0x3A, 0xA0 }, - }, - { - { 0x25, 0x6F, 0xD8, 0x6F, 0x52, 0x51, 0x34, 0x36, 0x1D, 0xA8, 0x0C, 0x18, 0xE5, 0xE2, 0x9F, 0x75, - 0xF1, 0x10, 0xCA, 0x94, 0xB6, 0x2C, 0xD7, 0x18, 0x33, 0x1A, 0xDE, 0xBF, 0x81, 0x64, 0x6B, 0x3E }, - }, - { - { 0x25, 0x8C, 0x68, 0x91, 0xF0, 0x89, 0xB5, 0x09, 0x4B, 0xE3, 0x3D, 0x6C, 0x82, 0x21, 0x5E, 0x72, - 0x65, 0xAC, 0xA9, 0x3F, 0x7C, 0x9B, 0x41, 0x45, 0xD0, 0x8A, 0xFF, 0x1F, 0x48, 0x30, 0x58, 0xAA }, - }, { { 0x26, 0x03, 0xCB, 0xDF, 0x69, 0x75, 0xE3, 0x68, 0x83, 0x7F, 0x95, 0x1A, 0x00, 0x49, 0xFD, 0xC3, 0xC4, 0xB2, 0x39, 0xF0, 0x82, 0xF6, 0xBF, 0x89, 0x5D, 0xB8, 0xF3, 0x27, 0x05, 0xE6, 0x9C, 0xF3 }, }, - { - { 0x26, 0x33, 0xFD, 0x33, 0x50, 0xF8, 0x73, 0x50, 0x2D, 0x94, 0x53, 0x7A, 0xD8, 0x66, 0x3D, 0x2A, - 0xEF, 0xA5, 0x9A, 0x03, 0x57, 0x28, 0x8C, 0x64, 0x42, 0x3C, 0x74, 0xC8, 0x6F, 0x8C, 0x92, 0xB9 }, - }, - { - { 0x26, 0x5F, 0x09, 0x6C, 0x74, 0xF9, 0xC4, 0x5A, 0x3B, 0xD3, 0x7C, 0x2B, 0xC8, 0x23, 0xEE, 0x27, - 0x1A, 0x23, 0xF8, 0xF5, 0xC0, 0x9E, 0x1B, 0x71, 0x68, 0x7A, 0xEC, 0x17, 0xE3, 0x8E, 0x46, 0x91 }, - }, - { - { 0x26, 0xB2, 0x11, 0xCC, 0x34, 0x6D, 0x60, 0x37, 0x1B, 0x24, 0xBD, 0x0D, 0xBA, 0xB3, 0xF4, 0x3D, - 0x5D, 0xE3, 0xF2, 0x05, 0x47, 0xC1, 0x4C, 0x0B, 0xA1, 0xE0, 0xB2, 0xED, 0xDD, 0x73, 0x02, 0x64 }, - }, - { - { 0x26, 0xB9, 0x4C, 0xA0, 0x1E, 0x63, 0x4E, 0xD0, 0xCB, 0x4F, 0xF3, 0xC9, 0xBC, 0xC2, 0x8A, 0x5E, - 0x8F, 0x49, 0xCA, 0xCD, 0xE7, 0xEB, 0xA2, 0x63, 0x2D, 0x3D, 0x30, 0x3F, 0xB2, 0xED, 0xE8, 0x63 }, - }, - { - { 0x27, 0x16, 0xE1, 0x51, 0x81, 0x4B, 0xC2, 0x23, 0x49, 0x83, 0xF6, 0x53, 0xBF, 0x4D, 0x47, 0x1D, - 0x37, 0x5B, 0xDA, 0xCB, 0x3E, 0xAA, 0xEA, 0x96, 0xB4, 0x80, 0xCD, 0xDA, 0xCA, 0x0D, 0x4C, 0xDA }, - }, { { 0x27, 0x50, 0x11, 0x93, 0xE4, 0x61, 0xCA, 0xCE, 0x55, 0x32, 0xFA, 0xD5, 0xD5, 0xB2, 0x7E, 0x01, 0x16, 0x57, 0x92, 0xE0, 0x4F, 0x24, 0x21, 0x93, 0x2F, 0x39, 0x28, 0xAF, 0x9F, 0xCD, 0xA4, 0xF3 }, @@ -872,18 +276,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x28, 0x07, 0x10, 0x60, 0x44, 0x03, 0x45, 0xD0, 0x0E, 0x80, 0xB9, 0xD7, 0xCB, 0xE1, 0x87, 0xC1, 0xD8, 0xB0, 0xF2, 0xEF, 0x5D, 0x0A, 0xAC, 0x9C, 0xCE, 0xEF, 0x9A, 0x8C, 0x5A, 0x06, 0xF3, 0x02 }, }, - { - { 0x28, 0x16, 0x1F, 0x94, 0xD5, 0xA3, 0xFE, 0x36, 0x1F, 0x3C, 0xD8, 0xBB, 0xFA, 0x8D, 0x9D, 0xB7, - 0x11, 0x05, 0x8B, 0xA9, 0x67, 0xEE, 0xBD, 0x8D, 0x42, 0xEC, 0xB9, 0x27, 0xBF, 0x09, 0xF4, 0x40 }, - }, - { - { 0x28, 0x76, 0x00, 0xE8, 0x45, 0x25, 0xA9, 0xE2, 0xEF, 0xB3, 0xC3, 0x30, 0xD8, 0x0E, 0xC6, 0x0C, - 0x3F, 0x7D, 0x7B, 0xB2, 0x07, 0x89, 0x4E, 0xB6, 0xCD, 0x7B, 0x85, 0xEE, 0x74, 0xFF, 0x9A, 0x46 }, - }, - { - { 0x28, 0xC2, 0x4D, 0x7A, 0xEF, 0xCB, 0xA0, 0x50, 0x94, 0x94, 0xEF, 0x21, 0x06, 0x48, 0x17, 0xFB, - 0xAA, 0x89, 0x1F, 0xB3, 0xC5, 0x2F, 0xC7, 0x17, 0x81, 0xDD, 0x5E, 0xAC, 0x18, 0xD7, 0x4D, 0x7A }, - }, { { 0x28, 0xD9, 0x51, 0x84, 0xB5, 0xEA, 0x14, 0x0F, 0x47, 0x4F, 0x3A, 0xF6, 0xCE, 0x70, 0x52, 0xE8, 0x59, 0x3C, 0xF3, 0xA5, 0x01, 0x0F, 0x52, 0x24, 0x1A, 0x1E, 0x36, 0x64, 0x60, 0xE5, 0x91, 0x9E }, @@ -892,66 +284,14 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x29, 0x01, 0x93, 0xE3, 0x7A, 0x38, 0x87, 0xFD, 0x36, 0x15, 0xDF, 0x12, 0x2E, 0x95, 0x21, 0x17, 0x42, 0x15, 0xEE, 0x68, 0xF7, 0x44, 0xB2, 0xFA, 0x35, 0xD2, 0x9C, 0x5D, 0xF1, 0x08, 0xF5, 0x5B }, }, - { - { 0x29, 0x0C, 0x79, 0x6F, 0x6D, 0x23, 0xDE, 0x2A, 0xAE, 0x80, 0x77, 0xAB, 0xCC, 0xFC, 0x52, 0xEE, - 0x5C, 0x71, 0x35, 0x3F, 0x9A, 0xB6, 0xBD, 0x56, 0x5C, 0x6A, 0xBD, 0x26, 0x9F, 0xF5, 0xE9, 0xBA }, - }, - { - { 0x29, 0x4A, 0x2B, 0xF8, 0x7B, 0x50, 0x1D, 0x28, 0x4F, 0x37, 0x80, 0x96, 0x0E, 0x8E, 0x72, 0xA1, - 0x8A, 0xF1, 0xC6, 0x3B, 0xD7, 0xDE, 0x4C, 0x4D, 0xDE, 0xA3, 0x7B, 0xF0, 0x27, 0xD4, 0x2C, 0xB8 }, - }, - { - { 0x29, 0x54, 0x18, 0x23, 0xE0, 0x69, 0x14, 0xB4, 0xD6, 0x2A, 0x93, 0x8D, 0xC4, 0x9C, 0x8A, 0x0D, - 0x17, 0xD9, 0x94, 0x96, 0x0E, 0xEE, 0xC7, 0xD9, 0x75, 0x31, 0xAF, 0x71, 0x5E, 0xDE, 0x4A, 0xDF }, - }, - { - { 0x29, 0x74, 0x8A, 0x69, 0xE9, 0x42, 0xA0, 0x67, 0xE6, 0xA6, 0xA3, 0x5A, 0x9D, 0x40, 0x00, 0x0A, - 0x31, 0x8D, 0x7D, 0xDF, 0x5F, 0x5A, 0x2F, 0x4D, 0x3D, 0x18, 0xBE, 0xBA, 0xD3, 0x96, 0x91, 0xEC }, - }, - { - { 0x29, 0x7A, 0xC8, 0x25, 0xC1, 0x98, 0x06, 0xFB, 0x88, 0x1F, 0xD9, 0x1C, 0x61, 0x2D, 0x6C, 0xC2, - 0x1B, 0x28, 0xE4, 0xA5, 0x72, 0xCF, 0xB7, 0x16, 0x04, 0xE5, 0x54, 0x41, 0x4D, 0xFD, 0xEA, 0xDC }, - }, - { - { 0x29, 0xA8, 0x28, 0x26, 0x64, 0x3D, 0x5A, 0x98, 0xC4, 0x7D, 0xF3, 0xA7, 0x8F, 0xBB, 0x84, 0x49, - 0xB3, 0xE6, 0xD3, 0xCC, 0xE6, 0x2C, 0xF4, 0x57, 0x12, 0xA4, 0xCD, 0x99, 0x21, 0xF3, 0xC6, 0x88 }, - }, - { - { 0x29, 0xD4, 0x91, 0x44, 0x01, 0x60, 0x8A, 0xE7, 0x65, 0x51, 0x53, 0xB6, 0x23, 0x67, 0x1F, 0x75, - 0x92, 0x99, 0x4D, 0x4B, 0xE3, 0x88, 0x39, 0x59, 0x13, 0xA3, 0x60, 0x22, 0x1F, 0x90, 0xC0, 0x91 }, - }, { { 0x2A, 0x0F, 0x70, 0x67, 0x6E, 0x18, 0x4D, 0x49, 0x39, 0xA4, 0x04, 0xDE, 0x35, 0xAC, 0x84, 0xAB, 0x81, 0xAF, 0xEC, 0x36, 0x17, 0xE7, 0xE1, 0xBF, 0x34, 0x67, 0xD4, 0x19, 0x25, 0x5D, 0xD8, 0x17 }, }, - { - { 0x2A, 0x6B, 0x9F, 0x6F, 0xDC, 0x43, 0xBF, 0x65, 0xE2, 0xA1, 0x0E, 0xDE, 0x36, 0x64, 0xC8, 0x3F, - 0xCB, 0xEC, 0x13, 0x9A, 0x6E, 0x6C, 0xC5, 0xC8, 0x32, 0xD3, 0x27, 0x89, 0x5B, 0x52, 0x0E, 0xA2 }, - }, { { 0x2A, 0xA6, 0x47, 0x8C, 0xC7, 0x5D, 0x67, 0xA8, 0xCA, 0x55, 0xB2, 0xE1, 0x63, 0xFD, 0xBB, 0xBC, 0x9D, 0x74, 0xB4, 0xE5, 0xF3, 0x7B, 0x7D, 0xBD, 0x13, 0xC9, 0x4E, 0x85, 0x8D, 0x40, 0xDA, 0xD0 }, }, - { - { 0x2A, 0xC0, 0x65, 0xAE, 0x39, 0x6B, 0x87, 0x54, 0x9C, 0x3F, 0x09, 0xE5, 0x8F, 0x16, 0x4B, 0x24, - 0x2E, 0xC5, 0x9D, 0x13, 0x92, 0xB1, 0xB2, 0x50, 0x14, 0xBF, 0x47, 0x94, 0xAC, 0x13, 0x01, 0xB0 }, - }, - { - { 0x2B, 0x36, 0xDE, 0x39, 0xD5, 0xED, 0x42, 0xE1, 0xEC, 0x06, 0x57, 0x49, 0xD5, 0x82, 0xE0, 0x14, - 0xB5, 0xAF, 0xF2, 0x67, 0xF8, 0x7C, 0x03, 0x15, 0x27, 0xD9, 0x15, 0xAB, 0x43, 0x02, 0x88, 0x9E }, - }, - { - { 0x2B, 0x66, 0x75, 0xF5, 0x89, 0x9B, 0x2D, 0x3F, 0x36, 0xAF, 0x0A, 0x0F, 0xFB, 0xB6, 0xDC, 0x60, - 0x3E, 0x4C, 0x9E, 0x82, 0x8D, 0xA2, 0xB2, 0xD0, 0x24, 0xE3, 0x04, 0x30, 0x71, 0xAB, 0x15, 0xCE }, - }, - { - { 0x2B, 0x6E, 0x7A, 0xF1, 0xDE, 0x52, 0xF4, 0xAF, 0x97, 0xCC, 0x3A, 0x13, 0x6D, 0xCB, 0x82, 0xE0, - 0xF2, 0xCA, 0x06, 0xA8, 0x73, 0x16, 0x9C, 0x02, 0x87, 0x86, 0x10, 0x18, 0x44, 0xC3, 0x05, 0x15 }, - }, - { - { 0x2B, 0xDC, 0xF7, 0x06, 0x67, 0x7A, 0x3B, 0x68, 0xF1, 0x37, 0xF7, 0xF6, 0x9B, 0x36, 0x6B, 0x79, - 0xCA, 0x5A, 0xEB, 0xD3, 0x35, 0xBF, 0xB9, 0xD0, 0x3D, 0x58, 0xBD, 0x85, 0xA8, 0x66, 0x36, 0xBB }, - }, { { 0x2B, 0xF1, 0xE3, 0xF0, 0x37, 0x5A, 0x9A, 0x21, 0xC0, 0x7A, 0x92, 0x18, 0x04, 0x2F, 0x18, 0x77, 0x3F, 0x43, 0xEA, 0xB0, 0xF5, 0xC0, 0x00, 0x26, 0x45, 0x40, 0x48, 0x2F, 0x04, 0xAE, 0x18, 0xEF }, @@ -960,10 +300,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x2C, 0x82, 0x47, 0x4F, 0x0E, 0xF6, 0xCB, 0x65, 0x0A, 0x13, 0xEF, 0x20, 0x99, 0x6E, 0x65, 0x7B, 0x67, 0x24, 0xF0, 0xA0, 0xD5, 0xEE, 0x24, 0x6D, 0x26, 0xBB, 0xFA, 0x0A, 0xBB, 0x2C, 0x22, 0xE1 }, }, - { - { 0x2C, 0x8C, 0xDE, 0x6B, 0xB0, 0xD1, 0x2C, 0xD2, 0xDD, 0x63, 0xE9, 0x40, 0x09, 0x4F, 0xD2, 0x62, - 0x5D, 0x2C, 0xFD, 0x9A, 0x64, 0x7E, 0x0C, 0x64, 0x0E, 0xCF, 0x1C, 0x78, 0x92, 0x1E, 0xEA, 0x17 }, - }, { { 0x2C, 0x9B, 0xE1, 0x2D, 0xA4, 0x99, 0xEA, 0xBB, 0x2F, 0xFD, 0xF9, 0x91, 0x6F, 0x2B, 0x27, 0x18, 0x81, 0x19, 0x5B, 0x74, 0x19, 0xBD, 0x1E, 0xEF, 0x8D, 0x50, 0x77, 0x2A, 0xB9, 0x46, 0x4A, 0xA8 }, @@ -972,42 +308,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x2C, 0xBD, 0xD5, 0x6C, 0xE4, 0xB4, 0x06, 0x09, 0xE9, 0xAA, 0x52, 0x1E, 0xAA, 0x76, 0xAC, 0x7E, 0x55, 0x73, 0x7B, 0xF4, 0x3E, 0x2B, 0x0C, 0x30, 0xDD, 0xCF, 0x59, 0x87, 0x2E, 0xAB, 0xE7, 0x7B }, }, - { - { 0x2C, 0xF2, 0x6D, 0xA5, 0x76, 0x7E, 0xDE, 0x07, 0xC3, 0x73, 0x58, 0xCD, 0x5F, 0x71, 0xD1, 0x23, - 0xBB, 0x19, 0x77, 0x28, 0x85, 0x87, 0xC7, 0x3F, 0x84, 0xB0, 0x8F, 0xF8, 0xAA, 0x01, 0x9A, 0x69 }, - }, - { - { 0x2D, 0x0C, 0xE9, 0x16, 0x71, 0xC2, 0x54, 0x4C, 0xF6, 0xBD, 0x10, 0x30, 0x6F, 0x9B, 0x2C, 0x91, - 0x75, 0xF2, 0xC3, 0x1A, 0x23, 0x8E, 0x14, 0x68, 0x67, 0x65, 0x97, 0x89, 0x87, 0x3D, 0xC1, 0x75 }, - }, - { - { 0x2D, 0x5F, 0x95, 0xEF, 0x95, 0xAD, 0x1C, 0xCA, 0xC8, 0xE8, 0x25, 0xC1, 0x61, 0x5F, 0x82, 0x1F, - 0x0F, 0x44, 0xDF, 0xB8, 0xAA, 0x31, 0xDD, 0xF2, 0xC9, 0x83, 0x3E, 0x50, 0xC6, 0x95, 0x1C, 0xC0 }, - }, - { - { 0x2D, 0x9C, 0xC0, 0x3B, 0xC4, 0x51, 0xD1, 0xE0, 0xBA, 0x65, 0x11, 0xF4, 0x89, 0x31, 0x75, 0xD0, - 0x43, 0x46, 0x85, 0x6A, 0x41, 0x69, 0x86, 0x99, 0x4E, 0x94, 0x60, 0xD7, 0x4A, 0x48, 0x40, 0xB9 }, - }, - { - { 0x2D, 0xB5, 0x36, 0x48, 0xA6, 0x14, 0x69, 0x57, 0x01, 0xC7, 0xC5, 0x1E, 0x35, 0xFF, 0x38, 0xD6, - 0x4F, 0x27, 0xA2, 0x7D, 0x55, 0xDF, 0xF4, 0xB1, 0x4A, 0xC4, 0x50, 0xC7, 0x5E, 0xB1, 0x18, 0x6E }, - }, - { - { 0x2D, 0xD5, 0xE6, 0xD3, 0x73, 0x36, 0x34, 0x2F, 0x01, 0x1E, 0xB9, 0x7A, 0x2B, 0x77, 0x38, 0x9D, - 0xE6, 0xD2, 0x23, 0x8D, 0x87, 0x69, 0x65, 0x08, 0x2F, 0xD7, 0x94, 0x47, 0x00, 0x50, 0xBE, 0x12 }, - }, { { 0x2D, 0xDE, 0xE4, 0x5F, 0x72, 0x78, 0x38, 0xDE, 0xAD, 0xE6, 0x7E, 0x9C, 0xA7, 0x05, 0xEB, 0xB4, 0xC2, 0xE9, 0x40, 0xAE, 0x1B, 0x9D, 0x62, 0x35, 0x72, 0x18, 0x04, 0x58, 0x31, 0xE9, 0x8F, 0xDE }, }, - { - { 0x2E, 0x17, 0x46, 0x49, 0x4E, 0x86, 0xD6, 0x93, 0x0B, 0x24, 0x98, 0x8B, 0x12, 0x9B, 0x38, 0x6B, - 0xC2, 0x08, 0xE2, 0xFB, 0xC8, 0xD3, 0xEA, 0x27, 0x7A, 0x23, 0xE5, 0x46, 0x33, 0xAF, 0xF1, 0x8F }, - }, - { - { 0x2E, 0x43, 0x2A, 0x54, 0x5D, 0xFE, 0x2D, 0xA3, 0xAD, 0x00, 0xCC, 0x87, 0x89, 0x23, 0xA1, 0x85, - 0xD6, 0xA3, 0xF9, 0x67, 0x5C, 0x36, 0xDC, 0x3C, 0xD3, 0x70, 0x2A, 0xEF, 0xEB, 0x27, 0x0C, 0x85 }, - }, { { 0x2E, 0x5D, 0xD2, 0x55, 0x09, 0x6D, 0x64, 0x83, 0x10, 0x5C, 0xB6, 0x03, 0x6C, 0x59, 0x17, 0x57, 0xFD, 0x98, 0x49, 0x70, 0x66, 0x05, 0x3F, 0x83, 0x39, 0xE4, 0xD8, 0xD0, 0xC3, 0x75, 0x49, 0x03 }, @@ -1016,46 +320,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x2E, 0xD2, 0x05, 0x8F, 0x39, 0xEA, 0xBA, 0x5C, 0xB3, 0xD7, 0xDF, 0x24, 0xCA, 0x74, 0xA7, 0x7D, 0xDC, 0x12, 0x06, 0x01, 0x52, 0x7B, 0x0F, 0x51, 0x06, 0x91, 0x05, 0xCA, 0x88, 0x37, 0x6E, 0x20 }, }, - { - { 0x2F, 0x39, 0xBB, 0x30, 0xAA, 0x5C, 0xBB, 0x62, 0x01, 0x7C, 0x6C, 0x79, 0x90, 0xE3, 0xF9, 0xA4, - 0x0D, 0x46, 0x9F, 0x76, 0x50, 0x59, 0x81, 0xC8, 0x6F, 0x95, 0x55, 0x4F, 0x48, 0x7A, 0x52, 0x76 }, - }, - { - { 0x2F, 0x79, 0xD6, 0xF6, 0xA3, 0x2F, 0x1B, 0xEE, 0x22, 0x37, 0xA0, 0x18, 0xE6, 0xAE, 0xC4, 0xF4, - 0x9E, 0x2C, 0x5C, 0x3C, 0xDB, 0xB6, 0x99, 0xE1, 0x6F, 0x8E, 0xF4, 0x14, 0xEE, 0xFF, 0x8D, 0xA3 }, - }, - { - { 0x2F, 0x8B, 0xC9, 0x6F, 0x12, 0x95, 0x05, 0x6C, 0x10, 0x67, 0x20, 0x39, 0x57, 0xE3, 0xCB, 0xCC, - 0x3B, 0x16, 0xC4, 0x91, 0xD4, 0xDA, 0xC0, 0xA7, 0xDE, 0xE4, 0x2D, 0xD5, 0x4C, 0x10, 0xD4, 0x96 }, - }, - { - { 0x2F, 0x9B, 0x7B, 0x60, 0xA3, 0xE8, 0x74, 0x2C, 0x5D, 0xBE, 0x3E, 0xC6, 0x01, 0x69, 0xD7, 0xA4, - 0x4F, 0x1B, 0xB5, 0x6D, 0x51, 0xF6, 0x51, 0x37, 0x2C, 0x28, 0x32, 0x69, 0x33, 0x7B, 0xF8, 0x15 }, - }, - { - { 0x2F, 0xEF, 0xA7, 0xCB, 0x12, 0x6B, 0x81, 0xC9, 0x47, 0x4D, 0x3E, 0x2C, 0x9B, 0x97, 0x3A, 0x83, - 0x69, 0xBB, 0x08, 0x43, 0x41, 0xD3, 0x82, 0xD3, 0x7E, 0x9E, 0x95, 0xC4, 0xDB, 0xE3, 0x71, 0xEE }, - }, - { - { 0x30, 0x2B, 0xC4, 0xAF, 0xFB, 0x52, 0xA9, 0xA6, 0xB9, 0x7A, 0x1D, 0xBF, 0x87, 0x98, 0xFA, 0xB2, - 0xAD, 0x57, 0xD3, 0x6F, 0x75, 0x84, 0x88, 0x8E, 0x03, 0x67, 0x4A, 0x5D, 0xD6, 0xE1, 0x09, 0x91 }, - }, - { - { 0x30, 0x2F, 0x5D, 0xC8, 0xF0, 0x75, 0xED, 0x03, 0x99, 0xD4, 0xBB, 0x3E, 0xA1, 0x92, 0x25, 0xDA, - 0x56, 0x3C, 0x9E, 0x3C, 0xF3, 0xA6, 0xF8, 0x0D, 0x28, 0x4D, 0x55, 0x31, 0xC2, 0xD0, 0xDD, 0xF7 }, - }, - { - { 0x30, 0x35, 0x3B, 0x41, 0x90, 0x04, 0xDD, 0x1B, 0xA0, 0x64, 0x4A, 0x2A, 0x0B, 0x7B, 0xE9, 0x4F, - 0xB8, 0x6F, 0x5E, 0x27, 0x5D, 0x67, 0x94, 0xA6, 0xDB, 0xBA, 0xA3, 0x21, 0x32, 0x3E, 0xD8, 0xB7 }, - }, { { 0x30, 0x7B, 0x09, 0x34, 0xEF, 0x97, 0x85, 0xE7, 0x08, 0xED, 0x48, 0x1A, 0x99, 0x7A, 0x8A, 0x88, 0xB7, 0xBF, 0x22, 0xDD, 0x26, 0xAA, 0x17, 0x17, 0x31, 0xB8, 0xF7, 0xE0, 0xD5, 0x97, 0xB7, 0x08 }, }, - { - { 0x30, 0x9B, 0x6E, 0x00, 0x40, 0x46, 0x87, 0x96, 0x01, 0xA0, 0xD8, 0xA0, 0x42, 0x3F, 0x73, 0xB1, - 0x6A, 0x91, 0xA4, 0xBC, 0x16, 0xED, 0x2A, 0x84, 0x60, 0x66, 0xCD, 0xC0, 0x38, 0x2F, 0x97, 0x71 }, - }, { { 0x30, 0xCB, 0x41, 0x11, 0xFB, 0x10, 0x08, 0x6F, 0xC6, 0xA4, 0x1F, 0x04, 0xB7, 0xE9, 0xD4, 0xCF, 0x66, 0x10, 0xBB, 0x06, 0x59, 0xD8, 0xE2, 0xAC, 0x80, 0x4F, 0xC8, 0x96, 0xB0, 0x25, 0x42, 0xBB }, @@ -1072,74 +340,18 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x31, 0xB8, 0x3E, 0x01, 0x90, 0x98, 0x95, 0xBC, 0x74, 0x2D, 0x6B, 0xE8, 0x40, 0x0A, 0xDE, 0x51, 0xB2, 0x09, 0x83, 0xF6, 0x83, 0xA2, 0xAA, 0xEE, 0xB2, 0x5F, 0x58, 0xDF, 0x98, 0x1B, 0xDE, 0x0D }, }, - { - { 0x31, 0xED, 0x8A, 0x8C, 0xC6, 0xEE, 0x5E, 0x88, 0x4F, 0x21, 0x4F, 0x26, 0x7F, 0xE3, 0xA2, 0x27, - 0xD4, 0xE6, 0xED, 0x36, 0xA7, 0x7F, 0xA2, 0x24, 0x6F, 0x0A, 0xD0, 0x77, 0x8A, 0x6B, 0x3F, 0x97 }, - }, - { - { 0x32, 0x36, 0x98, 0x50, 0x9D, 0x8F, 0x8B, 0xFB, 0xD4, 0xF9, 0x04, 0xBD, 0x1D, 0x84, 0x64, 0x12, - 0xC5, 0x27, 0xB7, 0x70, 0x06, 0x2A, 0xAD, 0xDF, 0x9E, 0x91, 0x9D, 0x84, 0x10, 0xEA, 0xA4, 0x9F }, - }, - { - { 0x32, 0x8B, 0x9A, 0x45, 0xEF, 0xEF, 0x20, 0xB5, 0xD1, 0x57, 0x39, 0xDD, 0xFA, 0xC1, 0x0C, 0x7E, - 0xFE, 0x5F, 0xA7, 0x96, 0xBF, 0xE0, 0x1E, 0xD1, 0xA1, 0x25, 0xA9, 0x15, 0x8E, 0x2F, 0x1B, 0x17 }, - }, - { - { 0x32, 0x9B, 0x70, 0xBF, 0x79, 0xD8, 0x11, 0x7E, 0x95, 0x3B, 0x49, 0x97, 0xBB, 0x62, 0x72, 0xDF, - 0x50, 0x49, 0x5F, 0xA0, 0xB4, 0x5B, 0xAD, 0xB3, 0xEC, 0x0A, 0x83, 0x16, 0x33, 0x6F, 0xE3, 0xA2 }, - }, - { - { 0x32, 0xDB, 0xC4, 0x6B, 0x80, 0x80, 0x5A, 0x56, 0x97, 0x4B, 0x2A, 0x5D, 0xDE, 0x67, 0x34, 0x28, - 0xED, 0x03, 0xB0, 0x76, 0x5E, 0x15, 0xD9, 0x4C, 0x55, 0xE5, 0x4D, 0x2F, 0x55, 0x70, 0xF2, 0x0B }, - }, { { 0x32, 0xEF, 0x13, 0x33, 0x86, 0xBF, 0x0C, 0x63, 0xCF, 0x29, 0xD6, 0x2B, 0x0D, 0x76, 0x88, 0x9E, 0x9D, 0x9D, 0x53, 0x2E, 0xE4, 0x90, 0x38, 0x94, 0x4D, 0xBC, 0x21, 0x49, 0xD8, 0xCA, 0xA5, 0xD1 }, }, - { - { 0x33, 0x03, 0x23, 0x10, 0x4C, 0x25, 0x2F, 0xCE, 0xB9, 0xE6, 0x63, 0x0D, 0x9F, 0xE7, 0x1F, 0x17, - 0xB6, 0xC2, 0x25, 0xA6, 0x5C, 0x76, 0x08, 0x15, 0xE4, 0x08, 0x74, 0x6C, 0x33, 0x1A, 0xB4, 0xF6 }, - }, - { - { 0x33, 0x0D, 0x78, 0x66, 0xC2, 0x5F, 0x7C, 0xE3, 0x47, 0x3C, 0x6D, 0x55, 0x9C, 0xEA, 0x4B, 0x94, - 0x01, 0xF9, 0xE5, 0x2E, 0x4C, 0x24, 0x7A, 0x5E, 0x49, 0xA1, 0xF1, 0x44, 0x59, 0x9A, 0x5A, 0x79 }, - }, - { - { 0x33, 0xC9, 0x15, 0x03, 0xBC, 0x7E, 0xBE, 0x5A, 0x5D, 0xD0, 0xCF, 0xBB, 0x37, 0x52, 0x64, 0xDD, - 0x5A, 0x31, 0x1E, 0x48, 0xF4, 0x26, 0x6B, 0x32, 0x50, 0x8A, 0x02, 0x5D, 0x04, 0xFA, 0xDF, 0x38 }, - }, { { 0x34, 0x06, 0x4F, 0xF9, 0x3B, 0x27, 0x4C, 0xF5, 0xA7, 0x24, 0xEC, 0x19, 0x64, 0x50, 0x4A, 0x71, 0x0A, 0xB9, 0x7B, 0xA1, 0x10, 0x3C, 0xD9, 0xB9, 0x8C, 0x81, 0xD0, 0xAB, 0xCF, 0x3B, 0x19, 0xBD }, }, - { - { 0x34, 0x15, 0x1A, 0x33, 0x82, 0x78, 0xDA, 0x7E, 0xC2, 0x62, 0x33, 0x81, 0x7D, 0x96, 0x44, 0xB5, - 0x6F, 0x8F, 0x48, 0xC1, 0xC3, 0x70, 0xCD, 0x25, 0xFC, 0xE7, 0xDE, 0x64, 0x54, 0x4F, 0xE9, 0x36 }, - }, { { 0x34, 0x65, 0xC2, 0xF9, 0xA0, 0xCF, 0x36, 0xE5, 0xEE, 0xF0, 0x27, 0x1C, 0x52, 0x91, 0x2D, 0x58, 0x6F, 0xB2, 0x0B, 0x94, 0x43, 0xE7, 0xD5, 0x82, 0xA3, 0xE2, 0x23, 0x93, 0xFA, 0xC8, 0x1B, 0xB4 }, }, - { - { 0x34, 0x9B, 0x72, 0x1D, 0x0B, 0xB9, 0xA4, 0xC4, 0xAA, 0x33, 0x43, 0x60, 0xA6, 0x6A, 0xC3, 0xA7, - 0x3F, 0xA8, 0xD8, 0xD3, 0x60, 0x0D, 0x89, 0x4E, 0xB0, 0xC7, 0xD2, 0x84, 0x23, 0xC6, 0x78, 0x57 }, - }, - { - { 0x34, 0xE6, 0xF1, 0x7A, 0x14, 0xD3, 0xD2, 0x8A, 0xFD, 0x51, 0xCF, 0x40, 0x49, 0x3A, 0xB2, 0xCF, - 0xE0, 0x18, 0xEF, 0x98, 0x1E, 0x23, 0xF1, 0xFC, 0x91, 0x60, 0xFB, 0x91, 0x2C, 0xDC, 0x5C, 0xB9 }, - }, - { - { 0x35, 0x13, 0x6F, 0x88, 0xB4, 0x24, 0x76, 0x0E, 0x17, 0x5E, 0xFC, 0x19, 0x9B, 0x75, 0xE5, 0x25, - 0x35, 0xF2, 0xDF, 0x59, 0xFF, 0xD0, 0x69, 0x3A, 0x5A, 0x3F, 0x78, 0x1F, 0x6F, 0xF4, 0xB6, 0x50 }, - }, - { - { 0x35, 0x49, 0xB6, 0xEC, 0xBD, 0x8D, 0x25, 0x2B, 0xE7, 0x17, 0xB9, 0x22, 0x73, 0x27, 0x38, 0x08, - 0x0B, 0xAF, 0xD5, 0x60, 0xB4, 0x5A, 0x05, 0x40, 0x33, 0xBD, 0x11, 0x0B, 0x3C, 0x39, 0x48, 0x22 }, - }, - { - { 0x35, 0x58, 0x91, 0xA3, 0x12, 0x34, 0xFD, 0xD0, 0x84, 0x79, 0xB8, 0xAB, 0xA8, 0x58, 0x1E, 0x85, - 0x7C, 0x6B, 0x5C, 0x6B, 0x40, 0xCF, 0xFC, 0x7B, 0x67, 0x80, 0x92, 0x65, 0x1F, 0x06, 0x87, 0xC1 }, - }, { { 0x35, 0x98, 0x10, 0xFF, 0xFE, 0xD1, 0x3A, 0x2C, 0x25, 0xCD, 0x91, 0xFC, 0xF0, 0x85, 0x59, 0x33, 0xC9, 0x94, 0xA9, 0xDF, 0xC9, 0x39, 0x2D, 0x97, 0x07, 0xC3, 0xC0, 0xE7, 0x30, 0x0F, 0x90, 0x8D }, @@ -1160,38 +372,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x36, 0xF5, 0xA9, 0x7D, 0x79, 0x3F, 0x84, 0x97, 0x44, 0xD6, 0xAB, 0x39, 0xB7, 0xA8, 0x18, 0xF8, 0x17, 0x6E, 0x65, 0x20, 0xDC, 0x86, 0x3D, 0xCE, 0x43, 0xB3, 0x98, 0xC3, 0x0B, 0x5E, 0xDB, 0x09 }, }, - { - { 0x37, 0x07, 0x9D, 0x98, 0x72, 0x7C, 0x42, 0xA4, 0x1D, 0x66, 0x18, 0xFC, 0xCD, 0xC6, 0xFF, 0xA1, - 0x5E, 0xD3, 0xB2, 0xFE, 0xC7, 0xAC, 0x0A, 0x09, 0x7B, 0x74, 0xC5, 0x72, 0xBB, 0xCD, 0xA8, 0xD7 }, - }, - { - { 0x37, 0x87, 0x37, 0xCD, 0x85, 0x19, 0xBA, 0xC5, 0x32, 0x2F, 0xDB, 0x28, 0xF4, 0x4A, 0x43, 0xC5, - 0x09, 0xA5, 0x44, 0x7A, 0xD2, 0x68, 0x3B, 0xA1, 0x90, 0x05, 0xE3, 0x1B, 0x0D, 0x54, 0x8C, 0x6D }, - }, - { - { 0x37, 0x98, 0xB3, 0x35, 0x53, 0x40, 0xD2, 0x76, 0x2A, 0x02, 0x08, 0xF3, 0x47, 0x20, 0xD2, 0xA1, - 0x52, 0xEF, 0xA9, 0xE8, 0x96, 0x57, 0x18, 0xB8, 0x93, 0x06, 0xF6, 0x91, 0x33, 0x56, 0x32, 0xE9 }, - }, - { - { 0x37, 0x99, 0x0F, 0x5B, 0x5C, 0x71, 0x11, 0x89, 0x98, 0xF9, 0xC8, 0xE1, 0x54, 0x65, 0x69, 0x16, - 0x1A, 0x82, 0xBB, 0xFB, 0x4B, 0x4F, 0xC4, 0xCA, 0xA3, 0xF4, 0xB7, 0xE7, 0x4A, 0xF5, 0x15, 0xFE }, - }, - { - { 0x37, 0xC9, 0x7A, 0x48, 0xF5, 0xEE, 0x3E, 0x68, 0xCC, 0x24, 0xB5, 0x4E, 0x7C, 0x4D, 0x9F, 0x91, - 0xC7, 0xD1, 0x8B, 0x8D, 0xB6, 0x1E, 0x04, 0xEE, 0x64, 0x25, 0x1E, 0x75, 0xB0, 0xD1, 0x9F, 0xC5 }, - }, - { - { 0x37, 0xEC, 0xDB, 0x1E, 0x7A, 0xBA, 0x93, 0xBB, 0x83, 0xC8, 0xC4, 0xB7, 0xBB, 0xDE, 0xAF, 0xFF, - 0xB5, 0x95, 0xC7, 0x3C, 0xA4, 0x21, 0x88, 0xAA, 0xB5, 0x0F, 0x06, 0x27, 0xD3, 0xE1, 0x70, 0x18 }, - }, { { 0x38, 0x23, 0x4E, 0x55, 0x9D, 0x30, 0x27, 0xD1, 0x61, 0xDA, 0x8C, 0x98, 0x88, 0x04, 0x9A, 0x4D, 0x20, 0xAC, 0xF2, 0x00, 0x90, 0xAD, 0x1A, 0x22, 0x2B, 0x73, 0x9A, 0xC8, 0x6E, 0xB7, 0x6F, 0x06 }, }, - { - { 0x38, 0x68, 0xB9, 0x52, 0x53, 0xEF, 0xDB, 0x85, 0x46, 0x62, 0x00, 0xDD, 0xE5, 0x0B, 0x0D, 0x52, - 0xDA, 0x5A, 0x2B, 0x8A, 0x01, 0xB7, 0x26, 0xCE, 0xF6, 0xCE, 0x3B, 0x13, 0x7C, 0x80, 0x6C, 0x05 }, - }, { { 0x39, 0x02, 0x27, 0xCE, 0x88, 0x1C, 0x71, 0x8B, 0x59, 0xA6, 0xBC, 0x31, 0x90, 0xD5, 0x17, 0xE7, 0x1E, 0x1E, 0x58, 0x66, 0x93, 0xC8, 0xBF, 0x8A, 0x30, 0x27, 0x26, 0x20, 0x13, 0xFE, 0x16, 0x63 }, @@ -1200,10 +384,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x39, 0x21, 0x5C, 0xAA, 0x37, 0x1A, 0xBE, 0x57, 0x6A, 0xB9, 0x3B, 0x18, 0xC2, 0xF3, 0x75, 0x5E, 0xE2, 0x6F, 0x8C, 0x3A, 0xDB, 0x75, 0x9B, 0x6F, 0x34, 0x78, 0x9F, 0xB8, 0xEC, 0xF0, 0x54, 0x28 }, }, - { - { 0x39, 0x23, 0xD1, 0x9C, 0x31, 0x06, 0x03, 0xCD, 0xFD, 0x06, 0x23, 0x92, 0xD1, 0x76, 0xC0, 0xC6, - 0x92, 0x55, 0xEF, 0xFE, 0xE4, 0xEF, 0xF1, 0x09, 0x29, 0x1C, 0x03, 0xA2, 0x21, 0xBA, 0x91, 0xE2 }, - }, { { 0x39, 0x7B, 0xA8, 0x8A, 0x05, 0xDA, 0xFD, 0x7D, 0x58, 0xFA, 0xCF, 0x45, 0x60, 0xA6, 0x88, 0xAB, 0xEE, 0xD2, 0x13, 0xE0, 0xF8, 0x8C, 0x76, 0xB6, 0x2A, 0xB2, 0xFD, 0xE3, 0x67, 0xC3, 0x2D, 0x32 }, @@ -1212,42 +392,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x39, 0x7D, 0x00, 0x6E, 0xF8, 0xAF, 0xB2, 0x0F, 0x43, 0x61, 0xA6, 0xC9, 0x72, 0xF0, 0xC5, 0x7C, 0xC0, 0x87, 0x74, 0x01, 0x06, 0x12, 0x78, 0x3F, 0xBA, 0xBC, 0xB8, 0xD6, 0xF6, 0x03, 0x9E, 0x2C }, }, - { - { 0x39, 0x7D, 0x03, 0x62, 0xFA, 0xED, 0xE6, 0xFA, 0x94, 0x27, 0x4F, 0xFC, 0xF9, 0x8F, 0xF3, 0x52, - 0x55, 0x31, 0x58, 0x5D, 0x18, 0x33, 0xE0, 0x07, 0x3E, 0x5D, 0x20, 0x2D, 0xED, 0x62, 0x39, 0x55 }, - }, - { - { 0x39, 0xB1, 0x9F, 0x06, 0x65, 0xD6, 0x87, 0x8D, 0xD2, 0x5C, 0xA7, 0x30, 0x15, 0xBA, 0x0A, 0xE3, - 0xBD, 0xBA, 0x87, 0xDB, 0xCF, 0xAD, 0x38, 0x7A, 0x94, 0x52, 0x59, 0x4D, 0x73, 0x68, 0xEA, 0x85 }, - }, - { - { 0x39, 0xD7, 0x44, 0x77, 0x31, 0x72, 0x8B, 0xBA, 0x92, 0x36, 0x72, 0x7D, 0xBD, 0x7C, 0x7E, 0xE1, - 0x70, 0xE5, 0x9F, 0x3B, 0x53, 0x73, 0x79, 0x6D, 0x7D, 0xE1, 0xC6, 0xA2, 0xBE, 0x31, 0x22, 0x18 }, - }, - { - { 0x39, 0xDA, 0x1B, 0xE6, 0x56, 0x43, 0x55, 0x34, 0x6E, 0x46, 0x99, 0x66, 0x3C, 0x19, 0x95, 0x54, - 0x87, 0xA0, 0x88, 0x56, 0xFF, 0xBE, 0xEE, 0x74, 0x01, 0x67, 0x99, 0xC7, 0xA3, 0x4B, 0x48, 0xEE }, - }, - { - { 0x39, 0xFF, 0x6E, 0x31, 0x69, 0x9F, 0x5D, 0x68, 0x92, 0x97, 0x6D, 0x11, 0xDD, 0xBB, 0x14, 0x24, - 0xED, 0x0C, 0xEC, 0x48, 0x36, 0x3E, 0x94, 0xEA, 0xE3, 0xCD, 0x5F, 0x4C, 0xAF, 0x1C, 0xBD, 0x2F }, - }, - { - { 0x3A, 0x02, 0xEA, 0xD6, 0x33, 0x22, 0x6E, 0x1E, 0x45, 0x3A, 0x58, 0x50, 0xAE, 0x4D, 0x7C, 0x8D, - 0x3E, 0x0C, 0x25, 0xA4, 0xC9, 0x5C, 0x1E, 0x2D, 0xFB, 0xB7, 0xFF, 0xEB, 0x27, 0xE3, 0x64, 0x7A }, - }, - { - { 0x3A, 0x1F, 0xF2, 0x01, 0x71, 0x88, 0x3F, 0x4E, 0x9B, 0xA9, 0x96, 0x68, 0x79, 0x04, 0xCD, 0xDB, - 0x7A, 0x25, 0xAA, 0x35, 0xB0, 0xAD, 0x8E, 0xA8, 0x78, 0xFB, 0x88, 0x6D, 0xD8, 0xCF, 0x93, 0xCF }, - }, - { - { 0x3A, 0x2D, 0x31, 0x0F, 0x13, 0x05, 0xB4, 0xEB, 0x9D, 0x10, 0x3A, 0xA2, 0x9D, 0x47, 0x86, 0xF7, - 0xDF, 0x41, 0xD8, 0x5D, 0x56, 0xEB, 0xC9, 0x8C, 0x3C, 0xAA, 0xDD, 0x4B, 0xAA, 0x3D, 0x57, 0xF9 }, - }, - { - { 0x3A, 0xB9, 0x0F, 0xFD, 0x22, 0x10, 0xEB, 0x89, 0x9C, 0x6F, 0xB7, 0xFD, 0x26, 0x8D, 0xE0, 0x0B, - 0x00, 0x9F, 0x50, 0xE8, 0x18, 0x70, 0xA2, 0x20, 0xFF, 0xAE, 0xA2, 0x4E, 0x41, 0x76, 0xDE, 0x45 }, - }, { { 0x3A, 0xCF, 0x85, 0x3C, 0x4E, 0x45, 0x02, 0xBD, 0x82, 0xD5, 0x85, 0xD5, 0xE0, 0x82, 0xC4, 0xB3, 0xAD, 0x03, 0xCD, 0xB6, 0xB5, 0x05, 0xCA, 0x80, 0x47, 0x19, 0x88, 0xEC, 0x4C, 0x58, 0x99, 0x9E }, @@ -1260,18 +404,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x3B, 0x47, 0x85, 0x0B, 0xF8, 0x4C, 0x4C, 0xF2, 0xCA, 0x6C, 0x31, 0xB3, 0x78, 0x39, 0xC9, 0x50, 0x76, 0x63, 0x70, 0xD7, 0xF4, 0xB6, 0x4A, 0xD0, 0x18, 0x55, 0xCA, 0xCF, 0xE3, 0x51, 0x2F, 0xC3 }, }, - { - { 0x3B, 0x4A, 0x9F, 0x55, 0x6C, 0xCA, 0xC7, 0x0C, 0xA1, 0xF3, 0x3A, 0xF6, 0xDE, 0xCC, 0x66, 0xCA, - 0xFD, 0x2D, 0x30, 0x1D, 0x49, 0x7B, 0x49, 0x0B, 0x30, 0x80, 0x46, 0x35, 0xBA, 0xD2, 0x56, 0x94 }, - }, { { 0x3B, 0x6E, 0x3B, 0xB7, 0x00, 0x04, 0xBD, 0x78, 0xC9, 0x69, 0xA7, 0xFB, 0xD5, 0x11, 0x33, 0xA2, 0xB3, 0xC4, 0xDF, 0xB6, 0xBA, 0x38, 0x5D, 0xCE, 0x3F, 0xB8, 0x4D, 0x73, 0x6B, 0xEA, 0xB1, 0xD9 }, }, - { - { 0x3B, 0x93, 0xAC, 0x19, 0x6E, 0xC6, 0x7B, 0xF2, 0x78, 0x7F, 0x42, 0x40, 0xC0, 0xD1, 0x11, 0x37, - 0xEF, 0x79, 0xA4, 0xED, 0x1F, 0x5D, 0x1F, 0x3D, 0x04, 0x24, 0x1F, 0x03, 0xDC, 0x2D, 0xA3, 0x70 }, - }, { { 0x3B, 0xAA, 0x31, 0x31, 0x70, 0x68, 0xAC, 0xE0, 0x89, 0xAE, 0xB4, 0xA8, 0x8D, 0x7E, 0xDE, 0xBE, 0x94, 0xAB, 0x4A, 0xCE, 0x46, 0xBB, 0xD2, 0x68, 0x3E, 0x3F, 0xDF, 0xF5, 0x59, 0x30, 0x0F, 0x93 }, @@ -1280,54 +416,14 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x3C, 0x38, 0x36, 0x2E, 0x16, 0x8B, 0xB4, 0xA7, 0x59, 0xC4, 0x80, 0x55, 0x1C, 0xB1, 0x65, 0x6F, 0x6A, 0x96, 0x8B, 0x9B, 0x43, 0xCB, 0xE0, 0xD7, 0x39, 0x75, 0x4A, 0xB7, 0x8A, 0x28, 0x87, 0x0E }, }, - { - { 0x3C, 0xE3, 0xF1, 0x9C, 0x03, 0xB3, 0x44, 0x00, 0x75, 0x6F, 0x64, 0x18, 0xE0, 0x12, 0xE9, 0x42, - 0x26, 0x5C, 0x27, 0x11, 0x98, 0x43, 0xFE, 0x0F, 0x44, 0x34, 0x5B, 0x94, 0xC1, 0xB0, 0x6C, 0xEF }, - }, { { 0x3D, 0x14, 0x47, 0x2D, 0xCE, 0x4A, 0xFD, 0xC2, 0x27, 0x6C, 0x81, 0x47, 0x97, 0xC7, 0xBC, 0x7A, 0x6C, 0x14, 0xF7, 0x95, 0x3E, 0x7E, 0x9F, 0xEA, 0x69, 0x51, 0x04, 0x0F, 0x2D, 0xAF, 0xBE, 0x9A }, }, - { - { 0x3D, 0x45, 0xBF, 0x0F, 0x64, 0x9B, 0xF5, 0xD1, 0xF8, 0x91, 0x85, 0x31, 0xA7, 0x7C, 0xF9, 0xBF, - 0x5C, 0xA1, 0x85, 0x0C, 0x82, 0x02, 0x69, 0xD7, 0xB2, 0xC8, 0xEC, 0xD0, 0x54, 0x3A, 0x61, 0x65 }, - }, - { - { 0x3D, 0x77, 0xB1, 0xCC, 0x1C, 0x46, 0xF8, 0x58, 0x03, 0x50, 0x53, 0x33, 0xCA, 0x8D, 0xE4, 0x77, - 0x71, 0xDD, 0xE8, 0x94, 0x4A, 0x51, 0x4E, 0xF4, 0x47, 0x08, 0xBF, 0x0E, 0xA6, 0x27, 0x58, 0x50 }, - }, - { - { 0x3D, 0xC7, 0xB5, 0x72, 0xD3, 0xEE, 0xCE, 0xFD, 0x48, 0x07, 0x16, 0x30, 0x9D, 0x2E, 0xC9, 0x24, - 0x8D, 0x4D, 0x5D, 0xD1, 0xD8, 0x4F, 0xDB, 0x3E, 0x70, 0x1B, 0x58, 0x2E, 0x72, 0xB2, 0xDF, 0xE0 }, - }, - { - { 0x3D, 0xE9, 0xE2, 0xFF, 0xBA, 0x92, 0xFC, 0x57, 0xB7, 0x96, 0x4E, 0xE0, 0x59, 0xA3, 0x38, 0x37, - 0x96, 0x37, 0x4E, 0xD8, 0x0D, 0xBE, 0x7F, 0x67, 0x7E, 0xDE, 0x79, 0x98, 0x11, 0xE7, 0xAC, 0x16 }, - }, - { - { 0x3E, 0x6F, 0x37, 0x53, 0xF1, 0xAB, 0x10, 0x62, 0x60, 0xDB, 0xEF, 0xA6, 0x8E, 0xC5, 0x85, 0x01, - 0x29, 0x1D, 0x1E, 0xB4, 0x00, 0x28, 0x8F, 0x06, 0xED, 0xF2, 0x9F, 0x8F, 0x8F, 0x66, 0xB0, 0x1A }, - }, { { 0x3E, 0x8E, 0x9B, 0xAD, 0x8E, 0xD9, 0xB5, 0x72, 0x38, 0x2E, 0x59, 0x8D, 0x2D, 0x73, 0x67, 0xE1, 0xFD, 0x6A, 0xF6, 0x95, 0x25, 0x00, 0x9D, 0x67, 0xB4, 0xE8, 0xAF, 0x80, 0xD9, 0x15, 0x85, 0x49 }, }, - { - { 0x3E, 0xC1, 0xC3, 0x43, 0xC6, 0x60, 0x05, 0x10, 0x57, 0x97, 0x47, 0xA7, 0x1A, 0xEA, 0xB3, 0x04, - 0x1A, 0x71, 0x8E, 0x4F, 0xC6, 0xE2, 0x96, 0xFE, 0xB7, 0x50, 0xA3, 0x12, 0x38, 0x72, 0x6E, 0xA5 }, - }, - { - { 0x3E, 0xD6, 0x85, 0x47, 0x65, 0x07, 0x91, 0x35, 0xAA, 0xEE, 0xB7, 0xD8, 0xA3, 0x79, 0x17, 0xDC, - 0x71, 0x74, 0x5E, 0xA6, 0x0F, 0xA9, 0x62, 0x1B, 0xAA, 0x30, 0x7F, 0xBE, 0x71, 0xA7, 0x3C, 0x43 }, - }, - { - { 0x3F, 0x08, 0x40, 0x27, 0x4E, 0x66, 0x15, 0x90, 0xC1, 0x46, 0x75, 0x96, 0x0F, 0xCC, 0x42, 0x06, - 0x95, 0x36, 0x58, 0x6F, 0x07, 0x60, 0x92, 0x48, 0x76, 0x24, 0x0F, 0x09, 0x04, 0x31, 0x78, 0x91 }, - }, - { - { 0x3F, 0x1B, 0x41, 0x14, 0xF9, 0x89, 0xE8, 0x56, 0x8F, 0x1B, 0x04, 0x53, 0x46, 0x5C, 0x11, 0x3F, - 0x32, 0xC3, 0x85, 0x10, 0xF5, 0x81, 0x77, 0x01, 0x81, 0x3D, 0x69, 0x3E, 0xF1, 0xA6, 0x8F, 0xCB }, - }, { { 0x3F, 0x27, 0xBD, 0xCA, 0x9B, 0x0E, 0x42, 0xF3, 0xF6, 0xD0, 0x91, 0x2C, 0x92, 0xE2, 0xDA, 0x65, 0xCB, 0x35, 0x8F, 0x0B, 0x8F, 0x80, 0x5B, 0xEC, 0x5D, 0xE9, 0x32, 0x51, 0xD9, 0xC4, 0xB1, 0x99 }, @@ -1336,46 +432,18 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x3F, 0x2E, 0xA6, 0x4E, 0xFB, 0xD6, 0xBF, 0xC4, 0x0A, 0xF0, 0xAD, 0x46, 0xA4, 0xA2, 0x57, 0x84, 0x19, 0xD8, 0x68, 0x6E, 0x38, 0x98, 0x8B, 0x91, 0x47, 0x01, 0x8C, 0x36, 0x29, 0x31, 0xE4, 0xF9 }, }, - { - { 0x3F, 0x3F, 0x08, 0x2F, 0xAB, 0x0C, 0xBD, 0x83, 0x16, 0xEA, 0x9D, 0xC1, 0xC7, 0x7E, 0xC6, 0x4C, - 0x32, 0x4D, 0x9C, 0x3D, 0x86, 0x08, 0xC7, 0x79, 0x56, 0xF1, 0x27, 0xA9, 0xB8, 0xF4, 0x9C, 0x46 }, - }, { { 0x3F, 0x4F, 0x28, 0x8B, 0xAF, 0x5B, 0xDE, 0x86, 0x72, 0xD6, 0xAD, 0xD1, 0x50, 0xE3, 0x23, 0x79, 0x49, 0x9A, 0x16, 0xC5, 0x81, 0xFB, 0x77, 0x37, 0xEC, 0x49, 0x80, 0xE4, 0xF9, 0xC3, 0x3D, 0x4D }, }, - { - { 0x3F, 0x5C, 0xFC, 0xAB, 0x44, 0x1A, 0x30, 0xD8, 0xF0, 0x1A, 0xC1, 0xAE, 0x9E, 0x08, 0xA2, 0xDB, - 0x70, 0xC4, 0xC1, 0x6D, 0xED, 0x03, 0xA4, 0x21, 0xD4, 0x1B, 0x8F, 0x42, 0xD5, 0xC1, 0x89, 0x6E }, - }, { { 0x3F, 0x92, 0x54, 0x89, 0x64, 0xCC, 0xDE, 0xFB, 0x29, 0x96, 0x5A, 0x27, 0xC1, 0x6C, 0x2F, 0xED, 0x28, 0xD9, 0xB9, 0x14, 0x0E, 0x4F, 0xB5, 0x5B, 0x37, 0x22, 0x4C, 0x67, 0xB2, 0xA0, 0x55, 0x1F }, }, - { - { 0x3F, 0x93, 0x0A, 0x4E, 0xE4, 0x43, 0x8B, 0x20, 0xD0, 0x3B, 0xD6, 0x25, 0x6E, 0x18, 0xE1, 0x3D, - 0xB2, 0x45, 0x0E, 0x59, 0x38, 0xF9, 0x81, 0xA8, 0xC4, 0x19, 0x0D, 0x56, 0xF0, 0xD8, 0xAC, 0x88 }, - }, - { - { 0x3F, 0xB6, 0xC4, 0x03, 0x19, 0x63, 0xB9, 0x67, 0x28, 0xBF, 0x93, 0x8D, 0x9B, 0x59, 0xC9, 0x05, - 0x43, 0xA9, 0xA6, 0x3E, 0xA3, 0x9C, 0xD2, 0x76, 0x14, 0xF2, 0x41, 0x28, 0xA9, 0x64, 0xEF, 0x84 }, - }, - { - { 0x3F, 0xD9, 0x29, 0x81, 0x1E, 0x0A, 0x80, 0xA3, 0xF4, 0xCD, 0xA3, 0x50, 0x2E, 0x1C, 0x20, 0x29, - 0xA7, 0xA3, 0xC1, 0x61, 0x06, 0x95, 0x5D, 0x3D, 0x93, 0x16, 0x71, 0x15, 0xFE, 0x7B, 0xC6, 0xE2 }, - }, { { 0x40, 0x58, 0xEC, 0x4A, 0x7A, 0x7B, 0xA0, 0xB8, 0x65, 0xA7, 0x39, 0xA0, 0x0C, 0x85, 0xF3, 0x44, 0x58, 0x79, 0xD6, 0x5E, 0x1D, 0x42, 0x2E, 0xED, 0x07, 0x65, 0x5A, 0x8E, 0x3E, 0xC3, 0x18, 0xCF }, }, - { - { 0x40, 0x89, 0x12, 0x59, 0x8B, 0x4D, 0x99, 0x69, 0x1D, 0x46, 0xDC, 0x3C, 0x06, 0x19, 0x82, 0xB9, - 0x48, 0x74, 0x3F, 0x0C, 0x0D, 0x26, 0xFF, 0x38, 0x50, 0xA3, 0xCA, 0x6B, 0x78, 0x97, 0x91, 0x5E }, - }, - { - { 0x41, 0x1E, 0x5A, 0x18, 0x2A, 0x48, 0x3C, 0x67, 0x0F, 0x89, 0xAC, 0xEE, 0xA6, 0xDA, 0xA1, 0xF9, - 0xA6, 0x22, 0x7E, 0xDF, 0x04, 0x9C, 0x05, 0xE3, 0xC4, 0xCF, 0xF7, 0x28, 0x42, 0x45, 0x9A, 0xA2 }, - }, { { 0x41, 0x29, 0x6B, 0x9F, 0xAA, 0xD6, 0x41, 0x33, 0xFC, 0xCB, 0xA6, 0xBA, 0x74, 0x54, 0x11, 0xEC, 0xC9, 0x11, 0xFD, 0x8E, 0xD5, 0x41, 0x90, 0x0F, 0x9E, 0x20, 0x36, 0x08, 0xEE, 0xA3, 0x59, 0x2D }, @@ -1388,4201 +456,1129 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0x41, 0xA6, 0x8D, 0xFD, 0x90, 0xDA, 0x6D, 0x12, 0x09, 0x84, 0x85, 0xBF, 0x6F, 0x87, 0x24, 0x5F, 0x4E, 0xC0, 0x54, 0x71, 0xDA, 0x59, 0xD0, 0x81, 0x06, 0x01, 0x53, 0xA2, 0x22, 0x25, 0x23, 0x7F }, }, - { - { 0x41, 0xAB, 0x57, 0x74, 0x49, 0xA7, 0x50, 0xEF, 0x45, 0x0D, 0x86, 0x4D, 0xB0, 0x6B, 0x7C, 0xBA, - 0x1F, 0x63, 0xE1, 0x1D, 0x1D, 0x86, 0xB7, 0x8C, 0x70, 0x5B, 0xB4, 0x27, 0x34, 0xF5, 0x05, 0x2D }, - }, { { 0x42, 0x08, 0x71, 0xD8, 0xAC, 0x49, 0x3C, 0xF9, 0x46, 0x8B, 0xB3, 0x76, 0x97, 0x6D, 0x65, 0x5E, 0xF0, 0xAF, 0xAA, 0xC2, 0x3D, 0x77, 0x00, 0x92, 0x20, 0xC3, 0xAF, 0x8B, 0xDD, 0x37, 0x5A, 0x24 }, }, - { - { 0x42, 0x53, 0xEB, 0x35, 0x06, 0x2F, 0x32, 0x3B, 0x82, 0xDE, 0xD0, 0x0D, 0x53, 0x83, 0x18, 0x06, - 0x7F, 0xE0, 0xDF, 0x41, 0x2B, 0xC9, 0x20, 0x77, 0x92, 0x5B, 0x76, 0x92, 0xCC, 0xCB, 0x27, 0x29 }, - }, { { 0x42, 0x5D, 0x4E, 0xBF, 0x1B, 0xDE, 0x0B, 0xF8, 0xD1, 0xDB, 0xD3, 0x3D, 0x8D, 0x16, 0x34, 0xC4, 0xFA, 0xFE, 0xB6, 0xF8, 0x05, 0xF1, 0xCC, 0xB5, 0x34, 0xAC, 0xB7, 0x2A, 0xED, 0xA2, 0xCD, 0x0A }, }, { - { 0x42, 0x7B, 0x6D, 0x3D, 0x1F, 0x9E, 0xF7, 0x34, 0xC7, 0x3B, 0x89, 0x23, 0xD0, 0xE0, 0x9A, 0x7C, - 0xB2, 0xD4, 0x7C, 0x78, 0xE0, 0x26, 0x2B, 0x4E, 0x71, 0x32, 0xB4, 0xB8, 0xF0, 0xF7, 0xFB, 0x40 }, + { 0x44, 0x12, 0x63, 0x80, 0xA0, 0x73, 0xFE, 0xA1, 0xA2, 0x00, 0x4F, 0x71, 0x1D, 0xF2, 0xCA, 0x47, + 0xC2, 0xC4, 0xB4, 0xFF, 0x64, 0x4E, 0x76, 0xAF, 0xBE, 0x27, 0x97, 0xC9, 0x63, 0x7C, 0x6A, 0xF9 }, }, { - { 0x42, 0xB0, 0x75, 0xEB, 0xF9, 0xFF, 0x9D, 0x6F, 0xCD, 0xF1, 0xBA, 0x60, 0x80, 0x72, 0x8D, 0x21, - 0xC9, 0xCD, 0x6F, 0xBA, 0xA5, 0x45, 0xDA, 0x03, 0x6C, 0xC6, 0x59, 0xCF, 0x90, 0x5F, 0xB3, 0x0C }, + { 0x44, 0x25, 0xDD, 0xFB, 0xBA, 0xFB, 0xE1, 0xAA, 0xCE, 0x25, 0x85, 0x70, 0x48, 0x96, 0x9D, 0xC8, + 0x9D, 0xF5, 0x97, 0x7B, 0xB2, 0xE3, 0x34, 0x7C, 0x9C, 0xEB, 0x0E, 0x5A, 0x7B, 0x68, 0xC5, 0x31 }, }, { - { 0x43, 0x05, 0xD8, 0x7B, 0xE4, 0xB6, 0xCF, 0x63, 0xA5, 0x00, 0xEE, 0x4B, 0x8D, 0x09, 0x4F, 0x02, - 0x40, 0xAF, 0x3B, 0x0E, 0x9B, 0xF5, 0x9B, 0xB9, 0xAC, 0x20, 0x32, 0xEE, 0xB9, 0x1D, 0x23, 0xDF }, + { 0x45, 0x63, 0xCF, 0x13, 0xC2, 0x49, 0x2C, 0xAA, 0x92, 0xF5, 0x5B, 0x17, 0x26, 0x3A, 0xDD, 0x72, + 0x04, 0xA8, 0x0F, 0xE6, 0x24, 0x0C, 0x4D, 0x63, 0xE8, 0x39, 0x59, 0x58, 0xF6, 0x94, 0xCD, 0x33 }, }, { - { 0x43, 0x09, 0x9D, 0xB4, 0xCF, 0x34, 0x1D, 0x41, 0x3E, 0xCC, 0xEE, 0xFC, 0xAF, 0xCD, 0x58, 0xE7, - 0xE3, 0xB7, 0x77, 0xCF, 0x72, 0x80, 0xF3, 0x23, 0xF4, 0x72, 0x08, 0x61, 0x04, 0x9F, 0x55, 0xFE }, + { 0x45, 0xCB, 0x86, 0xCA, 0x97, 0x52, 0x29, 0xB7, 0xD5, 0xDA, 0xFC, 0x05, 0xEB, 0x0C, 0x53, 0x65, + 0x82, 0x3A, 0x91, 0xA9, 0x8B, 0x7D, 0xBE, 0x81, 0xAB, 0x5F, 0x17, 0x8B, 0x2D, 0xA4, 0xAD, 0x9E }, }, { - { 0x43, 0x13, 0x91, 0xE1, 0x14, 0x14, 0xEC, 0x0C, 0x5C, 0xF5, 0xE7, 0xB3, 0x9C, 0x65, 0xFE, 0xDB, - 0x2E, 0xC8, 0x8C, 0x54, 0x48, 0xBF, 0x35, 0xEE, 0x17, 0x0D, 0xC3, 0xB5, 0xE1, 0x7E, 0xD0, 0x88 }, + { 0x46, 0x9B, 0xD8, 0x04, 0xE9, 0x98, 0xAE, 0x27, 0x9A, 0xC3, 0xFE, 0x1B, 0x52, 0x88, 0x46, 0xE7, + 0xAE, 0xC7, 0x6C, 0x56, 0xB8, 0x0B, 0x40, 0xF3, 0x24, 0x20, 0x8F, 0x5A, 0x9F, 0x64, 0x5C, 0xB5 }, }, { - { 0x43, 0x30, 0xEB, 0xAF, 0x74, 0xBD, 0xD4, 0x36, 0x56, 0xA7, 0x2B, 0x3F, 0xAB, 0x4D, 0x66, 0xDF, - 0x0B, 0x45, 0xCA, 0xB4, 0x93, 0x7D, 0x01, 0xBE, 0xB8, 0xDE, 0x9B, 0x0F, 0x2F, 0xDA, 0xAE, 0xAD }, + { 0x46, 0xCD, 0x08, 0x08, 0x8D, 0x36, 0x06, 0x2C, 0x56, 0x71, 0x09, 0x2C, 0x02, 0x76, 0x7A, 0x25, + 0x0D, 0xE7, 0x0B, 0xF3, 0xE1, 0x53, 0x63, 0x69, 0x66, 0xE6, 0x6E, 0xC5, 0x7E, 0x8E, 0xE9, 0xF5 }, }, { - { 0x43, 0x71, 0x9B, 0x00, 0xB1, 0xEB, 0xBE, 0x02, 0xD2, 0x57, 0x72, 0xE8, 0x41, 0x22, 0x1E, 0xC7, - 0x53, 0x00, 0x02, 0x0B, 0x75, 0x8D, 0xEC, 0x19, 0xD4, 0x2E, 0x33, 0x8E, 0x92, 0xBA, 0x49, 0x4C }, + { 0x47, 0x84, 0xF6, 0xCD, 0x59, 0x3D, 0x7B, 0x31, 0x2E, 0xB1, 0xF6, 0x19, 0xE1, 0x11, 0xDF, 0x3B, + 0x48, 0x6D, 0x1B, 0xF8, 0x37, 0x15, 0xAD, 0x8D, 0xAB, 0xA5, 0x72, 0xAF, 0xB2, 0x61, 0xD5, 0xBE }, }, { - { 0x43, 0x9D, 0x38, 0x5E, 0x8B, 0x11, 0x68, 0x0E, 0x0F, 0xB7, 0x4F, 0x78, 0xA9, 0x74, 0xBD, 0x64, - 0x6D, 0xDE, 0xB5, 0x4E, 0x06, 0x71, 0x42, 0x25, 0x97, 0xB2, 0xFA, 0x88, 0x5D, 0x05, 0x59, 0x28 }, + { 0x48, 0xC5, 0xD4, 0xFF, 0x5D, 0x08, 0x4A, 0xC1, 0x95, 0xB1, 0xA6, 0xA2, 0x19, 0xF8, 0x1B, 0xBD, + 0xF9, 0xD2, 0xE5, 0xC0, 0x70, 0xEC, 0x97, 0xDF, 0x3C, 0xB0, 0xB7, 0x3E, 0xF4, 0x70, 0xDC, 0xE9 }, }, { - { 0x44, 0x12, 0x63, 0x80, 0xA0, 0x73, 0xFE, 0xA1, 0xA2, 0x00, 0x4F, 0x71, 0x1D, 0xF2, 0xCA, 0x47, - 0xC2, 0xC4, 0xB4, 0xFF, 0x64, 0x4E, 0x76, 0xAF, 0xBE, 0x27, 0x97, 0xC9, 0x63, 0x7C, 0x6A, 0xF9 }, + { 0x49, 0xDC, 0xF8, 0xFA, 0x68, 0xE9, 0x2B, 0x5C, 0x21, 0xFE, 0xF9, 0x3D, 0x26, 0x0C, 0x24, 0x8C, + 0xE3, 0xBE, 0x98, 0x62, 0x68, 0x68, 0xE7, 0x5A, 0x3F, 0x63, 0x34, 0xBB, 0x7D, 0xC1, 0x81, 0xEC }, }, { - { 0x44, 0x25, 0xDD, 0xFB, 0xBA, 0xFB, 0xE1, 0xAA, 0xCE, 0x25, 0x85, 0x70, 0x48, 0x96, 0x9D, 0xC8, - 0x9D, 0xF5, 0x97, 0x7B, 0xB2, 0xE3, 0x34, 0x7C, 0x9C, 0xEB, 0x0E, 0x5A, 0x7B, 0x68, 0xC5, 0x31 }, + { 0x4B, 0x1F, 0xC8, 0x2D, 0x24, 0x72, 0x92, 0x7A, 0xC1, 0x7C, 0x58, 0x43, 0x07, 0xCB, 0x96, 0xD6, + 0xFD, 0xDB, 0x8D, 0x50, 0xA5, 0x29, 0x53, 0x07, 0xD3, 0x0C, 0x75, 0x88, 0x59, 0x6A, 0xD4, 0x0B }, }, { - { 0x44, 0x5C, 0x03, 0x3A, 0x43, 0xC2, 0x23, 0x38, 0x8E, 0x1C, 0x54, 0x26, 0x92, 0xAB, 0xE5, 0x7D, - 0x27, 0xC3, 0x35, 0x6E, 0x40, 0x95, 0x0F, 0x1D, 0xBA, 0x03, 0x91, 0xAD, 0xC9, 0x1B, 0x10, 0xC8 }, + { 0x4B, 0x35, 0x02, 0xFF, 0xAD, 0x64, 0x16, 0x39, 0x4F, 0x2F, 0x78, 0x47, 0x76, 0x13, 0x39, 0x69, + 0xA5, 0x5C, 0xA8, 0xF3, 0x9F, 0x78, 0x3C, 0x26, 0x0F, 0xFE, 0xDB, 0xA8, 0xFC, 0xE4, 0x19, 0x70 }, }, { - { 0x44, 0xA0, 0x6E, 0xB4, 0x9A, 0x72, 0xBC, 0xA4, 0x4A, 0x58, 0x1F, 0x4F, 0x10, 0x91, 0xAB, 0xEF, - 0x33, 0x2D, 0x8A, 0x7C, 0xEF, 0x60, 0xE6, 0x8D, 0xAF, 0x84, 0x13, 0x23, 0x26, 0x12, 0x90, 0xF0 }, + { 0x4B, 0x51, 0xFC, 0x11, 0x4B, 0xAC, 0x8E, 0x2D, 0x2A, 0xF2, 0xAE, 0x56, 0x84, 0x42, 0x9C, 0xCA, + 0xAB, 0x21, 0x39, 0xC9, 0xB3, 0x51, 0xBF, 0x7E, 0x1B, 0x03, 0x0A, 0xE8, 0x62, 0x4A, 0xC1, 0x72 }, }, { - { 0x44, 0xC2, 0x00, 0x2E, 0xEA, 0xBE, 0x55, 0xAA, 0x9B, 0xF9, 0x7C, 0xF3, 0xEF, 0xD4, 0xFB, 0x06, - 0xEC, 0xE5, 0x10, 0xB4, 0xAB, 0xE9, 0xAC, 0xB8, 0x2C, 0x36, 0xEF, 0x23, 0x5B, 0x9D, 0xC8, 0xA1 }, + { 0x4C, 0xD0, 0xD6, 0x7E, 0xCC, 0x3B, 0x01, 0xC8, 0xC2, 0x63, 0x4E, 0x7A, 0x73, 0x76, 0x12, 0xF6, + 0x3A, 0x17, 0xFF, 0x51, 0x0A, 0x77, 0xA8, 0x04, 0xBB, 0x33, 0x1B, 0x2B, 0xE5, 0x8D, 0xFE, 0x0C }, }, { - { 0x44, 0xEB, 0x83, 0xC7, 0xEB, 0xD4, 0x1D, 0x2C, 0x09, 0x67, 0x45, 0xFA, 0x9D, 0x7B, 0x3B, 0xC9, - 0x4D, 0xA5, 0x61, 0x82, 0x92, 0xB7, 0x0E, 0x3A, 0xB2, 0x50, 0xE3, 0x83, 0x53, 0x98, 0xC6, 0x7C }, + { 0x4D, 0xCF, 0xEB, 0xDC, 0x15, 0x4B, 0x0C, 0x85, 0x46, 0x7F, 0x6F, 0x52, 0xAD, 0x80, 0x4E, 0x19, + 0x1D, 0x5B, 0xC8, 0x13, 0x51, 0x72, 0x0E, 0xC0, 0xD1, 0x9B, 0xD2, 0x5B, 0xF8, 0xF0, 0xA5, 0x53 }, }, { - { 0x45, 0x3E, 0x22, 0x73, 0x3C, 0xBF, 0xBD, 0xAC, 0x2F, 0xFD, 0x38, 0x74, 0x3D, 0x54, 0xB8, 0x88, - 0xD0, 0x8F, 0x9C, 0x44, 0xBB, 0x59, 0xDC, 0x55, 0x0D, 0xF0, 0x25, 0xC2, 0xA0, 0x0E, 0x4D, 0x3B }, + { 0x4F, 0x19, 0xDD, 0x12, 0x92, 0x4C, 0xE0, 0xC1, 0x4F, 0x82, 0xC0, 0x56, 0xC7, 0xD4, 0x2B, 0xAC, + 0x43, 0xD0, 0x13, 0x3A, 0xAF, 0x89, 0xC1, 0xEF, 0xDC, 0xFA, 0x3C, 0x3E, 0x47, 0x09, 0x7D, 0x59 }, }, { - { 0x45, 0x60, 0xDB, 0xDB, 0x1C, 0x43, 0x68, 0x50, 0xEF, 0xB0, 0x03, 0x1E, 0xF8, 0x2B, 0x9F, 0x70, - 0x88, 0x21, 0x9E, 0xCE, 0xD2, 0x69, 0x56, 0x1F, 0xB4, 0xD1, 0xB0, 0x18, 0x3C, 0x44, 0xC2, 0xB5 }, + { 0x4F, 0xFB, 0x59, 0x19, 0xBC, 0x38, 0x5C, 0x8C, 0x58, 0xE4, 0x62, 0xBF, 0x13, 0x22, 0x10, 0xD8, + 0xB7, 0x86, 0x12, 0xD0, 0xC2, 0x2A, 0x6B, 0x6A, 0x68, 0x2E, 0x0B, 0x9E, 0x9C, 0x9F, 0x9A, 0x44 }, }, { - { 0x45, 0x63, 0xCF, 0x13, 0xC2, 0x49, 0x2C, 0xAA, 0x92, 0xF5, 0x5B, 0x17, 0x26, 0x3A, 0xDD, 0x72, - 0x04, 0xA8, 0x0F, 0xE6, 0x24, 0x0C, 0x4D, 0x63, 0xE8, 0x39, 0x59, 0x58, 0xF6, 0x94, 0xCD, 0x33 }, + { 0x50, 0xF4, 0x78, 0x1E, 0xB1, 0xC1, 0x46, 0x70, 0xD9, 0xA5, 0x52, 0xC3, 0x49, 0x5F, 0xB9, 0xF6, + 0xAE, 0x86, 0x8A, 0xB1, 0xC9, 0xD9, 0x83, 0xE0, 0x82, 0x68, 0x65, 0xA1, 0x02, 0xEC, 0xA6, 0xD3 }, }, { - { 0x45, 0x86, 0xDA, 0x12, 0xA9, 0x43, 0xE6, 0x33, 0xD0, 0xD4, 0x43, 0x91, 0x85, 0x44, 0x39, 0x57, - 0x25, 0x58, 0x7F, 0x0A, 0xA8, 0x41, 0xCA, 0xFD, 0xC6, 0xC8, 0x5D, 0x26, 0x1D, 0x3C, 0xD6, 0x79 }, + { 0x51, 0x6A, 0x2F, 0x33, 0x60, 0xC7, 0x6F, 0xC4, 0x6A, 0xB2, 0x88, 0x7F, 0x88, 0xE8, 0xD0, 0x8E, + 0xFB, 0xD8, 0x44, 0x5A, 0xA7, 0xBB, 0xD2, 0x29, 0xDF, 0xC7, 0x1A, 0x90, 0x4F, 0x55, 0xAE, 0xB4 }, }, { - { 0x45, 0xA7, 0x1A, 0x5C, 0xC4, 0x37, 0xDF, 0x07, 0xE3, 0x86, 0x55, 0x43, 0x6D, 0x96, 0xD8, 0x49, - 0x66, 0xE4, 0x83, 0x9D, 0x37, 0xAD, 0xCC, 0xE9, 0xE9, 0xB2, 0x2B, 0x6E, 0xCB, 0x48, 0x92, 0x8E }, + { 0x52, 0x1F, 0x6C, 0x6A, 0x84, 0x36, 0x65, 0x79, 0xCA, 0x2D, 0xEA, 0xEB, 0x23, 0x15, 0xBF, 0x8E, + 0x53, 0x1C, 0x9F, 0xA4, 0x7B, 0x89, 0x9D, 0xA2, 0x72, 0x16, 0xA9, 0x98, 0x82, 0x86, 0xAF, 0xE5 }, }, { - { 0x45, 0xCB, 0x86, 0xCA, 0x97, 0x52, 0x29, 0xB7, 0xD5, 0xDA, 0xFC, 0x05, 0xEB, 0x0C, 0x53, 0x65, - 0x82, 0x3A, 0x91, 0xA9, 0x8B, 0x7D, 0xBE, 0x81, 0xAB, 0x5F, 0x17, 0x8B, 0x2D, 0xA4, 0xAD, 0x9E }, + { 0x52, 0xFF, 0x8B, 0x6E, 0x98, 0xB0, 0x96, 0x19, 0x90, 0x03, 0xDE, 0x97, 0xBC, 0xCF, 0xD2, 0xA7, + 0xF1, 0xAC, 0x57, 0xA8, 0x31, 0x35, 0xB9, 0x55, 0xFF, 0x68, 0x63, 0x36, 0xA6, 0x91, 0xD5, 0xCA }, }, { - { 0x45, 0xCC, 0x74, 0xA3, 0xDB, 0xCB, 0x59, 0xA1, 0x35, 0x35, 0x39, 0xFA, 0x5B, 0x1A, 0xF9, 0x74, - 0x6B, 0xA5, 0xC7, 0xF0, 0xF1, 0x6F, 0x7C, 0xC1, 0xF7, 0x0C, 0x71, 0x32, 0x38, 0x82, 0x7E, 0x37 }, + { 0x53, 0x79, 0x64, 0x58, 0xDA, 0x97, 0xCE, 0x36, 0x78, 0xF2, 0xD1, 0xD9, 0xB2, 0xA5, 0xB2, 0xFB, + 0x30, 0x75, 0xEA, 0xFA, 0xF6, 0xFF, 0x04, 0x78, 0xB5, 0x72, 0xDD, 0xFD, 0x70, 0x99, 0xAE, 0xE2 }, }, { - { 0x45, 0xD1, 0xF0, 0xB3, 0x4E, 0x90, 0xDC, 0x45, 0x86, 0x4E, 0x40, 0x4E, 0x21, 0xE4, 0x73, 0xF5, - 0x54, 0x2E, 0x6A, 0x07, 0x5A, 0x18, 0x9E, 0x6D, 0x9E, 0xF5, 0xC1, 0x16, 0xE0, 0xCE, 0x97, 0xFC }, + { 0x53, 0x9C, 0xA9, 0xE1, 0xF0, 0x6A, 0xF2, 0x10, 0x7F, 0x96, 0xBF, 0x4B, 0x7D, 0xD4, 0xCE, 0xCD, + 0x9E, 0xD1, 0x1A, 0x38, 0xD6, 0x70, 0x91, 0x69, 0x9C, 0x56, 0x26, 0xE2, 0x7A, 0x1F, 0x54, 0xA5 }, }, { - { 0x45, 0xD7, 0x98, 0xFB, 0xC7, 0x66, 0x6C, 0xD7, 0xA0, 0x39, 0x5E, 0x45, 0x0C, 0x5B, 0x4E, 0x1D, - 0x98, 0xFD, 0x0E, 0xDC, 0x7F, 0x97, 0xA0, 0x31, 0x3A, 0x3B, 0x13, 0x86, 0x27, 0x8D, 0xDB, 0x08 }, + { 0x55, 0x21, 0xF9, 0x63, 0x57, 0x81, 0x58, 0xB8, 0xD0, 0xE7, 0xC4, 0x91, 0xCD, 0xB8, 0x5C, 0x3D, + 0xE9, 0xD5, 0x2E, 0xA5, 0x1F, 0xFC, 0xB0, 0x93, 0xD3, 0x12, 0x28, 0x11, 0x13, 0x14, 0x97, 0xEB }, }, { - { 0x45, 0xE9, 0xCF, 0x0A, 0xF0, 0x43, 0xA3, 0xC2, 0xBB, 0x74, 0xD4, 0x63, 0x66, 0x93, 0x1C, 0x3D, - 0xFC, 0xA5, 0x3D, 0x36, 0x26, 0x64, 0x37, 0xD2, 0xA9, 0x46, 0x84, 0xFE, 0xE9, 0x4E, 0x0C, 0x0D }, + { 0x55, 0xD0, 0xEB, 0xE3, 0x2C, 0xBA, 0x09, 0xF6, 0x58, 0x4D, 0x9E, 0x7B, 0x57, 0x92, 0xA4, 0x03, + 0xC2, 0x1D, 0x39, 0xD6, 0xE1, 0xF5, 0xE8, 0xED, 0x37, 0xB9, 0x3F, 0xA6, 0x1D, 0x88, 0x35, 0x16 }, }, { - { 0x46, 0x9B, 0xD8, 0x04, 0xE9, 0x98, 0xAE, 0x27, 0x9A, 0xC3, 0xFE, 0x1B, 0x52, 0x88, 0x46, 0xE7, - 0xAE, 0xC7, 0x6C, 0x56, 0xB8, 0x0B, 0x40, 0xF3, 0x24, 0x20, 0x8F, 0x5A, 0x9F, 0x64, 0x5C, 0xB5 }, + { 0x58, 0x1A, 0xDE, 0x64, 0x84, 0x95, 0xB4, 0xB1, 0x62, 0x9C, 0x3C, 0x7C, 0x78, 0xEF, 0xBE, 0xF2, + 0x75, 0x06, 0x56, 0x65, 0xB2, 0x41, 0x1C, 0x0E, 0x5F, 0xCF, 0xBC, 0x7E, 0xB4, 0xBE, 0x34, 0x0B }, }, { - { 0x46, 0xCD, 0x08, 0x08, 0x8D, 0x36, 0x06, 0x2C, 0x56, 0x71, 0x09, 0x2C, 0x02, 0x76, 0x7A, 0x25, - 0x0D, 0xE7, 0x0B, 0xF3, 0xE1, 0x53, 0x63, 0x69, 0x66, 0xE6, 0x6E, 0xC5, 0x7E, 0x8E, 0xE9, 0xF5 }, + { 0x59, 0xC9, 0xE8, 0xDF, 0x03, 0x0B, 0x1C, 0xD5, 0x89, 0xA8, 0xB3, 0x4F, 0xE7, 0x42, 0x51, 0xEA, + 0xD5, 0xA5, 0xFB, 0xE9, 0xE6, 0x13, 0x67, 0xCA, 0x76, 0xAF, 0xD9, 0xDD, 0xD9, 0xC6, 0xF1, 0x6F }, }, { - { 0x46, 0xE3, 0x7D, 0x9C, 0x51, 0xC6, 0x40, 0x06, 0x4C, 0xD9, 0x5C, 0x8F, 0xEA, 0x7D, 0x65, 0x78, - 0x0C, 0x2C, 0x4F, 0x0E, 0xB8, 0xEE, 0x56, 0x67, 0xEF, 0x5D, 0xCC, 0xD3, 0x1F, 0x44, 0xE0, 0x8D }, + { 0x59, 0xE9, 0xFA, 0x2F, 0xF0, 0x76, 0x89, 0x33, 0x28, 0x33, 0xC6, 0x40, 0xF5, 0x05, 0xFA, 0x24, + 0x09, 0xEB, 0x88, 0x93, 0x32, 0x57, 0xC1, 0x93, 0xB0, 0x07, 0xD3, 0xA2, 0x89, 0x6A, 0x98, 0x50 }, }, { - { 0x46, 0xEC, 0x1D, 0x4F, 0x78, 0xCA, 0xA6, 0xEC, 0x0B, 0xCB, 0x5C, 0x8C, 0x60, 0x63, 0x04, 0x73, - 0x9B, 0xA5, 0x10, 0xB5, 0x97, 0xB4, 0xC8, 0x46, 0x30, 0x81, 0xF3, 0x1F, 0x7C, 0xDB, 0x4E, 0xC1 }, + { 0x59, 0xEE, 0x9B, 0x36, 0x80, 0xAE, 0x20, 0x56, 0x83, 0x9C, 0x0B, 0xF6, 0x9E, 0xE6, 0x63, 0x26, + 0x57, 0x16, 0xA8, 0xE2, 0x4C, 0xC6, 0x49, 0x95, 0xFB, 0xA6, 0xCB, 0x6F, 0x0C, 0x12, 0x39, 0xDC }, }, { - { 0x46, 0xED, 0x9B, 0x23, 0xA0, 0x9E, 0x91, 0x19, 0xD7, 0x96, 0xE4, 0xFE, 0xC1, 0x1C, 0x26, 0x3C, - 0x74, 0x89, 0x28, 0xB0, 0xA9, 0x90, 0x09, 0x5D, 0xA8, 0xA6, 0x3E, 0x71, 0x47, 0x19, 0x49, 0x1E }, + { 0x5A, 0x84, 0xAF, 0xE6, 0x74, 0x05, 0xAB, 0xE8, 0x4A, 0x0C, 0xD4, 0x2C, 0x2B, 0xA2, 0xE4, 0xC8, + 0x8F, 0x35, 0xE0, 0xA5, 0x95, 0xE5, 0x69, 0xA3, 0xE1, 0x86, 0x69, 0x44, 0x40, 0x5B, 0xE7, 0x36 }, }, { - { 0x47, 0x78, 0xD4, 0xA5, 0x37, 0x9B, 0x45, 0x4E, 0x69, 0x68, 0x79, 0x20, 0xC1, 0xFE, 0x05, 0xB9, - 0x17, 0xAD, 0x50, 0x0C, 0x00, 0x57, 0xE9, 0x07, 0x19, 0xDC, 0x26, 0x15, 0xAF, 0x97, 0x44, 0x22 }, + { 0x5A, 0x8E, 0x86, 0x21, 0x2C, 0x06, 0x33, 0x94, 0x94, 0xF8, 0x5B, 0x5F, 0x85, 0x11, 0xDF, 0x00, + 0x00, 0x23, 0x94, 0x07, 0x8F, 0xFC, 0x77, 0x4D, 0x43, 0x6F, 0x0D, 0x63, 0x86, 0xD7, 0xA6, 0xF7 }, }, { - { 0x47, 0x84, 0xF6, 0xCD, 0x59, 0x3D, 0x7B, 0x31, 0x2E, 0xB1, 0xF6, 0x19, 0xE1, 0x11, 0xDF, 0x3B, - 0x48, 0x6D, 0x1B, 0xF8, 0x37, 0x15, 0xAD, 0x8D, 0xAB, 0xA5, 0x72, 0xAF, 0xB2, 0x61, 0xD5, 0xBE }, + { 0x5A, 0xC0, 0x98, 0x2D, 0xA0, 0xC8, 0x3D, 0x0B, 0xA9, 0x38, 0x1A, 0x5C, 0xD8, 0x7B, 0x80, 0xD1, + 0x10, 0xF2, 0x6E, 0xE8, 0x39, 0x27, 0x1B, 0xC2, 0x70, 0x60, 0x8F, 0xD1, 0x43, 0x7F, 0x55, 0xB0 }, }, { - { 0x47, 0xB2, 0xF4, 0xD6, 0xB8, 0x4E, 0xB7, 0x44, 0x53, 0xA9, 0xEC, 0xDC, 0x2D, 0x21, 0xC9, 0xD6, - 0xBE, 0x8A, 0x3D, 0x83, 0xF8, 0xA3, 0x8B, 0x31, 0x8D, 0x87, 0x26, 0x1A, 0xA9, 0x86, 0x98, 0x5E }, + { 0x5B, 0x29, 0x3D, 0x30, 0x9F, 0x64, 0x24, 0xBC, 0x26, 0x4F, 0x4B, 0xB0, 0x18, 0xAE, 0xF5, 0x0E, + 0x63, 0xE3, 0x37, 0xD1, 0x4D, 0xF0, 0x64, 0xC5, 0x7A, 0x23, 0x52, 0x83, 0x42, 0x16, 0x1C, 0x68 }, }, { - { 0x48, 0x08, 0x68, 0xBA, 0xB4, 0x84, 0xC5, 0x05, 0x38, 0x7C, 0x95, 0x7E, 0xBC, 0x12, 0x2F, 0x01, - 0x4D, 0x79, 0xC5, 0xEC, 0x63, 0xA8, 0x74, 0xD7, 0x33, 0xCF, 0x81, 0x7E, 0x3D, 0xED, 0x0D, 0x46 }, + { 0x5C, 0x7F, 0xF0, 0x55, 0xC2, 0xFD, 0x03, 0x3F, 0x34, 0xC4, 0xC4, 0xF7, 0xC4, 0xFB, 0x7D, 0xDA, + 0xAA, 0xFB, 0x43, 0x56, 0xC5, 0x60, 0xC9, 0x9E, 0xDF, 0xF0, 0x74, 0xDA, 0x04, 0xAF, 0x65, 0x7C }, }, { - { 0x48, 0x09, 0x80, 0xFC, 0xEB, 0x50, 0xEB, 0x37, 0x4C, 0x91, 0x6C, 0xB2, 0xA4, 0x3A, 0xFB, 0xD5, - 0x35, 0x21, 0x1A, 0xEA, 0x9B, 0x12, 0xB7, 0xA4, 0x5A, 0xAF, 0x90, 0xBA, 0x9C, 0xA4, 0x70, 0x0F }, + { 0x5C, 0xD2, 0x44, 0x6A, 0x8E, 0x4A, 0x0F, 0xA7, 0xE3, 0xCD, 0xF8, 0x00, 0x5D, 0xED, 0xCE, 0xBA, + 0xE9, 0xE6, 0x81, 0x9A, 0x8A, 0x69, 0x87, 0x31, 0x55, 0x5B, 0x7D, 0xC9, 0xD0, 0xA2, 0x3F, 0xC0 }, }, { - { 0x48, 0x13, 0x2A, 0xF3, 0x5F, 0x2F, 0x63, 0x53, 0x2E, 0xAC, 0x4D, 0x64, 0x4B, 0xA3, 0x11, 0x09, - 0xCF, 0xEB, 0xE6, 0x56, 0x48, 0x3A, 0x76, 0x43, 0x7A, 0xDC, 0xA1, 0xD8, 0x44, 0x3C, 0x22, 0xCF }, + { 0x5C, 0xEB, 0xEB, 0xD8, 0x34, 0x01, 0xB7, 0x0B, 0xAC, 0xB5, 0x4F, 0x66, 0xA9, 0xB7, 0x78, 0x55, + 0x69, 0x6E, 0xCE, 0x16, 0x7F, 0xE6, 0xC6, 0x0A, 0x05, 0x16, 0x8B, 0xE4, 0x39, 0x19, 0xC8, 0x0F }, }, { - { 0x48, 0x1F, 0xEB, 0xED, 0xD0, 0x11, 0xFC, 0xB0, 0x3F, 0xBD, 0xD5, 0x8F, 0xC9, 0x97, 0x85, 0x20, - 0xF5, 0x00, 0x63, 0x83, 0x6D, 0x0F, 0xB0, 0x8E, 0x9F, 0xDC, 0x42, 0x7C, 0x14, 0xC7, 0x97, 0xB7 }, + { 0x5E, 0x23, 0xDB, 0xD4, 0xD0, 0xC9, 0xBF, 0xB1, 0x5F, 0x61, 0x6A, 0x95, 0x17, 0xA1, 0x30, 0xD8, + 0x66, 0xA8, 0xCB, 0x0B, 0x18, 0x96, 0x3D, 0x54, 0xE7, 0xED, 0xAE, 0xE2, 0x61, 0xCB, 0x1C, 0x19 }, }, { - { 0x48, 0x4B, 0x8B, 0xC1, 0xE6, 0xCB, 0xBA, 0x3F, 0x01, 0xF7, 0xA9, 0x34, 0x5A, 0x88, 0x4C, 0xF5, - 0xF1, 0x5D, 0x82, 0xDA, 0x56, 0x98, 0xB6, 0xB3, 0x71, 0xE4, 0xDC, 0x6B, 0xBD, 0x6C, 0x8A, 0xE8 }, + { 0x5F, 0x8B, 0x88, 0x8E, 0xE9, 0x6C, 0x0C, 0x0F, 0x5A, 0x91, 0x72, 0x90, 0xAC, 0xA6, 0x5A, 0xFD, + 0x6E, 0xBD, 0xAE, 0x05, 0xA0, 0x2A, 0xAF, 0x04, 0x29, 0xE9, 0x72, 0xEC, 0x01, 0x90, 0xEC, 0xFC }, }, { - { 0x48, 0x5C, 0xF2, 0xB0, 0xA5, 0xE6, 0x9A, 0x0A, 0x9A, 0xAB, 0x03, 0xFF, 0x82, 0xBD, 0x6B, 0x7B, - 0x2E, 0xDF, 0x8E, 0x1B, 0x54, 0x45, 0x8E, 0x14, 0x2A, 0xEB, 0x88, 0xBA, 0xA8, 0x84, 0x0E, 0x5B }, + { 0x62, 0x2E, 0xC3, 0xBE, 0x7C, 0xF5, 0xE4, 0xE6, 0x3F, 0x74, 0x18, 0x69, 0x28, 0x74, 0x40, 0x05, + 0xCB, 0xB7, 0x8D, 0xF3, 0x06, 0xB8, 0x67, 0xC3, 0xFC, 0xAD, 0x5E, 0x2B, 0xA7, 0x53, 0x96, 0x83 }, }, { - { 0x48, 0x61, 0x56, 0x1A, 0xE5, 0x65, 0x86, 0xB8, 0xCD, 0xA5, 0xC2, 0xF8, 0x75, 0x0B, 0x8D, 0x34, - 0x38, 0x51, 0x53, 0xE4, 0xB8, 0x44, 0x0A, 0x9A, 0x37, 0xD6, 0x6D, 0xF8, 0x76, 0x94, 0x5F, 0x3F }, + { 0x62, 0x6F, 0x7E, 0xB4, 0xFD, 0x9B, 0x71, 0xFF, 0xAA, 0x0C, 0x8E, 0xC9, 0x65, 0x54, 0x64, 0xE6, + 0x5E, 0x7F, 0x96, 0xCF, 0xA3, 0x82, 0x73, 0x97, 0x41, 0x35, 0x66, 0xAA, 0x2C, 0xC1, 0xE5, 0x72 }, }, { - { 0x48, 0xC5, 0xD4, 0xFF, 0x5D, 0x08, 0x4A, 0xC1, 0x95, 0xB1, 0xA6, 0xA2, 0x19, 0xF8, 0x1B, 0xBD, - 0xF9, 0xD2, 0xE5, 0xC0, 0x70, 0xEC, 0x97, 0xDF, 0x3C, 0xB0, 0xB7, 0x3E, 0xF4, 0x70, 0xDC, 0xE9 }, + { 0x63, 0x64, 0x15, 0x61, 0x77, 0xDC, 0xDF, 0x60, 0x4D, 0xF9, 0x1E, 0x31, 0x32, 0x2E, 0x57, 0x74, + 0x69, 0x1E, 0x0C, 0x41, 0xFA, 0x0D, 0x2F, 0x25, 0x7A, 0xD7, 0xF9, 0xF0, 0x25, 0x98, 0x14, 0x45 }, }, { - { 0x48, 0xE9, 0xC3, 0xDB, 0x3A, 0x8F, 0x3B, 0x82, 0x60, 0x20, 0x9F, 0x05, 0x13, 0x3D, 0xBA, 0xDB, - 0xF5, 0x11, 0x7F, 0xB1, 0x0D, 0x11, 0x14, 0xA8, 0xC9, 0x26, 0x83, 0x45, 0x41, 0x59, 0x41, 0x63 }, + { 0x65, 0x66, 0x00, 0xA4, 0x5E, 0x45, 0x6A, 0xBA, 0x5B, 0x00, 0x8D, 0x87, 0x91, 0x54, 0xB7, 0x69, + 0x0D, 0x7F, 0x27, 0x31, 0x02, 0x09, 0x7D, 0x8F, 0xD8, 0xC3, 0xDE, 0xAB, 0x30, 0xD8, 0x4A, 0xB2 }, }, { - { 0x49, 0x64, 0xF3, 0x85, 0xCC, 0x36, 0x3B, 0xF0, 0x61, 0x7E, 0x05, 0x66, 0xB2, 0xE0, 0xD3, 0x03, - 0x3E, 0xB1, 0x26, 0x27, 0x0E, 0x00, 0xD3, 0x22, 0xF0, 0x95, 0xEC, 0xBA, 0x13, 0x06, 0x88, 0x8C }, + { 0x65, 0xED, 0x61, 0xA8, 0x8C, 0x55, 0xEF, 0xB0, 0x38, 0x07, 0x1A, 0xEE, 0xDE, 0xF8, 0xE1, 0x83, + 0xE2, 0x37, 0x38, 0x46, 0x97, 0x26, 0xEB, 0x99, 0x68, 0x0C, 0xD2, 0x44, 0x72, 0x73, 0x6B, 0xEC }, }, { - { 0x49, 0xDC, 0xF8, 0xFA, 0x68, 0xE9, 0x2B, 0x5C, 0x21, 0xFE, 0xF9, 0x3D, 0x26, 0x0C, 0x24, 0x8C, - 0xE3, 0xBE, 0x98, 0x62, 0x68, 0x68, 0xE7, 0x5A, 0x3F, 0x63, 0x34, 0xBB, 0x7D, 0xC1, 0x81, 0xEC }, + { 0x66, 0x50, 0xB2, 0xEA, 0x64, 0x4C, 0x3F, 0x4E, 0x8C, 0x9E, 0x3C, 0x46, 0xAC, 0xEA, 0xC4, 0x52, + 0x33, 0xD8, 0x66, 0xE3, 0x98, 0xFF, 0x90, 0xEB, 0x59, 0xB2, 0xC6, 0x25, 0x20, 0x82, 0xAC, 0x04 }, }, { - { 0x49, 0xE0, 0xD6, 0x97, 0x5A, 0x23, 0x47, 0x67, 0x2C, 0xC4, 0x1A, 0x76, 0x86, 0x3A, 0xA9, 0x30, - 0xB6, 0x7C, 0x2A, 0xA4, 0xF6, 0x65, 0x1F, 0x9A, 0x28, 0xF7, 0xFB, 0x38, 0xB4, 0xA4, 0x41, 0x96 }, + { 0x66, 0xBE, 0x7E, 0xA1, 0x13, 0x8B, 0xCB, 0xA4, 0xDE, 0x0B, 0x41, 0x28, 0x5D, 0x9A, 0x13, 0x3F, + 0xA7, 0xF5, 0x70, 0xA3, 0xC8, 0x13, 0x55, 0x79, 0xB8, 0x60, 0x19, 0x9D, 0x0A, 0x51, 0x45, 0x7C }, }, { - { 0x49, 0xF3, 0x0D, 0xB3, 0x32, 0xF4, 0x53, 0x6A, 0xD4, 0x53, 0xBC, 0x68, 0x9C, 0x2C, 0x63, 0x10, - 0x6F, 0xFF, 0xC2, 0xB1, 0x86, 0x23, 0xAA, 0x0B, 0xDE, 0xAA, 0xB4, 0xF9, 0xEB, 0x7C, 0x0E, 0x42 }, + { 0x69, 0x01, 0x4B, 0xBC, 0x84, 0x29, 0xD8, 0x5F, 0x41, 0xC2, 0x22, 0xD9, 0x7F, 0x7E, 0xD5, 0x35, + 0xCF, 0x81, 0x23, 0x9A, 0xF2, 0x7A, 0xCC, 0x88, 0x70, 0xDC, 0xD4, 0x08, 0x34, 0x8B, 0x48, 0xBA }, }, { - { 0x4A, 0x10, 0xBC, 0x78, 0x52, 0x2D, 0xAA, 0x83, 0xF4, 0x55, 0x81, 0xE5, 0xFB, 0xF6, 0x3D, 0xE8, - 0x47, 0x92, 0x4F, 0x93, 0x78, 0x3C, 0xB0, 0x5C, 0xAE, 0x3C, 0x1C, 0x5B, 0x57, 0x01, 0x04, 0x69 }, + { 0x69, 0x21, 0x1F, 0x36, 0x3A, 0x2D, 0xBE, 0x01, 0x5B, 0x31, 0xCB, 0xD9, 0xFC, 0x5E, 0x94, 0xC2, + 0xF6, 0xF4, 0x3C, 0x58, 0xDB, 0xDE, 0xE9, 0xE3, 0xE4, 0x6B, 0x19, 0xD7, 0x59, 0xBB, 0xB8, 0x81 }, }, { - { 0x4A, 0x47, 0x5B, 0x01, 0xD5, 0xE2, 0x70, 0xAB, 0xEE, 0xA0, 0xCC, 0x08, 0xAF, 0x77, 0xB9, 0x6C, - 0x8A, 0xE2, 0x82, 0x6F, 0x32, 0x61, 0xA0, 0xFD, 0xA3, 0x7A, 0xCA, 0xD3, 0xC9, 0xC8, 0x60, 0x41 }, + { 0x69, 0x75, 0x67, 0xBB, 0xAC, 0x94, 0xEE, 0xC3, 0xE6, 0xFA, 0x4A, 0x4E, 0x46, 0xFA, 0x51, 0x74, + 0x05, 0xF3, 0x77, 0xC0, 0xDE, 0xE3, 0xD4, 0x29, 0x91, 0x4E, 0x6B, 0x7E, 0xA0, 0x8C, 0xB1, 0xA6 }, }, { - { 0x4A, 0x8E, 0x3A, 0xDB, 0xDC, 0xBE, 0x3E, 0x7E, 0xD8, 0x7D, 0x81, 0x4F, 0x60, 0x46, 0x1B, 0x82, - 0x36, 0x24, 0xF4, 0x9B, 0xE3, 0x5D, 0x66, 0x39, 0x09, 0xEC, 0xB1, 0x8F, 0xBF, 0x06, 0x01, 0x3F }, + { 0x6A, 0xAC, 0xC5, 0x09, 0x2F, 0x12, 0xBC, 0x94, 0xA0, 0xAD, 0x0E, 0x9E, 0xF6, 0x36, 0x43, 0x7D, + 0x36, 0x0D, 0xC7, 0xC9, 0xF1, 0x40, 0x44, 0x17, 0xA3, 0x36, 0x91, 0x94, 0x4E, 0x76, 0x31, 0x36 }, }, { - { 0x4A, 0x90, 0x3B, 0x61, 0xE8, 0x1B, 0x53, 0xDA, 0xEF, 0x8E, 0xD3, 0xF7, 0x72, 0x14, 0xC6, 0xB7, - 0x74, 0xD4, 0xD2, 0x9D, 0xD6, 0x75, 0xC9, 0x1C, 0xDB, 0x2E, 0x0C, 0xEB, 0x36, 0xBC, 0x66, 0xE7 }, + { 0x6B, 0x4A, 0x8C, 0xB6, 0x07, 0xF5, 0x1C, 0x83, 0x0D, 0xE7, 0x20, 0xF4, 0xBB, 0xDE, 0xDF, 0x49, + 0x10, 0x15, 0x13, 0xDF, 0xD1, 0xDB, 0x0B, 0x0A, 0x97, 0xCC, 0x3F, 0xDD, 0x9A, 0x39, 0xC6, 0xE7 }, }, { - { 0x4A, 0xA7, 0xD5, 0xCD, 0xB1, 0x8E, 0x5E, 0xAE, 0x05, 0x9D, 0x54, 0x10, 0xFD, 0x5B, 0x44, 0xA5, - 0x9E, 0xBA, 0x0D, 0xE9, 0x66, 0x3C, 0x42, 0x2F, 0x42, 0x35, 0x87, 0x04, 0xC3, 0x2C, 0x90, 0x2D }, + { 0x6C, 0x8F, 0xD1, 0xE6, 0xE1, 0x1B, 0xAF, 0xA6, 0x17, 0x78, 0x13, 0xA0, 0x44, 0x40, 0xB1, 0xB9, + 0x6A, 0x1C, 0xDB, 0x7C, 0x2D, 0x70, 0x3F, 0x55, 0xDE, 0x85, 0x7C, 0x80, 0xA8, 0x9E, 0x73, 0x25 }, }, { - { 0x4A, 0xCF, 0x9D, 0xA9, 0x05, 0x2F, 0x0B, 0x8C, 0xFF, 0xF7, 0x37, 0xCD, 0xA3, 0x39, 0x11, 0xC2, - 0x9E, 0xFC, 0xBF, 0xFD, 0x4B, 0xF4, 0xB7, 0x24, 0x83, 0xFA, 0xA7, 0xC7, 0x45, 0x1D, 0xFD, 0x42 }, + { 0x6C, 0xC6, 0xDC, 0xDA, 0x58, 0xC6, 0x1F, 0xB2, 0x86, 0x70, 0xD1, 0xC2, 0x01, 0x76, 0x57, 0xB0, + 0xC5, 0xD6, 0x1A, 0x26, 0xC9, 0xCB, 0xD1, 0xEA, 0x75, 0x5C, 0x68, 0x20, 0xB5, 0xF6, 0xD6, 0x7D }, }, { - { 0x4A, 0xD2, 0x17, 0xA9, 0x6E, 0x15, 0x30, 0xCB, 0xC5, 0xDE, 0xB8, 0x6A, 0xFF, 0x27, 0x63, 0x55, - 0x23, 0x59, 0xDA, 0x5B, 0x59, 0x82, 0xE5, 0x38, 0xBA, 0xB7, 0xC9, 0x2A, 0x15, 0x9C, 0xB8, 0x3C }, + { 0x6D, 0x32, 0xF4, 0x93, 0x40, 0x56, 0xEE, 0x17, 0x14, 0xCA, 0x72, 0x70, 0x3F, 0x64, 0x46, 0x9B, + 0x98, 0x58, 0xFC, 0x39, 0x96, 0x4B, 0x4C, 0x03, 0x93, 0xB3, 0x7D, 0xDE, 0xAB, 0x8B, 0x19, 0x75 }, }, { - { 0x4A, 0xE5, 0xE5, 0x1E, 0x7F, 0xF1, 0x67, 0x47, 0x77, 0x5E, 0x2B, 0x2C, 0x05, 0x72, 0x1D, 0x95, - 0xEB, 0xEB, 0x8C, 0x46, 0x01, 0xFD, 0xDC, 0xDC, 0x90, 0xFB, 0xCE, 0x69, 0x7E, 0x35, 0x01, 0x2C }, + { 0x6D, 0xC9, 0x87, 0x5C, 0xD3, 0x46, 0xA2, 0x2B, 0x47, 0xB2, 0x80, 0xB1, 0xB1, 0x45, 0x0D, 0x87, + 0x8E, 0x09, 0x8B, 0xB2, 0xE2, 0xA9, 0xE3, 0xC2, 0x5C, 0xC7, 0x6A, 0xFF, 0x93, 0xC0, 0xBE, 0xAB }, }, { - { 0x4B, 0x04, 0x83, 0x2E, 0x6C, 0x99, 0xEA, 0x3A, 0x31, 0xF4, 0x83, 0x76, 0x82, 0xB5, 0x43, 0x7C, - 0x09, 0x99, 0x78, 0x1E, 0x77, 0xCB, 0xDE, 0xB8, 0x93, 0xDB, 0xFE, 0xF3, 0x1E, 0x0E, 0xE3, 0x3E }, + { 0x6E, 0x1A, 0x88, 0x63, 0xF2, 0x93, 0x4B, 0x39, 0x01, 0x23, 0x7E, 0x84, 0xD0, 0x76, 0x27, 0x04, + 0x23, 0x06, 0x78, 0x7F, 0x2D, 0xE0, 0x66, 0x30, 0xBD, 0x37, 0xD8, 0x03, 0x94, 0x35, 0xBF, 0xCA }, }, { - { 0x4B, 0x1F, 0xC8, 0x2D, 0x24, 0x72, 0x92, 0x7A, 0xC1, 0x7C, 0x58, 0x43, 0x07, 0xCB, 0x96, 0xD6, - 0xFD, 0xDB, 0x8D, 0x50, 0xA5, 0x29, 0x53, 0x07, 0xD3, 0x0C, 0x75, 0x88, 0x59, 0x6A, 0xD4, 0x0B }, + { 0x6F, 0x3B, 0xB3, 0x4B, 0x5D, 0x32, 0x91, 0xDF, 0xB3, 0xE4, 0x12, 0x71, 0xA1, 0xD7, 0x30, 0xCD, + 0xBC, 0xFF, 0xC1, 0x0B, 0x68, 0x05, 0x9D, 0xCC, 0xD3, 0x1C, 0x47, 0x4B, 0xB7, 0x44, 0x16, 0xE5 }, }, { - { 0x4B, 0x2D, 0xF9, 0xFA, 0xF4, 0x2F, 0x2B, 0x06, 0x61, 0x28, 0x80, 0xD2, 0x69, 0x04, 0x2B, 0x6C, - 0x1C, 0x51, 0xE7, 0xAC, 0xF0, 0x45, 0x91, 0xB6, 0x68, 0x66, 0x33, 0x5F, 0xCE, 0x7C, 0xC6, 0x84 }, + { 0x6F, 0xBD, 0xCD, 0xF1, 0xB4, 0x37, 0x9F, 0xC4, 0x73, 0xAB, 0x5E, 0xEA, 0x4E, 0xC2, 0xF4, 0x84, + 0xCE, 0x91, 0xD1, 0x0E, 0x31, 0x34, 0x5F, 0x15, 0xA7, 0x6A, 0x84, 0x85, 0xB8, 0xFF, 0xFB, 0x7E }, }, { - { 0x4B, 0x35, 0x02, 0xFF, 0xAD, 0x64, 0x16, 0x39, 0x4F, 0x2F, 0x78, 0x47, 0x76, 0x13, 0x39, 0x69, - 0xA5, 0x5C, 0xA8, 0xF3, 0x9F, 0x78, 0x3C, 0x26, 0x0F, 0xFE, 0xDB, 0xA8, 0xFC, 0xE4, 0x19, 0x70 }, + { 0x6F, 0xDC, 0x18, 0xD6, 0x55, 0x14, 0xDD, 0xCE, 0xF0, 0x2F, 0xEA, 0x81, 0x7A, 0x1B, 0x70, 0x84, + 0x71, 0x95, 0xFF, 0x5C, 0x07, 0xB1, 0x3D, 0x6A, 0x97, 0x1E, 0x0E, 0x77, 0x4B, 0x44, 0x10, 0xA0 }, }, { - { 0x4B, 0x51, 0xFC, 0x11, 0x4B, 0xAC, 0x8E, 0x2D, 0x2A, 0xF2, 0xAE, 0x56, 0x84, 0x42, 0x9C, 0xCA, - 0xAB, 0x21, 0x39, 0xC9, 0xB3, 0x51, 0xBF, 0x7E, 0x1B, 0x03, 0x0A, 0xE8, 0x62, 0x4A, 0xC1, 0x72 }, + { 0x70, 0xB8, 0xEC, 0xD5, 0x62, 0xEC, 0x3D, 0x9F, 0x48, 0x64, 0x75, 0x2A, 0x3A, 0x8C, 0x54, 0x39, + 0x93, 0xB4, 0x38, 0x72, 0x8F, 0xE2, 0x71, 0x81, 0xF4, 0xC0, 0x8D, 0xE6, 0xA0, 0xD8, 0xB7, 0x9A }, }, { - { 0x4B, 0x5D, 0xBF, 0x01, 0x0B, 0x3E, 0x62, 0x78, 0x9C, 0x43, 0x8E, 0x07, 0x18, 0xEC, 0xB4, 0x4A, - 0x5D, 0xC0, 0x8F, 0xEB, 0xCF, 0xF7, 0x0A, 0xDF, 0x5B, 0xE0, 0x0A, 0x6E, 0x49, 0xE5, 0x71, 0xF7 }, + { 0x71, 0x1E, 0xF0, 0x96, 0x33, 0x43, 0x8A, 0xC5, 0xBE, 0x9D, 0xA8, 0x12, 0x2E, 0x7A, 0xCF, 0x0E, + 0xA2, 0x68, 0xB8, 0x72, 0xAD, 0xDC, 0x3E, 0xE8, 0x37, 0x2B, 0x91, 0x6D, 0x60, 0x65, 0xCF, 0xA8 }, }, { - { 0x4B, 0x92, 0xDC, 0xFD, 0x0E, 0xDA, 0x00, 0x5D, 0x9A, 0x37, 0x3D, 0x91, 0xA6, 0x1F, 0x23, 0x12, - 0x9D, 0x7B, 0x85, 0x3D, 0x79, 0x52, 0x87, 0xC9, 0x5C, 0x7E, 0x17, 0x24, 0xA9, 0x1C, 0x53, 0xB3 }, + { 0x72, 0x1B, 0x1F, 0x92, 0x9D, 0xA7, 0xEA, 0xF8, 0x96, 0x24, 0x64, 0x7B, 0xA3, 0xCC, 0x4E, 0x1E, + 0xD1, 0x57, 0x54, 0xAB, 0x83, 0x6E, 0x33, 0x58, 0xB0, 0x35, 0xA1, 0xF2, 0x27, 0x4A, 0x43, 0xBE }, }, { - { 0x4B, 0xB1, 0x83, 0xDE, 0xB1, 0x16, 0xAC, 0x82, 0xAD, 0xC2, 0xC1, 0x0F, 0x61, 0x4C, 0x13, 0x11, - 0xBF, 0xE9, 0xAA, 0xAB, 0x0D, 0x34, 0x87, 0x00, 0xC4, 0xD2, 0xD3, 0x52, 0xFD, 0xBA, 0x67, 0x7E }, + { 0x72, 0xE7, 0x49, 0x87, 0x21, 0x0C, 0x7E, 0xF6, 0x67, 0x46, 0xE4, 0x9A, 0x96, 0xDF, 0x55, 0xCC, + 0x6F, 0xAD, 0xF7, 0xA6, 0x31, 0xC7, 0xAE, 0x3F, 0x3E, 0x9E, 0x18, 0x72, 0x3D, 0xE5, 0x2A, 0x6E }, }, { - { 0x4C, 0x08, 0x8A, 0x68, 0x93, 0x6D, 0x5F, 0x6F, 0x12, 0xCB, 0x4A, 0x8F, 0x97, 0xA8, 0xF4, 0xAB, - 0x94, 0x96, 0x4C, 0xF6, 0xFB, 0x27, 0x6F, 0x0A, 0x9D, 0x78, 0x9E, 0xA6, 0x73, 0xB2, 0x7E, 0x04 }, + { 0x73, 0x3B, 0x42, 0x24, 0x25, 0x8D, 0xEE, 0x07, 0x0E, 0xDF, 0xA3, 0x41, 0x1F, 0xBC, 0x9B, 0xAD, + 0x31, 0x65, 0xBE, 0x66, 0x0F, 0x34, 0x0A, 0xA2, 0x30, 0x8A, 0x5A, 0x33, 0x23, 0xFA, 0xBF, 0xA7 }, }, { - { 0x4C, 0x33, 0x6E, 0x46, 0x9E, 0x9C, 0x01, 0xC3, 0x84, 0xAB, 0x9A, 0xA2, 0x2E, 0x9E, 0x3F, 0x36, - 0xF1, 0xE5, 0x9C, 0xFE, 0x05, 0x0F, 0x66, 0xEC, 0x07, 0xD0, 0xFD, 0x02, 0x30, 0xCC, 0xF4, 0x23 }, + { 0x76, 0x98, 0x67, 0x60, 0xAC, 0xFE, 0x55, 0x59, 0xA2, 0xA2, 0xAB, 0x2A, 0x4E, 0x85, 0x49, 0x83, + 0xC5, 0xFD, 0xE6, 0x73, 0xCE, 0x8E, 0xB1, 0x71, 0x23, 0x49, 0x48, 0x64, 0x86, 0x7A, 0x98, 0xB1 }, }, { - { 0x4C, 0x3A, 0x76, 0xD1, 0x2C, 0x70, 0x0C, 0x25, 0x1B, 0x02, 0x04, 0xBA, 0x9F, 0x27, 0xC0, 0xDA, - 0xCB, 0x2E, 0x47, 0x37, 0x72, 0x64, 0xCD, 0x31, 0xC4, 0xFE, 0xA4, 0xA4, 0x58, 0x5A, 0x99, 0x60 }, + { 0x77, 0xDD, 0xC8, 0x1B, 0xD2, 0x8B, 0x9D, 0x46, 0x1E, 0x7D, 0x3C, 0xD4, 0xA8, 0x12, 0x2A, 0xA9, + 0x8A, 0x24, 0x60, 0xFB, 0xA0, 0x8F, 0x1B, 0x7B, 0xAC, 0xB6, 0x6C, 0x92, 0xD7, 0x99, 0x1C, 0xCC }, }, { - { 0x4C, 0x3C, 0x7C, 0xBC, 0x42, 0x1C, 0xE0, 0xD1, 0x84, 0x4E, 0xA7, 0xB4, 0x6F, 0x61, 0xD7, 0x87, - 0xE0, 0x4F, 0x94, 0x01, 0x71, 0x49, 0xBE, 0xA3, 0x28, 0xED, 0xC3, 0x6C, 0x20, 0xE3, 0x2F, 0xAA }, + { 0x78, 0x0C, 0x33, 0xFE, 0x95, 0x4C, 0xC4, 0xDB, 0x39, 0x04, 0xD7, 0x6A, 0x68, 0x58, 0xBC, 0xD1, + 0x01, 0x7F, 0x52, 0xDA, 0x59, 0x9D, 0x36, 0xDA, 0xE6, 0x66, 0xC0, 0x4E, 0x41, 0xAF, 0x8D, 0xCD }, }, { - { 0x4C, 0x4B, 0xB6, 0x05, 0x65, 0xB5, 0xCA, 0x7F, 0x02, 0xF8, 0xF5, 0x9B, 0xFA, 0x1D, 0x1D, 0x62, - 0x71, 0xB2, 0xF1, 0x4D, 0x5C, 0xD3, 0xA0, 0x43, 0x51, 0xC3, 0xC4, 0x9D, 0x3F, 0xA0, 0x43, 0xB4 }, + { 0x78, 0xC9, 0x30, 0x40, 0x5A, 0x72, 0x0D, 0x9F, 0x00, 0x66, 0xDD, 0x88, 0xA2, 0xA8, 0xDA, 0xFB, + 0xBE, 0x6C, 0xD6, 0x5D, 0x54, 0xB7, 0x76, 0x06, 0x42, 0x1B, 0x45, 0x43, 0x8C, 0x65, 0x8A, 0xD4 }, }, { - { 0x4C, 0x8A, 0x29, 0xB5, 0x81, 0x7D, 0x90, 0x99, 0xA4, 0xFE, 0xD1, 0xE7, 0x93, 0xB2, 0x8E, 0x2F, - 0xAF, 0x6E, 0x87, 0x14, 0xEE, 0x77, 0x60, 0xA7, 0xD5, 0x3E, 0x31, 0x15, 0x2C, 0x18, 0xAC, 0xC2 }, + { 0x79, 0x8F, 0x83, 0xB1, 0xC4, 0xC6, 0x5C, 0x4D, 0x5D, 0xEA, 0x13, 0x03, 0x53, 0x53, 0xD8, 0xED, + 0xE5, 0xD7, 0x1D, 0x99, 0x47, 0xF4, 0x34, 0xFD, 0xEA, 0x0D, 0xBC, 0x1E, 0xC8, 0x2F, 0x45, 0x35 }, }, { - { 0x4C, 0xBA, 0x10, 0x70, 0x0C, 0x5F, 0xA6, 0xE0, 0x4F, 0x2E, 0xDF, 0xE5, 0x40, 0x2A, 0xDD, 0x82, - 0xBD, 0x8E, 0xAF, 0xAB, 0x38, 0x44, 0x71, 0x11, 0xBE, 0x62, 0x63, 0x7D, 0x64, 0x9F, 0xE3, 0xC6 }, + { 0x79, 0xA8, 0xFC, 0x72, 0x70, 0xB2, 0xE5, 0xF3, 0x35, 0x6B, 0x09, 0xC6, 0xB8, 0x64, 0xFC, 0x92, + 0xE5, 0xFB, 0xC9, 0xE6, 0x9B, 0xEC, 0x93, 0xA4, 0xE3, 0x3B, 0x8D, 0xF5, 0x75, 0x60, 0x17, 0xBE }, }, { - { 0x4C, 0xD0, 0xD6, 0x7E, 0xCC, 0x3B, 0x01, 0xC8, 0xC2, 0x63, 0x4E, 0x7A, 0x73, 0x76, 0x12, 0xF6, - 0x3A, 0x17, 0xFF, 0x51, 0x0A, 0x77, 0xA8, 0x04, 0xBB, 0x33, 0x1B, 0x2B, 0xE5, 0x8D, 0xFE, 0x0C }, + { 0x7B, 0xFE, 0x47, 0xAE, 0xBA, 0x8B, 0x0A, 0x3A, 0x94, 0x5A, 0x88, 0xD8, 0xEF, 0x18, 0x91, 0xC9, + 0x89, 0x97, 0x8A, 0xBF, 0x12, 0x2E, 0xC5, 0xE0, 0x51, 0x4B, 0xE3, 0x6C, 0x3A, 0x7F, 0x22, 0x9B }, }, { - { 0x4C, 0xD6, 0xDC, 0xC0, 0x71, 0xC6, 0x81, 0x56, 0x6F, 0x1F, 0xB5, 0x46, 0x95, 0x12, 0x67, 0xE3, - 0x2A, 0x36, 0x9D, 0x64, 0xAD, 0x95, 0x1A, 0xB4, 0xCA, 0x83, 0x36, 0xF6, 0xEE, 0x86, 0xC6, 0x08 }, + { 0x7D, 0x20, 0xC7, 0xA9, 0x27, 0x26, 0x2B, 0xE7, 0x38, 0xD2, 0x58, 0xD0, 0xFD, 0x97, 0x6E, 0x9A, + 0xF3, 0x6E, 0xF7, 0x99, 0x5F, 0x05, 0xE2, 0x87, 0x6A, 0x29, 0xAE, 0xBC, 0x3A, 0x24, 0xAA, 0xCE }, }, { - { 0x4C, 0xD8, 0x6A, 0xA6, 0x0C, 0xB3, 0x69, 0x00, 0xA9, 0xAA, 0x3B, 0x7B, 0x02, 0x7D, 0x71, 0x4C, - 0x0F, 0x76, 0x07, 0xC3, 0x56, 0x73, 0x3B, 0xA2, 0x21, 0xAA, 0xE4, 0x09, 0x47, 0xF7, 0xFA, 0xCB }, + { 0x7E, 0x2E, 0xDB, 0x9D, 0x38, 0xF9, 0x29, 0x3C, 0xDD, 0xD6, 0x03, 0xB1, 0x75, 0xC9, 0xB2, 0x05, + 0xAC, 0x0B, 0x55, 0x3A, 0x4B, 0xF5, 0xFB, 0x08, 0xC2, 0x46, 0xEC, 0xF9, 0xC8, 0x49, 0xDB, 0x28 }, }, { - { 0x4D, 0x25, 0x2E, 0x6E, 0x1A, 0x15, 0x9A, 0xC2, 0x22, 0xB3, 0x2E, 0x9D, 0xD0, 0x31, 0x56, 0x7B, - 0x69, 0x31, 0x4B, 0xE8, 0xE8, 0x21, 0x1C, 0x1F, 0xB3, 0xC8, 0xB5, 0x3C, 0x26, 0x0A, 0x74, 0xE5 }, + { 0x7F, 0x95, 0x9B, 0x06, 0x34, 0xDA, 0x94, 0xFA, 0xCA, 0xDA, 0xB0, 0x21, 0xCF, 0x94, 0x20, 0x78, + 0x16, 0x00, 0x36, 0x13, 0xEF, 0x09, 0xEB, 0x54, 0xF6, 0x48, 0x60, 0x50, 0x08, 0x19, 0x02, 0x75 }, }, { - { 0x4D, 0x54, 0x4D, 0x4E, 0x41, 0xC0, 0xFB, 0x15, 0x5F, 0x04, 0x7D, 0x7F, 0xB1, 0xEF, 0x29, 0xD1, - 0x1B, 0xDF, 0xEC, 0xA9, 0xD4, 0x11, 0xAF, 0x8B, 0x12, 0x54, 0x1F, 0x11, 0x50, 0xC0, 0xB4, 0x44 }, + { 0x7F, 0x9A, 0x69, 0xCF, 0xA2, 0xF5, 0x0C, 0x13, 0xE1, 0xB7, 0x11, 0xDD, 0x6B, 0x14, 0x69, 0x2B, + 0xDB, 0x77, 0xD9, 0xFF, 0xD8, 0xC1, 0x10, 0xAE, 0x5D, 0x05, 0xA4, 0xCB, 0x73, 0x12, 0x37, 0x48 }, }, { - { 0x4D, 0xCF, 0xEB, 0xDC, 0x15, 0x4B, 0x0C, 0x85, 0x46, 0x7F, 0x6F, 0x52, 0xAD, 0x80, 0x4E, 0x19, - 0x1D, 0x5B, 0xC8, 0x13, 0x51, 0x72, 0x0E, 0xC0, 0xD1, 0x9B, 0xD2, 0x5B, 0xF8, 0xF0, 0xA5, 0x53 }, + { 0x80, 0x20, 0x56, 0xE1, 0xDB, 0x9D, 0x9B, 0x73, 0x21, 0xD1, 0xFF, 0xBB, 0xE1, 0x2F, 0x5C, 0xBE, + 0xDE, 0xC3, 0x6D, 0x0B, 0x5E, 0xC2, 0xA4, 0xE1, 0x8D, 0x99, 0x54, 0x36, 0x4C, 0xEC, 0x81, 0x29 }, }, { - { 0x4D, 0xE2, 0x4B, 0x7F, 0xE2, 0x6D, 0x50, 0x6E, 0x76, 0xAC, 0x3A, 0xCB, 0x32, 0x53, 0x3D, 0x50, - 0x1B, 0xC1, 0x6A, 0x2D, 0x50, 0xB5, 0x6D, 0x65, 0x96, 0xB3, 0x0B, 0x21, 0xB0, 0x1E, 0x4D, 0x09 }, + { 0x80, 0x97, 0x63, 0x4C, 0xE3, 0x3D, 0x41, 0x53, 0x3D, 0x41, 0x5D, 0xAF, 0xDB, 0x8B, 0xA1, 0x91, + 0xC0, 0x30, 0x52, 0xAC, 0x8B, 0xAA, 0x25, 0x54, 0x34, 0x77, 0x3A, 0x16, 0x4B, 0x91, 0x1D, 0x6E }, }, { - { 0x4D, 0xE5, 0xA5, 0xDE, 0x12, 0x4E, 0x27, 0x69, 0x81, 0x79, 0x67, 0x53, 0xDD, 0x20, 0x20, 0xB1, - 0x10, 0x54, 0x09, 0x32, 0xF7, 0x4F, 0x97, 0x41, 0xD9, 0x6C, 0x1D, 0xB9, 0x50, 0x5D, 0x5F, 0xF1 }, + { 0x80, 0xD0, 0x17, 0x09, 0x34, 0xD2, 0x2A, 0xEA, 0x73, 0x3F, 0x11, 0x5E, 0x52, 0x42, 0xC6, 0xB8, + 0x6D, 0x7F, 0xCF, 0xB4, 0x90, 0x4E, 0x65, 0xB7, 0xB7, 0xB9, 0x07, 0xF2, 0xCA, 0x94, 0xED, 0x71 }, }, { - { 0x4E, 0x33, 0x78, 0xEC, 0x23, 0x7C, 0x01, 0xA3, 0xCD, 0x85, 0x9E, 0x1D, 0xC9, 0x29, 0xD6, 0xA6, - 0xEF, 0xB6, 0x36, 0x7A, 0x72, 0x58, 0x41, 0xCF, 0x54, 0x13, 0x25, 0xC0, 0x61, 0xF8, 0xBF, 0xD4 }, + { 0x81, 0x1D, 0xF2, 0xF4, 0x73, 0x6F, 0x85, 0x62, 0xE2, 0x02, 0xFD, 0x00, 0x75, 0x32, 0xF1, 0xDE, + 0x40, 0x17, 0x86, 0x1E, 0xFA, 0xBE, 0x67, 0x34, 0x20, 0xC2, 0x7F, 0x2E, 0x2A, 0x33, 0xFA, 0xC1 }, }, { - { 0x4E, 0x48, 0xC1, 0x6C, 0x9D, 0x0D, 0xE5, 0xDD, 0x8C, 0x9C, 0x36, 0x37, 0x35, 0xDD, 0xFB, 0xC3, - 0xDB, 0xD2, 0x6E, 0xA0, 0xAE, 0xCD, 0xE1, 0xC7, 0x62, 0xBB, 0x56, 0xBB, 0x3F, 0xE4, 0xFA, 0x74 }, + { 0x81, 0x1E, 0x37, 0x86, 0x37, 0xB1, 0xD2, 0xCB, 0xB1, 0x89, 0xAF, 0xD6, 0x74, 0x95, 0xFE, 0x8A, + 0xB9, 0xD8, 0x3A, 0x74, 0x2E, 0x35, 0x8C, 0xBB, 0xDB, 0xD1, 0x54, 0x98, 0xBF, 0x9C, 0x7B, 0x56 }, }, { - { 0x4E, 0x56, 0x28, 0x87, 0x76, 0x0B, 0xA6, 0xC0, 0x2C, 0x8B, 0x1D, 0x54, 0xC6, 0x05, 0xD2, 0x67, - 0x5A, 0xC9, 0x9B, 0x13, 0x24, 0x52, 0xDE, 0x6F, 0xE9, 0x6B, 0xAE, 0x54, 0x75, 0x5E, 0xD8, 0x90 }, + { 0x81, 0xA0, 0xF1, 0xD0, 0x29, 0x46, 0x8E, 0xE8, 0x66, 0x36, 0x4A, 0x19, 0x8A, 0x26, 0x08, 0x58, + 0x30, 0xC2, 0xA4, 0x16, 0xE4, 0x9E, 0x22, 0x4C, 0xE8, 0x09, 0x66, 0xFC, 0xC4, 0x99, 0xD6, 0x36 }, }, { - { 0x4E, 0x59, 0x82, 0xAC, 0x8E, 0xB9, 0x51, 0x12, 0x2D, 0x08, 0x77, 0xBB, 0xED, 0x12, 0x8C, 0x14, - 0xC3, 0x30, 0xE4, 0xFE, 0x98, 0xB9, 0x20, 0x04, 0x91, 0x58, 0x75, 0x10, 0x38, 0x26, 0xDE, 0x30 }, + { 0x82, 0x56, 0x8B, 0x3B, 0xB3, 0xC6, 0x55, 0xD7, 0xF2, 0x2D, 0x8C, 0x97, 0xA5, 0x66, 0x9C, 0xC8, + 0x34, 0xA2, 0xDD, 0x7C, 0xDA, 0xE7, 0x5A, 0x26, 0x45, 0x59, 0x55, 0x16, 0x46, 0x55, 0x8E, 0x14 }, }, { - { 0x4E, 0x6F, 0xB7, 0x05, 0x5D, 0xA4, 0x37, 0xEB, 0x46, 0x8D, 0x77, 0x94, 0x59, 0x96, 0xBE, 0x17, - 0x7E, 0x97, 0xDD, 0xA8, 0x9E, 0xF9, 0xA4, 0xB0, 0x61, 0x17, 0xB4, 0xE9, 0x75, 0xE1, 0xC5, 0x50 }, + { 0x82, 0x7C, 0x8C, 0x80, 0x11, 0x1F, 0xF2, 0x21, 0xC3, 0xEB, 0x1E, 0xF5, 0xC0, 0xD5, 0xD4, 0x34, + 0x48, 0x31, 0x86, 0xE2, 0x09, 0x00, 0x75, 0x63, 0x15, 0x8E, 0x9E, 0x76, 0xD2, 0x79, 0x0F, 0x1C }, }, { - { 0x4E, 0xF1, 0x31, 0x9C, 0x31, 0x26, 0xF0, 0x22, 0xAD, 0x27, 0xE5, 0xC4, 0x1A, 0x6C, 0x03, 0xFE, - 0x93, 0x05, 0x70, 0x7B, 0xF2, 0x02, 0x9A, 0xF3, 0x7F, 0x9F, 0x89, 0xE0, 0xF2, 0x5A, 0x93, 0x1C }, + { 0x82, 0x92, 0x67, 0xC5, 0xAD, 0x70, 0xE5, 0x45, 0x18, 0x02, 0x3A, 0xB7, 0x85, 0xFA, 0x3C, 0xDE, + 0xD6, 0x6F, 0x42, 0x5D, 0xE1, 0xF3, 0x2F, 0xCD, 0x72, 0x1B, 0x49, 0x46, 0x3A, 0x5A, 0x5F, 0x5B }, }, { - { 0x4F, 0x19, 0xDD, 0x12, 0x92, 0x4C, 0xE0, 0xC1, 0x4F, 0x82, 0xC0, 0x56, 0xC7, 0xD4, 0x2B, 0xAC, - 0x43, 0xD0, 0x13, 0x3A, 0xAF, 0x89, 0xC1, 0xEF, 0xDC, 0xFA, 0x3C, 0x3E, 0x47, 0x09, 0x7D, 0x59 }, + { 0x83, 0x34, 0xEA, 0xB8, 0x1C, 0x60, 0x4E, 0x99, 0xD5, 0x40, 0x51, 0x3E, 0xF2, 0xE3, 0x7A, 0xBA, + 0x71, 0x4F, 0x07, 0xB2, 0xBA, 0x01, 0x0A, 0xD7, 0x1D, 0xC4, 0xE1, 0x1A, 0x92, 0x18, 0xC1, 0x8C }, }, { - { 0x4F, 0x23, 0xC6, 0x87, 0x0C, 0x7C, 0xFA, 0x6D, 0x31, 0x92, 0x70, 0x3D, 0xCA, 0xFD, 0x8F, 0x46, - 0xB7, 0xBC, 0xC3, 0x72, 0xDC, 0x6D, 0x1C, 0x61, 0x00, 0x9A, 0x01, 0x75, 0x20, 0xE9, 0xF3, 0xDF }, + { 0x83, 0x54, 0x7A, 0xCA, 0x3C, 0xED, 0x73, 0xDF, 0x99, 0x14, 0xF3, 0x15, 0x60, 0x74, 0x63, 0x79, + 0x29, 0x4C, 0x76, 0x0E, 0xF9, 0xA8, 0xB7, 0x6E, 0x00, 0x06, 0x46, 0xC7, 0x39, 0x07, 0x21, 0x65 }, }, { - { 0x4F, 0x54, 0x31, 0xA9, 0xA1, 0x5E, 0x08, 0x9B, 0x70, 0x53, 0xB6, 0x61, 0x47, 0xE2, 0xB6, 0x23, - 0xD5, 0x87, 0x6F, 0x9A, 0x04, 0x56, 0x44, 0x67, 0xAE, 0x16, 0x13, 0xF6, 0xA8, 0x15, 0x98, 0x38 }, + { 0x83, 0x89, 0xC8, 0x79, 0xB6, 0x3B, 0x82, 0x9D, 0x2D, 0x39, 0xA8, 0xCF, 0xB7, 0x87, 0xE7, 0x72, + 0x77, 0xD5, 0xCF, 0xA3, 0xE3, 0x6F, 0xDA, 0xCB, 0xAB, 0x4D, 0x18, 0xB2, 0xB0, 0x4E, 0x32, 0x94 }, }, { - { 0x4F, 0x79, 0xC7, 0x9D, 0x52, 0x62, 0x28, 0xB1, 0x0C, 0x70, 0xD3, 0xD7, 0x2A, 0xAA, 0x71, 0x87, - 0xB7, 0x2C, 0x7E, 0xCD, 0x48, 0xF9, 0x16, 0x95, 0xCA, 0x41, 0xA3, 0x6C, 0x55, 0x5C, 0x6C, 0x43 }, + { 0x84, 0x23, 0xB3, 0xF1, 0xCC, 0x85, 0x2B, 0x49, 0xCF, 0x81, 0xB7, 0xD5, 0xFF, 0x51, 0xA7, 0xA5, + 0x6A, 0x84, 0x78, 0x3A, 0x2D, 0xF7, 0x43, 0x61, 0xFF, 0x2E, 0xEE, 0x0F, 0x92, 0x12, 0xC1, 0x59 }, }, { - { 0x4F, 0x9A, 0xCC, 0x0B, 0x75, 0xCE, 0xAA, 0x7C, 0xB3, 0x88, 0x47, 0x09, 0x52, 0xC9, 0x98, 0x08, - 0xE4, 0xF3, 0xCB, 0x99, 0xA7, 0x73, 0xA6, 0x00, 0xCD, 0xDF, 0x2C, 0xF3, 0x1A, 0xE7, 0xEC, 0x72 }, + { 0x84, 0x7B, 0x5F, 0x1E, 0xEB, 0x2A, 0x44, 0x13, 0xC8, 0xFA, 0x37, 0x98, 0x21, 0x97, 0x37, 0xE1, + 0x92, 0xBA, 0x72, 0x72, 0xA1, 0x08, 0xB7, 0x17, 0x28, 0xA8, 0xD1, 0x65, 0x17, 0xF6, 0x1E, 0x9D }, }, { - { 0x4F, 0xAF, 0xAE, 0xBC, 0x7E, 0x20, 0x21, 0xC8, 0x43, 0x86, 0xEC, 0x9D, 0x82, 0xA4, 0x9C, 0x24, - 0xDB, 0xEF, 0xEB, 0x71, 0x2E, 0xA7, 0x2C, 0x0D, 0x64, 0x73, 0x51, 0x86, 0x13, 0x53, 0xCD, 0x69 }, + { 0x85, 0x31, 0xB2, 0xBF, 0xC5, 0x45, 0x79, 0xE8, 0xF1, 0x8F, 0x27, 0xB2, 0xE6, 0xEC, 0xC0, 0xF8, + 0x90, 0x64, 0xEE, 0x86, 0x87, 0x0E, 0xCC, 0x8B, 0xBE, 0x0C, 0xE6, 0x86, 0xEC, 0xDA, 0x2C, 0x17 }, }, { - { 0x4F, 0xE9, 0xF1, 0x68, 0x70, 0x6A, 0x07, 0x5D, 0xA9, 0x6C, 0x71, 0x3D, 0xA4, 0x32, 0x61, 0xE3, - 0x39, 0xA9, 0x93, 0x6E, 0xDD, 0xD5, 0x88, 0x8B, 0xD6, 0x35, 0x00, 0xCA, 0xA6, 0xEF, 0xBF, 0xA8 }, + { 0x85, 0x76, 0x0F, 0x59, 0x51, 0x90, 0xE9, 0xB4, 0x67, 0x8B, 0xBF, 0x44, 0xEF, 0xB5, 0xCF, 0x8F, + 0x6B, 0x19, 0x37, 0xA9, 0xB8, 0x6B, 0x31, 0xB7, 0x51, 0xBE, 0xCF, 0x72, 0x18, 0x03, 0xB0, 0x1C }, }, { - { 0x4F, 0xFB, 0x59, 0x19, 0xBC, 0x38, 0x5C, 0x8C, 0x58, 0xE4, 0x62, 0xBF, 0x13, 0x22, 0x10, 0xD8, - 0xB7, 0x86, 0x12, 0xD0, 0xC2, 0x2A, 0x6B, 0x6A, 0x68, 0x2E, 0x0B, 0x9E, 0x9C, 0x9F, 0x9A, 0x44 }, + { 0x85, 0xF0, 0x79, 0x36, 0xB4, 0x29, 0x1F, 0x36, 0xD9, 0xB7, 0x5F, 0x42, 0xE8, 0xB7, 0xEE, 0x8A, + 0x64, 0xE6, 0x32, 0xA1, 0x18, 0x11, 0x65, 0xFE, 0x72, 0xB4, 0x88, 0x23, 0xC3, 0xD9, 0x9D, 0x9D }, }, { - { 0x50, 0x15, 0xB9, 0xC9, 0x92, 0xC8, 0x87, 0xC2, 0x4C, 0x99, 0x15, 0x38, 0xDD, 0xD5, 0x1D, 0x01, - 0x49, 0xCD, 0x9F, 0xF3, 0x60, 0x49, 0xF3, 0xD8, 0xA0, 0xB2, 0xD2, 0x92, 0x23, 0xF7, 0x91, 0x38 }, + { 0x86, 0x12, 0x9F, 0xE7, 0x61, 0x99, 0x4D, 0x7B, 0x64, 0xE4, 0x02, 0x85, 0x8F, 0x88, 0xC5, 0x2B, + 0x3E, 0xB9, 0xC0, 0x71, 0xFF, 0xBE, 0x80, 0x02, 0x80, 0xAC, 0x8C, 0x0C, 0x6F, 0x79, 0xE7, 0xA6 }, }, { - { 0x50, 0x30, 0x55, 0x80, 0x8F, 0x4C, 0x49, 0xCF, 0xFC, 0xDE, 0x02, 0x27, 0x3C, 0x13, 0x16, 0x38, - 0xF4, 0x3D, 0x38, 0x56, 0x13, 0xE0, 0x73, 0x3D, 0xB4, 0x5F, 0xBD, 0x2A, 0x29, 0x11, 0xD6, 0xE4 }, + { 0x86, 0x19, 0x6B, 0x0F, 0xD3, 0x0F, 0x8F, 0x57, 0x56, 0x98, 0xB5, 0xEE, 0xF2, 0x69, 0xD0, 0x69, + 0x2F, 0x88, 0xAD, 0xEA, 0xC4, 0x83, 0x6A, 0x62, 0x67, 0xAB, 0xC8, 0x36, 0x23, 0x34, 0x00, 0x86 }, }, { - { 0x50, 0x3C, 0x0A, 0xE6, 0x83, 0x4E, 0x46, 0xCA, 0xED, 0x49, 0x7C, 0x43, 0x73, 0x3F, 0x39, 0x7E, - 0x04, 0xD3, 0x06, 0xD5, 0xF8, 0x10, 0x11, 0xD2, 0x0E, 0x5A, 0x03, 0xC5, 0x6B, 0x89, 0xDA, 0x15 }, + { 0x86, 0xD1, 0x8B, 0xCD, 0xDE, 0x16, 0x45, 0x42, 0x48, 0x6E, 0x56, 0x44, 0x2C, 0xE1, 0xB8, 0x8B, + 0x1A, 0x10, 0x73, 0x7C, 0xBD, 0x5E, 0xA4, 0xAA, 0xB8, 0xD5, 0xB8, 0xAF, 0x51, 0xF5, 0x29, 0x09 }, }, { - { 0x50, 0x81, 0x1D, 0x6E, 0x9D, 0xAF, 0x31, 0x2A, 0x6A, 0xC2, 0xAF, 0x6B, 0x52, 0x13, 0xC9, 0x56, - 0x20, 0xE0, 0x24, 0xE0, 0x87, 0xAE, 0x5E, 0xB0, 0xCC, 0x8A, 0xA2, 0x6F, 0xBE, 0xD9, 0xD9, 0x85 }, + { 0x88, 0x8D, 0x6D, 0x77, 0xD8, 0x1C, 0x62, 0x91, 0xCB, 0x84, 0xD9, 0xD6, 0x56, 0x27, 0x82, 0xFD, + 0x2E, 0xB3, 0x42, 0x5D, 0x49, 0x1E, 0x68, 0x74, 0x20, 0x28, 0x4B, 0x76, 0xA1, 0xDE, 0xBF, 0xAB }, }, { - { 0x50, 0xF4, 0x78, 0x1E, 0xB1, 0xC1, 0x46, 0x70, 0xD9, 0xA5, 0x52, 0xC3, 0x49, 0x5F, 0xB9, 0xF6, - 0xAE, 0x86, 0x8A, 0xB1, 0xC9, 0xD9, 0x83, 0xE0, 0x82, 0x68, 0x65, 0xA1, 0x02, 0xEC, 0xA6, 0xD3 }, + { 0x89, 0xAF, 0x0E, 0x54, 0xC7, 0x62, 0x77, 0x86, 0x93, 0x52, 0x9D, 0x0A, 0x95, 0x0B, 0x78, 0x33, + 0xF5, 0xEA, 0xBA, 0xF3, 0x42, 0x79, 0x72, 0x60, 0x7F, 0xB2, 0xC7, 0x0C, 0x96, 0xA3, 0x21, 0x61 }, }, { - { 0x51, 0x19, 0xB5, 0x19, 0x01, 0x56, 0xDD, 0x6D, 0x6B, 0x34, 0x16, 0x60, 0xF8, 0xA3, 0xC6, 0x25, - 0x0A, 0xC5, 0x2D, 0x82, 0xBD, 0x26, 0xC3, 0x30, 0x7E, 0x28, 0xB4, 0x03, 0xD3, 0x84, 0x94, 0x9F }, + { 0x89, 0xDA, 0xC7, 0x89, 0x6B, 0x46, 0xF2, 0xFC, 0x8B, 0xEA, 0x62, 0x11, 0xFF, 0x98, 0xB6, 0x1F, + 0xAA, 0x15, 0x7B, 0xA8, 0xC4, 0xAD, 0x6F, 0xD1, 0x75, 0x92, 0x75, 0xCE, 0x39, 0x41, 0xC3, 0x28 }, }, { - { 0x51, 0x3E, 0x76, 0xB7, 0xBF, 0xB0, 0xF4, 0xEE, 0x3F, 0x09, 0x94, 0xC9, 0x56, 0xB9, 0xCD, 0x4F, - 0xFF, 0x03, 0xFA, 0x14, 0x38, 0x68, 0xCF, 0x3C, 0x59, 0x9B, 0x7C, 0x33, 0xCC, 0x41, 0xA2, 0xF4 }, + { 0x8A, 0x09, 0x85, 0xBF, 0x86, 0xE8, 0xC9, 0xB9, 0x17, 0xEC, 0x84, 0xDA, 0x2A, 0x56, 0x73, 0x1E, + 0x75, 0x2A, 0xA0, 0xDC, 0x52, 0x87, 0xC2, 0xBF, 0x39, 0x51, 0x0B, 0xB3, 0xF0, 0xF2, 0x0A, 0xD1 }, }, { - { 0x51, 0x45, 0x0F, 0x2B, 0x44, 0x5C, 0x6D, 0xED, 0x83, 0x9C, 0xD9, 0x97, 0x86, 0xD4, 0x03, 0x01, - 0x1C, 0x2D, 0xBE, 0xDC, 0x72, 0x96, 0xDB, 0xC8, 0x55, 0x44, 0xAC, 0x1B, 0x71, 0xDA, 0x4A, 0x95 }, + { 0x8A, 0xAF, 0x36, 0x3C, 0xC9, 0xD8, 0x44, 0x15, 0xA7, 0xEB, 0x0D, 0x72, 0xDA, 0x08, 0xB3, 0x58, + 0x80, 0x68, 0x55, 0x9C, 0xB0, 0xA9, 0xAE, 0x92, 0xB8, 0xF4, 0x60, 0x2E, 0xDA, 0x23, 0x82, 0xAA }, }, { - { 0x51, 0x6A, 0x2F, 0x33, 0x60, 0xC7, 0x6F, 0xC4, 0x6A, 0xB2, 0x88, 0x7F, 0x88, 0xE8, 0xD0, 0x8E, - 0xFB, 0xD8, 0x44, 0x5A, 0xA7, 0xBB, 0xD2, 0x29, 0xDF, 0xC7, 0x1A, 0x90, 0x4F, 0x55, 0xAE, 0xB4 }, + { 0x8A, 0xB2, 0x77, 0x62, 0xF4, 0xA2, 0xE3, 0x11, 0x22, 0x04, 0x96, 0x98, 0x39, 0x99, 0xC8, 0xC4, + 0x60, 0x96, 0x3D, 0xFC, 0x1B, 0x88, 0x51, 0x11, 0x1D, 0xA4, 0x1D, 0x3F, 0x3B, 0x0A, 0x6E, 0x94 }, }, { - { 0x51, 0xC5, 0x2A, 0x80, 0xBC, 0x2E, 0x24, 0xFB, 0x47, 0x1F, 0xE4, 0x5E, 0x78, 0xCF, 0x01, 0x84, - 0xE0, 0xC4, 0x67, 0x0E, 0x20, 0xE6, 0xCA, 0xDA, 0x20, 0xBD, 0xF9, 0x6E, 0x2D, 0x71, 0x20, 0xF7 }, + { 0x8A, 0xD1, 0xD5, 0x48, 0x95, 0x27, 0xB5, 0x28, 0xE5, 0xB5, 0xD6, 0xA5, 0x95, 0x78, 0x87, 0x08, + 0x88, 0x8A, 0x3F, 0xB1, 0x9F, 0x2C, 0x7C, 0x8B, 0x38, 0x07, 0x0E, 0x1F, 0x38, 0x98, 0x96, 0x8B }, }, { - { 0x52, 0x1F, 0x6C, 0x6A, 0x84, 0x36, 0x65, 0x79, 0xCA, 0x2D, 0xEA, 0xEB, 0x23, 0x15, 0xBF, 0x8E, - 0x53, 0x1C, 0x9F, 0xA4, 0x7B, 0x89, 0x9D, 0xA2, 0x72, 0x16, 0xA9, 0x98, 0x82, 0x86, 0xAF, 0xE5 }, + { 0x8A, 0xDB, 0x49, 0xD4, 0x15, 0x53, 0x56, 0x70, 0x5B, 0x64, 0x42, 0x6A, 0x99, 0x0F, 0x58, 0xB3, + 0xA0, 0x71, 0xEF, 0x78, 0x2E, 0x6C, 0x09, 0x53, 0x07, 0xD7, 0x74, 0x74, 0xD5, 0xB5, 0x7A, 0x62 }, }, { - { 0x52, 0x75, 0xC2, 0x38, 0x02, 0x7B, 0x22, 0xAA, 0x51, 0x9B, 0x36, 0xA8, 0x03, 0xAF, 0xF5, 0x6E, - 0xBB, 0x4E, 0x1A, 0x6C, 0x56, 0x9A, 0x81, 0xEA, 0xDE, 0xD5, 0x86, 0x35, 0xA7, 0x7B, 0x15, 0x80 }, + { 0x8B, 0x3A, 0x10, 0x35, 0xC3, 0xFD, 0xF3, 0x45, 0xFB, 0x70, 0x80, 0x44, 0x83, 0xA5, 0x04, 0x49, + 0xA3, 0xD7, 0x60, 0xC6, 0xBA, 0x48, 0xF5, 0xB8, 0x2D, 0x6B, 0xB2, 0x62, 0xED, 0x9D, 0xE3, 0x73 }, }, { - { 0x52, 0xE4, 0x38, 0x85, 0x10, 0x91, 0xB9, 0x8C, 0x01, 0xFE, 0x1A, 0x5E, 0xC5, 0x4F, 0xA9, 0x8A, - 0xA0, 0x64, 0xAB, 0xA6, 0xE1, 0xB3, 0x3D, 0xD9, 0x83, 0xC4, 0x15, 0x15, 0x28, 0x96, 0xF0, 0xB8 }, + { 0x8B, 0x3A, 0x75, 0xCB, 0xC3, 0x62, 0xD2, 0x35, 0x57, 0x0E, 0x5D, 0xE7, 0x04, 0x29, 0x38, 0x70, + 0x8A, 0x1B, 0x0F, 0xCE, 0xB4, 0x59, 0x86, 0x2A, 0x38, 0x67, 0xB7, 0x34, 0xCD, 0xCB, 0x97, 0x94 }, }, { - { 0x52, 0xFF, 0x8B, 0x6E, 0x98, 0xB0, 0x96, 0x19, 0x90, 0x03, 0xDE, 0x97, 0xBC, 0xCF, 0xD2, 0xA7, - 0xF1, 0xAC, 0x57, 0xA8, 0x31, 0x35, 0xB9, 0x55, 0xFF, 0x68, 0x63, 0x36, 0xA6, 0x91, 0xD5, 0xCA }, + { 0x8C, 0x3E, 0x7C, 0x1D, 0xCC, 0x7D, 0xD8, 0xE7, 0xD8, 0xBF, 0x7B, 0x5B, 0x3A, 0xE5, 0xE0, 0x27, + 0x2E, 0x81, 0x1A, 0xB9, 0xF3, 0xC3, 0xC5, 0x38, 0xE5, 0x74, 0x71, 0x77, 0xE6, 0x2D, 0x62, 0x92 }, }, { - { 0x53, 0x49, 0x98, 0x5A, 0x83, 0x22, 0xC0, 0xA9, 0x54, 0x1F, 0xB6, 0x81, 0x31, 0xC2, 0xA4, 0xF4, - 0x7D, 0x46, 0xC5, 0xBB, 0x3B, 0xAC, 0x23, 0x76, 0x6A, 0x26, 0x55, 0x17, 0x43, 0x71, 0x40, 0xB6 }, + { 0x8C, 0x7C, 0x65, 0x7B, 0xDA, 0x13, 0xCA, 0x62, 0xF2, 0x9A, 0x65, 0xC6, 0xD5, 0x19, 0x3A, 0x93, + 0xCF, 0x6C, 0x58, 0x77, 0x18, 0xAD, 0xCA, 0x67, 0x15, 0x8E, 0x97, 0xD3, 0x6A, 0x62, 0x3E, 0xCA }, }, { - { 0x53, 0x79, 0x64, 0x58, 0xDA, 0x97, 0xCE, 0x36, 0x78, 0xF2, 0xD1, 0xD9, 0xB2, 0xA5, 0xB2, 0xFB, - 0x30, 0x75, 0xEA, 0xFA, 0xF6, 0xFF, 0x04, 0x78, 0xB5, 0x72, 0xDD, 0xFD, 0x70, 0x99, 0xAE, 0xE2 }, + { 0x8C, 0xA6, 0x79, 0x62, 0xC4, 0xA8, 0x09, 0x13, 0x33, 0xF2, 0x4E, 0xFD, 0x60, 0xEE, 0x70, 0xCF, + 0xED, 0xDB, 0xD6, 0x41, 0x59, 0x04, 0x70, 0x9E, 0x78, 0x5C, 0x33, 0x1B, 0x1E, 0xF5, 0x8F, 0x8E }, }, { - { 0x53, 0x96, 0x8B, 0x36, 0x22, 0x80, 0xFE, 0xB7, 0x27, 0x51, 0xF6, 0xED, 0xB9, 0xB2, 0x7C, 0x5F, - 0x50, 0xDD, 0x4C, 0x0E, 0x43, 0x4A, 0x54, 0x09, 0x76, 0xA5, 0xBE, 0xE3, 0x40, 0x3C, 0x92, 0x7E }, + { 0x8E, 0x18, 0xFD, 0xBD, 0xB0, 0x08, 0x16, 0x00, 0x35, 0xFA, 0xF5, 0x01, 0x5B, 0xE7, 0xDA, 0xF4, + 0x63, 0xB5, 0xC4, 0x14, 0xEA, 0xBC, 0x8B, 0x89, 0xF3, 0xDB, 0xA2, 0x05, 0xAB, 0x09, 0xA6, 0x43 }, }, { - { 0x53, 0x96, 0xB9, 0x32, 0x9D, 0xE7, 0xB3, 0x55, 0x2E, 0x18, 0x0D, 0xDD, 0x33, 0x17, 0x63, 0x53, - 0xBA, 0xCD, 0x65, 0x66, 0x18, 0x2B, 0x2B, 0x23, 0x05, 0x71, 0x67, 0x0A, 0xCE, 0xB0, 0xC1, 0x91 }, + { 0x8F, 0x10, 0x10, 0x47, 0x93, 0xE8, 0x55, 0x42, 0xBC, 0x06, 0x04, 0xD6, 0xCF, 0x21, 0x5F, 0x78, + 0x80, 0xBD, 0x6A, 0x4D, 0xD0, 0xFD, 0xF1, 0xE7, 0xA5, 0xB9, 0xCA, 0x12, 0x46, 0xF5, 0xC4, 0x09 }, }, { - { 0x53, 0x9C, 0xA9, 0xE1, 0xF0, 0x6A, 0xF2, 0x10, 0x7F, 0x96, 0xBF, 0x4B, 0x7D, 0xD4, 0xCE, 0xCD, - 0x9E, 0xD1, 0x1A, 0x38, 0xD6, 0x70, 0x91, 0x69, 0x9C, 0x56, 0x26, 0xE2, 0x7A, 0x1F, 0x54, 0xA5 }, + { 0x8F, 0x71, 0x27, 0x76, 0x2E, 0xE7, 0x51, 0x69, 0xBD, 0xC3, 0x5B, 0x04, 0xA7, 0x28, 0xE9, 0xD3, + 0x1B, 0x7E, 0x4D, 0x37, 0x89, 0xAA, 0x2C, 0x46, 0xD8, 0xA3, 0x1B, 0x3D, 0xFA, 0x81, 0xA9, 0x7E }, }, { - { 0x53, 0xAF, 0xBD, 0xDB, 0xFA, 0xC7, 0x4E, 0xBC, 0xA1, 0xBE, 0xF4, 0xBA, 0xCD, 0xEB, 0x45, 0x29, - 0x7C, 0x43, 0xF0, 0xF7, 0x4E, 0x8D, 0x04, 0xBA, 0x81, 0x79, 0xB4, 0xF3, 0x72, 0x41, 0xBE, 0x6C }, + { 0x8F, 0x94, 0x15, 0x92, 0x6F, 0x40, 0x49, 0xEA, 0x41, 0x8A, 0x30, 0x7C, 0x76, 0x36, 0xE4, 0x9B, + 0x14, 0x4F, 0xA5, 0x3E, 0x52, 0xE1, 0x04, 0x15, 0x5F, 0x58, 0x03, 0x5E, 0x45, 0x41, 0xCD, 0x6E }, }, { - { 0x53, 0xB6, 0xE2, 0xAA, 0xA6, 0x2D, 0x18, 0x5A, 0x42, 0x3E, 0x92, 0x9D, 0x8C, 0x75, 0xD7, 0xE3, - 0x2B, 0x37, 0x2F, 0x5D, 0xF0, 0x06, 0x0A, 0x73, 0xBA, 0xFA, 0xC4, 0x9A, 0xA8, 0x51, 0x1E, 0x24 }, + { 0x90, 0xB3, 0xA1, 0x85, 0x36, 0x86, 0xAF, 0xEB, 0x15, 0x4A, 0xEF, 0x7E, 0x84, 0x0D, 0x38, 0x04, + 0x4E, 0x7D, 0x7F, 0x6D, 0xC4, 0xCE, 0x82, 0x8C, 0xE3, 0x97, 0x55, 0xAC, 0x88, 0xE4, 0x2E, 0x07 }, }, { - { 0x53, 0xEB, 0xD5, 0x29, 0x2D, 0x32, 0xCE, 0xA0, 0x08, 0x60, 0x96, 0x78, 0xC4, 0x3B, 0xDD, 0xAB, - 0x90, 0x28, 0xBA, 0x6C, 0x17, 0x68, 0x4C, 0x51, 0x22, 0x42, 0x62, 0x43, 0xCB, 0x61, 0x2A, 0x29 }, + { 0x90, 0xE2, 0x51, 0x86, 0x7F, 0x6B, 0x0C, 0x14, 0xBD, 0x9B, 0x51, 0x0C, 0xFD, 0xA8, 0x48, 0x49, + 0x72, 0xFD, 0xF0, 0xE0, 0x6D, 0xC1, 0x1F, 0x5D, 0x1D, 0x59, 0x0B, 0xE3, 0xFC, 0x38, 0xDF, 0xF0 }, }, { - { 0x53, 0xED, 0x84, 0xE5, 0xC9, 0xAD, 0x2B, 0xD1, 0xCB, 0x2C, 0xC8, 0x36, 0x52, 0xEA, 0x0C, 0xC3, - 0x71, 0xCD, 0x53, 0x4B, 0xD5, 0x97, 0xCE, 0x7E, 0x07, 0x37, 0xA0, 0xAB, 0x10, 0x65, 0x73, 0xAA }, + { 0x91, 0x90, 0xF8, 0x25, 0x51, 0x0C, 0x65, 0x98, 0xE1, 0x9D, 0x17, 0xDB, 0xBE, 0x6E, 0x7C, 0x82, + 0x31, 0x86, 0x9C, 0xA7, 0xF6, 0xE3, 0x07, 0xA2, 0xC2, 0xCC, 0x54, 0x77, 0x8D, 0x4A, 0x89, 0xB3 }, }, { - { 0x54, 0x1B, 0xED, 0x16, 0x7D, 0x7D, 0xE0, 0x5F, 0x80, 0x63, 0x73, 0xA3, 0x86, 0x8F, 0x73, 0x4C, - 0xBD, 0xF7, 0x09, 0x53, 0x6B, 0x3B, 0xCF, 0x20, 0x64, 0xB2, 0x59, 0xFE, 0x2A, 0x83, 0x76, 0xAA }, + { 0x91, 0xC7, 0x6E, 0xF8, 0xC7, 0x05, 0x3B, 0x2A, 0x27, 0x0B, 0x97, 0x19, 0x78, 0x3C, 0x85, 0x10, + 0xA2, 0x89, 0x0A, 0x48, 0x40, 0x18, 0x63, 0x72, 0x6E, 0x23, 0x3A, 0x82, 0xBF, 0x9A, 0x0B, 0xCF }, }, { - { 0x54, 0x41, 0xFB, 0xB0, 0x5D, 0x6D, 0x4A, 0xED, 0xE0, 0x3B, 0x48, 0x2F, 0x51, 0x95, 0x1C, 0x7E, - 0xF0, 0x73, 0x45, 0x53, 0xCE, 0xC7, 0x80, 0xFB, 0xDC, 0xFA, 0x30, 0x0C, 0xC1, 0x79, 0x0D, 0x66 }, + { 0x92, 0x3F, 0x0F, 0x8C, 0x40, 0x5A, 0x02, 0xE6, 0x82, 0xC4, 0xB4, 0x66, 0x5A, 0x7E, 0xE7, 0x16, + 0xAA, 0x57, 0xE0, 0xA5, 0x86, 0xC2, 0x4A, 0x16, 0x5A, 0xAD, 0x7E, 0x5B, 0xDA, 0x22, 0x78, 0x24 }, }, { - { 0x54, 0xA5, 0x1F, 0x64, 0xD6, 0x28, 0x61, 0x49, 0xF2, 0x3A, 0x43, 0xCC, 0x73, 0x67, 0x00, 0x0E, - 0xF0, 0x16, 0x03, 0x89, 0x9C, 0xBC, 0x94, 0xA1, 0xA4, 0xE3, 0xBE, 0xEC, 0xFE, 0xE8, 0x40, 0x66 }, + { 0x92, 0x71, 0x44, 0x12, 0x1C, 0x23, 0x63, 0x57, 0x07, 0xE9, 0x40, 0x7F, 0x7F, 0xFF, 0x6A, 0x64, + 0x63, 0x5D, 0x7C, 0xE9, 0x06, 0x66, 0xD4, 0x29, 0x94, 0x09, 0x7A, 0xF4, 0x0C, 0x31, 0x36, 0xFB }, }, { - { 0x55, 0x21, 0xF9, 0x63, 0x57, 0x81, 0x58, 0xB8, 0xD0, 0xE7, 0xC4, 0x91, 0xCD, 0xB8, 0x5C, 0x3D, - 0xE9, 0xD5, 0x2E, 0xA5, 0x1F, 0xFC, 0xB0, 0x93, 0xD3, 0x12, 0x28, 0x11, 0x13, 0x14, 0x97, 0xEB }, - }, - { - { 0x55, 0x54, 0xEC, 0x61, 0xF2, 0x57, 0x6E, 0x34, 0xE7, 0x21, 0x56, 0xA6, 0xF6, 0xFD, 0x5E, 0xE8, - 0xF4, 0x26, 0x2A, 0xB5, 0x3F, 0x7B, 0xC9, 0xF1, 0x8B, 0xB6, 0xD7, 0xEB, 0x3E, 0x16, 0x28, 0xDE }, - }, - { - { 0x55, 0xB2, 0x84, 0x5F, 0x48, 0x44, 0xA7, 0x72, 0x46, 0x36, 0x41, 0x78, 0xA1, 0x71, 0xC2, 0x26, - 0xFC, 0xFD, 0x75, 0xC7, 0x63, 0xBA, 0xD0, 0x87, 0xF6, 0x02, 0xE7, 0xB4, 0xAC, 0xD9, 0xEC, 0xB3 }, - }, - { - { 0x55, 0xD0, 0xEB, 0xE3, 0x2C, 0xBA, 0x09, 0xF6, 0x58, 0x4D, 0x9E, 0x7B, 0x57, 0x92, 0xA4, 0x03, - 0xC2, 0x1D, 0x39, 0xD6, 0xE1, 0xF5, 0xE8, 0xED, 0x37, 0xB9, 0x3F, 0xA6, 0x1D, 0x88, 0x35, 0x16 }, - }, - { - { 0x56, 0x65, 0xC2, 0xE5, 0x64, 0x33, 0x29, 0x85, 0xB8, 0xD2, 0xC4, 0xFB, 0x61, 0x14, 0x57, 0xD8, - 0xD5, 0x65, 0x9A, 0xE0, 0x05, 0x87, 0x4C, 0x6F, 0x30, 0x34, 0xD2, 0x9F, 0x2A, 0x9A, 0x78, 0x32 }, - }, - { - { 0x56, 0x81, 0x4B, 0xB4, 0x69, 0xC3, 0x87, 0x31, 0xFC, 0x0D, 0x84, 0xB8, 0x6F, 0x87, 0xB3, 0x5B, - 0xAF, 0xF3, 0x2A, 0x0F, 0x13, 0xC2, 0x61, 0x64, 0x02, 0x70, 0x36, 0xC9, 0x4E, 0x8D, 0x64, 0x3F }, - }, - { - { 0x56, 0x8F, 0x37, 0xB3, 0xAB, 0xBD, 0xA3, 0xE8, 0x03, 0x12, 0xB1, 0xB1, 0x43, 0x27, 0x2C, 0x44, - 0xE1, 0xFB, 0x78, 0xEE, 0x3F, 0x30, 0x0F, 0x5B, 0x54, 0xF5, 0xB2, 0x9A, 0x7A, 0xD8, 0xD7, 0x43 }, - }, - { - { 0x56, 0x96, 0x18, 0xD5, 0x4E, 0x3C, 0x61, 0x1B, 0x79, 0x7E, 0xEB, 0x01, 0xDF, 0x9C, 0x1C, 0x5C, - 0x14, 0x6D, 0x87, 0xB3, 0xB1, 0x29, 0xBA, 0x42, 0x29, 0x88, 0x88, 0x82, 0x10, 0x04, 0xFD, 0xCB }, - }, - { - { 0x57, 0xB8, 0xBF, 0xB7, 0x22, 0x41, 0x15, 0xB7, 0xF2, 0xAE, 0x12, 0x89, 0x74, 0xB6, 0xD0, 0x74, - 0x1B, 0xB2, 0x8F, 0x48, 0x0B, 0xE8, 0x96, 0xEE, 0x09, 0x7C, 0xEE, 0x68, 0x6E, 0xA3, 0xAA, 0xAB }, - }, - { - { 0x57, 0xC1, 0x4C, 0x78, 0x2C, 0xF5, 0x8C, 0x3B, 0x72, 0x28, 0x0F, 0xEF, 0x7D, 0xA9, 0xE2, 0xD9, - 0x71, 0xE5, 0x25, 0x03, 0xC4, 0x15, 0x99, 0x59, 0x68, 0xB6, 0x04, 0x37, 0x2A, 0x18, 0x96, 0xBF }, - }, - { - { 0x58, 0x0C, 0x45, 0xD6, 0xE2, 0x55, 0x8E, 0x7C, 0x7D, 0xA8, 0x19, 0xA5, 0x99, 0xD5, 0xB1, 0x6F, - 0x0E, 0x18, 0x79, 0xF0, 0xCB, 0x58, 0x31, 0xDF, 0xDB, 0x9A, 0xB2, 0xFF, 0x6E, 0x8E, 0x4B, 0xA0 }, - }, - { - { 0x58, 0x1A, 0xDE, 0x64, 0x84, 0x95, 0xB4, 0xB1, 0x62, 0x9C, 0x3C, 0x7C, 0x78, 0xEF, 0xBE, 0xF2, - 0x75, 0x06, 0x56, 0x65, 0xB2, 0x41, 0x1C, 0x0E, 0x5F, 0xCF, 0xBC, 0x7E, 0xB4, 0xBE, 0x34, 0x0B }, - }, - { - { 0x58, 0x36, 0x98, 0x46, 0xC0, 0x25, 0x15, 0x0E, 0xCF, 0xB2, 0x2C, 0xCE, 0xB8, 0xE4, 0xDE, 0x9A, - 0xC3, 0xD0, 0x2D, 0x9E, 0x23, 0x6C, 0x02, 0xEF, 0xB5, 0x5F, 0x63, 0xEB, 0xAF, 0xEA, 0xF7, 0x5B }, - }, - { - { 0x58, 0x98, 0xBE, 0xD1, 0x46, 0x1E, 0x18, 0x9D, 0xC5, 0x97, 0x73, 0x75, 0x9C, 0xB6, 0x9B, 0xE3, - 0x36, 0x86, 0xB2, 0xD8, 0x0E, 0x73, 0x21, 0x9F, 0x07, 0x96, 0xEB, 0x8F, 0x0F, 0x79, 0x59, 0x09 }, - }, - { - { 0x59, 0x3F, 0x23, 0x88, 0x0B, 0x59, 0xED, 0x5A, 0xA4, 0x8A, 0x2D, 0xB5, 0x01, 0x44, 0xFC, 0x8E, - 0xAB, 0xB7, 0xB5, 0x35, 0xA6, 0x2A, 0x61, 0x7B, 0x28, 0x82, 0xB8, 0x5D, 0xCF, 0x50, 0xB8, 0x02 }, - }, - { - { 0x59, 0x43, 0x09, 0x51, 0x02, 0x8B, 0x87, 0x78, 0x01, 0x67, 0xC9, 0x56, 0x47, 0x9A, 0x81, 0x5F, - 0x91, 0xBC, 0x6C, 0x00, 0xC2, 0xE5, 0x0C, 0x35, 0xF0, 0x5F, 0xCF, 0xF5, 0x27, 0x68, 0xC7, 0x37 }, - }, - { - { 0x59, 0xC9, 0xE8, 0xDF, 0x03, 0x0B, 0x1C, 0xD5, 0x89, 0xA8, 0xB3, 0x4F, 0xE7, 0x42, 0x51, 0xEA, - 0xD5, 0xA5, 0xFB, 0xE9, 0xE6, 0x13, 0x67, 0xCA, 0x76, 0xAF, 0xD9, 0xDD, 0xD9, 0xC6, 0xF1, 0x6F }, - }, - { - { 0x59, 0xE8, 0x20, 0x27, 0xA5, 0xF6, 0x28, 0x1A, 0xBC, 0xFB, 0x41, 0xA9, 0x9F, 0xFC, 0xB5, 0xBA, - 0xB1, 0x3A, 0xA1, 0x32, 0x57, 0xFC, 0x12, 0xE1, 0xDD, 0x4C, 0x38, 0x08, 0xB9, 0x64, 0x27, 0x39 }, - }, - { - { 0x59, 0xE9, 0xFA, 0x2F, 0xF0, 0x76, 0x89, 0x33, 0x28, 0x33, 0xC6, 0x40, 0xF5, 0x05, 0xFA, 0x24, - 0x09, 0xEB, 0x88, 0x93, 0x32, 0x57, 0xC1, 0x93, 0xB0, 0x07, 0xD3, 0xA2, 0x89, 0x6A, 0x98, 0x50 }, - }, - { - { 0x59, 0xEE, 0x2C, 0xB6, 0x0C, 0x80, 0xE7, 0x37, 0x33, 0x72, 0x1C, 0xA6, 0xCD, 0x0C, 0x88, 0x63, - 0xDD, 0x9A, 0xF6, 0xB8, 0x2F, 0x35, 0x0C, 0xE9, 0x88, 0x72, 0xF2, 0x2E, 0x23, 0x89, 0x5A, 0x55 }, - }, - { - { 0x59, 0xEE, 0x9B, 0x36, 0x80, 0xAE, 0x20, 0x56, 0x83, 0x9C, 0x0B, 0xF6, 0x9E, 0xE6, 0x63, 0x26, - 0x57, 0x16, 0xA8, 0xE2, 0x4C, 0xC6, 0x49, 0x95, 0xFB, 0xA6, 0xCB, 0x6F, 0x0C, 0x12, 0x39, 0xDC }, - }, - { - { 0x5A, 0x28, 0x15, 0x08, 0x72, 0x33, 0x83, 0xE1, 0x3D, 0x56, 0x37, 0x61, 0x41, 0x19, 0x23, 0xFB, - 0x20, 0xD5, 0xC2, 0x83, 0x56, 0x64, 0xAB, 0xFC, 0x9C, 0x02, 0x4E, 0x54, 0xE9, 0x5B, 0xCA, 0x87 }, - }, - { - { 0x5A, 0x2A, 0x8B, 0xCB, 0xEF, 0x60, 0xF7, 0x79, 0x13, 0xB1, 0xB6, 0xAE, 0xDF, 0xD3, 0xAE, 0x8F, - 0xE5, 0xFC, 0x42, 0x2F, 0xDB, 0x3B, 0xA7, 0x9E, 0xF7, 0x17, 0xA9, 0xBE, 0x19, 0xFA, 0x89, 0xDC }, - }, - { - { 0x5A, 0x6B, 0xB1, 0x1F, 0x2E, 0xFD, 0x5E, 0x60, 0x25, 0xC6, 0x06, 0xF5, 0x58, 0x81, 0x30, 0xE1, - 0x7C, 0x88, 0xED, 0xAE, 0xDC, 0x2A, 0xA9, 0x41, 0xE2, 0x54, 0x3A, 0xDD, 0x77, 0x25, 0x31, 0xBE }, - }, - { - { 0x5A, 0x84, 0xAF, 0xE6, 0x74, 0x05, 0xAB, 0xE8, 0x4A, 0x0C, 0xD4, 0x2C, 0x2B, 0xA2, 0xE4, 0xC8, - 0x8F, 0x35, 0xE0, 0xA5, 0x95, 0xE5, 0x69, 0xA3, 0xE1, 0x86, 0x69, 0x44, 0x40, 0x5B, 0xE7, 0x36 }, - }, - { - { 0x5A, 0x87, 0x99, 0x5F, 0x97, 0xBB, 0x5A, 0x55, 0x61, 0x7F, 0x5F, 0x8B, 0xE9, 0x53, 0xB9, 0x5E, - 0x3C, 0x45, 0xE2, 0x51, 0x5E, 0x7D, 0x38, 0xB6, 0xA4, 0x33, 0xD8, 0xC4, 0xA4, 0xAA, 0x4E, 0xF4 }, - }, - { - { 0x5A, 0x8C, 0x3A, 0x7D, 0x66, 0xEA, 0x0F, 0x6E, 0x88, 0xBE, 0x15, 0xD3, 0x28, 0x62, 0xFB, 0x39, - 0xF2, 0x5F, 0xEA, 0xAC, 0x12, 0xC2, 0xCD, 0x6A, 0x68, 0xE8, 0x9C, 0x4C, 0x30, 0xEE, 0x73, 0x63 }, - }, - { - { 0x5A, 0x8E, 0x86, 0x21, 0x2C, 0x06, 0x33, 0x94, 0x94, 0xF8, 0x5B, 0x5F, 0x85, 0x11, 0xDF, 0x00, - 0x00, 0x23, 0x94, 0x07, 0x8F, 0xFC, 0x77, 0x4D, 0x43, 0x6F, 0x0D, 0x63, 0x86, 0xD7, 0xA6, 0xF7 }, - }, - { - { 0x5A, 0xC0, 0x98, 0x2D, 0xA0, 0xC8, 0x3D, 0x0B, 0xA9, 0x38, 0x1A, 0x5C, 0xD8, 0x7B, 0x80, 0xD1, - 0x10, 0xF2, 0x6E, 0xE8, 0x39, 0x27, 0x1B, 0xC2, 0x70, 0x60, 0x8F, 0xD1, 0x43, 0x7F, 0x55, 0xB0 }, - }, - { - { 0x5A, 0xD0, 0x17, 0xDD, 0x25, 0x23, 0xF2, 0x51, 0xAF, 0x5E, 0xDC, 0xE4, 0x2A, 0x8F, 0x18, 0x5E, - 0x6D, 0x0E, 0x7D, 0xC8, 0x00, 0xF4, 0xA5, 0x9A, 0xF7, 0x7C, 0x12, 0x47, 0x37, 0x69, 0xD9, 0x37 }, - }, - { - { 0x5A, 0xE2, 0xFA, 0x90, 0x43, 0x53, 0x46, 0x3B, 0xAE, 0xE6, 0x96, 0x53, 0xB2, 0x19, 0xC1, 0x5B, - 0xC9, 0xCD, 0x80, 0xE7, 0x01, 0x40, 0x08, 0xE7, 0x26, 0x31, 0x09, 0x79, 0x52, 0x54, 0x8C, 0x60 }, - }, - { - { 0x5A, 0xED, 0x28, 0x2D, 0x88, 0x21, 0xAA, 0xDF, 0x6E, 0x01, 0x0D, 0x94, 0x66, 0x66, 0x09, 0x25, - 0x7C, 0xA0, 0xAF, 0x4C, 0xE5, 0xBD, 0x7F, 0xC9, 0xCD, 0x8C, 0x9F, 0x32, 0x5F, 0xEB, 0xAE, 0x6D }, - }, - { - { 0x5B, 0x1F, 0x32, 0x78, 0x8D, 0xD9, 0xD7, 0xE9, 0x06, 0x80, 0x7D, 0x03, 0x01, 0x45, 0xC8, 0xAD, - 0x20, 0x11, 0x03, 0x0C, 0xDB, 0xF0, 0xA6, 0x03, 0x08, 0x14, 0x93, 0x7E, 0x54, 0xD1, 0x54, 0x68 }, - }, - { - { 0x5B, 0x1F, 0x32, 0xF6, 0x88, 0x12, 0xD9, 0xC3, 0xD3, 0x34, 0x99, 0x39, 0x48, 0x4E, 0x3E, 0xDF, - 0xC6, 0xC2, 0x33, 0xB6, 0x5F, 0x9D, 0xDB, 0x3D, 0x4B, 0x30, 0xFC, 0x4B, 0xE2, 0x0E, 0x0D, 0x84 }, - }, - { - { 0x5B, 0x29, 0x3D, 0x30, 0x9F, 0x64, 0x24, 0xBC, 0x26, 0x4F, 0x4B, 0xB0, 0x18, 0xAE, 0xF5, 0x0E, - 0x63, 0xE3, 0x37, 0xD1, 0x4D, 0xF0, 0x64, 0xC5, 0x7A, 0x23, 0x52, 0x83, 0x42, 0x16, 0x1C, 0x68 }, - }, - { - { 0x5C, 0x06, 0x2F, 0x0D, 0x7E, 0x21, 0x91, 0xDF, 0xC1, 0x60, 0xE4, 0xC0, 0x59, 0xAE, 0xD4, 0xD1, - 0x83, 0xBD, 0x2D, 0x0F, 0x40, 0x98, 0x3D, 0x03, 0xB4, 0xE8, 0xDA, 0xA1, 0x1F, 0xF5, 0xE8, 0x95 }, - }, - { - { 0x5C, 0x35, 0x91, 0x21, 0x9B, 0x7A, 0x55, 0x9A, 0x0D, 0x78, 0xAF, 0xE0, 0x6D, 0xFC, 0x80, 0x85, - 0x78, 0x23, 0xD2, 0x49, 0x56, 0x30, 0x08, 0x22, 0xBB, 0x1D, 0x6E, 0x60, 0x01, 0x98, 0x11, 0xE8 }, - }, - { - { 0x5C, 0x7F, 0xF0, 0x55, 0xC2, 0xFD, 0x03, 0x3F, 0x34, 0xC4, 0xC4, 0xF7, 0xC4, 0xFB, 0x7D, 0xDA, - 0xAA, 0xFB, 0x43, 0x56, 0xC5, 0x60, 0xC9, 0x9E, 0xDF, 0xF0, 0x74, 0xDA, 0x04, 0xAF, 0x65, 0x7C }, - }, - { - { 0x5C, 0xD2, 0x44, 0x6A, 0x8E, 0x4A, 0x0F, 0xA7, 0xE3, 0xCD, 0xF8, 0x00, 0x5D, 0xED, 0xCE, 0xBA, - 0xE9, 0xE6, 0x81, 0x9A, 0x8A, 0x69, 0x87, 0x31, 0x55, 0x5B, 0x7D, 0xC9, 0xD0, 0xA2, 0x3F, 0xC0 }, - }, - { - { 0x5C, 0xEB, 0xEB, 0xD8, 0x34, 0x01, 0xB7, 0x0B, 0xAC, 0xB5, 0x4F, 0x66, 0xA9, 0xB7, 0x78, 0x55, - 0x69, 0x6E, 0xCE, 0x16, 0x7F, 0xE6, 0xC6, 0x0A, 0x05, 0x16, 0x8B, 0xE4, 0x39, 0x19, 0xC8, 0x0F }, - }, - { - { 0x5D, 0x01, 0x5E, 0x1F, 0xF4, 0x40, 0xD8, 0x3E, 0x1E, 0x1C, 0xE0, 0x99, 0x9C, 0x42, 0x6C, 0xED, - 0xD8, 0x75, 0xEE, 0x22, 0x6F, 0x79, 0xA6, 0xD6, 0xB8, 0xFB, 0xBF, 0x14, 0x6A, 0x43, 0xF4, 0x2D }, - }, - { - { 0x5D, 0x69, 0x52, 0x4D, 0xE6, 0x3A, 0x8B, 0xE0, 0x1A, 0x82, 0x31, 0xB4, 0x33, 0x3E, 0xC8, 0x97, - 0x74, 0xC5, 0x8D, 0x82, 0xB4, 0xAD, 0xBD, 0x20, 0x91, 0x42, 0x84, 0x06, 0xA0, 0x6B, 0x16, 0xB0 }, - }, - { - { 0x5E, 0x23, 0xDB, 0xD4, 0xD0, 0xC9, 0xBF, 0xB1, 0x5F, 0x61, 0x6A, 0x95, 0x17, 0xA1, 0x30, 0xD8, - 0x66, 0xA8, 0xCB, 0x0B, 0x18, 0x96, 0x3D, 0x54, 0xE7, 0xED, 0xAE, 0xE2, 0x61, 0xCB, 0x1C, 0x19 }, - }, - { - { 0x5E, 0xAE, 0xD7, 0x13, 0x5C, 0x21, 0x69, 0x76, 0xAD, 0x4E, 0xDC, 0x4D, 0xBB, 0x3F, 0x1F, 0xA1, - 0xF7, 0xC2, 0x85, 0x54, 0xF1, 0x4F, 0x1A, 0xD1, 0xC6, 0x2A, 0xBA, 0xBB, 0x00, 0xCF, 0x7B, 0x66 }, - }, - { - { 0x5F, 0x1E, 0xAE, 0xF6, 0xB7, 0xE3, 0x2F, 0x26, 0xC8, 0x7A, 0xD9, 0x4A, 0x10, 0xF9, 0x0B, 0xF2, - 0xB3, 0x4F, 0x0E, 0x21, 0x13, 0x71, 0x37, 0x0C, 0xB3, 0xDA, 0xCD, 0xE1, 0x00, 0x63, 0x9D, 0xBE }, - }, - { - { 0x5F, 0x30, 0xF0, 0x3A, 0x89, 0xBF, 0x8F, 0x2B, 0x9B, 0x82, 0xC9, 0x35, 0xF8, 0x8E, 0xC6, 0x87, - 0xEC, 0x07, 0xBC, 0xC8, 0x0E, 0xC8, 0x24, 0xE5, 0x74, 0x51, 0x72, 0xB4, 0x50, 0x29, 0x90, 0xBE }, - }, - { - { 0x5F, 0x5C, 0xCA, 0x19, 0x1E, 0xC9, 0x2F, 0x4D, 0xAD, 0x96, 0x6D, 0xAA, 0xFD, 0x6D, 0xE7, 0x56, - 0x34, 0x44, 0x18, 0x60, 0x4D, 0x8A, 0xD5, 0x0A, 0x78, 0x14, 0xF4, 0x39, 0xF4, 0xF2, 0x0A, 0xF1 }, - }, - { - { 0x5F, 0x85, 0xDE, 0xA9, 0xBB, 0x0D, 0x94, 0x81, 0xC2, 0x47, 0x23, 0x2E, 0xF2, 0x5C, 0x77, 0xE8, - 0x4E, 0x68, 0x95, 0x60, 0x0D, 0x0B, 0xDA, 0xF8, 0xE7, 0x0E, 0x82, 0x8A, 0xDC, 0x6F, 0xD4, 0xFF }, - }, - { - { 0x5F, 0x8B, 0x88, 0x8E, 0xE9, 0x6C, 0x0C, 0x0F, 0x5A, 0x91, 0x72, 0x90, 0xAC, 0xA6, 0x5A, 0xFD, - 0x6E, 0xBD, 0xAE, 0x05, 0xA0, 0x2A, 0xAF, 0x04, 0x29, 0xE9, 0x72, 0xEC, 0x01, 0x90, 0xEC, 0xFC }, - }, - { - { 0x60, 0x1A, 0xF7, 0x2F, 0xB0, 0x6F, 0xE6, 0x68, 0x79, 0x92, 0xC5, 0x8F, 0xAC, 0x32, 0xE3, 0x0C, - 0x01, 0x9E, 0xAF, 0x41, 0xE0, 0xB3, 0x85, 0x7E, 0xA9, 0x00, 0xA1, 0x61, 0x08, 0xEB, 0x34, 0xDE }, - }, - { - { 0x60, 0x28, 0x6B, 0x5F, 0xB1, 0xA4, 0x7F, 0x8C, 0x79, 0x3E, 0xBE, 0x0A, 0x4F, 0x9E, 0xA0, 0xEF, - 0xB6, 0xFF, 0xF7, 0xD0, 0x1C, 0x79, 0x10, 0xEF, 0xF7, 0x4E, 0xD3, 0xB2, 0x88, 0xF4, 0xE6, 0x27 }, - }, - { - { 0x60, 0x38, 0x42, 0xEB, 0x89, 0xDA, 0xAD, 0xF7, 0x17, 0xF7, 0xE0, 0x91, 0x22, 0xA0, 0x6A, 0xC8, - 0x19, 0x04, 0x51, 0x2C, 0x2D, 0xA1, 0xCB, 0xC2, 0x90, 0xCC, 0x52, 0xD4, 0xDC, 0x0C, 0x7F, 0xEC }, - }, - { - { 0x60, 0x47, 0xA1, 0x61, 0x21, 0xDA, 0x00, 0xB4, 0x31, 0x60, 0x6D, 0x15, 0xE8, 0x40, 0x5F, 0x0D, - 0x19, 0xCF, 0xFE, 0x7C, 0xDE, 0x91, 0x69, 0x8C, 0x79, 0x4B, 0x3A, 0x35, 0x1D, 0xB1, 0x4D, 0x6B }, - }, - { - { 0x60, 0x4C, 0xE5, 0x2B, 0x8F, 0xC5, 0x72, 0xF0, 0xEC, 0x55, 0xF1, 0xC6, 0x37, 0x08, 0xDF, 0xD9, - 0x7E, 0xF1, 0xC7, 0x99, 0xD4, 0x8C, 0x27, 0x6B, 0x37, 0x34, 0x75, 0xE3, 0xA4, 0x61, 0xF3, 0x12 }, - }, - { - { 0x60, 0x69, 0xE0, 0x4E, 0xF3, 0x7E, 0xE3, 0x29, 0xCF, 0x15, 0xE9, 0xFD, 0x64, 0x1F, 0x18, 0x24, - 0xB8, 0x4B, 0x34, 0x4B, 0x63, 0x80, 0x30, 0x05, 0x81, 0x66, 0x2B, 0x2D, 0x44, 0x31, 0x3A, 0x95 }, - }, - { - { 0x60, 0xA3, 0xFB, 0x74, 0x7C, 0xF6, 0x5B, 0x04, 0xE9, 0xBE, 0x15, 0xDA, 0x26, 0xA9, 0xDD, 0x99, - 0x59, 0x71, 0xA9, 0x1A, 0x6F, 0x02, 0xE0, 0x14, 0xA9, 0xD7, 0x4D, 0x1F, 0x69, 0x45, 0xE1, 0x2E }, - }, - { - { 0x60, 0xCA, 0x81, 0xE3, 0x5B, 0x9A, 0x6F, 0x07, 0xE1, 0x3C, 0x02, 0xAE, 0x41, 0x15, 0xB0, 0x00, - 0x54, 0x30, 0xCF, 0x46, 0x0E, 0xFC, 0x7D, 0xBA, 0xF1, 0x5F, 0x51, 0xF7, 0xA9, 0x4A, 0xD1, 0x6A }, - }, - { - { 0x60, 0xDF, 0xF2, 0xAB, 0xA6, 0x5C, 0x74, 0xB5, 0x07, 0x49, 0x16, 0x32, 0xAD, 0x81, 0xC0, 0x9A, - 0x54, 0x71, 0xAE, 0xE8, 0x7C, 0xA1, 0x58, 0x03, 0x5D, 0x66, 0x79, 0x47, 0x83, 0x5E, 0xA8, 0xBF }, - }, - { - { 0x61, 0x65, 0xFD, 0x7A, 0x3D, 0xCB, 0x29, 0xAD, 0x23, 0xCC, 0x44, 0x64, 0x4F, 0xC2, 0x23, 0x25, - 0x94, 0x5D, 0xDF, 0xED, 0x0C, 0x18, 0xB3, 0x5B, 0x17, 0x43, 0xAD, 0x96, 0x28, 0x43, 0x69, 0xBE }, - }, - { - { 0x61, 0x91, 0x5B, 0xC8, 0xDF, 0x67, 0x8C, 0x52, 0xA2, 0x3C, 0x2D, 0x53, 0xC6, 0x47, 0x31, 0x4E, - 0x63, 0x6E, 0xEF, 0xC5, 0x40, 0x81, 0xA7, 0x0D, 0x3A, 0xC1, 0x45, 0x28, 0x66, 0x1D, 0x62, 0xFF }, - }, - { - { 0x61, 0xA7, 0x62, 0xEF, 0x47, 0xBC, 0xA4, 0xEE, 0x77, 0xA5, 0xC8, 0xAF, 0x03, 0x98, 0x9A, 0x9D, - 0xEA, 0xCA, 0x4D, 0x82, 0x8A, 0x53, 0xD9, 0x23, 0xE7, 0x0B, 0xFB, 0xC7, 0x25, 0x4A, 0xC7, 0x70 }, - }, - { - { 0x61, 0xC8, 0xF2, 0xE2, 0x97, 0xD0, 0x51, 0x91, 0x32, 0x07, 0xEF, 0x02, 0x93, 0x63, 0xB8, 0xE7, - 0x33, 0x7A, 0x39, 0x6E, 0x09, 0x9C, 0xA9, 0xDC, 0xF8, 0x07, 0x33, 0x97, 0x32, 0x66, 0x4B, 0x74 }, - }, - { - { 0x62, 0x2E, 0xC3, 0xBE, 0x7C, 0xF5, 0xE4, 0xE6, 0x3F, 0x74, 0x18, 0x69, 0x28, 0x74, 0x40, 0x05, - 0xCB, 0xB7, 0x8D, 0xF3, 0x06, 0xB8, 0x67, 0xC3, 0xFC, 0xAD, 0x5E, 0x2B, 0xA7, 0x53, 0x96, 0x83 }, - }, - { - { 0x62, 0x61, 0x3D, 0xA8, 0x69, 0xE5, 0xA2, 0x36, 0xC1, 0x29, 0x21, 0x73, 0x87, 0x25, 0xE9, 0x7C, - 0x68, 0x05, 0x8D, 0x04, 0x0A, 0x07, 0xE9, 0x65, 0x4B, 0x2D, 0xF5, 0xE2, 0xD8, 0x7D, 0x05, 0x1F }, - }, - { - { 0x62, 0x6F, 0x7E, 0xB4, 0xFD, 0x9B, 0x71, 0xFF, 0xAA, 0x0C, 0x8E, 0xC9, 0x65, 0x54, 0x64, 0xE6, - 0x5E, 0x7F, 0x96, 0xCF, 0xA3, 0x82, 0x73, 0x97, 0x41, 0x35, 0x66, 0xAA, 0x2C, 0xC1, 0xE5, 0x72 }, - }, - { - { 0x63, 0x35, 0x8C, 0x6D, 0xEB, 0xDF, 0x48, 0x2B, 0xB2, 0xD3, 0x21, 0x13, 0xD3, 0xF0, 0xB1, 0x73, - 0x77, 0xE2, 0xF7, 0xC9, 0x25, 0xB9, 0xFE, 0xB3, 0x47, 0x8B, 0xD9, 0x94, 0x56, 0x31, 0x3E, 0x78 }, - }, - { - { 0x63, 0x64, 0x15, 0x61, 0x77, 0xDC, 0xDF, 0x60, 0x4D, 0xF9, 0x1E, 0x31, 0x32, 0x2E, 0x57, 0x74, - 0x69, 0x1E, 0x0C, 0x41, 0xFA, 0x0D, 0x2F, 0x25, 0x7A, 0xD7, 0xF9, 0xF0, 0x25, 0x98, 0x14, 0x45 }, - }, - { - { 0x63, 0x65, 0xEB, 0x4E, 0x37, 0xEA, 0x23, 0x8B, 0xBC, 0x40, 0xA7, 0x65, 0x1E, 0xDD, 0x9A, 0x1C, - 0x65, 0xFC, 0x54, 0xE3, 0xB8, 0x8F, 0xA7, 0xA0, 0x6D, 0x92, 0xC6, 0x13, 0xAE, 0xDE, 0xD6, 0x5D }, - }, - { - { 0x63, 0x6A, 0x25, 0xBD, 0xDB, 0xB6, 0x5E, 0x7C, 0xC0, 0xE6, 0x1F, 0x91, 0xCA, 0xFE, 0xB1, 0xFE, - 0x5D, 0xD2, 0x67, 0xAC, 0x67, 0x32, 0x25, 0xCC, 0x81, 0x8E, 0xA0, 0x2B, 0x9C, 0xC9, 0x4B, 0xE2 }, - }, - { - { 0x63, 0x80, 0x65, 0xEC, 0x95, 0xF1, 0xEA, 0x81, 0xD9, 0x5B, 0xA4, 0xDB, 0x9E, 0xA9, 0xA2, 0xEF, - 0xE2, 0xD6, 0xCD, 0x78, 0x75, 0x88, 0x67, 0x04, 0x5C, 0x06, 0xB6, 0x48, 0xA5, 0xDA, 0x89, 0xB2 }, - }, - { - { 0x63, 0xEA, 0x63, 0x4F, 0x3C, 0x84, 0x62, 0x3C, 0xF7, 0xB0, 0x61, 0x29, 0xE2, 0x7A, 0xCD, 0xF2, - 0x13, 0xD2, 0x52, 0xBE, 0x85, 0x87, 0xEB, 0xB0, 0x7A, 0x63, 0x68, 0x07, 0x78, 0x2B, 0xBD, 0x61 }, - }, - { - { 0x64, 0x87, 0xC9, 0x20, 0xB1, 0x30, 0x16, 0xF4, 0xA0, 0xAA, 0xD3, 0x9F, 0xE1, 0x97, 0x8B, 0xEC, - 0xE9, 0xF4, 0xFA, 0x13, 0xED, 0x0C, 0x42, 0x4D, 0xAA, 0x41, 0x6B, 0xAA, 0x75, 0x89, 0x62, 0x01 }, - }, - { - { 0x64, 0xD4, 0x92, 0x41, 0x6E, 0xE0, 0x55, 0x57, 0x9C, 0x46, 0x3B, 0x21, 0x1A, 0xFE, 0xF7, 0x46, - 0xC3, 0x30, 0xCA, 0x05, 0xF4, 0x4D, 0x85, 0x90, 0x85, 0x59, 0x5D, 0x6F, 0x10, 0xE5, 0x0E, 0xC4 }, - }, - { - { 0x64, 0xDE, 0xB1, 0x36, 0xA4, 0x3E, 0x7D, 0x21, 0x62, 0x29, 0x9B, 0x82, 0xA4, 0xFE, 0x8D, 0xB9, - 0x60, 0xC6, 0x61, 0x7C, 0x60, 0x3B, 0x7D, 0x96, 0x72, 0xA6, 0x2C, 0xA1, 0x40, 0xA6, 0xDA, 0x6A }, - }, - { - { 0x65, 0x66, 0x00, 0xA4, 0x5E, 0x45, 0x6A, 0xBA, 0x5B, 0x00, 0x8D, 0x87, 0x91, 0x54, 0xB7, 0x69, - 0x0D, 0x7F, 0x27, 0x31, 0x02, 0x09, 0x7D, 0x8F, 0xD8, 0xC3, 0xDE, 0xAB, 0x30, 0xD8, 0x4A, 0xB2 }, - }, - { - { 0x65, 0xC1, 0x3A, 0x93, 0x7F, 0xCD, 0x1E, 0xAC, 0x7D, 0x52, 0x33, 0x03, 0xB9, 0x09, 0x91, 0x75, - 0xFE, 0xB7, 0xC3, 0x57, 0x0F, 0xBD, 0xA2, 0xE5, 0x7D, 0x57, 0xD3, 0xFC, 0x47, 0x24, 0xDC, 0xB5 }, - }, - { - { 0x65, 0xEB, 0x8A, 0x1C, 0x57, 0x67, 0x6D, 0x21, 0x53, 0xF2, 0x1A, 0x34, 0x11, 0xB8, 0x9C, 0xCD, - 0x71, 0xBC, 0xC8, 0xC9, 0xDC, 0x2C, 0xC6, 0x1F, 0x83, 0x65, 0x27, 0xE0, 0x81, 0xC0, 0x56, 0x72 }, - }, - { - { 0x65, 0xED, 0x61, 0xA8, 0x8C, 0x55, 0xEF, 0xB0, 0x38, 0x07, 0x1A, 0xEE, 0xDE, 0xF8, 0xE1, 0x83, - 0xE2, 0x37, 0x38, 0x46, 0x97, 0x26, 0xEB, 0x99, 0x68, 0x0C, 0xD2, 0x44, 0x72, 0x73, 0x6B, 0xEC }, - }, - { - { 0x66, 0x07, 0xDF, 0xFF, 0x5D, 0x0B, 0xD3, 0xC9, 0x75, 0x92, 0xCC, 0x75, 0x39, 0x4D, 0x8B, 0x58, - 0x59, 0xF7, 0x5D, 0xA5, 0x12, 0x31, 0x34, 0xD7, 0xC7, 0xE2, 0x1A, 0xA7, 0x48, 0x91, 0x84, 0xEB }, - }, - { - { 0x66, 0x30, 0xB4, 0x4A, 0x1A, 0x28, 0xDE, 0xCB, 0x3B, 0x58, 0xED, 0xCE, 0xEC, 0x13, 0xB2, 0xC5, - 0xA7, 0x4F, 0x38, 0x6A, 0x1B, 0xF1, 0x18, 0x73, 0x75, 0xDE, 0x17, 0x8E, 0x4E, 0x9B, 0xB2, 0x8E }, - }, - { - { 0x66, 0x49, 0xE0, 0x34, 0xC6, 0x9D, 0x14, 0x24, 0xD2, 0x8C, 0x42, 0x68, 0xBA, 0x95, 0x1E, 0xE1, - 0xB4, 0x8A, 0xE1, 0x5F, 0xEB, 0xE7, 0xD6, 0xBE, 0x9D, 0x75, 0xF6, 0xA4, 0xAC, 0x7A, 0xC2, 0x53 }, - }, - { - { 0x66, 0x50, 0xB2, 0xEA, 0x64, 0x4C, 0x3F, 0x4E, 0x8C, 0x9E, 0x3C, 0x46, 0xAC, 0xEA, 0xC4, 0x52, - 0x33, 0xD8, 0x66, 0xE3, 0x98, 0xFF, 0x90, 0xEB, 0x59, 0xB2, 0xC6, 0x25, 0x20, 0x82, 0xAC, 0x04 }, - }, - { - { 0x66, 0x72, 0x1F, 0xE0, 0x69, 0xF1, 0xAA, 0x25, 0x32, 0x11, 0x68, 0x0E, 0xAD, 0x5C, 0x9E, 0x3D, - 0x12, 0x3C, 0x21, 0x24, 0xD3, 0xA2, 0xA4, 0xBD, 0x78, 0x82, 0xF7, 0x36, 0x5A, 0x33, 0x05, 0xA3 }, - }, - { - { 0x66, 0x79, 0x28, 0x7E, 0xBB, 0xC5, 0x67, 0x48, 0xEE, 0xD6, 0x8F, 0x9E, 0x4C, 0xCF, 0x24, 0xEF, - 0x96, 0xA4, 0x1F, 0x73, 0xBB, 0x83, 0x4A, 0x51, 0x71, 0x64, 0xF0, 0x41, 0xCC, 0x5D, 0x86, 0x05 }, - }, - { - { 0x66, 0xBE, 0x7E, 0xA1, 0x13, 0x8B, 0xCB, 0xA4, 0xDE, 0x0B, 0x41, 0x28, 0x5D, 0x9A, 0x13, 0x3F, - 0xA7, 0xF5, 0x70, 0xA3, 0xC8, 0x13, 0x55, 0x79, 0xB8, 0x60, 0x19, 0x9D, 0x0A, 0x51, 0x45, 0x7C }, - }, - { - { 0x66, 0xC9, 0x9A, 0x49, 0x61, 0x2E, 0x60, 0x18, 0x90, 0x02, 0xE2, 0x03, 0x04, 0xD2, 0xFC, 0xC5, - 0xBE, 0x07, 0x59, 0xDF, 0xBA, 0x84, 0x04, 0x70, 0x7E, 0x85, 0x37, 0x00, 0x26, 0x51, 0x84, 0x85 }, - }, - { - { 0x67, 0xA1, 0xBD, 0x09, 0x91, 0x6A, 0x22, 0xC0, 0x53, 0x3D, 0x0B, 0xF6, 0xCA, 0x1F, 0x3B, 0x03, - 0x3F, 0xAD, 0xCA, 0xC1, 0xFF, 0x8A, 0x89, 0x94, 0xD7, 0xF5, 0xC4, 0x79, 0xAD, 0x3A, 0x2E, 0xF5 }, - }, - { - { 0x67, 0xC3, 0xC0, 0xA1, 0x60, 0xE9, 0x28, 0x5E, 0x35, 0xA4, 0x22, 0xBB, 0x43, 0x4B, 0xFF, 0xFF, - 0xEE, 0x28, 0x79, 0xC6, 0xC0, 0xA5, 0x69, 0x36, 0x56, 0xE7, 0x73, 0xA6, 0xDD, 0x68, 0x5F, 0x0E }, - }, - { - { 0x67, 0xCF, 0x34, 0x6C, 0xF2, 0x46, 0x77, 0x1B, 0x3F, 0x5F, 0x3E, 0x51, 0xCD, 0x75, 0x4E, 0x10, - 0x93, 0x27, 0x3D, 0x35, 0x69, 0x88, 0x80, 0x84, 0x26, 0xF5, 0xDD, 0x2E, 0xD4, 0x8B, 0xBF, 0x49 }, - }, - { - { 0x68, 0x6E, 0xA9, 0xA7, 0x73, 0x2C, 0x5A, 0x6E, 0xDC, 0xA8, 0x44, 0xA6, 0x1F, 0x9D, 0xFD, 0x05, - 0xAC, 0x2F, 0x80, 0xF6, 0xC7, 0xED, 0x5E, 0xDF, 0x19, 0x9B, 0x8B, 0xD2, 0x78, 0x5D, 0x92, 0xFC }, - }, - { - { 0x68, 0x99, 0x4C, 0xFE, 0x06, 0x8D, 0xE8, 0x75, 0xEC, 0x56, 0x82, 0xBE, 0x3C, 0x5C, 0xB3, 0x25, - 0x47, 0x3B, 0x21, 0x25, 0xE6, 0xF1, 0xF3, 0xEA, 0x57, 0xCC, 0x09, 0xFE, 0x25, 0xB5, 0xB6, 0x93 }, - }, - { - { 0x68, 0xD3, 0x49, 0x5B, 0x3C, 0xAE, 0xE4, 0x1A, 0x70, 0x9A, 0x41, 0x65, 0xD4, 0x9D, 0xFE, 0xE7, - 0x4D, 0xCF, 0xB6, 0xD1, 0x3F, 0x7C, 0xF9, 0x43, 0xAA, 0xFF, 0xB9, 0xE6, 0xDC, 0x81, 0xDB, 0x04 }, - }, - { - { 0x69, 0x01, 0x4B, 0xBC, 0x84, 0x29, 0xD8, 0x5F, 0x41, 0xC2, 0x22, 0xD9, 0x7F, 0x7E, 0xD5, 0x35, - 0xCF, 0x81, 0x23, 0x9A, 0xF2, 0x7A, 0xCC, 0x88, 0x70, 0xDC, 0xD4, 0x08, 0x34, 0x8B, 0x48, 0xBA }, - }, - { - { 0x69, 0x21, 0x1F, 0x36, 0x3A, 0x2D, 0xBE, 0x01, 0x5B, 0x31, 0xCB, 0xD9, 0xFC, 0x5E, 0x94, 0xC2, - 0xF6, 0xF4, 0x3C, 0x58, 0xDB, 0xDE, 0xE9, 0xE3, 0xE4, 0x6B, 0x19, 0xD7, 0x59, 0xBB, 0xB8, 0x81 }, - }, - { - { 0x69, 0x44, 0xFE, 0x2E, 0xFD, 0x6C, 0x78, 0xE1, 0x40, 0x74, 0xBC, 0x3D, 0x9A, 0xC2, 0x3C, 0x8A, - 0x65, 0x7D, 0x0E, 0x8E, 0xBD, 0xF7, 0x4E, 0xC2, 0xCD, 0x26, 0x67, 0x74, 0x9D, 0x9D, 0xAD, 0xCB }, - }, - { - { 0x69, 0x52, 0x89, 0x99, 0x34, 0xD7, 0x23, 0x2B, 0xF9, 0xF6, 0x96, 0x8B, 0xCA, 0x13, 0x43, 0x92, - 0x47, 0xBF, 0xC3, 0x65, 0x92, 0x98, 0x00, 0x3D, 0xB1, 0xEE, 0xB7, 0x43, 0x92, 0x81, 0xB1, 0xD6 }, - }, - { - { 0x69, 0x54, 0x0E, 0x3B, 0xAB, 0x9A, 0x6E, 0x46, 0x58, 0x62, 0xCF, 0x2B, 0xCA, 0x5A, 0x63, 0x62, - 0x55, 0xF6, 0x9D, 0x46, 0x26, 0x39, 0xD3, 0xD9, 0x23, 0xFF, 0x93, 0x91, 0x90, 0x1B, 0x6C, 0x92 }, - }, - { - { 0x69, 0x75, 0x67, 0xBB, 0xAC, 0x94, 0xEE, 0xC3, 0xE6, 0xFA, 0x4A, 0x4E, 0x46, 0xFA, 0x51, 0x74, - 0x05, 0xF3, 0x77, 0xC0, 0xDE, 0xE3, 0xD4, 0x29, 0x91, 0x4E, 0x6B, 0x7E, 0xA0, 0x8C, 0xB1, 0xA6 }, - }, - { - { 0x69, 0xD3, 0x38, 0xE5, 0xD8, 0xC0, 0x69, 0xE7, 0xDC, 0x10, 0xD3, 0x82, 0x1F, 0x7A, 0x83, 0x0D, - 0xEB, 0x5D, 0x95, 0x7C, 0x8E, 0xC6, 0xEC, 0xD2, 0x5A, 0xF7, 0x24, 0x3E, 0xD0, 0xE4, 0xDC, 0x26 }, - }, - { - { 0x6A, 0x9C, 0x89, 0x45, 0x1E, 0xF3, 0xC9, 0xE3, 0xA2, 0x96, 0x2F, 0x8D, 0xB6, 0xF8, 0x7D, 0x20, - 0x77, 0x8D, 0x05, 0xA8, 0x74, 0x34, 0xA0, 0x78, 0x2B, 0x02, 0x53, 0x6D, 0xCD, 0x02, 0x4B, 0x4B }, - }, - { - { 0x6A, 0xAC, 0xC5, 0x09, 0x2F, 0x12, 0xBC, 0x94, 0xA0, 0xAD, 0x0E, 0x9E, 0xF6, 0x36, 0x43, 0x7D, - 0x36, 0x0D, 0xC7, 0xC9, 0xF1, 0x40, 0x44, 0x17, 0xA3, 0x36, 0x91, 0x94, 0x4E, 0x76, 0x31, 0x36 }, - }, - { - { 0x6A, 0xC3, 0x2D, 0xA9, 0x16, 0x8F, 0x70, 0xD0, 0x9F, 0xE9, 0xF7, 0x55, 0x3E, 0x67, 0x0F, 0xA4, - 0xAA, 0xAC, 0xE8, 0x7B, 0x5A, 0x0B, 0x9A, 0x3F, 0x22, 0x2D, 0x7A, 0x8B, 0xBA, 0x76, 0xD2, 0xF2 }, - }, - { - { 0x6A, 0xE7, 0x98, 0xD7, 0xDE, 0x07, 0x84, 0x90, 0xA5, 0x0F, 0x73, 0x89, 0x86, 0xD4, 0x03, 0x39, - 0x42, 0x97, 0x9D, 0xE2, 0x42, 0x6A, 0xFA, 0x95, 0x42, 0x24, 0x2E, 0x76, 0x3F, 0xEC, 0xF4, 0xA6 }, - }, - { - { 0x6B, 0x15, 0x66, 0xBF, 0x94, 0xA2, 0x26, 0xEE, 0x7C, 0xF3, 0x67, 0x5D, 0x63, 0x92, 0x73, 0x16, - 0x54, 0x56, 0x4B, 0x05, 0xC7, 0x2F, 0xCD, 0x7F, 0x6A, 0x97, 0xBA, 0xA1, 0x53, 0xE7, 0x6A, 0x18 }, - }, - { - { 0x6B, 0x37, 0xDD, 0x56, 0xDB, 0xC9, 0x97, 0x01, 0xEE, 0x6B, 0x55, 0x75, 0x23, 0x8B, 0x1E, 0xCF, - 0x35, 0xDF, 0x1B, 0x5E, 0x85, 0x91, 0x09, 0x1D, 0xB6, 0x8C, 0xC3, 0x5B, 0xD5, 0xA3, 0x6C, 0xE4 }, - }, - { - { 0x6B, 0x4A, 0x8C, 0xB6, 0x07, 0xF5, 0x1C, 0x83, 0x0D, 0xE7, 0x20, 0xF4, 0xBB, 0xDE, 0xDF, 0x49, - 0x10, 0x15, 0x13, 0xDF, 0xD1, 0xDB, 0x0B, 0x0A, 0x97, 0xCC, 0x3F, 0xDD, 0x9A, 0x39, 0xC6, 0xE7 }, - }, - { - { 0x6C, 0x07, 0x12, 0x67, 0x53, 0x03, 0x6A, 0x21, 0xBD, 0x20, 0xFC, 0x64, 0xEC, 0x6B, 0xA6, 0xE7, - 0x32, 0x59, 0x19, 0x1C, 0xBB, 0xBB, 0xFF, 0x21, 0x03, 0x74, 0xC8, 0x9E, 0x64, 0xF4, 0xD8, 0xD6 }, - }, - { - { 0x6C, 0x21, 0xDC, 0xB3, 0x38, 0x5C, 0x2B, 0x75, 0xA1, 0x5B, 0x2F, 0x61, 0x22, 0xFB, 0x58, 0xA1, - 0x24, 0x86, 0xAA, 0x4A, 0x4D, 0x23, 0x9E, 0xD0, 0x16, 0x74, 0x35, 0x8C, 0x9C, 0x71, 0x48, 0x6D }, - }, - { - { 0x6C, 0x67, 0xE6, 0x03, 0x63, 0x52, 0x5A, 0x65, 0x0A, 0x86, 0xB5, 0xE9, 0x46, 0x09, 0xDE, 0x13, - 0xF6, 0xBD, 0xB9, 0x0E, 0xCC, 0x2B, 0xB2, 0xA1, 0x8F, 0xDA, 0x99, 0x59, 0x52, 0x3A, 0x18, 0xD9 }, - }, - { - { 0x6C, 0x72, 0x94, 0x87, 0xC9, 0x02, 0x5D, 0x18, 0x10, 0x51, 0x29, 0xFA, 0x0B, 0xA2, 0x94, 0x4D, - 0xA8, 0x6A, 0xF1, 0xDB, 0x2D, 0x03, 0x4B, 0xE2, 0xBB, 0x73, 0x64, 0x50, 0x0C, 0x05, 0xA6, 0xDE }, - }, - { - { 0x6C, 0x8D, 0x4E, 0x52, 0x7E, 0x74, 0x08, 0x82, 0x6D, 0xB8, 0x4D, 0x04, 0x1A, 0x0E, 0x29, 0xD6, - 0xDE, 0x13, 0xA6, 0x1E, 0x63, 0x6B, 0xF6, 0xB6, 0xF5, 0xF6, 0x75, 0x42, 0x7A, 0xCE, 0xCE, 0x9E }, - }, - { - { 0x6C, 0x8F, 0xD1, 0xE6, 0xE1, 0x1B, 0xAF, 0xA6, 0x17, 0x78, 0x13, 0xA0, 0x44, 0x40, 0xB1, 0xB9, - 0x6A, 0x1C, 0xDB, 0x7C, 0x2D, 0x70, 0x3F, 0x55, 0xDE, 0x85, 0x7C, 0x80, 0xA8, 0x9E, 0x73, 0x25 }, - }, - { - { 0x6C, 0xC6, 0xDC, 0xDA, 0x58, 0xC6, 0x1F, 0xB2, 0x86, 0x70, 0xD1, 0xC2, 0x01, 0x76, 0x57, 0xB0, - 0xC5, 0xD6, 0x1A, 0x26, 0xC9, 0xCB, 0xD1, 0xEA, 0x75, 0x5C, 0x68, 0x20, 0xB5, 0xF6, 0xD6, 0x7D }, - }, - { - { 0x6C, 0xC8, 0x0F, 0x47, 0x96, 0x4E, 0x0D, 0xCB, 0x39, 0xE4, 0xD0, 0x1B, 0x3B, 0x3E, 0xBC, 0x8B, - 0x9C, 0x77, 0xB4, 0x08, 0x59, 0xBB, 0x5D, 0x5C, 0x31, 0x27, 0x4D, 0xA5, 0x39, 0xFA, 0xCA, 0x8D }, - }, - { - { 0x6D, 0x32, 0xF4, 0x93, 0x40, 0x56, 0xEE, 0x17, 0x14, 0xCA, 0x72, 0x70, 0x3F, 0x64, 0x46, 0x9B, - 0x98, 0x58, 0xFC, 0x39, 0x96, 0x4B, 0x4C, 0x03, 0x93, 0xB3, 0x7D, 0xDE, 0xAB, 0x8B, 0x19, 0x75 }, - }, - { - { 0x6D, 0x4E, 0xD4, 0x29, 0x38, 0x15, 0x90, 0xBD, 0x3C, 0x6B, 0x7C, 0xB7, 0xE4, 0xE4, 0x25, 0xC8, - 0xE2, 0x1F, 0x79, 0xFF, 0x4D, 0x40, 0x00, 0xB9, 0x65, 0x3F, 0xA1, 0x27, 0xE1, 0x41, 0xD3, 0x50 }, - }, - { - { 0x6D, 0x4E, 0xE5, 0x3B, 0xF9, 0x9F, 0xFA, 0xBB, 0x1C, 0x9B, 0x77, 0x96, 0x66, 0xEF, 0xC4, 0x5E, - 0x6A, 0xB3, 0xFA, 0x74, 0xAB, 0x37, 0x30, 0x9F, 0x8C, 0xDE, 0xF7, 0x2C, 0x94, 0x39, 0x23, 0xEE }, - }, - { - { 0x6D, 0x84, 0x0B, 0xBB, 0xA9, 0x3F, 0x53, 0x9B, 0xE0, 0x84, 0x9D, 0x26, 0xD5, 0x27, 0x7B, 0xD7, - 0xF2, 0x4B, 0xBA, 0x93, 0x5E, 0x05, 0x0D, 0x11, 0x26, 0xD7, 0x78, 0x22, 0xB5, 0x90, 0x26, 0x83 }, - }, - { - { 0x6D, 0xC9, 0x87, 0x5C, 0xD3, 0x46, 0xA2, 0x2B, 0x47, 0xB2, 0x80, 0xB1, 0xB1, 0x45, 0x0D, 0x87, - 0x8E, 0x09, 0x8B, 0xB2, 0xE2, 0xA9, 0xE3, 0xC2, 0x5C, 0xC7, 0x6A, 0xFF, 0x93, 0xC0, 0xBE, 0xAB }, - }, - { - { 0x6E, 0x0C, 0x0B, 0x5D, 0x7B, 0x82, 0x23, 0x21, 0x87, 0x41, 0xE6, 0x7B, 0x87, 0x6C, 0xCB, 0x8C, - 0xB5, 0x81, 0x11, 0x48, 0x82, 0x87, 0xDA, 0x8C, 0x30, 0x64, 0xE8, 0x2E, 0xCC, 0xC2, 0x70, 0x12 }, - }, - { - { 0x6E, 0x16, 0x35, 0x9E, 0x05, 0xEB, 0x14, 0xEC, 0x86, 0xEE, 0xE5, 0x9D, 0x01, 0x0C, 0xD6, 0x4F, - 0x1D, 0x1B, 0x4B, 0xA1, 0xEF, 0x46, 0xA2, 0x0F, 0x35, 0xC6, 0xA6, 0x3D, 0xC5, 0x3A, 0x2A, 0xCB }, - }, - { - { 0x6E, 0x1A, 0x88, 0x63, 0xF2, 0x93, 0x4B, 0x39, 0x01, 0x23, 0x7E, 0x84, 0xD0, 0x76, 0x27, 0x04, - 0x23, 0x06, 0x78, 0x7F, 0x2D, 0xE0, 0x66, 0x30, 0xBD, 0x37, 0xD8, 0x03, 0x94, 0x35, 0xBF, 0xCA }, - }, - { - { 0x6E, 0x1C, 0xB1, 0x2A, 0x08, 0x3C, 0x89, 0x08, 0xFB, 0x06, 0x04, 0x56, 0xEE, 0xE8, 0x74, 0xED, - 0xD9, 0xFA, 0x71, 0x3F, 0x26, 0x95, 0xEE, 0x5E, 0xE8, 0x59, 0x84, 0x83, 0xE3, 0x02, 0x8F, 0x0B }, - }, - { - { 0x6E, 0x8D, 0x55, 0xEE, 0x2F, 0x72, 0x5A, 0x0B, 0xA5, 0xDF, 0x43, 0x43, 0xA0, 0x6F, 0xD3, 0x71, - 0x54, 0x25, 0x6B, 0xCF, 0xF7, 0xCE, 0xE0, 0xB7, 0x00, 0xAC, 0xDD, 0x91, 0x56, 0x49, 0x79, 0x99 }, - }, - { - { 0x6E, 0xB8, 0xA7, 0xBA, 0x7F, 0xC2, 0x1C, 0x62, 0x40, 0x3F, 0x63, 0x76, 0xBB, 0x10, 0x44, 0x82, - 0x48, 0x8D, 0xA9, 0xC1, 0x41, 0x4A, 0xE3, 0xAB, 0x06, 0xE0, 0x1E, 0xD7, 0x32, 0x42, 0xAB, 0xD7 }, - }, - { - { 0x6E, 0xEB, 0x39, 0xDA, 0xD7, 0x3F, 0xC5, 0x99, 0x72, 0x42, 0x17, 0xCF, 0xF0, 0x21, 0xD5, 0xAC, - 0x4E, 0x7E, 0x2B, 0xF4, 0x76, 0xEA, 0xF4, 0xFD, 0x4D, 0x7B, 0xFB, 0x6E, 0x4F, 0x18, 0xC1, 0x73 }, - }, - { - { 0x6F, 0x1C, 0x4A, 0x29, 0x79, 0xFC, 0xBE, 0xAD, 0xC5, 0xD5, 0x80, 0xE5, 0xBF, 0xDB, 0xF8, 0x4C, - 0xC6, 0xA0, 0xF2, 0xA9, 0x2E, 0xB1, 0xC6, 0x88, 0xD5, 0x31, 0x3A, 0x0F, 0xDA, 0xCF, 0x0B, 0x56 }, - }, - { - { 0x6F, 0x3B, 0xB3, 0x4B, 0x5D, 0x32, 0x91, 0xDF, 0xB3, 0xE4, 0x12, 0x71, 0xA1, 0xD7, 0x30, 0xCD, - 0xBC, 0xFF, 0xC1, 0x0B, 0x68, 0x05, 0x9D, 0xCC, 0xD3, 0x1C, 0x47, 0x4B, 0xB7, 0x44, 0x16, 0xE5 }, - }, - { - { 0x6F, 0x7E, 0x99, 0xB2, 0x6C, 0xF2, 0x57, 0x61, 0xCA, 0x87, 0xD7, 0x0E, 0xB1, 0xDD, 0x32, 0xCD, - 0x0D, 0x2B, 0xD1, 0xFE, 0x7F, 0x62, 0x2E, 0xF6, 0x47, 0x18, 0x9C, 0xEB, 0x91, 0x43, 0x8D, 0x99 }, - }, - { - { 0x6F, 0x92, 0x7B, 0x13, 0xE5, 0x9C, 0xA9, 0x87, 0x61, 0x82, 0x07, 0xAF, 0xED, 0xE2, 0xE8, 0xE1, - 0xD9, 0xC3, 0x03, 0xE1, 0xF1, 0x2F, 0x19, 0x2D, 0xF3, 0xF7, 0x0E, 0x5D, 0x1D, 0x4D, 0x2C, 0x18 }, - }, - { - { 0x6F, 0x95, 0xDB, 0x28, 0x26, 0x61, 0x3C, 0xA6, 0x12, 0x0D, 0x81, 0x15, 0xFB, 0xA3, 0xDD, 0x0A, - 0x2A, 0x22, 0x31, 0x2D, 0x74, 0x88, 0xBF, 0x77, 0x0F, 0x9C, 0x57, 0x96, 0xC9, 0x02, 0xBC, 0xC3 }, - }, - { - { 0x6F, 0xB0, 0x06, 0xB4, 0x5F, 0x4A, 0xB6, 0xF5, 0x28, 0x12, 0xBD, 0x1F, 0x9D, 0x8C, 0xF1, 0x0E, - 0x2B, 0x4C, 0x8C, 0xE5, 0x2A, 0x4D, 0xF6, 0x56, 0x84, 0xF3, 0x08, 0x48, 0x1C, 0xEE, 0xC8, 0x93 }, - }, - { - { 0x6F, 0xBD, 0xCD, 0xF1, 0xB4, 0x37, 0x9F, 0xC4, 0x73, 0xAB, 0x5E, 0xEA, 0x4E, 0xC2, 0xF4, 0x84, - 0xCE, 0x91, 0xD1, 0x0E, 0x31, 0x34, 0x5F, 0x15, 0xA7, 0x6A, 0x84, 0x85, 0xB8, 0xFF, 0xFB, 0x7E }, - }, - { - { 0x6F, 0xDC, 0x18, 0xD6, 0x55, 0x14, 0xDD, 0xCE, 0xF0, 0x2F, 0xEA, 0x81, 0x7A, 0x1B, 0x70, 0x84, - 0x71, 0x95, 0xFF, 0x5C, 0x07, 0xB1, 0x3D, 0x6A, 0x97, 0x1E, 0x0E, 0x77, 0x4B, 0x44, 0x10, 0xA0 }, - }, - { - { 0x70, 0xB8, 0xEC, 0xD5, 0x62, 0xEC, 0x3D, 0x9F, 0x48, 0x64, 0x75, 0x2A, 0x3A, 0x8C, 0x54, 0x39, - 0x93, 0xB4, 0x38, 0x72, 0x8F, 0xE2, 0x71, 0x81, 0xF4, 0xC0, 0x8D, 0xE6, 0xA0, 0xD8, 0xB7, 0x9A }, - }, - { - { 0x70, 0xE0, 0xB7, 0xF5, 0xC7, 0xA3, 0xD1, 0xF3, 0x96, 0x85, 0x84, 0x5D, 0x94, 0xFC, 0x9E, 0x77, - 0x7C, 0x12, 0x69, 0xCF, 0x15, 0x31, 0x68, 0x51, 0x98, 0x3D, 0x60, 0x58, 0x76, 0x1C, 0xF0, 0x63 }, - }, - { - { 0x70, 0xED, 0x64, 0x0C, 0xBC, 0xE7, 0x84, 0xA6, 0x8E, 0xCD, 0xD6, 0x32, 0x0B, 0x61, 0x3C, 0x88, - 0x42, 0xE6, 0xD7, 0x09, 0xBD, 0x96, 0xF1, 0xD2, 0x43, 0xE4, 0xB2, 0x1E, 0xED, 0x8B, 0x12, 0x8C }, - }, - { - { 0x71, 0x1E, 0xF0, 0x96, 0x33, 0x43, 0x8A, 0xC5, 0xBE, 0x9D, 0xA8, 0x12, 0x2E, 0x7A, 0xCF, 0x0E, - 0xA2, 0x68, 0xB8, 0x72, 0xAD, 0xDC, 0x3E, 0xE8, 0x37, 0x2B, 0x91, 0x6D, 0x60, 0x65, 0xCF, 0xA8 }, - }, - { - { 0x71, 0xCF, 0x8D, 0x5C, 0x16, 0xF0, 0xDF, 0x67, 0xD2, 0x3F, 0x67, 0x06, 0xAE, 0xB9, 0x7C, 0x8E, - 0xAE, 0x2C, 0xAF, 0xC6, 0xBE, 0xC9, 0x4A, 0x4D, 0xB2, 0x40, 0x5A, 0x37, 0xFF, 0x30, 0x92, 0x5F }, - }, - { - { 0x72, 0x1B, 0x1F, 0x92, 0x9D, 0xA7, 0xEA, 0xF8, 0x96, 0x24, 0x64, 0x7B, 0xA3, 0xCC, 0x4E, 0x1E, - 0xD1, 0x57, 0x54, 0xAB, 0x83, 0x6E, 0x33, 0x58, 0xB0, 0x35, 0xA1, 0xF2, 0x27, 0x4A, 0x43, 0xBE }, - }, - { - { 0x72, 0xAA, 0x1A, 0xF2, 0x9A, 0xB0, 0x96, 0x5B, 0x34, 0x57, 0x14, 0x79, 0x84, 0x9B, 0x84, 0x74, - 0xB8, 0x81, 0x80, 0xE2, 0x1B, 0x98, 0x58, 0x92, 0x9B, 0xD6, 0x3E, 0x30, 0x91, 0x9C, 0xFC, 0xD9 }, - }, - { - { 0x72, 0xB6, 0x11, 0x01, 0x0E, 0xA4, 0x7D, 0x3D, 0x1E, 0x24, 0x53, 0xD7, 0x9D, 0x19, 0x03, 0x15, - 0x53, 0x4E, 0x55, 0x31, 0x2A, 0x7E, 0xBC, 0xAA, 0xB0, 0xE5, 0x5F, 0xF0, 0x03, 0x41, 0xD7, 0x14 }, - }, - { - { 0x72, 0xE7, 0x49, 0x87, 0x21, 0x0C, 0x7E, 0xF6, 0x67, 0x46, 0xE4, 0x9A, 0x96, 0xDF, 0x55, 0xCC, - 0x6F, 0xAD, 0xF7, 0xA6, 0x31, 0xC7, 0xAE, 0x3F, 0x3E, 0x9E, 0x18, 0x72, 0x3D, 0xE5, 0x2A, 0x6E }, - }, - { - { 0x73, 0x06, 0x2E, 0xFC, 0x20, 0xB4, 0x17, 0xF7, 0x4C, 0xD1, 0xA4, 0xE6, 0xA6, 0x36, 0x9F, 0x97, - 0x18, 0x86, 0x94, 0xFF, 0x9D, 0xCE, 0xFF, 0x1F, 0x5E, 0x4C, 0x11, 0x99, 0x74, 0x44, 0x6A, 0x3F }, - }, - { - { 0x73, 0x29, 0x62, 0x43, 0xC0, 0xDD, 0x61, 0xB1, 0x7F, 0x5C, 0x58, 0x89, 0x4C, 0x31, 0x3E, 0xF7, - 0xA8, 0x48, 0xAE, 0xE3, 0x1B, 0x08, 0x96, 0xE0, 0xB3, 0xE1, 0x51, 0x7F, 0x6E, 0x6D, 0x9F, 0x2F }, - }, - { - { 0x73, 0x3B, 0x42, 0x24, 0x25, 0x8D, 0xEE, 0x07, 0x0E, 0xDF, 0xA3, 0x41, 0x1F, 0xBC, 0x9B, 0xAD, - 0x31, 0x65, 0xBE, 0x66, 0x0F, 0x34, 0x0A, 0xA2, 0x30, 0x8A, 0x5A, 0x33, 0x23, 0xFA, 0xBF, 0xA7 }, - }, - { - { 0x73, 0x46, 0x99, 0x89, 0x4A, 0xD4, 0xB5, 0xA8, 0xA2, 0xDD, 0x9A, 0xB4, 0xFD, 0x5F, 0x63, 0x25, - 0x30, 0x3B, 0x49, 0x16, 0x4C, 0xA8, 0xD8, 0xE7, 0xBA, 0x99, 0x77, 0x81, 0x7E, 0x4A, 0xE2, 0x4F }, - }, - { - { 0x73, 0x9D, 0x17, 0x23, 0x23, 0xF2, 0xB2, 0x84, 0x07, 0x0A, 0xCE, 0x43, 0x09, 0x8C, 0x8B, 0x21, - 0xC4, 0x7A, 0x53, 0xF9, 0x98, 0x5F, 0x2F, 0xAD, 0x5F, 0x8B, 0x2E, 0xB7, 0x03, 0x4F, 0xDB, 0x21 }, - }, - { - { 0x73, 0xB4, 0x34, 0x22, 0x97, 0x6D, 0xAE, 0x7F, 0x98, 0x1E, 0xE5, 0x0A, 0xD7, 0x5B, 0xE2, 0x3A, - 0x41, 0xFF, 0x77, 0x09, 0xA7, 0x25, 0x2A, 0x4D, 0x15, 0x98, 0x52, 0x5F, 0x9D, 0x88, 0x22, 0x97 }, - }, - { - { 0x73, 0xBF, 0x46, 0xA8, 0x4B, 0x39, 0x94, 0xC7, 0x08, 0xA8, 0x2C, 0xD7, 0xC5, 0xB7, 0xAF, 0xFC, - 0xF9, 0x09, 0xF9, 0x6F, 0x16, 0x8E, 0x8D, 0xD1, 0xBD, 0x1A, 0xDB, 0xC7, 0x15, 0x99, 0xEC, 0xAA }, - }, - { - { 0x74, 0x2F, 0xCF, 0x73, 0x56, 0x51, 0xCE, 0xB1, 0x84, 0x3C, 0xE3, 0xD6, 0x56, 0x72, 0x34, 0x68, - 0xAB, 0x22, 0x85, 0x6C, 0x6A, 0x80, 0x56, 0xB9, 0x1C, 0x75, 0xC5, 0x8A, 0x67, 0xEC, 0xA8, 0xBE }, - }, - { - { 0x74, 0x54, 0x0F, 0xA5, 0x0A, 0x36, 0x2E, 0x68, 0x6D, 0x99, 0x17, 0x98, 0x18, 0x35, 0x09, 0x83, - 0x6C, 0x95, 0xA3, 0xFB, 0x04, 0x58, 0x00, 0x22, 0xF9, 0x68, 0x58, 0x4F, 0x8A, 0xCF, 0x60, 0x1F }, - }, - { - { 0x74, 0x8D, 0x42, 0x49, 0x6D, 0xA9, 0x25, 0x45, 0x90, 0x54, 0xE1, 0x3E, 0x38, 0xEC, 0x9F, 0x8E, - 0x6C, 0x5F, 0x97, 0x29, 0x7A, 0xB3, 0xA0, 0x14, 0x58, 0x99, 0x85, 0x26, 0xB0, 0xFD, 0x3A, 0xED }, - }, - { - { 0x74, 0xA9, 0x27, 0xE7, 0xB2, 0xF1, 0xF6, 0x48, 0x3D, 0xC2, 0x59, 0x21, 0xAB, 0xBE, 0x2F, 0x97, - 0x74, 0xA2, 0x0C, 0xB8, 0x96, 0xBA, 0xB5, 0x64, 0x8C, 0x2A, 0xB0, 0xF9, 0xDB, 0xDA, 0x3D, 0xA6 }, - }, - { - { 0x75, 0x83, 0x10, 0x84, 0x6A, 0xD5, 0x74, 0x05, 0x71, 0x1A, 0xDC, 0x4A, 0x1A, 0xF0, 0xEC, 0x51, - 0x8F, 0x82, 0x2D, 0x1A, 0x6C, 0xA9, 0x1E, 0xC2, 0x51, 0xF1, 0x22, 0xD4, 0x10, 0x6F, 0x99, 0xD9 }, - }, - { - { 0x75, 0x86, 0x5A, 0xA6, 0xFC, 0x45, 0x8E, 0x5A, 0x7B, 0x63, 0x04, 0x07, 0x07, 0x4F, 0x43, 0x11, - 0x1D, 0xD9, 0x21, 0x24, 0xB7, 0x7C, 0xE4, 0x02, 0x6D, 0x82, 0x41, 0xCF, 0x23, 0x71, 0xD9, 0xCC }, - }, - { - { 0x75, 0xBB, 0x15, 0x25, 0x09, 0xB7, 0x19, 0x04, 0xE4, 0x40, 0x0F, 0xB4, 0x23, 0xA5, 0x80, 0xAA, - 0xE1, 0xDD, 0xB7, 0x68, 0xF6, 0xFD, 0x36, 0xE6, 0x30, 0x94, 0xEB, 0xE3, 0x92, 0x15, 0xF3, 0x90 }, - }, - { - { 0x75, 0xC1, 0x6D, 0x87, 0x10, 0x9A, 0x9D, 0x86, 0xE3, 0x90, 0x2E, 0xE1, 0xE0, 0x7B, 0xE1, 0x13, - 0xB4, 0x15, 0x53, 0x0D, 0xC7, 0x3F, 0x7F, 0x7F, 0x1D, 0x7F, 0xE0, 0xDB, 0x7B, 0x02, 0x50, 0x30 }, - }, - { - { 0x75, 0xE9, 0xA1, 0x5D, 0x94, 0x88, 0x0C, 0x66, 0x14, 0x82, 0xCF, 0xC1, 0x96, 0x4C, 0xBC, 0xE2, - 0xB1, 0xCA, 0x7A, 0x9F, 0x81, 0xD4, 0x07, 0x30, 0x12, 0x47, 0x1F, 0x27, 0x23, 0xCB, 0x72, 0x8A }, - }, - { - { 0x76, 0x73, 0x18, 0x0F, 0x9D, 0x9A, 0x85, 0x48, 0x4B, 0x5C, 0x16, 0x99, 0xA2, 0xDC, 0x17, 0xFC, - 0x61, 0x13, 0xA3, 0xED, 0x5B, 0xC9, 0xC0, 0x55, 0x8C, 0xB8, 0x2D, 0xFF, 0x9E, 0x50, 0x32, 0x09 }, - }, - { - { 0x76, 0x98, 0x67, 0x60, 0xAC, 0xFE, 0x55, 0x59, 0xA2, 0xA2, 0xAB, 0x2A, 0x4E, 0x85, 0x49, 0x83, - 0xC5, 0xFD, 0xE6, 0x73, 0xCE, 0x8E, 0xB1, 0x71, 0x23, 0x49, 0x48, 0x64, 0x86, 0x7A, 0x98, 0xB1 }, - }, - { - { 0x76, 0xBC, 0x5D, 0x17, 0xFE, 0x9F, 0x0E, 0x89, 0x7E, 0x4D, 0xDB, 0x87, 0xD5, 0xB8, 0xDD, 0x2E, - 0xB2, 0xAC, 0x82, 0xF6, 0xA3, 0x11, 0x06, 0xED, 0xFD, 0x67, 0xDD, 0xCD, 0xE6, 0xA4, 0x3F, 0x17 }, - }, - { - { 0x76, 0xCA, 0x72, 0xCC, 0x37, 0xAB, 0x2A, 0xA3, 0x83, 0x98, 0x71, 0x0F, 0x02, 0x20, 0xFA, 0xF3, - 0x30, 0x1D, 0x54, 0x49, 0x38, 0xFB, 0x24, 0x19, 0x2D, 0xEC, 0x32, 0xF7, 0x44, 0xE4, 0x22, 0x10 }, - }, - { - { 0x76, 0xCD, 0xF0, 0x78, 0xA8, 0x89, 0x1F, 0x1B, 0x3D, 0x0A, 0xA7, 0x1D, 0x6E, 0x18, 0xD7, 0x6A, - 0x4D, 0x20, 0x7A, 0xAF, 0x84, 0xC6, 0x12, 0x95, 0x0E, 0xDF, 0xCD, 0x92, 0x82, 0xA1, 0x11, 0x44 }, - }, - { - { 0x77, 0x4F, 0x40, 0x72, 0x98, 0x9C, 0xA1, 0x55, 0x18, 0x17, 0x73, 0xB0, 0x55, 0x07, 0x6F, 0xFD, - 0x10, 0x21, 0x82, 0xC6, 0xAB, 0xE2, 0xA9, 0xCE, 0x03, 0x0F, 0x8D, 0xF2, 0x99, 0x56, 0xE1, 0x48 }, - }, - { - { 0x77, 0x59, 0x71, 0xD4, 0x48, 0x9D, 0xBE, 0x27, 0x72, 0xDB, 0x72, 0xAC, 0x28, 0xB8, 0xB3, 0x71, - 0xB0, 0x21, 0xC3, 0xD6, 0x26, 0x14, 0xD0, 0x7B, 0x6F, 0x5B, 0x8C, 0x2A, 0x57, 0x70, 0x25, 0xAE }, - }, - { - { 0x77, 0x95, 0x6B, 0x48, 0xCD, 0xD9, 0x15, 0x0B, 0xD8, 0x7D, 0x8D, 0x81, 0x50, 0x60, 0xAC, 0x8C, - 0x84, 0x81, 0x3A, 0x53, 0x87, 0x1A, 0x58, 0x6A, 0x69, 0x8B, 0x18, 0x79, 0x89, 0x13, 0xD3, 0xB8 }, - }, - { - { 0x77, 0xAC, 0x72, 0x54, 0x6A, 0x39, 0xCA, 0x2F, 0x24, 0xE2, 0xD1, 0x3C, 0x0D, 0x74, 0x91, 0x5F, - 0x67, 0xBC, 0xD4, 0x37, 0x09, 0xA9, 0xE5, 0xDB, 0x8B, 0x33, 0x1A, 0x55, 0x77, 0xFD, 0x50, 0x88 }, - }, - { - { 0x77, 0xB7, 0xCC, 0x99, 0xCE, 0x02, 0x4E, 0x0B, 0x7E, 0xD5, 0x33, 0xC9, 0x9C, 0xC8, 0x25, 0x08, - 0xEB, 0xA6, 0xAC, 0x3A, 0x0B, 0xE5, 0xBC, 0xBF, 0x7A, 0xC9, 0x94, 0x95, 0x2B, 0x6D, 0x35, 0x07 }, - }, - { - { 0x77, 0xB9, 0x6A, 0x00, 0x77, 0x15, 0xA0, 0x8C, 0x6A, 0x22, 0xDB, 0x14, 0xC7, 0xF4, 0xF1, 0xD7, - 0xF4, 0xA7, 0x41, 0xCE, 0x47, 0x32, 0xEC, 0xF8, 0x3E, 0x74, 0xC1, 0xC9, 0x63, 0x22, 0x83, 0xCD }, - }, - { - { 0x77, 0xDD, 0xC8, 0x1B, 0xD2, 0x8B, 0x9D, 0x46, 0x1E, 0x7D, 0x3C, 0xD4, 0xA8, 0x12, 0x2A, 0xA9, - 0x8A, 0x24, 0x60, 0xFB, 0xA0, 0x8F, 0x1B, 0x7B, 0xAC, 0xB6, 0x6C, 0x92, 0xD7, 0x99, 0x1C, 0xCC }, - }, - { - { 0x78, 0x0C, 0x33, 0xFE, 0x95, 0x4C, 0xC4, 0xDB, 0x39, 0x04, 0xD7, 0x6A, 0x68, 0x58, 0xBC, 0xD1, - 0x01, 0x7F, 0x52, 0xDA, 0x59, 0x9D, 0x36, 0xDA, 0xE6, 0x66, 0xC0, 0x4E, 0x41, 0xAF, 0x8D, 0xCD }, - }, - { - { 0x78, 0x41, 0x36, 0x37, 0x9B, 0xA0, 0xDB, 0xD7, 0xB3, 0xBA, 0xDC, 0x52, 0xDC, 0xE6, 0xBB, 0x81, - 0x07, 0xA3, 0x56, 0xC8, 0x48, 0x3F, 0x13, 0xE1, 0x69, 0x75, 0x0B, 0xC2, 0x07, 0x0A, 0x67, 0xD9 }, - }, - { - { 0x78, 0xC9, 0x30, 0x40, 0x5A, 0x72, 0x0D, 0x9F, 0x00, 0x66, 0xDD, 0x88, 0xA2, 0xA8, 0xDA, 0xFB, - 0xBE, 0x6C, 0xD6, 0x5D, 0x54, 0xB7, 0x76, 0x06, 0x42, 0x1B, 0x45, 0x43, 0x8C, 0x65, 0x8A, 0xD4 }, - }, - { - { 0x79, 0x17, 0x21, 0x35, 0x7E, 0x4B, 0xA1, 0x38, 0xE0, 0x3D, 0x59, 0xBA, 0xC1, 0x41, 0x42, 0x80, - 0x52, 0xE9, 0x88, 0x42, 0x39, 0x84, 0x7A, 0x4D, 0x92, 0xCA, 0xC0, 0x9F, 0xEB, 0xFE, 0x6A, 0xA4 }, - }, - { - { 0x79, 0x44, 0x5A, 0x43, 0x7B, 0xBE, 0xB4, 0xA5, 0x59, 0xC8, 0x1C, 0x8E, 0x57, 0xBB, 0xFB, 0x18, - 0x66, 0xE2, 0xE2, 0xBF, 0x6E, 0x70, 0xA5, 0x63, 0x22, 0x1B, 0x62, 0x7B, 0x71, 0x7D, 0xE6, 0xB1 }, - }, - { - { 0x79, 0x8F, 0x83, 0xB1, 0xC4, 0xC6, 0x5C, 0x4D, 0x5D, 0xEA, 0x13, 0x03, 0x53, 0x53, 0xD8, 0xED, - 0xE5, 0xD7, 0x1D, 0x99, 0x47, 0xF4, 0x34, 0xFD, 0xEA, 0x0D, 0xBC, 0x1E, 0xC8, 0x2F, 0x45, 0x35 }, - }, - { - { 0x79, 0x94, 0x68, 0xFC, 0x28, 0x7D, 0x4F, 0x78, 0x13, 0xBD, 0xC1, 0x53, 0xF2, 0x8F, 0x77, 0x91, - 0x24, 0xCB, 0x79, 0xAE, 0xC9, 0x35, 0xB2, 0x2C, 0x7A, 0x6A, 0xAC, 0xB9, 0x8D, 0xD5, 0x14, 0x0C }, - }, - { - { 0x79, 0xA8, 0xFC, 0x72, 0x70, 0xB2, 0xE5, 0xF3, 0x35, 0x6B, 0x09, 0xC6, 0xB8, 0x64, 0xFC, 0x92, - 0xE5, 0xFB, 0xC9, 0xE6, 0x9B, 0xEC, 0x93, 0xA4, 0xE3, 0x3B, 0x8D, 0xF5, 0x75, 0x60, 0x17, 0xBE }, - }, - { - { 0x79, 0xBE, 0x4E, 0x3A, 0x42, 0x2B, 0x14, 0x29, 0x92, 0xEA, 0x5B, 0xAB, 0xFC, 0x3A, 0xAD, 0x5F, - 0x31, 0xDB, 0x1C, 0x40, 0xEF, 0x82, 0x9A, 0x38, 0x03, 0xF7, 0xF5, 0xCF, 0xEF, 0xEF, 0xD1, 0x60 }, - }, - { - { 0x7A, 0x1E, 0x5E, 0xA4, 0xE9, 0x74, 0xEB, 0x10, 0x8A, 0xDA, 0x2D, 0xDF, 0xBD, 0x06, 0x8A, 0xC3, - 0x5D, 0x0F, 0x9D, 0xFA, 0xE6, 0x70, 0xF3, 0xE3, 0x95, 0xD4, 0x03, 0x7C, 0x3F, 0x8C, 0x4D, 0xD0 }, - }, - { - { 0x7A, 0x31, 0xB7, 0x14, 0x7A, 0x27, 0x75, 0x33, 0x8B, 0xFA, 0x3D, 0x0B, 0xBB, 0x68, 0x56, 0x33, - 0xFE, 0xB8, 0x5E, 0x2A, 0xF9, 0x4D, 0x71, 0xBF, 0x2B, 0x64, 0x0B, 0xE1, 0xE7, 0x1C, 0xE8, 0x34 }, - }, - { - { 0x7A, 0x33, 0x5D, 0x4D, 0xB3, 0x54, 0x8B, 0xA0, 0xA4, 0x73, 0x79, 0x7D, 0x3A, 0x5B, 0xE2, 0x58, - 0x4B, 0x42, 0x55, 0x83, 0xAD, 0x6F, 0x28, 0x69, 0xD4, 0x79, 0xB9, 0x72, 0xBD, 0x0F, 0x53, 0xCA }, - }, - { - { 0x7A, 0x42, 0xD5, 0x7B, 0x05, 0x32, 0x4E, 0x85, 0x83, 0x55, 0x05, 0x58, 0x26, 0xB1, 0x55, 0x17, - 0x42, 0x5B, 0x5A, 0x18, 0x9C, 0x17, 0xB4, 0x7C, 0x18, 0x4C, 0xAC, 0xE7, 0xAC, 0x63, 0x18, 0xD0 }, - }, - { - { 0x7A, 0x4C, 0x08, 0x9A, 0x75, 0xD1, 0x85, 0x93, 0x3C, 0xA0, 0xB8, 0x24, 0xB3, 0x86, 0x08, 0xE2, - 0x6F, 0x2D, 0xF0, 0x15, 0x01, 0x62, 0x26, 0xD2, 0x15, 0x8A, 0x7B, 0x3B, 0x82, 0x02, 0x9A, 0x05 }, - }, - { - { 0x7A, 0x5B, 0x68, 0x1E, 0x54, 0x45, 0x1D, 0xCB, 0x0A, 0xA6, 0x0D, 0x9F, 0x02, 0xFD, 0x13, 0x7F, - 0xA5, 0xC1, 0x9E, 0x2B, 0xF7, 0x30, 0xC8, 0x9F, 0x36, 0xC9, 0x1C, 0xC6, 0xE7, 0x8C, 0xC6, 0xFB }, - }, - { - { 0x7B, 0x2C, 0x84, 0x1F, 0x5A, 0x96, 0x35, 0x28, 0xC8, 0x79, 0x9F, 0x4B, 0x71, 0x48, 0xF9, 0xF2, - 0xA5, 0x05, 0x15, 0x76, 0x06, 0x9D, 0xEF, 0xD9, 0xF6, 0xC0, 0xCA, 0x31, 0x3D, 0xF2, 0xDB, 0x99 }, - }, - { - { 0x7B, 0x78, 0xBF, 0x4D, 0x71, 0x4E, 0xDF, 0xD5, 0xCE, 0x84, 0xA3, 0x86, 0x6D, 0xDF, 0x14, 0x82, - 0x36, 0xBD, 0x80, 0xFC, 0xCA, 0x6B, 0x9E, 0xF2, 0x6D, 0xC5, 0xB0, 0xDF, 0x9F, 0xE3, 0xE2, 0x0F }, - }, - { - { 0x7B, 0x8D, 0xD4, 0xFC, 0x3F, 0xC9, 0xA9, 0x00, 0x77, 0x96, 0x0E, 0x15, 0x32, 0x2F, 0x9C, 0xD2, - 0x29, 0x8C, 0xF2, 0xED, 0x16, 0xC0, 0xDD, 0x3D, 0xDA, 0xB2, 0x3E, 0xDD, 0xBF, 0x4E, 0x28, 0xC0 }, - }, - { - { 0x7B, 0x93, 0xA8, 0x76, 0x2E, 0x89, 0x97, 0x0B, 0xFB, 0x19, 0xEC, 0x06, 0xE9, 0x39, 0x1E, 0x87, - 0x48, 0xB1, 0x69, 0x95, 0x1A, 0x8D, 0xA9, 0x86, 0x8F, 0x07, 0xEC, 0x68, 0xD0, 0x6A, 0x57, 0x34 }, - }, - { - { 0x7B, 0xFE, 0x47, 0xAE, 0xBA, 0x8B, 0x0A, 0x3A, 0x94, 0x5A, 0x88, 0xD8, 0xEF, 0x18, 0x91, 0xC9, - 0x89, 0x97, 0x8A, 0xBF, 0x12, 0x2E, 0xC5, 0xE0, 0x51, 0x4B, 0xE3, 0x6C, 0x3A, 0x7F, 0x22, 0x9B }, - }, - { - { 0x7C, 0x30, 0xFF, 0x35, 0xE7, 0x8A, 0xBA, 0x08, 0xF8, 0xA9, 0xB4, 0xD9, 0x8E, 0xA2, 0x9A, 0xE4, - 0xA5, 0xA4, 0x24, 0x72, 0xF5, 0x91, 0xCA, 0x11, 0xFB, 0x5E, 0x11, 0x21, 0x06, 0x28, 0x63, 0x96 }, - }, - { - { 0x7C, 0x63, 0xB8, 0x8E, 0x58, 0x19, 0x07, 0x0F, 0xC1, 0x4A, 0xDB, 0x67, 0xD6, 0xDA, 0xA1, 0x29, - 0x83, 0x14, 0x30, 0x4A, 0x9C, 0x05, 0x30, 0x18, 0x02, 0x7D, 0xF8, 0x36, 0x91, 0x4D, 0x73, 0xD4 }, - }, - { - { 0x7C, 0xA0, 0x86, 0x8B, 0xEB, 0xAE, 0x8A, 0xCA, 0x9D, 0x0F, 0x75, 0x38, 0x65, 0xC3, 0x2A, 0x0D, - 0x2D, 0xD4, 0xF1, 0x48, 0x6E, 0x37, 0x34, 0xA6, 0xA3, 0x71, 0x0E, 0xCC, 0x3E, 0x57, 0xF9, 0xED }, - }, - { - { 0x7C, 0xF9, 0x2F, 0x75, 0xBB, 0xE7, 0xA1, 0x4D, 0x86, 0x93, 0xF9, 0x93, 0xC3, 0xD1, 0xA6, 0x08, - 0xDB, 0xE0, 0xD1, 0x8F, 0x80, 0x8E, 0x21, 0x2D, 0xC8, 0xE1, 0xF5, 0xDA, 0x58, 0x04, 0xB3, 0x07 }, - }, - { - { 0x7D, 0x0D, 0x63, 0xAC, 0x53, 0x9B, 0xB6, 0xC1, 0x0F, 0x2C, 0xAC, 0x34, 0xC4, 0xE8, 0x08, 0xC5, - 0x23, 0xCB, 0x5F, 0xE2, 0x79, 0x44, 0xF3, 0xD1, 0x58, 0x84, 0x95, 0xCC, 0xB3, 0xFC, 0xF8, 0xE0 }, - }, - { - { 0x7D, 0x20, 0xC7, 0xA9, 0x27, 0x26, 0x2B, 0xE7, 0x38, 0xD2, 0x58, 0xD0, 0xFD, 0x97, 0x6E, 0x9A, - 0xF3, 0x6E, 0xF7, 0x99, 0x5F, 0x05, 0xE2, 0x87, 0x6A, 0x29, 0xAE, 0xBC, 0x3A, 0x24, 0xAA, 0xCE }, - }, - { - { 0x7D, 0x27, 0x04, 0xF3, 0x8E, 0x5D, 0x3F, 0x86, 0x0E, 0x58, 0xE9, 0x5F, 0xBD, 0x13, 0x57, 0x37, - 0xE6, 0x29, 0xE3, 0xF5, 0x3C, 0x07, 0xE2, 0x11, 0xBF, 0x48, 0x33, 0x86, 0x0C, 0xA5, 0x40, 0xC3 }, - }, - { - { 0x7D, 0x2D, 0x31, 0x2B, 0xA8, 0x5E, 0x81, 0xC4, 0xC5, 0xF0, 0x4B, 0xCB, 0x48, 0x3F, 0xF8, 0xCB, - 0x62, 0xFA, 0xF8, 0x32, 0xBE, 0x9F, 0x1E, 0xA0, 0x95, 0x0A, 0x12, 0x6E, 0xA2, 0x52, 0xBC, 0xE6 }, - }, - { - { 0x7D, 0xB2, 0x70, 0xBC, 0xAC, 0xD6, 0x26, 0x5D, 0x05, 0x05, 0x60, 0x85, 0x24, 0xA9, 0x03, 0xF9, - 0x87, 0xC1, 0xC8, 0xC9, 0xEA, 0xF5, 0x1F, 0x66, 0x65, 0x5E, 0xB8, 0x36, 0xB5, 0x05, 0xA6, 0xDA }, - }, - { - { 0x7D, 0xF7, 0x1C, 0x35, 0x19, 0x78, 0x05, 0x7A, 0x4D, 0x30, 0x0E, 0x15, 0xAD, 0xB7, 0xCF, 0x28, - 0xF1, 0xA5, 0xBB, 0x76, 0x92, 0x9C, 0x58, 0xA2, 0x50, 0x25, 0x3C, 0x30, 0x48, 0xF2, 0x88, 0xDB }, - }, - { - { 0x7E, 0x2E, 0xDB, 0x9D, 0x38, 0xF9, 0x29, 0x3C, 0xDD, 0xD6, 0x03, 0xB1, 0x75, 0xC9, 0xB2, 0x05, - 0xAC, 0x0B, 0x55, 0x3A, 0x4B, 0xF5, 0xFB, 0x08, 0xC2, 0x46, 0xEC, 0xF9, 0xC8, 0x49, 0xDB, 0x28 }, - }, - { - { 0x7E, 0x70, 0x13, 0x07, 0x36, 0xAE, 0xD9, 0xBC, 0xD2, 0x18, 0x44, 0x96, 0x6D, 0x0D, 0x1E, 0x2F, - 0xBA, 0x58, 0xE7, 0xC3, 0x9E, 0xA1, 0x47, 0x76, 0x13, 0xF7, 0x9E, 0x0F, 0x60, 0x40, 0xB5, 0x44 }, - }, - { - { 0x7E, 0x8A, 0x44, 0x80, 0xAB, 0x99, 0xAB, 0x10, 0x36, 0x89, 0xF4, 0x6F, 0xC9, 0xB7, 0x9F, 0xA0, - 0xD9, 0xFD, 0xA4, 0x64, 0xAF, 0x96, 0xEC, 0x20, 0xCC, 0xE6, 0xA2, 0x5B, 0x9C, 0xF7, 0xDC, 0xD3 }, - }, - { - { 0x7F, 0x41, 0xA6, 0x10, 0x7E, 0x34, 0x2B, 0x5D, 0x73, 0x80, 0x8D, 0xB0, 0x2A, 0x86, 0x8B, 0xB0, - 0xA8, 0xCB, 0xDE, 0xA3, 0x6A, 0x70, 0x54, 0x54, 0xAA, 0x8D, 0x86, 0xC8, 0xDE, 0x5C, 0x40, 0x55 }, - }, - { - { 0x7F, 0x83, 0xAC, 0xEF, 0xC5, 0x22, 0xD2, 0xAC, 0x23, 0xB2, 0x22, 0x10, 0xAF, 0x23, 0xE2, 0x99, - 0xEB, 0x69, 0x9A, 0x32, 0x1C, 0xBF, 0xDC, 0x78, 0xE4, 0x3A, 0x8C, 0xCB, 0x8F, 0x08, 0x6A, 0x84 }, - }, - { - { 0x7F, 0x86, 0xD3, 0xAA, 0x7E, 0xA7, 0x5C, 0x18, 0x03, 0x9D, 0x6A, 0xF9, 0x9C, 0xEF, 0x75, 0x04, - 0xCE, 0x7B, 0x05, 0x05, 0x9B, 0xBF, 0xE7, 0x3F, 0xCD, 0xEC, 0xFC, 0x71, 0xB2, 0x53, 0x8D, 0x72 }, - }, - { - { 0x7F, 0x95, 0x9B, 0x06, 0x34, 0xDA, 0x94, 0xFA, 0xCA, 0xDA, 0xB0, 0x21, 0xCF, 0x94, 0x20, 0x78, - 0x16, 0x00, 0x36, 0x13, 0xEF, 0x09, 0xEB, 0x54, 0xF6, 0x48, 0x60, 0x50, 0x08, 0x19, 0x02, 0x75 }, - }, - { - { 0x7F, 0x9A, 0x69, 0xCF, 0xA2, 0xF5, 0x0C, 0x13, 0xE1, 0xB7, 0x11, 0xDD, 0x6B, 0x14, 0x69, 0x2B, - 0xDB, 0x77, 0xD9, 0xFF, 0xD8, 0xC1, 0x10, 0xAE, 0x5D, 0x05, 0xA4, 0xCB, 0x73, 0x12, 0x37, 0x48 }, - }, - { - { 0x7F, 0xDD, 0xAE, 0x79, 0x7D, 0xA7, 0x9C, 0x9F, 0xA8, 0xD6, 0x9C, 0x15, 0x79, 0x31, 0x69, 0x22, - 0x13, 0x64, 0xEA, 0x95, 0xE7, 0xC1, 0xB2, 0x39, 0x71, 0x32, 0x3D, 0xB1, 0xB0, 0x88, 0xDE, 0x9C }, - }, - { - { 0x7F, 0xE5, 0x74, 0x9C, 0xA3, 0xF3, 0xDB, 0x71, 0xD5, 0xC7, 0x40, 0xD9, 0x75, 0x87, 0x16, 0x3D, - 0x21, 0x1E, 0xFF, 0xAF, 0x79, 0x40, 0xDA, 0x62, 0xA6, 0xAA, 0x07, 0xEC, 0x64, 0xBD, 0xFB, 0x2D }, - }, - { - { 0x80, 0x20, 0x56, 0xE1, 0xDB, 0x9D, 0x9B, 0x73, 0x21, 0xD1, 0xFF, 0xBB, 0xE1, 0x2F, 0x5C, 0xBE, - 0xDE, 0xC3, 0x6D, 0x0B, 0x5E, 0xC2, 0xA4, 0xE1, 0x8D, 0x99, 0x54, 0x36, 0x4C, 0xEC, 0x81, 0x29 }, - }, - { - { 0x80, 0x47, 0x74, 0x1D, 0x79, 0x7E, 0xB4, 0xED, 0x49, 0xE5, 0x1E, 0xD6, 0x77, 0x45, 0xA4, 0xE4, - 0xEE, 0x90, 0x23, 0xC4, 0x37, 0xAE, 0x53, 0x23, 0xCB, 0xEE, 0x97, 0x05, 0xEF, 0x9C, 0x4C, 0xD6 }, - }, - { - { 0x80, 0x58, 0x7F, 0x37, 0x5E, 0xA1, 0x5D, 0x52, 0x19, 0x26, 0xD7, 0x0B, 0x35, 0x26, 0xC0, 0x80, - 0xF4, 0x8C, 0x05, 0x6E, 0x9B, 0x13, 0x40, 0xCB, 0xBA, 0x1F, 0x9E, 0x11, 0xBB, 0xE8, 0x78, 0x96 }, - }, - { - { 0x80, 0x97, 0x63, 0x4C, 0xE3, 0x3D, 0x41, 0x53, 0x3D, 0x41, 0x5D, 0xAF, 0xDB, 0x8B, 0xA1, 0x91, - 0xC0, 0x30, 0x52, 0xAC, 0x8B, 0xAA, 0x25, 0x54, 0x34, 0x77, 0x3A, 0x16, 0x4B, 0x91, 0x1D, 0x6E }, - }, - { - { 0x80, 0xD0, 0x17, 0x09, 0x34, 0xD2, 0x2A, 0xEA, 0x73, 0x3F, 0x11, 0x5E, 0x52, 0x42, 0xC6, 0xB8, - 0x6D, 0x7F, 0xCF, 0xB4, 0x90, 0x4E, 0x65, 0xB7, 0xB7, 0xB9, 0x07, 0xF2, 0xCA, 0x94, 0xED, 0x71 }, - }, - { - { 0x80, 0xDC, 0xF7, 0x3D, 0xE4, 0x85, 0x8B, 0xDC, 0x49, 0x33, 0x9C, 0x62, 0xA6, 0xB6, 0x96, 0x93, - 0x31, 0x10, 0x03, 0x6E, 0x4F, 0x9E, 0xFD, 0x83, 0x4F, 0x22, 0xA7, 0xB6, 0x62, 0xF9, 0x5C, 0x6A }, - }, - { - { 0x80, 0xE7, 0x3A, 0x40, 0x88, 0xF2, 0x8A, 0x18, 0x67, 0xD5, 0x5D, 0xA9, 0x87, 0x67, 0xEF, 0x22, - 0xA5, 0xAE, 0xE8, 0xF4, 0x45, 0x0B, 0x61, 0x1B, 0x4B, 0x32, 0x78, 0xEF, 0x25, 0x87, 0xB6, 0x6B }, - }, - { - { 0x80, 0xF3, 0xEB, 0x58, 0xEA, 0x6A, 0xA2, 0x85, 0x11, 0xB0, 0x9B, 0x68, 0xF2, 0xDE, 0xF9, 0xB4, - 0xAF, 0xA9, 0x9C, 0x97, 0x44, 0xC0, 0xBE, 0x4E, 0x23, 0x94, 0x89, 0xF0, 0x4F, 0x75, 0xA3, 0xA5 }, - }, - { - { 0x80, 0xF6, 0xC1, 0xE5, 0x6A, 0xEC, 0x30, 0x64, 0x72, 0x50, 0x23, 0x05, 0x61, 0x06, 0x61, 0xF9, - 0x8A, 0x00, 0xA5, 0xAD, 0x10, 0x33, 0x1D, 0x57, 0xBE, 0xF0, 0xD9, 0x7F, 0x32, 0x2A, 0xD8, 0x48 }, - }, - { - { 0x81, 0x1D, 0xF2, 0xF4, 0x73, 0x6F, 0x85, 0x62, 0xE2, 0x02, 0xFD, 0x00, 0x75, 0x32, 0xF1, 0xDE, - 0x40, 0x17, 0x86, 0x1E, 0xFA, 0xBE, 0x67, 0x34, 0x20, 0xC2, 0x7F, 0x2E, 0x2A, 0x33, 0xFA, 0xC1 }, - }, - { - { 0x81, 0x1E, 0x37, 0x86, 0x37, 0xB1, 0xD2, 0xCB, 0xB1, 0x89, 0xAF, 0xD6, 0x74, 0x95, 0xFE, 0x8A, - 0xB9, 0xD8, 0x3A, 0x74, 0x2E, 0x35, 0x8C, 0xBB, 0xDB, 0xD1, 0x54, 0x98, 0xBF, 0x9C, 0x7B, 0x56 }, - }, - { - { 0x81, 0x21, 0x5F, 0x4C, 0x05, 0x58, 0x6C, 0x90, 0x8B, 0xA6, 0x65, 0x15, 0xD6, 0xA2, 0x64, 0x81, - 0xED, 0xDC, 0xD9, 0x89, 0x44, 0xAC, 0x01, 0x98, 0x40, 0xE9, 0xE3, 0x32, 0x2E, 0x35, 0x8D, 0xD2 }, - }, - { - { 0x81, 0xA0, 0xF1, 0xD0, 0x29, 0x46, 0x8E, 0xE8, 0x66, 0x36, 0x4A, 0x19, 0x8A, 0x26, 0x08, 0x58, - 0x30, 0xC2, 0xA4, 0x16, 0xE4, 0x9E, 0x22, 0x4C, 0xE8, 0x09, 0x66, 0xFC, 0xC4, 0x99, 0xD6, 0x36 }, - }, - { - { 0x81, 0xA9, 0x15, 0x6B, 0x26, 0x47, 0xCA, 0xFA, 0x38, 0xB2, 0xE3, 0x15, 0x1A, 0x5A, 0x5D, 0x17, - 0xDB, 0xED, 0x81, 0xE9, 0x07, 0x54, 0xD1, 0xE8, 0x25, 0xF0, 0xBF, 0xC9, 0x13, 0x7C, 0x8B, 0xBF }, - }, - { - { 0x81, 0xD4, 0xB0, 0x8A, 0xCD, 0x90, 0xF2, 0xDE, 0xE1, 0x8A, 0xC4, 0x20, 0xF5, 0x1D, 0xA9, 0x91, - 0x05, 0x35, 0x82, 0x47, 0xBB, 0x03, 0x87, 0xCF, 0xA9, 0x4D, 0xD9, 0x67, 0xA9, 0xCC, 0x18, 0x68 }, - }, - { - { 0x81, 0xEE, 0x8C, 0x58, 0x6E, 0xC3, 0xE4, 0x77, 0xC8, 0x1E, 0xF4, 0x44, 0xDF, 0x09, 0x5A, 0xE0, - 0x99, 0xD8, 0x06, 0x9B, 0x89, 0xFF, 0xB1, 0xD0, 0x8F, 0xAD, 0x75, 0x3E, 0xE4, 0xE9, 0x4F, 0x71 }, - }, - { - { 0x82, 0x2E, 0xBE, 0x7B, 0x2E, 0x8A, 0xF1, 0x78, 0x8A, 0x36, 0x08, 0x83, 0x84, 0xF4, 0xC0, 0x6A, - 0x6D, 0x65, 0x9D, 0x95, 0x56, 0x83, 0xF0, 0x99, 0xE2, 0x54, 0x2D, 0x97, 0x58, 0xE1, 0xA6, 0x21 }, - }, - { - { 0x82, 0x33, 0xDE, 0x42, 0x18, 0xE4, 0xEF, 0x19, 0x38, 0xE6, 0xA8, 0xA3, 0x8A, 0xB0, 0xBC, 0x1A, - 0x96, 0x4B, 0xA5, 0x76, 0x1A, 0x52, 0x99, 0x50, 0x22, 0x15, 0x0C, 0x86, 0x02, 0x6B, 0x90, 0xC9 }, - }, - { - { 0x82, 0x42, 0x7C, 0x6E, 0xF1, 0x1E, 0xCE, 0x3B, 0x94, 0x0B, 0xE6, 0xB3, 0x93, 0x62, 0x2F, 0xC9, - 0x51, 0x7D, 0xBC, 0xE1, 0xC0, 0x0C, 0xF9, 0x18, 0x50, 0x89, 0x64, 0x43, 0xF5, 0x38, 0x2F, 0x89 }, - }, - { - { 0x82, 0x4E, 0xF3, 0x18, 0x7F, 0x9C, 0xFE, 0x14, 0x27, 0x10, 0x13, 0xBC, 0xFB, 0x85, 0xE1, 0x4B, - 0x5A, 0x8E, 0x0D, 0x72, 0x1C, 0x3F, 0x53, 0x6E, 0x0F, 0xDD, 0xFF, 0x42, 0x4D, 0x1F, 0xA0, 0xD8 }, - }, - { - { 0x82, 0x56, 0x8B, 0x3B, 0xB3, 0xC6, 0x55, 0xD7, 0xF2, 0x2D, 0x8C, 0x97, 0xA5, 0x66, 0x9C, 0xC8, - 0x34, 0xA2, 0xDD, 0x7C, 0xDA, 0xE7, 0x5A, 0x26, 0x45, 0x59, 0x55, 0x16, 0x46, 0x55, 0x8E, 0x14 }, - }, - { - { 0x82, 0x7C, 0x8C, 0x80, 0x11, 0x1F, 0xF2, 0x21, 0xC3, 0xEB, 0x1E, 0xF5, 0xC0, 0xD5, 0xD4, 0x34, - 0x48, 0x31, 0x86, 0xE2, 0x09, 0x00, 0x75, 0x63, 0x15, 0x8E, 0x9E, 0x76, 0xD2, 0x79, 0x0F, 0x1C }, - }, - { - { 0x82, 0x92, 0x67, 0xC5, 0xAD, 0x70, 0xE5, 0x45, 0x18, 0x02, 0x3A, 0xB7, 0x85, 0xFA, 0x3C, 0xDE, - 0xD6, 0x6F, 0x42, 0x5D, 0xE1, 0xF3, 0x2F, 0xCD, 0x72, 0x1B, 0x49, 0x46, 0x3A, 0x5A, 0x5F, 0x5B }, - }, - { - { 0x82, 0xAF, 0x5C, 0xB6, 0xAD, 0x08, 0x2A, 0xDA, 0x2C, 0x25, 0x2F, 0x74, 0x96, 0x7B, 0xED, 0x01, - 0xAB, 0xA0, 0x87, 0x88, 0x42, 0x02, 0xD4, 0x5D, 0xD4, 0x80, 0xFB, 0x1C, 0x3D, 0x1C, 0x0C, 0x63 }, - }, - { - { 0x82, 0xB1, 0xDD, 0x9C, 0x01, 0xE8, 0xCD, 0x57, 0xDD, 0xA5, 0x1C, 0xCC, 0x29, 0x0B, 0x32, 0xE2, - 0xBB, 0xFD, 0x08, 0x8C, 0x2B, 0xDF, 0x75, 0x46, 0xA8, 0x9C, 0x60, 0x99, 0x78, 0xC8, 0x1B, 0xC2 }, - }, - { - { 0x82, 0xC0, 0x7B, 0x94, 0x4B, 0xBA, 0xC1, 0xB2, 0x95, 0xE2, 0x5F, 0x91, 0xA5, 0xFB, 0x0F, 0x2A, - 0xFC, 0xBA, 0x7E, 0x09, 0xB2, 0x17, 0x27, 0xEE, 0xD8, 0x13, 0x0C, 0xDE, 0x8F, 0x08, 0x0F, 0xCA }, - }, - { - { 0x82, 0xD1, 0x9B, 0xD8, 0x0A, 0x88, 0x6B, 0x28, 0x61, 0xC3, 0x09, 0x97, 0x4C, 0x1C, 0x99, 0x3D, - 0xBE, 0xC3, 0x7E, 0x30, 0x85, 0xC1, 0x47, 0xC4, 0x1F, 0x23, 0xD9, 0xF1, 0x20, 0xD8, 0x9B, 0x68 }, - }, - { - { 0x82, 0xE1, 0xBD, 0xB3, 0xDC, 0x4F, 0x02, 0x36, 0x3A, 0x79, 0x6B, 0x60, 0xA8, 0x8E, 0x4E, 0x71, - 0xBD, 0x33, 0xB0, 0xBE, 0x4C, 0xC5, 0xB8, 0x33, 0x25, 0x2B, 0x83, 0x27, 0xB8, 0x0B, 0xD7, 0xE2 }, - }, - { - { 0x83, 0x23, 0xBD, 0x61, 0x09, 0xFD, 0x94, 0xD5, 0x5F, 0x57, 0xA9, 0x60, 0x42, 0xA2, 0x16, 0xD8, - 0x6A, 0x04, 0xEC, 0xDB, 0x65, 0x7C, 0xEF, 0xEE, 0x62, 0x8C, 0x35, 0xF2, 0x1F, 0x29, 0x4A, 0x68 }, - }, - { - { 0x83, 0x25, 0x41, 0x78, 0xAE, 0x2C, 0x8B, 0xAA, 0x1A, 0xCB, 0xB9, 0x99, 0x82, 0x63, 0x8C, 0x79, - 0x9B, 0x9B, 0x37, 0x9D, 0xA4, 0xD0, 0x2B, 0x28, 0x91, 0x86, 0x20, 0xE2, 0xF1, 0xD8, 0x35, 0xC5 }, - }, - { - { 0x83, 0x34, 0xEA, 0xB8, 0x1C, 0x60, 0x4E, 0x99, 0xD5, 0x40, 0x51, 0x3E, 0xF2, 0xE3, 0x7A, 0xBA, - 0x71, 0x4F, 0x07, 0xB2, 0xBA, 0x01, 0x0A, 0xD7, 0x1D, 0xC4, 0xE1, 0x1A, 0x92, 0x18, 0xC1, 0x8C }, - }, - { - { 0x83, 0x54, 0x7A, 0xCA, 0x3C, 0xED, 0x73, 0xDF, 0x99, 0x14, 0xF3, 0x15, 0x60, 0x74, 0x63, 0x79, - 0x29, 0x4C, 0x76, 0x0E, 0xF9, 0xA8, 0xB7, 0x6E, 0x00, 0x06, 0x46, 0xC7, 0x39, 0x07, 0x21, 0x65 }, - }, - { - { 0x83, 0x89, 0xC8, 0x79, 0xB6, 0x3B, 0x82, 0x9D, 0x2D, 0x39, 0xA8, 0xCF, 0xB7, 0x87, 0xE7, 0x72, - 0x77, 0xD5, 0xCF, 0xA3, 0xE3, 0x6F, 0xDA, 0xCB, 0xAB, 0x4D, 0x18, 0xB2, 0xB0, 0x4E, 0x32, 0x94 }, - }, - { - { 0x83, 0xF8, 0x00, 0xB3, 0xE5, 0x28, 0x52, 0xDE, 0xBC, 0xC5, 0x04, 0xC2, 0x5B, 0x63, 0x58, 0x34, - 0x30, 0x7B, 0x14, 0x5E, 0x38, 0x87, 0x50, 0xAA, 0xC1, 0x63, 0x90, 0x9D, 0x30, 0x4B, 0xE3, 0xD2 }, - }, - { - { 0x84, 0x23, 0xB3, 0xF1, 0xCC, 0x85, 0x2B, 0x49, 0xCF, 0x81, 0xB7, 0xD5, 0xFF, 0x51, 0xA7, 0xA5, - 0x6A, 0x84, 0x78, 0x3A, 0x2D, 0xF7, 0x43, 0x61, 0xFF, 0x2E, 0xEE, 0x0F, 0x92, 0x12, 0xC1, 0x59 }, - }, - { - { 0x84, 0x26, 0xBC, 0x06, 0xDB, 0xB5, 0x18, 0x71, 0x34, 0x66, 0xC7, 0x6A, 0xEA, 0x52, 0x1B, 0xCE, - 0x39, 0xD3, 0x91, 0xA8, 0x89, 0xCB, 0xBA, 0x9B, 0x7B, 0x72, 0xDC, 0xDA, 0x89, 0xF3, 0x46, 0x55 }, - }, - { - { 0x84, 0x3D, 0x84, 0x33, 0x2B, 0x42, 0xAB, 0xBA, 0xB3, 0x71, 0xC9, 0xD9, 0xEF, 0xEC, 0xEB, 0x34, - 0x21, 0x8B, 0x72, 0xF5, 0xD8, 0x79, 0x29, 0xE2, 0xE5, 0x6C, 0xA2, 0xFD, 0x0A, 0x60, 0x41, 0xB6 }, - }, - { - { 0x84, 0x7B, 0x5F, 0x1E, 0xEB, 0x2A, 0x44, 0x13, 0xC8, 0xFA, 0x37, 0x98, 0x21, 0x97, 0x37, 0xE1, - 0x92, 0xBA, 0x72, 0x72, 0xA1, 0x08, 0xB7, 0x17, 0x28, 0xA8, 0xD1, 0x65, 0x17, 0xF6, 0x1E, 0x9D }, - }, - { - { 0x84, 0x88, 0x61, 0x71, 0x6D, 0x7A, 0xD3, 0xF9, 0x6F, 0xFF, 0x73, 0xF8, 0x2E, 0x6C, 0x75, 0x7C, - 0x43, 0x35, 0xAE, 0x5D, 0x3A, 0x1F, 0x52, 0xC4, 0xB6, 0x24, 0x08, 0xDB, 0x51, 0xDF, 0x9E, 0xB2 }, - }, - { - { 0x85, 0x04, 0x81, 0x97, 0xF0, 0x2B, 0xF1, 0xA0, 0x38, 0x81, 0x27, 0xE3, 0x2B, 0x5F, 0x0A, 0xD5, - 0xBC, 0xD9, 0x39, 0x89, 0x14, 0x1E, 0x2C, 0xF3, 0x2B, 0x04, 0x6F, 0x19, 0x01, 0x50, 0x59, 0xC8 }, - }, - { - { 0x85, 0x09, 0xCC, 0xB8, 0x81, 0xDB, 0x1D, 0x96, 0x1D, 0xD9, 0xA0, 0x6C, 0xE9, 0x8A, 0xA6, 0x2F, - 0x19, 0xC9, 0x5F, 0x3C, 0x2A, 0xC3, 0x60, 0x2E, 0x0C, 0xD3, 0xC6, 0xC3, 0x8E, 0x68, 0x6E, 0xD4 }, - }, - { - { 0x85, 0x31, 0xB2, 0xBF, 0xC5, 0x45, 0x79, 0xE8, 0xF1, 0x8F, 0x27, 0xB2, 0xE6, 0xEC, 0xC0, 0xF8, - 0x90, 0x64, 0xEE, 0x86, 0x87, 0x0E, 0xCC, 0x8B, 0xBE, 0x0C, 0xE6, 0x86, 0xEC, 0xDA, 0x2C, 0x17 }, - }, - { - { 0x85, 0x76, 0x0F, 0x59, 0x51, 0x90, 0xE9, 0xB4, 0x67, 0x8B, 0xBF, 0x44, 0xEF, 0xB5, 0xCF, 0x8F, - 0x6B, 0x19, 0x37, 0xA9, 0xB8, 0x6B, 0x31, 0xB7, 0x51, 0xBE, 0xCF, 0x72, 0x18, 0x03, 0xB0, 0x1C }, - }, - { - { 0x85, 0xF0, 0x79, 0x36, 0xB4, 0x29, 0x1F, 0x36, 0xD9, 0xB7, 0x5F, 0x42, 0xE8, 0xB7, 0xEE, 0x8A, - 0x64, 0xE6, 0x32, 0xA1, 0x18, 0x11, 0x65, 0xFE, 0x72, 0xB4, 0x88, 0x23, 0xC3, 0xD9, 0x9D, 0x9D }, - }, - { - { 0x86, 0x12, 0x9F, 0xE7, 0x61, 0x99, 0x4D, 0x7B, 0x64, 0xE4, 0x02, 0x85, 0x8F, 0x88, 0xC5, 0x2B, - 0x3E, 0xB9, 0xC0, 0x71, 0xFF, 0xBE, 0x80, 0x02, 0x80, 0xAC, 0x8C, 0x0C, 0x6F, 0x79, 0xE7, 0xA6 }, - }, - { - { 0x86, 0x19, 0x6B, 0x0F, 0xD3, 0x0F, 0x8F, 0x57, 0x56, 0x98, 0xB5, 0xEE, 0xF2, 0x69, 0xD0, 0x69, - 0x2F, 0x88, 0xAD, 0xEA, 0xC4, 0x83, 0x6A, 0x62, 0x67, 0xAB, 0xC8, 0x36, 0x23, 0x34, 0x00, 0x86 }, - }, - { - { 0x86, 0xD1, 0x8B, 0xCD, 0xDE, 0x16, 0x45, 0x42, 0x48, 0x6E, 0x56, 0x44, 0x2C, 0xE1, 0xB8, 0x8B, - 0x1A, 0x10, 0x73, 0x7C, 0xBD, 0x5E, 0xA4, 0xAA, 0xB8, 0xD5, 0xB8, 0xAF, 0x51, 0xF5, 0x29, 0x09 }, - }, - { - { 0x87, 0x09, 0x8D, 0x69, 0x5D, 0xA4, 0xA2, 0x84, 0x8D, 0xD4, 0x18, 0xF2, 0xC6, 0x4A, 0xDF, 0x3B, - 0xD7, 0x11, 0x7C, 0x98, 0xE9, 0xB7, 0x2E, 0x0F, 0x46, 0xA3, 0x67, 0x80, 0x64, 0x5E, 0x4F, 0x80 }, - }, - { - { 0x87, 0xEB, 0xCB, 0xB0, 0x73, 0x7A, 0xE3, 0x27, 0xC6, 0xBE, 0x9D, 0x3F, 0xA2, 0xC7, 0x5D, 0x1E, - 0xEA, 0x0A, 0xE6, 0x6D, 0x20, 0xD3, 0x8A, 0xF6, 0xED, 0x76, 0xE6, 0xB1, 0x49, 0x9C, 0x83, 0x1F }, - }, - { - { 0x87, 0xEB, 0xCD, 0x34, 0x6C, 0xBF, 0xD5, 0x3E, 0x1A, 0x0E, 0x38, 0x25, 0x69, 0x69, 0x07, 0xE2, - 0x9F, 0x26, 0x9F, 0xEB, 0x06, 0x64, 0xA9, 0x42, 0x67, 0x78, 0xF5, 0x73, 0xC0, 0x68, 0xA6, 0x96 }, - }, - { - { 0x88, 0x51, 0x76, 0x78, 0x61, 0xC9, 0x72, 0x7D, 0x92, 0x77, 0x63, 0x62, 0x78, 0xFB, 0x94, 0x1B, - 0x88, 0x85, 0xD9, 0x99, 0x02, 0x48, 0xBF, 0x91, 0x45, 0x9E, 0x52, 0x7C, 0xE7, 0xF0, 0x6C, 0xF6 }, - }, - { - { 0x88, 0x76, 0x88, 0xDC, 0x6E, 0x9F, 0xE3, 0xDB, 0x05, 0x05, 0x7F, 0xC6, 0x38, 0xEB, 0x8B, 0x29, - 0x4C, 0x3D, 0x8E, 0x0A, 0xAE, 0x17, 0x51, 0xF7, 0x58, 0xF6, 0x36, 0x70, 0x37, 0x2E, 0x66, 0x6D }, - }, - { - { 0x88, 0x8D, 0x6D, 0x77, 0xD8, 0x1C, 0x62, 0x91, 0xCB, 0x84, 0xD9, 0xD6, 0x56, 0x27, 0x82, 0xFD, - 0x2E, 0xB3, 0x42, 0x5D, 0x49, 0x1E, 0x68, 0x74, 0x20, 0x28, 0x4B, 0x76, 0xA1, 0xDE, 0xBF, 0xAB }, - }, - { - { 0x88, 0xB0, 0x25, 0x04, 0x88, 0x31, 0x94, 0xB9, 0x9F, 0xD1, 0xB8, 0x1D, 0x5D, 0x5D, 0xC4, 0x99, - 0xD3, 0x97, 0x65, 0x62, 0x1F, 0x7F, 0x43, 0x0C, 0x73, 0x46, 0xA7, 0x7B, 0x23, 0x39, 0x43, 0x82 }, - }, - { - { 0x89, 0x76, 0xB5, 0x94, 0xAC, 0xDD, 0xC1, 0xB2, 0xAB, 0xD7, 0x5F, 0xA1, 0xA1, 0xEA, 0x24, 0x59, - 0x92, 0x9A, 0x7E, 0x81, 0x4C, 0x9E, 0xE3, 0xF7, 0xBA, 0x21, 0xB3, 0x80, 0x82, 0x88, 0xBE, 0xBB }, - }, - { - { 0x89, 0xAF, 0x0E, 0x54, 0xC7, 0x62, 0x77, 0x86, 0x93, 0x52, 0x9D, 0x0A, 0x95, 0x0B, 0x78, 0x33, - 0xF5, 0xEA, 0xBA, 0xF3, 0x42, 0x79, 0x72, 0x60, 0x7F, 0xB2, 0xC7, 0x0C, 0x96, 0xA3, 0x21, 0x61 }, - }, - { - { 0x89, 0xB6, 0xA4, 0x32, 0x03, 0xD5, 0x82, 0x55, 0xD9, 0x1C, 0xC4, 0x67, 0x25, 0x4B, 0x85, 0x2F, - 0xE6, 0x43, 0x47, 0x38, 0x97, 0x44, 0x79, 0xCE, 0x21, 0x64, 0x0B, 0x7E, 0xC3, 0x5F, 0x24, 0xAC }, - }, - { - { 0x89, 0xCE, 0x0F, 0xE0, 0xE0, 0xB3, 0xE3, 0xAC, 0x38, 0x6E, 0x3A, 0xD6, 0x70, 0xF3, 0x45, 0x57, - 0xE4, 0x73, 0xB8, 0x01, 0xBC, 0x56, 0xE4, 0x1D, 0xBD, 0x91, 0xD7, 0x5A, 0xA1, 0x9A, 0x47, 0x31 }, - }, - { - { 0x89, 0xDA, 0xC7, 0x89, 0x6B, 0x46, 0xF2, 0xFC, 0x8B, 0xEA, 0x62, 0x11, 0xFF, 0x98, 0xB6, 0x1F, - 0xAA, 0x15, 0x7B, 0xA8, 0xC4, 0xAD, 0x6F, 0xD1, 0x75, 0x92, 0x75, 0xCE, 0x39, 0x41, 0xC3, 0x28 }, - }, - { - { 0x8A, 0x09, 0x85, 0xBF, 0x86, 0xE8, 0xC9, 0xB9, 0x17, 0xEC, 0x84, 0xDA, 0x2A, 0x56, 0x73, 0x1E, - 0x75, 0x2A, 0xA0, 0xDC, 0x52, 0x87, 0xC2, 0xBF, 0x39, 0x51, 0x0B, 0xB3, 0xF0, 0xF2, 0x0A, 0xD1 }, - }, - { - { 0x8A, 0x1A, 0xD8, 0x6B, 0xC0, 0x1D, 0x05, 0x9D, 0x53, 0xD7, 0x8D, 0xE1, 0x97, 0xAC, 0x42, 0x99, - 0x8F, 0xEE, 0x20, 0x88, 0x8A, 0xF0, 0xF2, 0x5F, 0x2F, 0x79, 0x7D, 0x62, 0x00, 0xAF, 0xF0, 0xBE }, - }, - { - { 0x8A, 0x59, 0x4E, 0xB2, 0xF8, 0x23, 0x64, 0x65, 0xF0, 0x91, 0x8A, 0xED, 0x99, 0xA7, 0x36, 0x48, - 0x2B, 0x80, 0xAF, 0xD3, 0xD3, 0x3E, 0x9F, 0x17, 0x46, 0x90, 0x8C, 0x21, 0x57, 0xCA, 0xD2, 0x89 }, - }, - { - { 0x8A, 0x74, 0xC4, 0x83, 0xDB, 0x8B, 0x72, 0xDC, 0x6A, 0x59, 0x80, 0xA4, 0x8E, 0x26, 0x2A, 0x5F, - 0x3B, 0x7D, 0xB2, 0xBF, 0xF7, 0xAE, 0xB2, 0xB9, 0xC7, 0xD7, 0x28, 0xF5, 0x4E, 0x55, 0xD6, 0xDD }, - }, - { - { 0x8A, 0xAF, 0x36, 0x3C, 0xC9, 0xD8, 0x44, 0x15, 0xA7, 0xEB, 0x0D, 0x72, 0xDA, 0x08, 0xB3, 0x58, - 0x80, 0x68, 0x55, 0x9C, 0xB0, 0xA9, 0xAE, 0x92, 0xB8, 0xF4, 0x60, 0x2E, 0xDA, 0x23, 0x82, 0xAA }, - }, - { - { 0x8A, 0xB2, 0x77, 0x62, 0xF4, 0xA2, 0xE3, 0x11, 0x22, 0x04, 0x96, 0x98, 0x39, 0x99, 0xC8, 0xC4, - 0x60, 0x96, 0x3D, 0xFC, 0x1B, 0x88, 0x51, 0x11, 0x1D, 0xA4, 0x1D, 0x3F, 0x3B, 0x0A, 0x6E, 0x94 }, - }, - { - { 0x8A, 0xB4, 0x2A, 0x77, 0xBE, 0x55, 0x99, 0xD7, 0x0E, 0x6F, 0xDB, 0xB7, 0x87, 0xE6, 0xA0, 0xFF, - 0x21, 0xC5, 0x09, 0x5F, 0x86, 0xE2, 0xD7, 0x62, 0x34, 0x0D, 0x3D, 0xDD, 0xCC, 0x75, 0x87, 0x0C }, - }, - { - { 0x8A, 0xC9, 0x1B, 0x83, 0x10, 0x9D, 0x39, 0x9C, 0xC2, 0xBC, 0x69, 0x98, 0x49, 0x03, 0x73, 0x37, - 0x9B, 0xDD, 0xE4, 0xDA, 0x04, 0xBA, 0x8B, 0xAA, 0x3B, 0x22, 0x5C, 0x37, 0xDD, 0x21, 0x3C, 0xD9 }, - }, - { - { 0x8A, 0xD1, 0xD5, 0x48, 0x95, 0x27, 0xB5, 0x28, 0xE5, 0xB5, 0xD6, 0xA5, 0x95, 0x78, 0x87, 0x08, - 0x88, 0x8A, 0x3F, 0xB1, 0x9F, 0x2C, 0x7C, 0x8B, 0x38, 0x07, 0x0E, 0x1F, 0x38, 0x98, 0x96, 0x8B }, - }, - { - { 0x8A, 0xDB, 0x49, 0xD4, 0x15, 0x53, 0x56, 0x70, 0x5B, 0x64, 0x42, 0x6A, 0x99, 0x0F, 0x58, 0xB3, - 0xA0, 0x71, 0xEF, 0x78, 0x2E, 0x6C, 0x09, 0x53, 0x07, 0xD7, 0x74, 0x74, 0xD5, 0xB5, 0x7A, 0x62 }, - }, - { - { 0x8B, 0x00, 0xC4, 0x18, 0xC1, 0x50, 0x94, 0x4B, 0x2B, 0x53, 0x2F, 0x5D, 0x87, 0x9F, 0x7D, 0x42, - 0xF8, 0xFE, 0x71, 0x1E, 0x77, 0x35, 0xC6, 0x5D, 0x3C, 0xA0, 0x68, 0x50, 0x74, 0xA2, 0xEA, 0x48 }, - }, - { - { 0x8B, 0x1B, 0x7C, 0x94, 0xB9, 0x94, 0x4F, 0x59, 0xA3, 0xDE, 0x10, 0x21, 0x3B, 0xF6, 0x2B, 0xDC, - 0x50, 0x15, 0x79, 0x0D, 0xDB, 0x18, 0x6F, 0x63, 0x18, 0x24, 0x1A, 0x01, 0x51, 0x51, 0x3C, 0xF6 }, - }, - { - { 0x8B, 0x3A, 0x10, 0x35, 0xC3, 0xFD, 0xF3, 0x45, 0xFB, 0x70, 0x80, 0x44, 0x83, 0xA5, 0x04, 0x49, - 0xA3, 0xD7, 0x60, 0xC6, 0xBA, 0x48, 0xF5, 0xB8, 0x2D, 0x6B, 0xB2, 0x62, 0xED, 0x9D, 0xE3, 0x73 }, - }, - { - { 0x8B, 0x3A, 0x75, 0xCB, 0xC3, 0x62, 0xD2, 0x35, 0x57, 0x0E, 0x5D, 0xE7, 0x04, 0x29, 0x38, 0x70, - 0x8A, 0x1B, 0x0F, 0xCE, 0xB4, 0x59, 0x86, 0x2A, 0x38, 0x67, 0xB7, 0x34, 0xCD, 0xCB, 0x97, 0x94 }, - }, - { - { 0x8B, 0x59, 0x74, 0x2D, 0xFF, 0xF2, 0xD5, 0xBF, 0x70, 0x92, 0x6D, 0x1F, 0xE8, 0x00, 0x7D, 0x35, - 0x57, 0x91, 0x63, 0xFA, 0x4E, 0xEE, 0x1D, 0x03, 0x38, 0xF4, 0x4E, 0xD8, 0xD9, 0xFB, 0x67, 0x28 }, - }, - { - { 0x8B, 0xBE, 0x23, 0x92, 0xCB, 0xCE, 0xEF, 0x09, 0x75, 0xC2, 0xF4, 0xAE, 0xA1, 0xC6, 0x5A, 0xFD, - 0x27, 0x53, 0x0C, 0x9B, 0x05, 0x67, 0x6E, 0x31, 0xA1, 0x17, 0xAF, 0x44, 0xDC, 0x0A, 0x26, 0x98 }, - }, - { - { 0x8B, 0xD6, 0x24, 0xA6, 0x83, 0x99, 0x17, 0xA1, 0x9B, 0x87, 0x13, 0x50, 0xE7, 0x88, 0x98, 0x0C, - 0xA8, 0xF4, 0x2B, 0xA0, 0x96, 0x64, 0x22, 0xE8, 0xB7, 0xDD, 0xB3, 0x75, 0xB4, 0xC3, 0x50, 0xD3 }, - }, - { - { 0x8C, 0x3E, 0x7C, 0x1D, 0xCC, 0x7D, 0xD8, 0xE7, 0xD8, 0xBF, 0x7B, 0x5B, 0x3A, 0xE5, 0xE0, 0x27, - 0x2E, 0x81, 0x1A, 0xB9, 0xF3, 0xC3, 0xC5, 0x38, 0xE5, 0x74, 0x71, 0x77, 0xE6, 0x2D, 0x62, 0x92 }, - }, - { - { 0x8C, 0x3F, 0x58, 0x3D, 0xA8, 0x5F, 0x57, 0x4D, 0xBA, 0x1F, 0xD1, 0xE2, 0x70, 0x28, 0xFF, 0x93, - 0x42, 0x32, 0x2E, 0xF9, 0x08, 0xBB, 0xFA, 0x8B, 0x66, 0x40, 0x65, 0x2C, 0x4A, 0x73, 0x93, 0x7E }, - }, - { - { 0x8C, 0x7C, 0x65, 0x7B, 0xDA, 0x13, 0xCA, 0x62, 0xF2, 0x9A, 0x65, 0xC6, 0xD5, 0x19, 0x3A, 0x93, - 0xCF, 0x6C, 0x58, 0x77, 0x18, 0xAD, 0xCA, 0x67, 0x15, 0x8E, 0x97, 0xD3, 0x6A, 0x62, 0x3E, 0xCA }, - }, - { - { 0x8C, 0xA6, 0x79, 0x62, 0xC4, 0xA8, 0x09, 0x13, 0x33, 0xF2, 0x4E, 0xFD, 0x60, 0xEE, 0x70, 0xCF, - 0xED, 0xDB, 0xD6, 0x41, 0x59, 0x04, 0x70, 0x9E, 0x78, 0x5C, 0x33, 0x1B, 0x1E, 0xF5, 0x8F, 0x8E }, - }, - { - { 0x8C, 0xB4, 0x26, 0x39, 0x8A, 0xD9, 0x7B, 0x04, 0x5D, 0x6A, 0xE9, 0x75, 0x3E, 0x4D, 0x48, 0xB1, - 0x79, 0x23, 0xB9, 0x36, 0x5A, 0x6B, 0x4B, 0x97, 0xC4, 0xEC, 0xAC, 0x4A, 0x4B, 0x37, 0x03, 0x4B }, - }, - { - { 0x8C, 0xCD, 0x79, 0x41, 0x63, 0x00, 0xCA, 0x61, 0xEE, 0x56, 0xA6, 0x0D, 0xA1, 0xC8, 0x09, 0x35, - 0xB8, 0x6E, 0x27, 0x91, 0x93, 0xAD, 0x3D, 0x05, 0x65, 0x72, 0x9D, 0x69, 0xE0, 0x8C, 0x86, 0x96 }, - }, - { - { 0x8C, 0xFA, 0x92, 0x51, 0xB4, 0xDA, 0xEF, 0x50, 0x81, 0x0D, 0x6E, 0x19, 0xF5, 0xF8, 0x8E, 0xA2, - 0xC6, 0x5D, 0xB7, 0xA2, 0xE8, 0xA5, 0x06, 0xF7, 0xDF, 0x99, 0x55, 0x81, 0x7D, 0xDD, 0xEB, 0xC8 }, - }, - { - { 0x8D, 0x44, 0xD4, 0x17, 0x60, 0x46, 0x06, 0x3E, 0x2E, 0xB3, 0xC7, 0x50, 0x38, 0x13, 0xBB, 0xBB, - 0xF6, 0xCA, 0x6D, 0x54, 0x3F, 0x40, 0xB3, 0x99, 0xCC, 0x43, 0xF1, 0x12, 0x4B, 0x28, 0xFB, 0x97 }, - }, - { - { 0x8D, 0x73, 0x19, 0x48, 0x17, 0xF0, 0x97, 0x86, 0x15, 0x84, 0x61, 0x36, 0xC9, 0x8A, 0x59, 0x01, - 0x72, 0x8A, 0xB7, 0xFE, 0x11, 0x92, 0xE4, 0xED, 0x6D, 0x59, 0xB1, 0xDA, 0x5A, 0x42, 0x7D, 0xDA }, - }, - { - { 0x8D, 0x74, 0xC0, 0xD6, 0x6B, 0xB2, 0xEE, 0xB2, 0x6B, 0x9A, 0x55, 0x74, 0x38, 0x5D, 0xA7, 0xB4, - 0x14, 0x0A, 0xF0, 0x70, 0x47, 0xD2, 0xFE, 0x64, 0x3D, 0x1D, 0x1A, 0xE5, 0xB1, 0x96, 0x90, 0x43 }, - }, - { - { 0x8D, 0x85, 0xDA, 0x44, 0x6F, 0x5C, 0x79, 0x54, 0xBD, 0xF7, 0x6C, 0x09, 0x0C, 0xD2, 0x46, 0x68, - 0xFF, 0x23, 0x3C, 0xCD, 0xF6, 0x6B, 0x94, 0xDA, 0xD9, 0x92, 0x98, 0xEB, 0xCB, 0x16, 0x8D, 0xC5 }, - }, - { - { 0x8D, 0x8A, 0xD7, 0xC2, 0x60, 0x58, 0x16, 0xDD, 0x44, 0xB4, 0x29, 0x77, 0x9E, 0xD3, 0x62, 0xB9, - 0x88, 0x37, 0x5B, 0x65, 0x90, 0x46, 0x36, 0x04, 0xF0, 0x86, 0x07, 0x6E, 0x30, 0xE0, 0xA9, 0x5D }, - }, - { - { 0x8D, 0xF5, 0x42, 0x29, 0x9F, 0x9B, 0xDD, 0xF5, 0xAD, 0x42, 0xEE, 0x39, 0x88, 0xDD, 0x21, 0xBF, - 0x21, 0x6B, 0x82, 0x70, 0x91, 0x47, 0xB1, 0x43, 0x1D, 0x08, 0x20, 0xA0, 0x10, 0xD1, 0xC6, 0xBE }, - }, - { - { 0x8D, 0xFE, 0x05, 0xBF, 0x3B, 0x70, 0x65, 0xA3, 0x6F, 0x66, 0xB4, 0xA9, 0x80, 0x6A, 0xBF, 0x8A, - 0x7F, 0x37, 0xF6, 0xD9, 0x2D, 0x3E, 0xB7, 0x11, 0x49, 0xCE, 0x49, 0x21, 0x42, 0xCC, 0x85, 0x79 }, - }, - { - { 0x8E, 0x18, 0xFD, 0xBD, 0xB0, 0x08, 0x16, 0x00, 0x35, 0xFA, 0xF5, 0x01, 0x5B, 0xE7, 0xDA, 0xF4, - 0x63, 0xB5, 0xC4, 0x14, 0xEA, 0xBC, 0x8B, 0x89, 0xF3, 0xDB, 0xA2, 0x05, 0xAB, 0x09, 0xA6, 0x43 }, - }, - { - { 0x8E, 0x2E, 0x4E, 0x29, 0xA3, 0xB4, 0x7F, 0x9B, 0x4A, 0xF7, 0xF6, 0x02, 0xE9, 0xD2, 0xBA, 0xBA, - 0xED, 0xC3, 0x2D, 0x4A, 0x9E, 0xF2, 0x1A, 0x74, 0x1B, 0x07, 0xCE, 0xC1, 0xE4, 0x24, 0x90, 0xCF }, - }, - { - { 0x8E, 0x38, 0x31, 0x6E, 0x38, 0x8B, 0x56, 0x17, 0x8E, 0x60, 0x10, 0xAD, 0xC2, 0xCA, 0xBB, 0x40, - 0x24, 0x92, 0x64, 0xB3, 0x34, 0x42, 0x20, 0xCE, 0xD9, 0xF6, 0xEC, 0xBC, 0xF0, 0x71, 0x1C, 0x34 }, - }, - { - { 0x8E, 0x57, 0x12, 0xC7, 0x5E, 0xC1, 0xE0, 0x31, 0x73, 0x15, 0x96, 0x35, 0x60, 0xF2, 0x6C, 0x8E, - 0xCB, 0x29, 0xA7, 0xA0, 0x28, 0x7F, 0x84, 0xE7, 0xCC, 0x29, 0x99, 0x67, 0x5E, 0x41, 0xA0, 0x5D }, - }, - { - { 0x8E, 0xB9, 0x24, 0x0B, 0x19, 0xA3, 0xCC, 0x2F, 0xF2, 0xCD, 0xF9, 0xAD, 0x2C, 0x71, 0x2E, 0x23, - 0xF4, 0x1E, 0x35, 0x2A, 0xE1, 0xDA, 0x79, 0x29, 0xD6, 0x08, 0xCB, 0xBC, 0x81, 0xA9, 0xE0, 0xC3 }, - }, - { - { 0x8F, 0x01, 0xE1, 0x2E, 0xF4, 0x24, 0x16, 0x9D, 0x2D, 0x5C, 0x2D, 0x25, 0x73, 0xD4, 0x97, 0x36, - 0xE6, 0x9B, 0x05, 0x74, 0x1D, 0x31, 0xB1, 0x62, 0x61, 0xB5, 0xBD, 0xB3, 0xB4, 0x48, 0x77, 0xE2 }, - }, - { - { 0x8F, 0x10, 0x10, 0x47, 0x93, 0xE8, 0x55, 0x42, 0xBC, 0x06, 0x04, 0xD6, 0xCF, 0x21, 0x5F, 0x78, - 0x80, 0xBD, 0x6A, 0x4D, 0xD0, 0xFD, 0xF1, 0xE7, 0xA5, 0xB9, 0xCA, 0x12, 0x46, 0xF5, 0xC4, 0x09 }, - }, - { - { 0x8F, 0x71, 0x27, 0x76, 0x2E, 0xE7, 0x51, 0x69, 0xBD, 0xC3, 0x5B, 0x04, 0xA7, 0x28, 0xE9, 0xD3, - 0x1B, 0x7E, 0x4D, 0x37, 0x89, 0xAA, 0x2C, 0x46, 0xD8, 0xA3, 0x1B, 0x3D, 0xFA, 0x81, 0xA9, 0x7E }, - }, - { - { 0x8F, 0x93, 0xC5, 0xA7, 0xC0, 0x96, 0x66, 0x8B, 0xD4, 0x51, 0x56, 0xBA, 0xD5, 0x6F, 0x06, 0x12, - 0x04, 0x5D, 0x63, 0x65, 0xB6, 0xBB, 0xAA, 0x63, 0xBA, 0xCB, 0xF2, 0xBE, 0x01, 0xB5, 0x2C, 0xD3 }, - }, - { - { 0x8F, 0x94, 0x15, 0x92, 0x6F, 0x40, 0x49, 0xEA, 0x41, 0x8A, 0x30, 0x7C, 0x76, 0x36, 0xE4, 0x9B, - 0x14, 0x4F, 0xA5, 0x3E, 0x52, 0xE1, 0x04, 0x15, 0x5F, 0x58, 0x03, 0x5E, 0x45, 0x41, 0xCD, 0x6E }, - }, - { - { 0x8F, 0x9F, 0x3E, 0x59, 0xD3, 0x6A, 0x9F, 0x33, 0x15, 0x04, 0x9B, 0x99, 0x1C, 0x89, 0xC3, 0x21, - 0xE1, 0xF1, 0xF6, 0x78, 0xE0, 0xA2, 0xA4, 0x2F, 0xC1, 0x44, 0xE5, 0xFF, 0xF2, 0x3B, 0x62, 0xA5 }, - }, - { - { 0x8F, 0xA2, 0x4B, 0x76, 0xD7, 0xAA, 0xD1, 0x53, 0x3F, 0xEA, 0xFE, 0x73, 0xE0, 0x0F, 0xFA, 0x8B, - 0x89, 0x4B, 0x95, 0xB4, 0xE7, 0x01, 0x59, 0x54, 0x9E, 0xAD, 0xA6, 0x58, 0xF6, 0xA2, 0x2B, 0x88 }, - }, - { - { 0x8F, 0xCB, 0x3C, 0x28, 0xE8, 0x1E, 0xFA, 0x6A, 0x1F, 0xE3, 0x4D, 0x03, 0x8A, 0x3B, 0xFB, 0x00, - 0x72, 0x96, 0xA0, 0x48, 0x24, 0xB3, 0xA2, 0x06, 0xE9, 0xEF, 0x28, 0x97, 0xE6, 0x97, 0x51, 0x10 }, - }, - { - { 0x90, 0x30, 0xEC, 0x29, 0x71, 0x10, 0x6A, 0x7C, 0x68, 0x8B, 0xBE, 0xA9, 0x1D, 0x70, 0xF3, 0x4D, - 0x75, 0xD6, 0x74, 0x5B, 0x30, 0x48, 0xFB, 0x1D, 0x9D, 0x3B, 0xC4, 0x9F, 0x9F, 0xC8, 0x78, 0xBA }, - }, - { - { 0x90, 0xB3, 0xA1, 0x85, 0x36, 0x86, 0xAF, 0xEB, 0x15, 0x4A, 0xEF, 0x7E, 0x84, 0x0D, 0x38, 0x04, - 0x4E, 0x7D, 0x7F, 0x6D, 0xC4, 0xCE, 0x82, 0x8C, 0xE3, 0x97, 0x55, 0xAC, 0x88, 0xE4, 0x2E, 0x07 }, - }, - { - { 0x90, 0xE2, 0x51, 0x86, 0x7F, 0x6B, 0x0C, 0x14, 0xBD, 0x9B, 0x51, 0x0C, 0xFD, 0xA8, 0x48, 0x49, - 0x72, 0xFD, 0xF0, 0xE0, 0x6D, 0xC1, 0x1F, 0x5D, 0x1D, 0x59, 0x0B, 0xE3, 0xFC, 0x38, 0xDF, 0xF0 }, - }, - { - { 0x90, 0xF2, 0xF3, 0x73, 0xB9, 0xA6, 0x2E, 0x3C, 0xC8, 0x15, 0x87, 0x57, 0x58, 0x13, 0x18, 0x9B, - 0xA6, 0x9C, 0x67, 0x28, 0x1F, 0x41, 0x93, 0xE4, 0x9B, 0x31, 0x68, 0x9A, 0xA3, 0x7C, 0x3C, 0x21 }, - }, - { - { 0x91, 0x02, 0x41, 0xA2, 0xDD, 0x40, 0xA2, 0x83, 0xEA, 0x1F, 0x0F, 0x4F, 0x31, 0xC9, 0x48, 0x9D, - 0x38, 0x45, 0x0F, 0x08, 0xCA, 0x8B, 0xCC, 0x21, 0x87, 0xF6, 0x90, 0xB4, 0x4F, 0x37, 0x30, 0x17 }, - }, - { - { 0x91, 0x31, 0x4F, 0xF3, 0xFB, 0x23, 0xD3, 0x41, 0x44, 0x63, 0x17, 0xF1, 0xC6, 0xCA, 0x9D, 0x6C, - 0x6D, 0xCB, 0x7A, 0x95, 0x65, 0x1D, 0xA7, 0xE3, 0xF1, 0x56, 0x00, 0xF4, 0x3A, 0x25, 0x8A, 0xF3 }, - }, - { - { 0x91, 0x3B, 0xE0, 0x71, 0xEC, 0x66, 0x46, 0x91, 0x37, 0x98, 0x38, 0x6E, 0x69, 0x4F, 0x08, 0x8B, - 0xF0, 0x9D, 0x48, 0xA3, 0x97, 0xF9, 0x79, 0xE1, 0x24, 0x4C, 0x20, 0x2F, 0x3C, 0x8E, 0x13, 0x8D }, - }, - { - { 0x91, 0x6B, 0x1A, 0x6B, 0x61, 0x6C, 0x6D, 0x8A, 0xC1, 0x49, 0xA3, 0x31, 0x04, 0x83, 0x51, 0x1A, - 0xF7, 0xA7, 0xD5, 0x3C, 0x60, 0x17, 0x9E, 0x7F, 0xA7, 0x93, 0x1E, 0x59, 0x70, 0xB7, 0x82, 0xF1 }, - }, - { - { 0x91, 0x90, 0xF8, 0x25, 0x51, 0x0C, 0x65, 0x98, 0xE1, 0x9D, 0x17, 0xDB, 0xBE, 0x6E, 0x7C, 0x82, - 0x31, 0x86, 0x9C, 0xA7, 0xF6, 0xE3, 0x07, 0xA2, 0xC2, 0xCC, 0x54, 0x77, 0x8D, 0x4A, 0x89, 0xB3 }, - }, - { - { 0x91, 0xC7, 0x6E, 0xF8, 0xC7, 0x05, 0x3B, 0x2A, 0x27, 0x0B, 0x97, 0x19, 0x78, 0x3C, 0x85, 0x10, - 0xA2, 0x89, 0x0A, 0x48, 0x40, 0x18, 0x63, 0x72, 0x6E, 0x23, 0x3A, 0x82, 0xBF, 0x9A, 0x0B, 0xCF }, - }, - { - { 0x92, 0x3F, 0x0F, 0x8C, 0x40, 0x5A, 0x02, 0xE6, 0x82, 0xC4, 0xB4, 0x66, 0x5A, 0x7E, 0xE7, 0x16, - 0xAA, 0x57, 0xE0, 0xA5, 0x86, 0xC2, 0x4A, 0x16, 0x5A, 0xAD, 0x7E, 0x5B, 0xDA, 0x22, 0x78, 0x24 }, - }, - { - { 0x92, 0x71, 0x44, 0x12, 0x1C, 0x23, 0x63, 0x57, 0x07, 0xE9, 0x40, 0x7F, 0x7F, 0xFF, 0x6A, 0x64, - 0x63, 0x5D, 0x7C, 0xE9, 0x06, 0x66, 0xD4, 0x29, 0x94, 0x09, 0x7A, 0xF4, 0x0C, 0x31, 0x36, 0xFB }, - }, - { - { 0x92, 0x83, 0x70, 0x07, 0x63, 0x1B, 0x8F, 0xFA, 0x02, 0x91, 0xD9, 0xE9, 0xC4, 0xB0, 0x8A, 0x5B, - 0xFA, 0x84, 0x5B, 0xA1, 0x7E, 0x79, 0xA2, 0x2D, 0x9D, 0x9D, 0x44, 0xB9, 0x02, 0x23, 0x3D, 0x16 }, - }, - { - { 0x92, 0x8C, 0x1C, 0xD7, 0x50, 0x82, 0x84, 0x1A, 0x02, 0xEF, 0x8B, 0x49, 0x45, 0x6D, 0x6D, 0x3B, - 0x72, 0xB9, 0x79, 0xFF, 0xDA, 0xFB, 0xFD, 0xE2, 0xC6, 0x50, 0xD3, 0x53, 0xDC, 0xD4, 0xF8, 0xFE }, - }, - { - { 0x93, 0x03, 0x43, 0xB5, 0xE8, 0xC1, 0x5D, 0x6D, 0x93, 0x9D, 0x0F, 0x39, 0xF0, 0x53, 0x7A, 0xA6, - 0x23, 0x3F, 0x61, 0x17, 0x93, 0x79, 0xCE, 0xBC, 0x8D, 0x7C, 0x62, 0x01, 0x09, 0x9F, 0xFD, 0xE2 }, - }, - { - { 0x93, 0x8A, 0xE3, 0xE7, 0x15, 0x48, 0xA9, 0xC3, 0x14, 0x27, 0xCB, 0xA7, 0x40, 0xBE, 0x2E, 0xB9, - 0x26, 0x88, 0x68, 0xBD, 0xAC, 0xC1, 0xDA, 0xA8, 0x67, 0x02, 0xFA, 0xB7, 0x93, 0x70, 0xB8, 0xF9 }, - }, - { - { 0x93, 0xAC, 0x4B, 0xBC, 0x6E, 0xBD, 0x52, 0x7E, 0xA9, 0x42, 0xAF, 0x29, 0x4A, 0x5D, 0xAB, 0xD1, - 0x4F, 0xE7, 0x7C, 0x5E, 0x6A, 0x4E, 0xEB, 0x14, 0xB8, 0x0D, 0x42, 0x9F, 0x39, 0xFD, 0xCC, 0xE7 }, - }, - { - { 0x94, 0x18, 0xEF, 0x6D, 0x9F, 0xF6, 0x06, 0xFD, 0xC7, 0x55, 0x78, 0xF0, 0xF5, 0xDE, 0xEA, 0xB1, - 0x39, 0x69, 0x80, 0xF5, 0xB5, 0xD3, 0x96, 0x9D, 0x7A, 0x0F, 0x23, 0x83, 0x70, 0x3F, 0x9B, 0xB1 }, - }, - { - { 0x94, 0x77, 0xCF, 0xEC, 0xDA, 0x46, 0x1D, 0xBC, 0x01, 0xA3, 0xA3, 0x0E, 0xA2, 0x64, 0x31, 0x42, - 0x5B, 0xD1, 0xB1, 0x0C, 0xF7, 0xC2, 0xF2, 0x06, 0x0E, 0xCB, 0x39, 0xF7, 0xD4, 0x15, 0x5B, 0x0D }, - }, - { - { 0x94, 0x97, 0xDC, 0x04, 0xAA, 0xBB, 0xED, 0xF0, 0xD9, 0xE7, 0x65, 0x40, 0x60, 0x02, 0x55, 0x76, - 0x7D, 0xF3, 0xB9, 0x70, 0x59, 0x67, 0x02, 0x86, 0x70, 0x7D, 0x85, 0x85, 0xE4, 0xD8, 0x2C, 0x63 }, - }, - { - { 0x94, 0x9E, 0x13, 0x59, 0x7F, 0x32, 0x06, 0x9F, 0xF3, 0xA6, 0xCF, 0x49, 0x07, 0x1E, 0x70, 0xF4, - 0x0C, 0x4A, 0x2E, 0x07, 0x2E, 0x98, 0x69, 0xFE, 0x15, 0x97, 0xEE, 0x8E, 0xB7, 0x16, 0x34, 0x09 }, - }, - { - { 0x94, 0xC5, 0x29, 0xAA, 0x2D, 0xFE, 0xB3, 0x9F, 0x5E, 0x6C, 0x66, 0xD3, 0x53, 0x37, 0x1E, 0xBC, - 0xD2, 0xCA, 0xED, 0xBD, 0x1F, 0x0E, 0x6C, 0x79, 0x75, 0x5E, 0xEE, 0x61, 0xE9, 0xE6, 0x24, 0xF4 }, - }, - { - { 0x94, 0xDC, 0x80, 0x07, 0x49, 0x1D, 0xA8, 0xBF, 0xB7, 0x39, 0x14, 0xAD, 0xCE, 0xF7, 0x1A, 0x12, - 0x41, 0x58, 0xBA, 0xD1, 0x7B, 0xA8, 0x8F, 0xA9, 0x46, 0x57, 0x9B, 0xBC, 0x2D, 0x64, 0x97, 0x8D }, - }, - { - { 0x95, 0x68, 0x33, 0xAE, 0xE6, 0x61, 0x19, 0x26, 0xE9, 0x52, 0x72, 0xA1, 0xF5, 0x88, 0xF9, 0x2A, - 0xF5, 0x2C, 0xAE, 0x70, 0x7A, 0xCD, 0xCC, 0x82, 0x63, 0x99, 0x7B, 0xFA, 0x8C, 0x71, 0x9C, 0xA8 }, - }, - { - { 0x95, 0x6D, 0xBC, 0x65, 0x57, 0x62, 0xCE, 0x49, 0xE5, 0xE8, 0x46, 0x99, 0x2C, 0x26, 0xEB, 0xF5, - 0x66, 0x60, 0x42, 0xD2, 0xC0, 0xD7, 0xE7, 0xCF, 0x74, 0x04, 0x26, 0xBE, 0x3C, 0x51, 0x99, 0x72 }, - }, - { - { 0x95, 0x89, 0xDA, 0xC9, 0xEC, 0xE7, 0x6D, 0xF5, 0x72, 0x01, 0x96, 0xDC, 0x58, 0x6D, 0x17, 0x9D, - 0x73, 0x5D, 0xF7, 0x17, 0x92, 0x6C, 0x06, 0x1E, 0xA7, 0x0C, 0x40, 0x85, 0x64, 0x8F, 0xF3, 0x12 }, - }, - { - { 0x95, 0xF4, 0x59, 0xAC, 0xF2, 0x57, 0x64, 0x4C, 0x90, 0x9A, 0xDC, 0xAE, 0xAD, 0xD8, 0x8A, 0x3C, - 0x57, 0x76, 0x2E, 0xCB, 0x09, 0x2C, 0x50, 0xB4, 0x51, 0xC1, 0x58, 0x6B, 0x21, 0x8E, 0x6B, 0x26 }, - }, - { - { 0x96, 0xA4, 0x59, 0x90, 0xFC, 0xD0, 0x1C, 0x9C, 0x2A, 0xF0, 0x64, 0x5F, 0x87, 0xB9, 0x69, 0x8B, - 0x05, 0xAF, 0xE6, 0x94, 0x32, 0xEB, 0x57, 0x01, 0x08, 0x20, 0x13, 0xBA, 0xC5, 0xB0, 0x55, 0x60 }, - }, - { - { 0x96, 0xEB, 0x44, 0xAA, 0x6A, 0x20, 0x49, 0xE6, 0xBA, 0xFF, 0xE6, 0xB5, 0x21, 0xC4, 0xAD, 0x8C, - 0x58, 0x77, 0x26, 0xCA, 0xA0, 0x12, 0xE8, 0xFB, 0x8E, 0x8E, 0x21, 0x89, 0x77, 0xBF, 0x1D, 0xF6 }, - }, - { - { 0x97, 0x4F, 0x51, 0xA6, 0x04, 0x68, 0x48, 0xFA, 0xA7, 0xB3, 0x3F, 0xD2, 0x39, 0x13, 0x86, 0x42, - 0x8B, 0xD5, 0x24, 0xEA, 0xEB, 0xA8, 0x01, 0x4E, 0x6D, 0x1F, 0xE2, 0x54, 0x38, 0x3F, 0x41, 0x79 }, - }, - { - { 0x97, 0x83, 0x7F, 0xE4, 0xCF, 0xBF, 0x4F, 0xF0, 0x37, 0x63, 0x1C, 0xF4, 0xB5, 0x3F, 0x9F, 0xA8, - 0xAB, 0x37, 0xA8, 0x30, 0x1C, 0xAB, 0x9E, 0x48, 0x71, 0x5F, 0x53, 0x7D, 0xD0, 0x8A, 0x68, 0x48 }, - }, - { - { 0x97, 0x8D, 0x6F, 0x1E, 0x9A, 0xA3, 0xA3, 0xCE, 0xB1, 0xAD, 0xA6, 0x09, 0xE2, 0x00, 0x95, 0xFB, - 0xC3, 0x3A, 0x6B, 0xBC, 0x6A, 0x21, 0xD8, 0x0A, 0x4E, 0xCB, 0x27, 0x3C, 0x60, 0xAC, 0x2A, 0xC7 }, - }, - { - { 0x97, 0xD6, 0x24, 0xEA, 0xC8, 0x80, 0x91, 0x03, 0x4A, 0x84, 0xB4, 0xDC, 0x63, 0x33, 0x92, 0x37, - 0xDA, 0xF4, 0xA2, 0xB0, 0xF6, 0xC6, 0xE2, 0x55, 0xE7, 0xEC, 0xE6, 0x82, 0x59, 0x1D, 0x5E, 0xDC }, - }, - { - { 0x97, 0xE2, 0x11, 0x70, 0x95, 0x44, 0x9C, 0xDF, 0xC0, 0xA8, 0x3E, 0xD4, 0x9E, 0x65, 0x0A, 0xDF, - 0xD9, 0xBC, 0x0B, 0x3C, 0x50, 0x04, 0x9D, 0x7B, 0x93, 0x24, 0x5A, 0xCC, 0x3A, 0x0C, 0x16, 0xAF }, - }, - { - { 0x98, 0x15, 0x9D, 0xD1, 0x88, 0x39, 0xFD, 0xF4, 0x3E, 0xC0, 0x00, 0x23, 0xAD, 0x1D, 0x4E, 0x27, - 0xD8, 0xF9, 0x50, 0xBE, 0xC8, 0x60, 0x40, 0x11, 0x1E, 0x84, 0x54, 0xCE, 0x44, 0x6F, 0xAB, 0x75 }, - }, - { - { 0x98, 0x39, 0xE6, 0x09, 0x46, 0xEF, 0x20, 0xE2, 0x44, 0x68, 0xC1, 0x81, 0x88, 0xBB, 0xB3, 0xC6, - 0xE8, 0x80, 0xF3, 0x6D, 0x0D, 0xED, 0xE8, 0xD2, 0x4A, 0x23, 0x05, 0x86, 0x3A, 0x5B, 0x5D, 0xFE }, - }, - { - { 0x98, 0x57, 0x02, 0xC0, 0x55, 0x05, 0xD9, 0xBA, 0xE0, 0xCE, 0x23, 0xAB, 0x2C, 0xB8, 0x65, 0xA1, - 0xD1, 0x3F, 0x7B, 0xE0, 0x4F, 0xAB, 0xC1, 0x19, 0x49, 0x4B, 0x4C, 0xC1, 0x0A, 0x7D, 0x9A, 0xDB }, - }, - { - { 0x98, 0x76, 0x8D, 0x66, 0x7E, 0x4D, 0xFC, 0x1D, 0x99, 0x5E, 0x42, 0xC7, 0x1E, 0x31, 0x93, 0x31, - 0x6C, 0xEF, 0x8C, 0x2A, 0xF5, 0x9A, 0x0E, 0xA6, 0x19, 0x81, 0xFB, 0x42, 0x00, 0x72, 0x57, 0xC7 }, - }, - { - { 0x98, 0x7A, 0xD4, 0x70, 0x5F, 0x65, 0x65, 0xAF, 0x64, 0x53, 0x0D, 0x09, 0x60, 0xB8, 0x82, 0x74, - 0x0A, 0xFB, 0x8A, 0x74, 0xD5, 0xCC, 0x3C, 0x68, 0x19, 0x34, 0x69, 0x83, 0xF2, 0x51, 0x33, 0x37 }, - }, - { - { 0x98, 0xAA, 0xB4, 0xED, 0x43, 0x89, 0xF3, 0x5E, 0x74, 0x23, 0x74, 0x90, 0x68, 0x01, 0x15, 0x3D, - 0xC7, 0xC8, 0xE3, 0x2D, 0x18, 0xB4, 0xD7, 0x81, 0x88, 0x28, 0x3A, 0x55, 0x77, 0xCB, 0x55, 0xFB }, - }, - { - { 0x98, 0xB5, 0x92, 0x4E, 0x06, 0xCD, 0xEA, 0x1B, 0xA1, 0x7F, 0xDB, 0x1B, 0x13, 0x97, 0x90, 0x24, - 0xB1, 0xC2, 0x5B, 0x0A, 0x69, 0x0C, 0xFE, 0x87, 0x8D, 0x4C, 0xB4, 0x07, 0x76, 0xB9, 0x6F, 0xB0 }, - }, - { - { 0x98, 0xEB, 0xC4, 0x98, 0xBD, 0x91, 0x23, 0x5E, 0xDF, 0xC2, 0xDC, 0x7B, 0xE1, 0x8D, 0x88, 0xF3, - 0x5E, 0x9F, 0x33, 0x41, 0xD8, 0x8E, 0xF4, 0x38, 0xA8, 0xD4, 0x11, 0xF1, 0x88, 0x11, 0x54, 0x56 }, - }, - { - { 0x99, 0x05, 0x0A, 0x48, 0x01, 0x8D, 0x00, 0xB3, 0xBF, 0xE5, 0xA8, 0x09, 0x24, 0x6E, 0x25, 0x54, - 0x5F, 0x36, 0xD2, 0x17, 0x8F, 0xD2, 0x02, 0xAE, 0x5D, 0xC8, 0xE7, 0xFF, 0x4D, 0x5A, 0x07, 0xF9 }, - }, - { - { 0x99, 0x08, 0xA8, 0xDD, 0x06, 0x0C, 0x74, 0xFA, 0xB2, 0x0C, 0x2F, 0x44, 0x17, 0x26, 0x0A, 0xFA, - 0xF0, 0x6D, 0x6C, 0x10, 0x81, 0xB2, 0x6C, 0x5F, 0x5F, 0x51, 0x5C, 0x2D, 0x04, 0xEB, 0x4A, 0x52 }, - }, - { - { 0x99, 0x45, 0xBA, 0x12, 0xC4, 0x4B, 0x5A, 0x01, 0x4D, 0xBC, 0x4D, 0xBB, 0xCA, 0x86, 0x10, 0x87, - 0xC1, 0x9E, 0xDD, 0x6D, 0xCE, 0xB1, 0x6D, 0x52, 0x88, 0x63, 0x63, 0xA7, 0xCD, 0xC8, 0x69, 0x5F }, - }, - { - { 0x99, 0xA5, 0x5F, 0x76, 0xCB, 0xEA, 0x0F, 0x3E, 0x60, 0x71, 0xD3, 0x82, 0x18, 0x1A, 0xF6, 0xCB, - 0x25, 0xBD, 0xC5, 0x87, 0x5E, 0x29, 0xF0, 0xF4, 0xD7, 0x19, 0xA9, 0xD3, 0x5B, 0x5B, 0xD6, 0xBF }, - }, - { - { 0x99, 0xB1, 0x38, 0xBB, 0x53, 0xC5, 0x4D, 0x1C, 0x7A, 0xC2, 0x9A, 0x57, 0x85, 0xC8, 0xB1, 0x9F, - 0xDD, 0xC3, 0x7D, 0x99, 0x4A, 0x3E, 0x6C, 0x31, 0xF7, 0x50, 0xA1, 0xBF, 0xEB, 0xE9, 0xFE, 0xF9 }, - }, - { - { 0x99, 0xB4, 0x6C, 0x68, 0x90, 0x62, 0x37, 0x40, 0x23, 0xDB, 0x68, 0x19, 0xF8, 0x89, 0xD3, 0xC1, - 0xBB, 0x8A, 0x83, 0x8C, 0x6B, 0x51, 0x7E, 0x32, 0x7E, 0xD9, 0x1C, 0x6C, 0x96, 0x2D, 0x06, 0x49 }, - }, - { - { 0x99, 0xE1, 0xFB, 0x3E, 0xEB, 0x89, 0x1E, 0xBA, 0x4F, 0x9B, 0xD4, 0x7F, 0x04, 0xBC, 0x9A, 0x62, - 0xBD, 0x3B, 0x61, 0x85, 0x45, 0x4B, 0xF5, 0x35, 0x9E, 0x39, 0x37, 0xE0, 0xB8, 0xA5, 0xFF, 0xB7 }, - }, - { - { 0x9A, 0x4B, 0x49, 0x93, 0xB4, 0xED, 0x8C, 0x27, 0xE7, 0x7F, 0x3C, 0x8A, 0xAF, 0xDB, 0xDC, 0x11, - 0x1A, 0x36, 0xB7, 0x3C, 0xCA, 0xDB, 0x87, 0x04, 0x98, 0x25, 0x00, 0xD1, 0xB0, 0xF1, 0x09, 0xF2 }, - }, - { - { 0x9A, 0x4C, 0xA1, 0x75, 0xC4, 0x6F, 0x5C, 0x17, 0x05, 0x5E, 0x28, 0x16, 0xC8, 0x37, 0x98, 0x54, - 0x89, 0x46, 0x76, 0xEE, 0xB3, 0x4C, 0xF7, 0x2A, 0x14, 0x83, 0x04, 0x97, 0xD8, 0x4A, 0x4F, 0x6C }, - }, - { - { 0x9A, 0x5D, 0x7A, 0xF0, 0xF3, 0xF4, 0x34, 0xBA, 0x6E, 0x67, 0x37, 0x65, 0x2C, 0x42, 0x87, 0x6A, - 0x8E, 0xC1, 0x9A, 0xCE, 0x0C, 0x7C, 0xBF, 0x3E, 0xCE, 0x5C, 0x32, 0x62, 0xAE, 0xEB, 0x77, 0xD4 }, - }, - { - { 0x9A, 0x5F, 0xAB, 0xE5, 0x8A, 0x1E, 0xAE, 0x4B, 0x20, 0xBA, 0xB3, 0xA7, 0xEB, 0x5E, 0x42, 0xA2, - 0xDA, 0x83, 0x11, 0x59, 0x25, 0x7D, 0xD4, 0xE3, 0x55, 0x2E, 0xC6, 0xF7, 0xD2, 0x67, 0xFA, 0xBA }, - }, - { - { 0x9A, 0x9F, 0x50, 0x16, 0x20, 0x70, 0x69, 0x62, 0xE5, 0x07, 0xF7, 0x57, 0xB2, 0xFE, 0x76, 0x44, - 0xA3, 0xF4, 0x96, 0x90, 0x57, 0x1A, 0x30, 0x34, 0xDB, 0xBC, 0x35, 0x96, 0xA4, 0xC1, 0x60, 0x2C }, - }, - { - { 0x9A, 0xA3, 0xBC, 0xD0, 0x80, 0x11, 0xE2, 0xF9, 0x0A, 0x59, 0x2A, 0xD7, 0xA4, 0x9D, 0xB2, 0x7F, - 0xAA, 0xD8, 0xA7, 0x3C, 0xEA, 0x24, 0x6C, 0x21, 0x65, 0x09, 0xBB, 0x36, 0x27, 0xE8, 0x2A, 0x22 }, - }, - { - { 0x9A, 0xAE, 0x9D, 0x45, 0xAA, 0x04, 0x03, 0x06, 0x4B, 0xC5, 0xA7, 0x4D, 0xD0, 0x32, 0x5D, 0xA4, - 0x1E, 0x12, 0xCF, 0x58, 0x6C, 0x46, 0x2E, 0xE0, 0x6C, 0x2B, 0xB4, 0x56, 0xF8, 0x44, 0x1C, 0x4F }, - }, - { - { 0x9A, 0xC0, 0xD1, 0x78, 0x82, 0x0B, 0xC5, 0x49, 0x96, 0x0A, 0xA1, 0x52, 0xBC, 0x17, 0x3D, 0x70, - 0xBA, 0x6B, 0x36, 0x24, 0x7E, 0x18, 0xA0, 0x42, 0xEB, 0x83, 0x05, 0x41, 0x96, 0x84, 0xA7, 0x2C }, - }, - { - { 0x9A, 0xC1, 0x48, 0xB3, 0x72, 0x12, 0xAD, 0x5D, 0xDE, 0xC4, 0x36, 0xB5, 0x65, 0x77, 0xF5, 0x4B, - 0x99, 0xEA, 0xFC, 0x69, 0x2C, 0x4E, 0x6F, 0xFD, 0x75, 0x85, 0x39, 0xCD, 0xAE, 0xFE, 0x30, 0x4D }, - }, - { - { 0x9A, 0xEE, 0x05, 0x8D, 0x61, 0x51, 0xE2, 0x65, 0xE2, 0x5F, 0x9A, 0x82, 0x34, 0x54, 0x38, 0xC5, - 0xA7, 0x42, 0x8C, 0xD6, 0xD8, 0xE2, 0xB4, 0xF3, 0x39, 0xC4, 0x7F, 0xB2, 0x38, 0xC0, 0x93, 0x3F }, - }, - { - { 0x9B, 0x4B, 0xBC, 0xEA, 0x3E, 0x22, 0xA4, 0x3B, 0xC5, 0xD6, 0x58, 0x7F, 0x58, 0x1D, 0x0A, 0x14, - 0x38, 0xD2, 0xEE, 0xA6, 0xDA, 0xD9, 0xF1, 0xAA, 0x23, 0xFC, 0x23, 0x09, 0x7A, 0xDF, 0x4D, 0x75 }, - }, - { - { 0x9B, 0x8F, 0x9F, 0xC4, 0xAF, 0xA7, 0x04, 0x0D, 0x4E, 0x59, 0x4D, 0x66, 0x7C, 0x44, 0x44, 0xB5, - 0x25, 0x88, 0x20, 0xC0, 0x8F, 0x89, 0x91, 0x0E, 0xD3, 0x42, 0x1C, 0xB4, 0xA9, 0x7B, 0xB7, 0x9E }, - }, - { - { 0x9B, 0xC8, 0xF4, 0xCD, 0x33, 0xB9, 0x19, 0xCF, 0xFC, 0x0B, 0x71, 0x72, 0x63, 0x1A, 0x87, 0xD3, - 0x5B, 0xAF, 0x27, 0xB8, 0xA4, 0x75, 0x28, 0xAE, 0x25, 0x29, 0x35, 0x8F, 0x42, 0x1A, 0xCC, 0xB1 }, - }, - { - { 0x9B, 0xD6, 0x5A, 0xC4, 0x0A, 0x62, 0x5A, 0x81, 0x90, 0x4F, 0xE7, 0x8F, 0x89, 0x35, 0x25, 0x1E, - 0x5C, 0x66, 0x91, 0xF0, 0xB3, 0xD7, 0x24, 0x54, 0xD3, 0x84, 0x12, 0x01, 0xF3, 0x9F, 0xCD, 0x1E }, - }, - { - { 0x9C, 0x70, 0x8D, 0x5B, 0xAB, 0x37, 0xF5, 0xB6, 0xBC, 0x8A, 0x77, 0x53, 0x12, 0x57, 0x2A, 0xB2, - 0x79, 0x21, 0x6D, 0x55, 0x6D, 0xA7, 0x4A, 0xC2, 0xA7, 0xC0, 0x41, 0xE8, 0xCE, 0xB0, 0xBE, 0x0A }, - }, - { - { 0x9C, 0x85, 0x31, 0xE7, 0xC8, 0xFB, 0xDA, 0xB8, 0x61, 0x4D, 0x56, 0x17, 0x79, 0x9E, 0x00, 0x6B, - 0x69, 0x42, 0xE4, 0x20, 0xC4, 0x07, 0x1D, 0x7D, 0xB8, 0x9C, 0xD7, 0x72, 0x81, 0x69, 0x16, 0x70 }, - }, - { - { 0x9C, 0xCA, 0x23, 0x7C, 0xDF, 0xCA, 0x2C, 0x72, 0xC6, 0x09, 0x25, 0x4A, 0x72, 0x57, 0xFE, 0xD5, - 0x3A, 0xF1, 0x44, 0xAB, 0xC2, 0x5E, 0xCD, 0x8E, 0xF7, 0x01, 0x30, 0x8C, 0xB1, 0x3C, 0xF7, 0x69 }, - }, - { - { 0x9C, 0xF9, 0x96, 0xC5, 0x3A, 0x2A, 0x7B, 0x1A, 0x99, 0xAE, 0x53, 0x0F, 0xC4, 0x36, 0x19, 0x62, - 0x28, 0xEA, 0xE4, 0x79, 0x72, 0xAE, 0x9C, 0xB0, 0x69, 0xB1, 0x8C, 0x29, 0xE3, 0x30, 0x40, 0x9C }, - }, - { - { 0x9D, 0x32, 0x0D, 0x7B, 0x3D, 0x46, 0x34, 0x5F, 0x0F, 0x2D, 0xEC, 0xB7, 0x62, 0xA4, 0x81, 0x7B, - 0x26, 0xA9, 0xA7, 0xCF, 0xE8, 0x71, 0xB1, 0x3E, 0x84, 0xE7, 0xEC, 0x81, 0x0A, 0xAE, 0xB6, 0x2C }, - }, - { - { 0x9D, 0x50, 0xB9, 0x1D, 0xB0, 0x1B, 0xD1, 0x89, 0x9A, 0xF8, 0x17, 0xAD, 0xBF, 0xDC, 0x24, 0x8F, - 0x75, 0xC8, 0x43, 0x53, 0xA9, 0xAE, 0x7A, 0x0B, 0xB4, 0xD1, 0x56, 0x32, 0x9B, 0xDB, 0x51, 0xE0 }, - }, - { - { 0x9D, 0x6B, 0xDF, 0xCF, 0x0C, 0xBF, 0xFE, 0xEA, 0x3B, 0x1A, 0xC7, 0xE9, 0x63, 0xCB, 0xB5, 0xF2, - 0x7F, 0xBD, 0xA8, 0x9D, 0x27, 0x77, 0xF6, 0x0E, 0x56, 0x5B, 0x27, 0x78, 0x54, 0xEF, 0xB0, 0x19 }, - }, - { - { 0x9D, 0xAC, 0x33, 0x14, 0xB2, 0x5B, 0xB7, 0x9A, 0x39, 0xCD, 0x01, 0xEC, 0x4B, 0x33, 0xA1, 0x2F, - 0x47, 0x51, 0x2F, 0x54, 0x09, 0xFF, 0x09, 0x5D, 0x40, 0xAA, 0xD6, 0x20, 0x84, 0xEF, 0x15, 0xBE }, - }, - { - { 0x9D, 0xAC, 0x9D, 0x66, 0xDE, 0xD0, 0xC1, 0x5D, 0x23, 0x24, 0x1A, 0x90, 0x78, 0xA9, 0x1E, 0xC1, - 0xE9, 0x40, 0x70, 0xA1, 0x5C, 0x70, 0x29, 0x45, 0x02, 0xFE, 0x73, 0x8D, 0x12, 0x1C, 0xCA, 0xAC }, - }, - { - { 0x9E, 0x0B, 0xF3, 0x1A, 0xC8, 0x33, 0xF8, 0xB1, 0x40, 0x4C, 0xCA, 0xB1, 0x23, 0x84, 0x63, 0x48, - 0xA0, 0x3C, 0x0F, 0xF5, 0x11, 0xC6, 0xEC, 0x05, 0xA8, 0x6D, 0xF0, 0xDB, 0x51, 0x92, 0xA5, 0x2B }, - }, - { - { 0x9E, 0x2E, 0xC8, 0xE6, 0x1C, 0x76, 0x0D, 0x8E, 0x1B, 0x94, 0x2C, 0xEA, 0x8C, 0x2D, 0x55, 0xA9, - 0xF1, 0x8D, 0x3C, 0xD8, 0x4C, 0x0B, 0x9B, 0x5B, 0x23, 0x4D, 0x15, 0xAC, 0x56, 0x8E, 0x0E, 0xCD }, - }, - { - { 0x9E, 0x80, 0xD0, 0x33, 0xE6, 0x10, 0x90, 0x7B, 0xFE, 0x1F, 0xD8, 0xDF, 0x2D, 0x36, 0xDD, 0xEF, - 0x00, 0xC8, 0xFC, 0x7B, 0xF7, 0xB7, 0xFD, 0x7E, 0x8D, 0x45, 0x92, 0xAB, 0xF3, 0xC4, 0x21, 0xDE }, - }, - { - { 0x9E, 0x85, 0xD4, 0xAC, 0x8B, 0x36, 0x0E, 0x4D, 0xB2, 0xED, 0x37, 0x34, 0x10, 0x16, 0xE3, 0x7B, - 0xD5, 0x5C, 0x2D, 0x59, 0x79, 0x5D, 0x0A, 0x7C, 0x26, 0xA4, 0x4E, 0x7E, 0x80, 0x98, 0x3E, 0x75 }, - }, - { - { 0x9E, 0x98, 0xF7, 0xDA, 0x04, 0x74, 0xD4, 0x86, 0x5A, 0xC7, 0x05, 0xD4, 0xD7, 0xAB, 0xBE, 0xB7, - 0x1A, 0xEF, 0xBA, 0x2C, 0xF2, 0xE0, 0x82, 0xF0, 0x5F, 0xED, 0x53, 0x62, 0x41, 0x4B, 0xD3, 0x93 }, - }, - { - { 0x9E, 0xEA, 0x28, 0xDF, 0x01, 0x4D, 0x91, 0x24, 0x4F, 0xF9, 0x31, 0x4F, 0x43, 0x4A, 0x84, 0x7B, - 0x65, 0x89, 0xC1, 0xF2, 0x03, 0x58, 0x33, 0x9D, 0x79, 0xFC, 0xA6, 0x76, 0x63, 0x2D, 0xFF, 0xFE }, - }, - { - { 0x9F, 0x24, 0x5C, 0x0A, 0x0E, 0xC6, 0x3A, 0xAA, 0xCB, 0xF9, 0x69, 0xC6, 0xFC, 0x24, 0xA1, 0x07, - 0x15, 0x83, 0xB7, 0x79, 0xA5, 0x8A, 0xB6, 0x23, 0xDD, 0x15, 0x31, 0xA2, 0xCA, 0x9F, 0x87, 0x51 }, - }, - { - { 0x9F, 0x41, 0xC4, 0x19, 0xDA, 0x0B, 0xE3, 0x20, 0x5E, 0xA3, 0x84, 0xF9, 0x08, 0xF0, 0x5F, 0x42, - 0x8E, 0xD9, 0x13, 0xB1, 0x49, 0x93, 0x3A, 0x67, 0x2F, 0x79, 0x67, 0x60, 0x0C, 0x02, 0x0F, 0x1E }, - }, - { - { 0x9F, 0xAF, 0x1C, 0x11, 0xA3, 0xC7, 0xE2, 0x41, 0xF8, 0x63, 0x71, 0x97, 0xE8, 0x99, 0x68, 0xDB, - 0x86, 0x6A, 0xD0, 0x1A, 0x5D, 0x4E, 0xD5, 0x34, 0x59, 0x48, 0x65, 0xB9, 0x70, 0x75, 0xF2, 0x60 }, - }, - { - { 0x9F, 0xC3, 0xA4, 0xDD, 0xD9, 0x8A, 0xDD, 0xB2, 0xCE, 0x89, 0x3B, 0xD6, 0x84, 0x2C, 0x48, 0x89, - 0xA3, 0x1F, 0x4B, 0x95, 0xE1, 0x69, 0xD2, 0x3D, 0xC5, 0x54, 0xE6, 0x02, 0x4D, 0xEC, 0x98, 0xA9 }, - }, - { - { 0x9F, 0xE0, 0x91, 0x58, 0x70, 0x38, 0x5D, 0xDB, 0xB6, 0x2F, 0xA6, 0xE3, 0x23, 0x95, 0xEB, 0xE8, - 0x33, 0x34, 0x46, 0x00, 0x43, 0x6D, 0xAC, 0xC9, 0xB5, 0x69, 0x21, 0x4E, 0xEB, 0x8C, 0x0A, 0xF0 }, - }, - { - { 0x9F, 0xF9, 0x38, 0x40, 0xB0, 0x1F, 0x96, 0xB6, 0xF3, 0xC3, 0x10, 0xA0, 0x21, 0x90, 0xAD, 0xC3, - 0x3A, 0x15, 0x69, 0x39, 0x5B, 0xBC, 0xEE, 0x11, 0x6A, 0x15, 0xE1, 0x58, 0xA6, 0x2B, 0xA5, 0x0B }, - }, - { - { 0x9F, 0xFA, 0x4E, 0xF4, 0xFC, 0xF2, 0xCF, 0xD1, 0xB2, 0x7C, 0x6A, 0x62, 0xE3, 0xC4, 0x23, 0x5B, - 0xD8, 0x3C, 0xC5, 0xE0, 0x06, 0xE9, 0x2A, 0x55, 0xE4, 0xA9, 0x86, 0xE6, 0x30, 0x53, 0x57, 0xE3 }, - }, - { - { 0xA0, 0x44, 0xF2, 0xC0, 0x41, 0xF4, 0x18, 0x5B, 0xC0, 0xFE, 0x1A, 0xD3, 0xE0, 0xA3, 0xE0, 0xC2, - 0x7E, 0x24, 0xF4, 0x58, 0xDC, 0xB7, 0xD9, 0x07, 0x39, 0xB6, 0x4A, 0x68, 0x94, 0x45, 0xD4, 0xB6 }, - }, - { - { 0xA0, 0x77, 0x42, 0xD5, 0xB2, 0x99, 0x96, 0x65, 0x06, 0x76, 0x2E, 0x02, 0xE4, 0x20, 0xF1, 0xA9, - 0xC4, 0xAB, 0x73, 0x29, 0xAE, 0x29, 0x5F, 0x01, 0x5F, 0x74, 0x7D, 0xA1, 0x82, 0xA9, 0xC3, 0x9C }, - }, - { - { 0xA0, 0xAB, 0x9F, 0x42, 0xD0, 0x9D, 0x06, 0x44, 0x23, 0x8C, 0x63, 0xF2, 0x19, 0x26, 0x52, 0x8F, - 0xA5, 0x3E, 0x56, 0x6D, 0x83, 0x3E, 0xF1, 0xB0, 0x8D, 0x9E, 0xE7, 0xF3, 0x4D, 0x2B, 0x6D, 0x8E }, - }, - { - { 0xA0, 0xC2, 0xD2, 0x07, 0xA4, 0x7E, 0x18, 0xD0, 0x37, 0x14, 0xD5, 0xB3, 0x44, 0x5D, 0x88, 0xBE, - 0x81, 0xFF, 0x5E, 0x1D, 0x16, 0x07, 0x3D, 0xC1, 0x16, 0x6B, 0xB5, 0x44, 0x8F, 0xF6, 0x52, 0xDF }, - }, - { - { 0xA0, 0xC8, 0xA5, 0x3F, 0xD7, 0x58, 0x3E, 0x43, 0x91, 0xBE, 0xB8, 0xD0, 0xFE, 0xD8, 0x43, 0x1F, - 0x61, 0xB8, 0x52, 0xC1, 0xBE, 0x43, 0xAB, 0x91, 0x61, 0x4B, 0xBB, 0xEB, 0x3B, 0x4F, 0x47, 0x4E }, - }, - { - { 0xA0, 0xFE, 0xF8, 0x2E, 0xAD, 0xF5, 0xFE, 0xEC, 0xF8, 0x99, 0x16, 0xDA, 0x89, 0x4B, 0x2F, 0xA5, - 0x18, 0x29, 0x25, 0x6E, 0xB9, 0x59, 0x01, 0x8D, 0x8B, 0xC5, 0x1C, 0x88, 0xB4, 0x50, 0xC9, 0xD3 }, - }, - { - { 0xA1, 0x14, 0xA3, 0x50, 0x0A, 0x66, 0x1C, 0x15, 0x5A, 0xB1, 0xA8, 0x99, 0x7E, 0xFC, 0xFD, 0xD7, - 0xA1, 0x38, 0x3E, 0xA0, 0x5E, 0x45, 0x2C, 0x55, 0x1B, 0xB0, 0xC8, 0xBD, 0x8E, 0x4A, 0xAA, 0xDA }, - }, - { - { 0xA1, 0x97, 0x7D, 0x0C, 0x92, 0x7C, 0x21, 0xEB, 0x47, 0x6F, 0x67, 0xBE, 0xFE, 0xD6, 0xCF, 0x2C, - 0x61, 0xB7, 0x45, 0xF0, 0xCE, 0x8D, 0x26, 0x58, 0x3D, 0x03, 0xB2, 0x70, 0x02, 0xD5, 0xCD, 0xAF }, - }, - { - { 0xA1, 0xA3, 0xF6, 0x88, 0xFF, 0x45, 0xF6, 0x56, 0x75, 0x7A, 0x24, 0x52, 0xD5, 0xDB, 0xCD, 0x15, - 0x39, 0x4A, 0xC1, 0x1A, 0xF3, 0x8C, 0x2F, 0xEA, 0x0C, 0x7C, 0x39, 0x07, 0xFE, 0xC4, 0xB7, 0x8C }, - }, - { - { 0xA1, 0xF7, 0xA0, 0x7A, 0x4A, 0x67, 0xF6, 0xFF, 0x96, 0xCB, 0x97, 0xB8, 0xAD, 0x2B, 0x59, 0xBE, - 0xF6, 0xB1, 0xF3, 0x03, 0x80, 0xAB, 0x38, 0x3F, 0xAD, 0xF1, 0x23, 0x95, 0xA4, 0xBB, 0x08, 0x14 }, - }, - { - { 0xA2, 0x39, 0x3F, 0x9C, 0x59, 0x6C, 0x5F, 0xE2, 0xC6, 0x49, 0x39, 0xC6, 0x00, 0x43, 0x70, 0x8D, - 0x5F, 0xC6, 0x5F, 0x0C, 0xE8, 0x3E, 0x00, 0x73, 0x9D, 0x75, 0xA3, 0x31, 0xCC, 0xEA, 0x84, 0x45 }, - }, - { - { 0xA2, 0x3E, 0xD1, 0xB5, 0x14, 0x44, 0x95, 0xF7, 0x29, 0xD1, 0x90, 0xAD, 0xE0, 0x7C, 0xA9, 0x38, - 0xBC, 0x7D, 0x9F, 0x6D, 0x26, 0xF7, 0xE4, 0xF6, 0x0B, 0x50, 0x52, 0xDE, 0x66, 0x64, 0xDD, 0x64 }, - }, - { - { 0xA2, 0x6B, 0xA6, 0x8B, 0xD5, 0x7F, 0x66, 0x70, 0x89, 0xB7, 0x52, 0x56, 0x1D, 0x87, 0x12, 0xF0, - 0x8C, 0x7D, 0x96, 0x3D, 0x0F, 0xCD, 0x36, 0xAC, 0x58, 0x99, 0x8E, 0x4C, 0x1F, 0xD3, 0xE2, 0xDA }, - }, - { - { 0xA2, 0x6C, 0x37, 0x5E, 0xB3, 0x19, 0x6E, 0x28, 0x3B, 0xEC, 0x60, 0x3D, 0xB6, 0xBB, 0xDA, 0xE2, - 0x49, 0x55, 0xE4, 0xBA, 0x91, 0x0C, 0xD4, 0x2D, 0x9E, 0xAC, 0x55, 0xCA, 0xC6, 0x10, 0x3A, 0xB9 }, - }, - { - { 0xA3, 0x36, 0x7E, 0xDD, 0x97, 0xBE, 0x14, 0x34, 0xBA, 0x2C, 0x9C, 0xD0, 0x05, 0xF0, 0x1F, 0x5C, - 0x91, 0xA9, 0x32, 0x78, 0xFA, 0x14, 0xAB, 0xEF, 0x73, 0x3C, 0x43, 0xA6, 0x9F, 0xCA, 0x09, 0x6E }, - }, - { - { 0xA3, 0x75, 0x46, 0x27, 0x03, 0x85, 0x5B, 0x0F, 0x31, 0x40, 0xFD, 0xA3, 0xB5, 0x3A, 0xC4, 0x2C, - 0x0E, 0x09, 0x0E, 0xA4, 0x91, 0x20, 0x21, 0xB0, 0x4B, 0x1E, 0xB4, 0xF2, 0xB2, 0xD5, 0xD9, 0xC6 }, - }, - { - { 0xA3, 0xA4, 0xFC, 0x03, 0xE1, 0x75, 0xF2, 0x68, 0x02, 0x57, 0x46, 0x34, 0xDE, 0x70, 0x7D, 0x2F, - 0x92, 0xF4, 0xD0, 0xCB, 0x90, 0xCD, 0xB6, 0x1D, 0xD1, 0x95, 0x8B, 0xCF, 0x0C, 0x55, 0x20, 0x86 }, - }, - { - { 0xA4, 0x46, 0x9F, 0x13, 0x11, 0x77, 0xD7, 0xFD, 0xAB, 0x22, 0x64, 0xB2, 0xC9, 0xFA, 0x76, 0xAC, - 0x05, 0x0F, 0x42, 0xC6, 0xD6, 0x80, 0x2B, 0xA4, 0x07, 0x22, 0xD6, 0x48, 0x51, 0x24, 0x25, 0x1C }, - }, - { - { 0xA4, 0x55, 0x6D, 0x49, 0x3B, 0x52, 0x03, 0xAD, 0xE9, 0xAC, 0x0A, 0xAB, 0x86, 0xE4, 0x21, 0xDB, - 0xCF, 0xB2, 0x61, 0x00, 0x84, 0x07, 0xF3, 0xC6, 0x7B, 0x10, 0xD7, 0xCF, 0x48, 0x9D, 0xB8, 0x83 }, - }, - { - { 0xA4, 0xB4, 0xE2, 0xA5, 0x14, 0x66, 0xB8, 0x81, 0x06, 0xD3, 0xA0, 0xCB, 0x4C, 0x75, 0x26, 0xF1, - 0x0D, 0x21, 0x80, 0x90, 0x30, 0x82, 0x80, 0x98, 0xF4, 0x87, 0x78, 0x5E, 0x98, 0x78, 0xE6, 0x9C }, - }, - { - { 0xA5, 0x22, 0xAD, 0x4E, 0x88, 0x20, 0xD2, 0x31, 0x0D, 0xF1, 0x36, 0x76, 0x2B, 0x25, 0x32, 0x41, - 0x2D, 0x00, 0xA5, 0x03, 0x1B, 0x70, 0x28, 0x9A, 0xE6, 0x06, 0xC9, 0xA5, 0x8B, 0xFB, 0xDB, 0xD7 }, - }, - { - { 0xA5, 0x58, 0xCC, 0x2E, 0x2F, 0xE1, 0x06, 0x81, 0x12, 0x0B, 0xD2, 0x57, 0x94, 0xF8, 0xCA, 0x20, - 0xB0, 0x94, 0x3F, 0xBD, 0x13, 0x6E, 0x4B, 0x36, 0x77, 0x30, 0xF0, 0x5E, 0x71, 0x21, 0xF8, 0x97 }, - }, - { - { 0xA5, 0x60, 0x81, 0x15, 0x27, 0xB1, 0xFC, 0x3E, 0x25, 0xAF, 0x12, 0xC6, 0x10, 0xD3, 0x58, 0x18, - 0x43, 0x32, 0x10, 0xD3, 0x15, 0x27, 0x56, 0x45, 0x67, 0xDB, 0x9F, 0xF1, 0xA2, 0xED, 0x66, 0x90 }, - }, - { - { 0xA5, 0x61, 0x59, 0x83, 0x9A, 0x9E, 0x88, 0xA6, 0x18, 0xED, 0xB3, 0xCE, 0x3B, 0x8F, 0x16, 0x52, - 0x35, 0x22, 0xAF, 0x8B, 0x0C, 0x53, 0xEE, 0x1E, 0xA0, 0x85, 0x38, 0xB8, 0x88, 0x29, 0xC9, 0x2D }, - }, - { - { 0xA5, 0x67, 0x98, 0x6C, 0xE0, 0xE3, 0x36, 0xF8, 0x4F, 0xDC, 0x08, 0x15, 0xB8, 0x6E, 0xA3, 0x03, - 0x34, 0x3C, 0xF8, 0xC1, 0x0F, 0x37, 0x27, 0x83, 0x27, 0x14, 0x86, 0xB9, 0xC9, 0x3B, 0x63, 0x67 }, - }, - { - { 0xA5, 0x6A, 0x64, 0x81, 0xFE, 0x83, 0xDA, 0xB2, 0xEB, 0xA7, 0x01, 0x1D, 0x91, 0x3D, 0xB1, 0xA5, - 0x65, 0x83, 0xB1, 0x3A, 0xA9, 0x69, 0xC8, 0x32, 0xE7, 0x7E, 0x22, 0xFE, 0xBC, 0xC9, 0xE1, 0x30 }, - }, - { - { 0xA5, 0x9C, 0xAE, 0xC7, 0x30, 0x06, 0xB3, 0x36, 0x8F, 0x19, 0x6D, 0x6E, 0x12, 0x17, 0x48, 0x2D, - 0xD6, 0x61, 0x0E, 0x39, 0x5F, 0x27, 0x1F, 0x91, 0x31, 0x51, 0x9C, 0x02, 0x2B, 0xE2, 0x1A, 0x02 }, - }, - { - { 0xA5, 0xDB, 0xAF, 0x01, 0xD3, 0xD5, 0x79, 0xEE, 0x8A, 0x48, 0x8E, 0xE8, 0xD7, 0x44, 0x09, 0x58, - 0xF7, 0xBF, 0x97, 0xA2, 0xBC, 0xA8, 0xD9, 0x71, 0xF6, 0xF8, 0x97, 0x10, 0xBC, 0x2D, 0x10, 0x6F }, - }, - { - { 0xA6, 0x13, 0x01, 0x30, 0x19, 0xBB, 0x3E, 0xEC, 0x44, 0xCC, 0xBA, 0x1B, 0x46, 0xBD, 0x14, 0x09, - 0x62, 0x5D, 0x25, 0x82, 0x4E, 0x88, 0x2A, 0x5F, 0xF8, 0x63, 0x5B, 0x4C, 0x41, 0x83, 0x2E, 0x3C }, - }, - { - { 0xA6, 0x21, 0xAE, 0x36, 0x54, 0xAC, 0xFD, 0x17, 0x23, 0x30, 0x70, 0xE9, 0xB1, 0x8D, 0xFD, 0x91, - 0x6A, 0x55, 0x2E, 0x6A, 0x8B, 0x82, 0x42, 0xBD, 0x57, 0xBB, 0xCD, 0xF4, 0xE6, 0x5E, 0x99, 0x76 }, - }, - { - { 0xA6, 0x26, 0x87, 0xDE, 0x88, 0x0C, 0xF3, 0x35, 0xAE, 0x42, 0x4D, 0x4A, 0xDE, 0x29, 0xC7, 0xEC, - 0x33, 0xBF, 0xB9, 0xF8, 0x6E, 0xC7, 0xFC, 0xAF, 0x61, 0x9D, 0x71, 0x7C, 0x86, 0xB8, 0xFB, 0xBC }, - }, - { - { 0xA6, 0x33, 0x5D, 0xF3, 0xAB, 0xA5, 0xEA, 0xDF, 0xBD, 0xC9, 0xC2, 0xDC, 0x9D, 0x6B, 0xE6, 0x0B, - 0xB6, 0x2D, 0xF2, 0xFE, 0x24, 0xEC, 0x7B, 0xA7, 0x67, 0xBE, 0x65, 0xD3, 0x7F, 0x3C, 0x90, 0xF8 }, - }, - { - { 0xA6, 0x5C, 0xAE, 0x6C, 0x12, 0xE4, 0x7F, 0x8F, 0x67, 0x0C, 0x69, 0x37, 0xB1, 0xF0, 0xE1, 0x5C, - 0xF3, 0xA4, 0x4C, 0x11, 0x9C, 0xAF, 0x5E, 0x32, 0x6D, 0x8D, 0xB0, 0x81, 0xBE, 0x4F, 0xC3, 0x0A }, - }, - { - { 0xA6, 0x62, 0xFC, 0x81, 0xC9, 0x09, 0x34, 0xB9, 0xB4, 0xD6, 0x30, 0xB5, 0xD8, 0x2E, 0x86, 0xF2, - 0x36, 0x3E, 0xC1, 0x5C, 0xCF, 0xCD, 0xAF, 0xA7, 0xA2, 0x0C, 0x9B, 0x4E, 0x3A, 0x90, 0x0D, 0xD1 }, - }, - { - { 0xA6, 0x90, 0xB4, 0x5E, 0x85, 0xD9, 0x97, 0xF3, 0x3C, 0xBE, 0x1B, 0xE7, 0x5B, 0xC3, 0xD8, 0xE7, - 0x66, 0x3A, 0xFC, 0x0B, 0x62, 0x00, 0xBF, 0x4D, 0x74, 0x79, 0x0C, 0x17, 0x9F, 0xF0, 0x6A, 0x10 }, - }, - { - { 0xA6, 0xA4, 0xA3, 0xF6, 0x1F, 0xA5, 0x8C, 0xE9, 0x70, 0xB4, 0x58, 0xB7, 0xC3, 0x7C, 0x05, 0x2E, - 0xAD, 0x1E, 0xB2, 0x0B, 0x85, 0x67, 0xE3, 0x51, 0xAD, 0x8E, 0x6F, 0xBA, 0x49, 0xC2, 0x69, 0x2C }, - }, - { - { 0xA6, 0xB6, 0xDA, 0xD4, 0x51, 0x5B, 0x1C, 0xFC, 0x70, 0x37, 0x1C, 0xFC, 0xFC, 0x32, 0x30, 0x71, - 0x0E, 0x30, 0xEF, 0xE4, 0x0F, 0x95, 0xD5, 0x20, 0xAF, 0xC8, 0x65, 0x31, 0xE8, 0xC8, 0xF8, 0x41 }, - }, - { - { 0xA6, 0xDE, 0x6C, 0x3B, 0x8C, 0x14, 0x05, 0xCB, 0xE1, 0x2D, 0xB4, 0x09, 0x97, 0x61, 0x71, 0xAC, - 0xB5, 0x1F, 0xB3, 0xDC, 0xFB, 0xB7, 0x6E, 0xE3, 0x84, 0x95, 0x39, 0xCD, 0x8A, 0xB0, 0x66, 0xDF }, - }, - { - { 0xA6, 0xF1, 0xFA, 0xC9, 0x75, 0x7D, 0xFC, 0xB0, 0x66, 0x9F, 0x1F, 0x54, 0x68, 0xAC, 0xF6, 0xEA, - 0x83, 0x84, 0xB7, 0xC2, 0xC3, 0x0E, 0x40, 0xAA, 0xA9, 0x39, 0x21, 0xF2, 0x38, 0x72, 0xCA, 0xED }, - }, - { - { 0xA7, 0x08, 0x0D, 0xEB, 0x9A, 0xFE, 0x85, 0xBA, 0x27, 0xFE, 0xB4, 0xA9, 0xC2, 0xF9, 0xA7, 0x54, - 0xF3, 0xD5, 0xFF, 0xE6, 0xC3, 0xC4, 0xEE, 0x95, 0x56, 0x63, 0x1C, 0xE7, 0xEA, 0x20, 0x22, 0x72 }, - }, - { - { 0xA7, 0x0F, 0x0C, 0xE2, 0xD4, 0xFB, 0xE6, 0x63, 0x6A, 0x7A, 0x48, 0x94, 0x3C, 0xBD, 0x2D, 0x99, - 0x0E, 0x40, 0xFA, 0xA6, 0xD8, 0x56, 0x87, 0x7F, 0x45, 0x5B, 0xF0, 0x15, 0xF5, 0x45, 0x11, 0x3C }, - }, - { - { 0xA7, 0x36, 0xB1, 0x97, 0xE6, 0xFB, 0x3B, 0x62, 0x32, 0xED, 0xB3, 0xC8, 0xD6, 0x8C, 0xE1, 0x35, - 0x1A, 0x48, 0xB5, 0x6F, 0x70, 0x11, 0xBB, 0x99, 0x20, 0xCF, 0xCA, 0x75, 0x7E, 0x57, 0xC6, 0xC4 }, - }, - { - { 0xA7, 0x5D, 0x18, 0x19, 0x6F, 0x2F, 0x30, 0xF0, 0x36, 0x12, 0x7C, 0x67, 0x58, 0x14, 0x9D, 0x1E, - 0xE3, 0xDC, 0x4F, 0x03, 0x02, 0x68, 0x74, 0x05, 0x9E, 0xA4, 0x58, 0x7C, 0x77, 0x5A, 0x65, 0x21 }, - }, - { - { 0xA7, 0x7C, 0x12, 0x1C, 0xCE, 0x27, 0x74, 0xBC, 0xDD, 0x8C, 0xD5, 0x64, 0x71, 0x8C, 0x83, 0x18, - 0xF8, 0x1A, 0xEC, 0x99, 0x97, 0x00, 0xD9, 0xB9, 0x85, 0x9C, 0x2D, 0xB7, 0x63, 0x8A, 0xAC, 0xC0 }, - }, - { - { 0xA7, 0x7E, 0x5C, 0x39, 0xEB, 0x66, 0xA9, 0x48, 0x74, 0x88, 0xC7, 0xD1, 0x44, 0xC6, 0x37, 0xB6, - 0xB4, 0xC5, 0xCD, 0xA2, 0x09, 0x02, 0xD8, 0x22, 0x95, 0xB7, 0x5B, 0xFF, 0xD5, 0xB9, 0x61, 0x98 }, - }, - { - { 0xA7, 0x86, 0x18, 0xD8, 0xA7, 0xF0, 0x08, 0xAF, 0xDC, 0x72, 0x44, 0x98, 0x2C, 0x11, 0x34, 0xC5, - 0xDC, 0x91, 0xEC, 0x94, 0x25, 0xBF, 0xEF, 0xC8, 0xCC, 0x0A, 0xF8, 0xF8, 0xC7, 0x59, 0x61, 0xC2 }, - }, - { - { 0xA8, 0x53, 0xAD, 0xC1, 0xC2, 0x18, 0x59, 0xAF, 0x7C, 0x46, 0x2B, 0x4A, 0xA0, 0xA5, 0x74, 0xCA, - 0x9F, 0xEE, 0xFB, 0x18, 0x5A, 0x1F, 0xDB, 0xB6, 0xC1, 0x0E, 0x17, 0xD6, 0x01, 0xB7, 0x09, 0x8F }, - }, - { - { 0xA8, 0x7F, 0x0D, 0xF3, 0xEB, 0x2C, 0x90, 0x1F, 0x11, 0x6F, 0x6A, 0x8B, 0x01, 0xE2, 0x95, 0xCD, - 0x60, 0x72, 0x69, 0x5A, 0xB1, 0x65, 0x4B, 0x7B, 0xF9, 0xC4, 0x7E, 0x06, 0x20, 0x25, 0x6F, 0x81 }, - }, - { - { 0xA8, 0xC6, 0xB0, 0x72, 0x2A, 0x0D, 0x13, 0xDC, 0x8B, 0x7F, 0xBB, 0x20, 0xBC, 0x66, 0xE6, 0x03, - 0x0E, 0x4B, 0xDE, 0x99, 0xEA, 0xCA, 0x9C, 0x96, 0x5D, 0x34, 0x65, 0xC9, 0xAB, 0xFF, 0x64, 0x11 }, - }, - { - { 0xA8, 0xDF, 0xF0, 0x6A, 0x17, 0x35, 0xB4, 0x6D, 0x17, 0xDA, 0xEB, 0xC3, 0x43, 0x43, 0x18, 0x31, - 0x3B, 0x2D, 0x9E, 0x7C, 0x3E, 0xF4, 0x8F, 0x28, 0x53, 0x75, 0x35, 0x13, 0xE1, 0xB2, 0x53, 0xA8 }, - }, - { - { 0xA8, 0xE3, 0x8C, 0x6E, 0xC0, 0x93, 0xF5, 0xAF, 0x53, 0x88, 0xF1, 0xE7, 0x66, 0xD7, 0x5F, 0xFB, - 0x57, 0xDD, 0xBE, 0x3E, 0x9D, 0xC2, 0xE0, 0xBE, 0x57, 0xBB, 0x88, 0x36, 0x46, 0xC5, 0xC0, 0x32 }, - }, - { - { 0xA9, 0x0B, 0x8D, 0xE1, 0x7F, 0x6B, 0x68, 0x37, 0x56, 0x21, 0x2D, 0xB3, 0xAB, 0x34, 0x89, 0x6E, - 0x91, 0x70, 0x93, 0x11, 0x3E, 0x47, 0xCA, 0x35, 0x96, 0x2E, 0xAC, 0xCA, 0x9C, 0xB3, 0x86, 0xF0 }, - }, - { - { 0xA9, 0x20, 0x6F, 0x6D, 0x45, 0x43, 0xED, 0x74, 0x4A, 0x5F, 0x15, 0x4A, 0xCB, 0x44, 0x50, 0x89, - 0x6B, 0x62, 0x5D, 0x7E, 0x32, 0x33, 0x85, 0xA9, 0xFD, 0x25, 0x63, 0x93, 0x2F, 0x9C, 0xCC, 0x1B }, - }, - { - { 0xA9, 0x4C, 0xC9, 0xDE, 0x55, 0x52, 0xA6, 0xD9, 0x6F, 0xE4, 0x10, 0xBE, 0x03, 0x97, 0x6F, 0x6B, - 0x0D, 0x4D, 0xA0, 0x5D, 0x73, 0x7A, 0xD2, 0xA3, 0x1E, 0x0B, 0xAD, 0x90, 0x82, 0xA5, 0x77, 0xB1 }, - }, - { - { 0xA9, 0x5C, 0x06, 0x3E, 0x9E, 0x35, 0x84, 0xE5, 0x99, 0x88, 0xF0, 0x73, 0x86, 0x4C, 0x18, 0x76, - 0xB5, 0xDF, 0x9B, 0x44, 0xC6, 0x1B, 0x4A, 0x8B, 0xE4, 0x83, 0xBE, 0x05, 0xCF, 0xD1, 0xA1, 0xA6 }, - }, - { - { 0xA9, 0x67, 0x07, 0x76, 0x47, 0x9A, 0xB3, 0xA1, 0x4F, 0xCD, 0x01, 0x56, 0x63, 0x86, 0xCC, 0x45, - 0xCF, 0xA0, 0x53, 0x5A, 0xE0, 0xE9, 0x54, 0x5F, 0x86, 0x3B, 0xCF, 0x7A, 0x7C, 0xD6, 0x1A, 0x2B }, - }, - { - { 0xA9, 0x71, 0x2F, 0x85, 0xED, 0x2E, 0x25, 0xAD, 0xA5, 0x7D, 0xC1, 0xF0, 0xF8, 0x6D, 0xE1, 0x07, - 0xB5, 0xE2, 0xF0, 0x36, 0x09, 0x53, 0xF1, 0xED, 0x12, 0x5E, 0x37, 0x07, 0x59, 0x47, 0x1D, 0x09 }, - }, - { - { 0xA9, 0x7C, 0x77, 0xCA, 0x22, 0xEB, 0x80, 0xCC, 0x7B, 0xA9, 0x62, 0xEB, 0x58, 0x03, 0xBF, 0xCE, - 0x89, 0x6D, 0x57, 0x43, 0xDB, 0x12, 0x84, 0xC8, 0xAD, 0xBA, 0x37, 0x91, 0x7D, 0xF8, 0x03, 0xB1 }, - }, - { - { 0xA9, 0x94, 0xC9, 0x09, 0x10, 0x60, 0x9A, 0xF5, 0x0A, 0x4C, 0x09, 0x22, 0x97, 0xC9, 0xB4, 0xC7, - 0xF1, 0x03, 0x96, 0xAF, 0x73, 0x95, 0xE9, 0xE1, 0xBF, 0xB8, 0x99, 0x53, 0xFA, 0x15, 0x25, 0x9B }, - }, - { - { 0xA9, 0xE2, 0x85, 0xD1, 0xC2, 0xE8, 0xCA, 0x53, 0xCE, 0x97, 0xBB, 0xA6, 0x54, 0x8C, 0xA2, 0xF8, - 0x59, 0xE4, 0xC1, 0xF5, 0xF3, 0x57, 0x6C, 0xA3, 0x2D, 0x03, 0x30, 0x6E, 0x42, 0x3E, 0xF2, 0x5E }, - }, - { - { 0xAA, 0x0E, 0x12, 0x52, 0x43, 0x6D, 0xEF, 0x79, 0x07, 0xFB, 0x99, 0xF7, 0x64, 0x15, 0x50, 0xD8, - 0x0F, 0xAF, 0xFB, 0xF3, 0x01, 0x71, 0x1C, 0x7B, 0x6B, 0xEF, 0x59, 0x6F, 0x94, 0x10, 0xEF, 0xD2 }, - }, - { - { 0xAA, 0xEB, 0xFE, 0x2D, 0x21, 0xB7, 0xE5, 0x35, 0x1B, 0xB9, 0x99, 0x69, 0x44, 0x44, 0x19, 0xEF, - 0x21, 0xC9, 0x68, 0x8C, 0xE0, 0x53, 0x24, 0x88, 0x84, 0xCA, 0xB0, 0xB8, 0x95, 0x10, 0x30, 0xFF }, - }, - { - { 0xAB, 0x41, 0x28, 0x10, 0x9C, 0xAB, 0x8A, 0x58, 0x7C, 0x8F, 0xF4, 0xC7, 0xF6, 0x87, 0x34, 0x49, - 0x98, 0x18, 0xD1, 0x3F, 0x52, 0x26, 0x76, 0xD0, 0x66, 0xB3, 0x52, 0x17, 0x6F, 0xD2, 0x35, 0x96 }, - }, - { - { 0xAB, 0x80, 0xD9, 0xBA, 0x0A, 0xEF, 0xAD, 0x7B, 0xEC, 0xCE, 0x7F, 0x5E, 0x61, 0x59, 0x9A, 0xF5, - 0x26, 0x69, 0xBF, 0x59, 0x50, 0x7F, 0x8E, 0xF1, 0x99, 0x13, 0xC4, 0x2E, 0xE1, 0x29, 0xDA, 0xF0 }, - }, - { - { 0xAB, 0xA1, 0x08, 0xA4, 0xB1, 0x89, 0x3D, 0x18, 0xA3, 0x88, 0xB7, 0x22, 0x54, 0x1C, 0xA2, 0xC0, - 0x05, 0xC2, 0x69, 0x9A, 0x61, 0xFE, 0xAB, 0xBF, 0x61, 0x7A, 0xAA, 0xDD, 0xD4, 0x9E, 0xA9, 0x4D }, - }, - { - { 0xAB, 0xA7, 0x8E, 0x90, 0xF3, 0x24, 0x17, 0xAE, 0xC2, 0x8E, 0xEA, 0x30, 0x22, 0xA2, 0xE2, 0xB7, - 0x66, 0x1A, 0xC7, 0x23, 0xC8, 0x7E, 0x0D, 0xBC, 0xE2, 0x33, 0xE2, 0x16, 0x8F, 0xCF, 0x91, 0xB3 }, - }, - { - { 0xAB, 0xDD, 0x1E, 0xA9, 0x43, 0xC2, 0x32, 0x71, 0x63, 0x8E, 0x8F, 0x96, 0xFC, 0xD0, 0xDD, 0x3D, - 0xF5, 0x45, 0x07, 0x9D, 0xB7, 0x08, 0xEA, 0x64, 0x92, 0x5B, 0x62, 0xAD, 0x92, 0x3C, 0x43, 0xD5 }, - }, - { - { 0xAB, 0xEB, 0x6A, 0xA0, 0xD1, 0xB0, 0xE0, 0x49, 0xD6, 0x9D, 0xF8, 0x3A, 0xDD, 0x19, 0xF7, 0x26, - 0x8A, 0x38, 0xDE, 0x6C, 0x00, 0x72, 0x60, 0x68, 0xC2, 0xEE, 0xE4, 0x55, 0x44, 0xF6, 0xD6, 0x7A }, - }, - { - { 0xAB, 0xED, 0xE5, 0xB0, 0xE2, 0xB1, 0x5F, 0xFE, 0xF1, 0x84, 0x71, 0xC4, 0x53, 0xF0, 0xC4, 0x85, - 0xD2, 0x78, 0xFD, 0xE6, 0x3F, 0x82, 0x74, 0x13, 0xCC, 0x10, 0xDE, 0x4B, 0x82, 0xDE, 0xF6, 0x8D }, - }, - { - { 0xAC, 0x1B, 0x4C, 0x64, 0x6C, 0xAE, 0xFB, 0x10, 0x8A, 0x54, 0xCA, 0xB5, 0x4A, 0x96, 0xE9, 0x66, - 0x6E, 0x72, 0xA8, 0x20, 0x22, 0x44, 0xEF, 0x3D, 0x7C, 0xA9, 0x34, 0xDF, 0xCC, 0x24, 0xFC, 0xA7 }, - }, - { - { 0xAC, 0x7C, 0x14, 0xB9, 0x56, 0x8F, 0x92, 0x07, 0x5A, 0xD4, 0xA3, 0xBA, 0x3D, 0x4B, 0x01, 0x84, - 0x91, 0xF3, 0x66, 0x1A, 0x37, 0x9B, 0x3D, 0xFE, 0xDD, 0x6F, 0xD3, 0xC3, 0x2E, 0xFA, 0x84, 0x7D }, - }, - { - { 0xAC, 0x8C, 0x6F, 0x03, 0xE4, 0xBA, 0xCF, 0x72, 0x20, 0x25, 0xDB, 0x54, 0xD0, 0xFA, 0xAE, 0x7D, - 0xBE, 0x51, 0x37, 0x97, 0x37, 0x39, 0x45, 0x05, 0xF0, 0x86, 0xAA, 0x89, 0xE2, 0xD4, 0xF7, 0x3B }, - }, - { - { 0xAC, 0x90, 0x98, 0xF6, 0x4F, 0xE1, 0x03, 0xC8, 0xC1, 0x40, 0x30, 0xDB, 0xCE, 0xDD, 0x63, 0xD1, - 0xD1, 0x7C, 0x33, 0x8E, 0xBD, 0x1D, 0x7D, 0xE5, 0x6C, 0x79, 0xD2, 0x1A, 0x6F, 0x2E, 0x47, 0xA7 }, - }, - { - { 0xAC, 0x91, 0x0B, 0x02, 0xB4, 0xAB, 0x08, 0x16, 0xF0, 0xD9, 0x52, 0x0C, 0x94, 0xD3, 0x6C, 0x28, - 0x93, 0x38, 0x8C, 0x6A, 0xE1, 0xCA, 0x37, 0xA2, 0x4D, 0x48, 0x92, 0x70, 0x2A, 0xC7, 0xCD, 0x0C }, - }, - { - { 0xAD, 0x4B, 0x2F, 0x8E, 0xF2, 0xDE, 0xFB, 0x01, 0x92, 0x3C, 0x9C, 0x0F, 0xE2, 0x5A, 0x9A, 0xCE, - 0x41, 0xFA, 0x9E, 0x69, 0x75, 0x85, 0xFC, 0x3D, 0xDF, 0x8D, 0x34, 0xE7, 0x45, 0xFF, 0x0F, 0x12 }, - }, - { - { 0xAD, 0x69, 0x54, 0x5F, 0x9F, 0x85, 0x25, 0x5F, 0xE4, 0x16, 0x51, 0x3D, 0x94, 0xDB, 0x31, 0x50, - 0x5F, 0x38, 0x4B, 0x52, 0x3C, 0x2C, 0xA2, 0x6E, 0xDC, 0x0A, 0x54, 0x9A, 0x8F, 0x16, 0x26, 0xF9 }, - }, - { - { 0xAD, 0xB7, 0xF8, 0xE5, 0x75, 0x00, 0x60, 0xD5, 0x87, 0xD6, 0x02, 0x54, 0x58, 0xFC, 0xB0, 0xB6, - 0xCE, 0x4F, 0x3D, 0x86, 0x79, 0x2B, 0xAF, 0xF0, 0xAA, 0xCC, 0x19, 0x0A, 0xB7, 0x0C, 0xB6, 0x2C }, - }, - { - { 0xAD, 0xF9, 0x1E, 0x85, 0x6E, 0xCA, 0xA9, 0xB5, 0x1C, 0x0A, 0x4A, 0x93, 0xA1, 0xAA, 0x53, 0xE5, - 0x2C, 0x31, 0x85, 0xB6, 0x7A, 0x72, 0xBD, 0x2F, 0x8F, 0x5B, 0x14, 0xB5, 0x84, 0x0E, 0x52, 0x9F }, - }, - { - { 0xAE, 0x03, 0x19, 0xFE, 0xA6, 0xA6, 0x5E, 0x84, 0xE8, 0x54, 0xB5, 0x15, 0x50, 0xEA, 0x44, 0x4F, - 0xA3, 0xB8, 0xBB, 0x50, 0xAE, 0x93, 0x74, 0x01, 0x3C, 0xFE, 0xF3, 0x88, 0x73, 0x5D, 0x0B, 0xD3 }, - }, - { - { 0xAE, 0x2F, 0x15, 0xEA, 0x4A, 0xA5, 0x39, 0x81, 0x41, 0x0F, 0x98, 0x93, 0x81, 0xA4, 0x41, 0x5A, - 0xF1, 0x84, 0x3D, 0x19, 0xE4, 0x39, 0x07, 0xAF, 0x53, 0xB2, 0x0F, 0x7F, 0xA7, 0x73, 0x2A, 0x93 }, - }, - { - { 0xAE, 0x4D, 0xF3, 0x97, 0x9B, 0x74, 0x27, 0x34, 0xA3, 0x39, 0xC4, 0x70, 0x1D, 0x5E, 0x13, 0x21, - 0x26, 0x3F, 0xF4, 0x4E, 0x67, 0x56, 0x49, 0x05, 0xF4, 0x9E, 0x25, 0x34, 0x62, 0xB8, 0x02, 0x25 }, - }, - { - { 0xAE, 0xE7, 0xD6, 0x4C, 0x89, 0x7A, 0x32, 0xDB, 0xCA, 0xF1, 0x15, 0x6F, 0xC7, 0xBF, 0xC8, 0x00, - 0x96, 0x73, 0x85, 0xD5, 0xB1, 0xE3, 0x25, 0xD8, 0xFA, 0x3B, 0x9C, 0x16, 0x25, 0xBC, 0x29, 0x92 }, - }, - { - { 0xAF, 0x0B, 0x21, 0x86, 0x24, 0x61, 0xD1, 0xF3, 0x9B, 0x07, 0x44, 0xFD, 0xC9, 0x28, 0x77, 0x99, - 0x62, 0x01, 0x1D, 0xFE, 0x0B, 0xD8, 0xD9, 0x56, 0xC2, 0x47, 0xB5, 0xF5, 0xB4, 0x43, 0x63, 0x1C }, - }, - { - { 0xAF, 0x1F, 0x37, 0x1F, 0x34, 0x84, 0x57, 0x51, 0x65, 0x2D, 0xC7, 0x48, 0x23, 0xF3, 0x01, 0x5C, - 0x5A, 0x11, 0xCA, 0x65, 0x3F, 0x28, 0x70, 0x1E, 0xDD, 0x4A, 0x7E, 0x0D, 0x23, 0x17, 0x1B, 0xBB }, - }, - { - { 0xAF, 0x6A, 0x9D, 0x88, 0xAD, 0xE1, 0x24, 0xDB, 0xF9, 0x50, 0xB2, 0xC4, 0x27, 0xBC, 0x40, 0x19, - 0x63, 0xB9, 0x61, 0x25, 0xC0, 0xA2, 0xAE, 0xBB, 0x7F, 0xB3, 0xF9, 0x8E, 0x48, 0x7A, 0x7F, 0xA6 }, - }, - { - { 0xAF, 0x6B, 0x80, 0x51, 0x47, 0x14, 0x0A, 0x0E, 0x41, 0x81, 0xD8, 0x6A, 0x7E, 0x8F, 0x07, 0x69, - 0xB6, 0x1D, 0x46, 0xD7, 0xB6, 0xFA, 0xC6, 0xE6, 0xF9, 0x59, 0x6D, 0xE9, 0x4A, 0xA8, 0xE2, 0xE8 }, - }, - { - { 0xAF, 0xB5, 0x7F, 0x89, 0x64, 0x9A, 0xB3, 0x0A, 0xF4, 0x88, 0x43, 0x05, 0xAF, 0x88, 0xEE, 0x56, - 0x5B, 0xA8, 0xD3, 0xC5, 0xC3, 0x57, 0x4A, 0xB8, 0x59, 0xFC, 0x07, 0x23, 0x2F, 0xC6, 0x73, 0xB9 }, - }, - { - { 0xAF, 0xBB, 0x40, 0x3C, 0xAD, 0x0D, 0x19, 0xCC, 0x26, 0xAE, 0x5B, 0x1E, 0x31, 0x0A, 0xC1, 0xAE, - 0x79, 0x47, 0x1B, 0xAD, 0x2B, 0xD7, 0x7B, 0xE4, 0x0F, 0x12, 0x50, 0x4C, 0x42, 0xE5, 0x22, 0x0B }, - }, - { - { 0xAF, 0xE7, 0xB8, 0xEE, 0xFD, 0xF5, 0x4E, 0x7F, 0x1C, 0x5A, 0x6B, 0xED, 0xF7, 0x54, 0xCE, 0x97, - 0x0F, 0xA1, 0x19, 0x59, 0xE7, 0x80, 0x38, 0xCC, 0x36, 0x8A, 0xC7, 0x78, 0xB7, 0x5C, 0x92, 0x4B }, - }, - { - { 0xAF, 0xE9, 0x28, 0xC5, 0x84, 0x8E, 0xCE, 0x02, 0xC2, 0xBD, 0xDC, 0xD9, 0x4B, 0x5A, 0x59, 0x30, - 0x31, 0x50, 0x9D, 0x78, 0x2B, 0xEB, 0x50, 0x20, 0xAC, 0xB3, 0x33, 0x71, 0x49, 0x18, 0xF0, 0x39 }, - }, - { - { 0xB0, 0x16, 0x77, 0xD9, 0xCA, 0x50, 0x46, 0x3F, 0x21, 0x8A, 0x5D, 0x33, 0x9E, 0x72, 0xF8, 0x59, - 0xF8, 0xB4, 0x1A, 0xE7, 0x9D, 0xCB, 0x8F, 0xA1, 0x65, 0x08, 0x45, 0xCE, 0xC4, 0xD8, 0xCB, 0x87 }, - }, - { - { 0xB0, 0x1E, 0xB1, 0x82, 0x68, 0x1A, 0xA9, 0x5D, 0x7B, 0xEA, 0xAF, 0x53, 0xBA, 0x75, 0x5B, 0x7F, - 0x3D, 0x0F, 0xB7, 0x97, 0x76, 0xD5, 0x62, 0xB9, 0x93, 0x8F, 0xFE, 0x98, 0x8D, 0x99, 0xB3, 0x13 }, - }, - { - { 0xB0, 0x5C, 0x14, 0x33, 0x61, 0x75, 0x9B, 0xE1, 0x52, 0xFD, 0x76, 0xA5, 0xFF, 0xA4, 0x87, 0x2D, - 0xD4, 0x2E, 0xA0, 0x60, 0xAE, 0x40, 0xA3, 0x83, 0x13, 0xB7, 0xB5, 0x4A, 0xEC, 0x06, 0x73, 0xC2 }, - }, - { - { 0xB0, 0x62, 0x43, 0x51, 0xFD, 0x68, 0x51, 0x23, 0x01, 0x38, 0x56, 0xEC, 0x40, 0x63, 0x25, 0xFC, - 0xCB, 0x16, 0x45, 0x76, 0x50, 0xA8, 0x71, 0xF5, 0xFB, 0x91, 0x5D, 0xDD, 0x75, 0x4A, 0x3B, 0xC9 }, - }, - { - { 0xB0, 0xB6, 0x32, 0x1C, 0x45, 0x9B, 0xDB, 0x78, 0x91, 0x8E, 0xC3, 0x16, 0xBD, 0x36, 0xEC, 0x5F, - 0x30, 0x55, 0x8E, 0xE0, 0x2E, 0xCC, 0x51, 0xE3, 0x77, 0xC5, 0xF8, 0xAB, 0xA4, 0x1D, 0xBA, 0x6D }, - }, - { - { 0xB0, 0xE0, 0xE1, 0x6C, 0x5F, 0x69, 0x1F, 0x66, 0xA9, 0x57, 0x3B, 0xD3, 0xCF, 0x43, 0xF9, 0xDF, - 0xD2, 0xAD, 0x3E, 0x56, 0x15, 0x54, 0x63, 0x7F, 0x1E, 0x7B, 0x71, 0x91, 0x4D, 0x62, 0x73, 0x38 }, - }, - { - { 0xB1, 0x61, 0xD6, 0x09, 0x5B, 0x6E, 0x9B, 0x1D, 0xB5, 0x16, 0xDA, 0x1C, 0x2D, 0xEF, 0x9C, 0xE9, - 0x11, 0xC7, 0xA5, 0xBB, 0x55, 0xEF, 0xF5, 0x05, 0x66, 0xD5, 0xD1, 0xE0, 0xDC, 0x4F, 0x45, 0xCD }, - }, - { - { 0xB1, 0x91, 0x9D, 0x6C, 0xFA, 0xC2, 0x0D, 0x03, 0x47, 0x76, 0x87, 0x1A, 0xB0, 0xA2, 0x57, 0x8A, - 0xC0, 0xB2, 0xDD, 0xB6, 0x8B, 0xE1, 0xDC, 0x75, 0x91, 0x80, 0x44, 0x1F, 0x05, 0x3A, 0x27, 0x2C }, - }, - { - { 0xB1, 0x92, 0x30, 0x7C, 0xFA, 0xEE, 0x42, 0x7B, 0x76, 0x7B, 0xC2, 0xF9, 0x9B, 0xC2, 0x26, 0x74, - 0x26, 0x0A, 0x4E, 0x8E, 0x1E, 0x6B, 0x36, 0x19, 0x8C, 0x2F, 0x4E, 0xEA, 0x67, 0xCA, 0x85, 0xEF }, - }, - { - { 0xB1, 0xA5, 0x89, 0x8E, 0x3B, 0x0D, 0x0A, 0x7A, 0x80, 0x76, 0x79, 0x3D, 0x6C, 0x63, 0xA3, 0x22, - 0xEA, 0xB7, 0x1F, 0x7E, 0x28, 0x74, 0x5D, 0xEF, 0xF5, 0xA0, 0xC3, 0x3A, 0x8E, 0xEC, 0xE4, 0xFA }, - }, - { - { 0xB2, 0xAF, 0x84, 0x2D, 0x01, 0x52, 0x07, 0x85, 0x37, 0x0E, 0x3E, 0xB5, 0x9C, 0xB8, 0x89, 0x29, - 0xDE, 0x38, 0xA7, 0x15, 0xBF, 0x4C, 0xEF, 0x45, 0xE5, 0x95, 0xCE, 0xED, 0x3F, 0xEA, 0x26, 0x79 }, - }, - { - { 0xB2, 0xBA, 0x3B, 0x49, 0xB8, 0xE5, 0x84, 0x51, 0x81, 0x6B, 0x10, 0x83, 0x6C, 0x4F, 0x1C, 0xA6, - 0xA3, 0x39, 0x37, 0xCE, 0xB8, 0xF0, 0xC0, 0x4B, 0x9F, 0x75, 0x8C, 0x5E, 0xB4, 0x78, 0x41, 0x1F }, - }, - { - { 0xB2, 0xC6, 0xF7, 0xC6, 0x2F, 0xA5, 0x6A, 0x4E, 0x57, 0xB7, 0x62, 0xA8, 0x9C, 0x3C, 0x55, 0xDD, - 0x81, 0xC1, 0x82, 0x7E, 0xDF, 0xB0, 0xD4, 0x41, 0x80, 0xE4, 0xFA, 0xDC, 0xEB, 0x23, 0x72, 0x73 }, - }, - { - { 0xB2, 0xDC, 0x86, 0x25, 0x6C, 0xCF, 0xF4, 0xBB, 0x14, 0xFD, 0x70, 0x27, 0x9F, 0xCC, 0x3C, 0xE9, - 0x25, 0xC5, 0x1F, 0xB7, 0x17, 0xE5, 0x87, 0x6F, 0x29, 0x1B, 0xA1, 0x70, 0x73, 0x43, 0x85, 0x68 }, - }, - { - { 0xB2, 0xE5, 0xFA, 0xF7, 0xEE, 0xBE, 0xD8, 0xC2, 0x9C, 0x7B, 0x83, 0x65, 0x3A, 0xF3, 0xFC, 0x9F, - 0x8D, 0xE4, 0x6E, 0xE5, 0x3B, 0x64, 0x9C, 0x94, 0x53, 0x87, 0xB0, 0xCF, 0xF8, 0xB7, 0x14, 0x93 }, - }, - { - { 0xB3, 0x07, 0x32, 0xE7, 0x56, 0x52, 0x9E, 0x38, 0x59, 0xC4, 0x31, 0x23, 0x86, 0x19, 0x53, 0x34, - 0x79, 0x8E, 0x43, 0xC4, 0xBE, 0xBC, 0xC4, 0xCF, 0xED, 0xFB, 0x2E, 0xBF, 0xA0, 0xDD, 0x80, 0x0E }, - }, - { - { 0xB3, 0x0D, 0x88, 0x44, 0x30, 0x43, 0xF5, 0xF3, 0x72, 0x32, 0xBB, 0x9B, 0xAC, 0xB9, 0x94, 0xC5, - 0xBA, 0xE9, 0x3A, 0x46, 0xFC, 0x87, 0xF1, 0x51, 0x29, 0xC9, 0x74, 0x69, 0xA5, 0x81, 0x4E, 0xCA }, - }, - { - { 0xB3, 0x19, 0xAF, 0x08, 0x28, 0x68, 0x1F, 0x97, 0x35, 0xA4, 0x8D, 0x11, 0x17, 0x39, 0xB8, 0x62, - 0x89, 0xAE, 0xF7, 0xFB, 0x81, 0x7C, 0x04, 0x7F, 0x12, 0x75, 0xA5, 0x87, 0xA7, 0x32, 0x2C, 0x0B }, - }, - { - { 0xB3, 0x1A, 0xF0, 0xC2, 0xE5, 0x1E, 0xA2, 0x1C, 0x91, 0x04, 0xF9, 0x4F, 0xAA, 0x66, 0xE0, 0xCC, - 0xC0, 0x41, 0x34, 0xD5, 0x80, 0x9A, 0x2A, 0x26, 0x70, 0xA3, 0xB7, 0xBC, 0x7D, 0xD9, 0x64, 0xF8 }, - }, - { - { 0xB3, 0x35, 0x93, 0x3F, 0xC9, 0x72, 0x3E, 0x9D, 0xAA, 0x0D, 0x0C, 0xE7, 0x1C, 0x66, 0x5A, 0xDD, - 0xA5, 0xAB, 0xDA, 0xF3, 0x5A, 0xDB, 0x10, 0xD7, 0x6E, 0xDC, 0x9C, 0x8E, 0x4E, 0xBA, 0x05, 0x6E }, - }, - { - { 0xB3, 0x95, 0x0E, 0x0B, 0xD2, 0x2C, 0x39, 0xFA, 0xB1, 0xDB, 0xD7, 0xBE, 0xB7, 0x42, 0x56, 0xAF, - 0xB1, 0x1D, 0xCB, 0x26, 0x35, 0x69, 0x70, 0x83, 0xD6, 0x8F, 0xDB, 0xEE, 0x80, 0xB0, 0x5F, 0x54 }, - }, - { - { 0xB3, 0xE6, 0x42, 0x06, 0x6E, 0x41, 0x78, 0x67, 0xD9, 0x0F, 0xB9, 0xB2, 0xBA, 0x15, 0x41, 0x98, - 0xA5, 0xC5, 0xF6, 0xCC, 0x82, 0x9B, 0x51, 0x39, 0xDF, 0xD6, 0x91, 0xE5, 0x1A, 0xD3, 0x74, 0xAD }, - }, - { - { 0xB3, 0xF4, 0xB1, 0x6F, 0x8E, 0xCE, 0xBB, 0x41, 0x47, 0x4F, 0x92, 0x4F, 0xEE, 0xF9, 0xB0, 0xBD, - 0x97, 0x9B, 0x36, 0x36, 0xC3, 0x4F, 0xF2, 0x72, 0x3F, 0x67, 0x3C, 0x8E, 0xEE, 0x2A, 0xF1, 0x52 }, - }, - { - { 0xB4, 0x02, 0x2C, 0x24, 0x25, 0xA5, 0xB7, 0x5A, 0x9B, 0x5E, 0x80, 0x08, 0x1C, 0x95, 0x3A, 0xD3, - 0xDB, 0x93, 0xB2, 0x52, 0xDA, 0x0E, 0x25, 0xEC, 0x8B, 0xAD, 0x0C, 0x36, 0xAA, 0x11, 0x09, 0x2E }, - }, - { - { 0xB4, 0x2A, 0x78, 0xB0, 0x6F, 0x28, 0x15, 0xD4, 0xA0, 0x49, 0xFE, 0x83, 0xF3, 0xD2, 0x9B, 0x38, - 0x5B, 0x90, 0xD3, 0xD0, 0x0B, 0xA8, 0x57, 0xD6, 0x2F, 0x19, 0x67, 0x81, 0xDD, 0xA3, 0xD1, 0x85 }, - }, - { - { 0xB4, 0x2C, 0x64, 0xF0, 0x25, 0xDF, 0x8F, 0x37, 0x0E, 0xB7, 0xA4, 0x69, 0x94, 0x2B, 0x97, 0xE2, - 0xF8, 0xB5, 0xF4, 0xBF, 0xAC, 0xC4, 0xCF, 0x17, 0xD2, 0xA0, 0x8F, 0xCA, 0x57, 0xBB, 0xC4, 0x9B }, - }, - { - { 0xB4, 0xAE, 0x2A, 0x6B, 0xFC, 0xA5, 0x31, 0xC9, 0x9C, 0x69, 0xB3, 0x5A, 0xFE, 0x67, 0x54, 0xFC, - 0x49, 0x27, 0x5B, 0x6C, 0xCA, 0xCD, 0xC8, 0x26, 0x9C, 0x27, 0x0C, 0xDB, 0x2B, 0x58, 0xC0, 0x8F }, - }, - { - { 0xB4, 0xD4, 0x67, 0xFC, 0x5E, 0x97, 0xDB, 0x25, 0xA1, 0xFD, 0xB0, 0x06, 0xD2, 0x77, 0x66, 0xB9, - 0x99, 0x5B, 0xB9, 0xC7, 0x7B, 0x66, 0x43, 0x97, 0x08, 0xA4, 0x59, 0xB0, 0x43, 0xD0, 0x33, 0x24 }, - }, - { - { 0xB4, 0xED, 0xCD, 0x6F, 0x8A, 0x01, 0x82, 0xB7, 0x17, 0xF0, 0x6F, 0xE1, 0xD7, 0xAC, 0x9C, 0x62, - 0x33, 0xD4, 0x38, 0x22, 0xE9, 0xFD, 0x14, 0xDB, 0x98, 0xF7, 0xF8, 0x4E, 0x32, 0x79, 0x6D, 0x08 }, - }, - { - { 0xB4, 0xF1, 0xEF, 0x4A, 0xA5, 0x1F, 0x02, 0x1E, 0xD2, 0x66, 0x26, 0x44, 0xCE, 0xDA, 0x31, 0x1D, - 0x86, 0xF5, 0x64, 0x0D, 0xAF, 0xE9, 0xA4, 0x39, 0x18, 0x89, 0x37, 0xD8, 0x09, 0x13, 0x90, 0x75 }, - }, - { - { 0xB5, 0x25, 0x36, 0x2F, 0x68, 0x54, 0x4A, 0xC1, 0x8C, 0x2F, 0x5C, 0x19, 0x51, 0x47, 0x94, 0x40, - 0x45, 0x8C, 0x59, 0xD7, 0xBB, 0x00, 0x5F, 0x19, 0x91, 0x17, 0x51, 0xB4, 0xD3, 0x97, 0x1D, 0x5C }, - }, - { - { 0xB5, 0x3B, 0x30, 0x01, 0x2D, 0xBC, 0xA0, 0x5E, 0x6A, 0xF7, 0xEB, 0x9C, 0xA2, 0xA7, 0xDD, 0xA7, - 0xDB, 0x0F, 0x61, 0x21, 0x6C, 0x9C, 0xA4, 0x7D, 0x48, 0x4F, 0xA0, 0x97, 0xCF, 0xBA, 0x2C, 0x46 }, - }, - { - { 0xB5, 0x53, 0x5E, 0x99, 0x84, 0x36, 0xBF, 0x17, 0x42, 0xCF, 0x3F, 0xB1, 0xC1, 0x9A, 0x66, 0x6B, - 0xDE, 0x55, 0x09, 0x4B, 0x3E, 0xD5, 0xCF, 0xB2, 0x09, 0x5D, 0xF0, 0x8E, 0xC6, 0xDD, 0xF6, 0x76 }, - }, - { - { 0xB5, 0xB8, 0xD0, 0x08, 0x69, 0xDD, 0x78, 0x64, 0x9D, 0xAB, 0xD4, 0x41, 0x14, 0x08, 0xA8, 0xFF, - 0x1A, 0xC5, 0x43, 0xEC, 0xA8, 0x80, 0xAE, 0xED, 0xB5, 0x83, 0x28, 0xED, 0xDA, 0x47, 0x1B, 0xFC }, - }, - { - { 0xB5, 0xE2, 0xAA, 0x4C, 0x7F, 0xA4, 0x65, 0xA9, 0x72, 0xAF, 0x17, 0x0E, 0x21, 0x76, 0xD1, 0x83, - 0x51, 0xE6, 0x8D, 0x94, 0x95, 0x0D, 0x87, 0x55, 0x9C, 0x65, 0x20, 0x43, 0xFE, 0xCB, 0x05, 0x2D }, - }, - { - { 0xB5, 0xE5, 0xDC, 0xDE, 0xCB, 0x8D, 0xEB, 0x27, 0x13, 0x4F, 0x02, 0xA5, 0x18, 0x79, 0x43, 0x16, - 0xF0, 0x8F, 0xAF, 0x9C, 0x2B, 0x1F, 0xDA, 0xD6, 0xD4, 0x86, 0x61, 0xF5, 0x7E, 0xA6, 0x45, 0xD9 }, - }, - { - { 0xB5, 0xEF, 0x42, 0xC4, 0xBC, 0xED, 0xF1, 0x7B, 0xEC, 0xC7, 0x5B, 0xF4, 0x63, 0x66, 0x49, 0xCE, - 0xBF, 0xF8, 0x71, 0x1B, 0xCE, 0xFF, 0xFA, 0x69, 0x5C, 0xC2, 0x52, 0xFA, 0x57, 0x4D, 0x42, 0x18 }, - }, - { - { 0xB6, 0x60, 0x21, 0xDE, 0x5D, 0xE8, 0x81, 0x36, 0xBB, 0x09, 0x49, 0x1A, 0x46, 0xE0, 0xFC, 0x6B, - 0x69, 0x33, 0x9B, 0xD9, 0xAC, 0xC9, 0xA4, 0xEA, 0x84, 0xCC, 0x76, 0x4C, 0x39, 0xF5, 0x70, 0xA3 }, - }, - { - { 0xB6, 0x66, 0x7D, 0x8E, 0xD2, 0x85, 0x85, 0x10, 0x8D, 0x3D, 0x97, 0x12, 0x72, 0xBC, 0xB5, 0x17, - 0x82, 0x84, 0x5B, 0xDD, 0xEB, 0x32, 0xFA, 0xBA, 0x96, 0x31, 0xE5, 0x0C, 0x0C, 0x04, 0x0B, 0x54 }, - }, - { - { 0xB6, 0x67, 0xDC, 0x46, 0x65, 0x60, 0x6A, 0xCA, 0xEE, 0xA4, 0xC1, 0x4D, 0xA9, 0x1D, 0xEC, 0x87, - 0x6C, 0x2E, 0xA3, 0x76, 0x0B, 0xCB, 0x1B, 0x1D, 0x50, 0xD7, 0x55, 0x98, 0xA2, 0x61, 0x8C, 0x56 }, - }, - { - { 0xB6, 0x82, 0x3C, 0x9D, 0xBC, 0x8E, 0x8C, 0x05, 0x4B, 0xCF, 0x60, 0xF2, 0x38, 0x21, 0xAC, 0x6C, - 0x58, 0x19, 0x73, 0x51, 0xEA, 0xCF, 0xA5, 0x57, 0x4C, 0xF0, 0x41, 0xB4, 0xCE, 0x6B, 0x84, 0x04 }, - }, - { - { 0xB6, 0x8D, 0x56, 0xB6, 0x8C, 0xC0, 0x99, 0xFF, 0xDE, 0xE7, 0xD5, 0x70, 0x1F, 0x1E, 0x1E, 0x97, - 0x26, 0xDC, 0x75, 0x7C, 0x22, 0x22, 0xB0, 0xA0, 0x1E, 0x4A, 0x32, 0x72, 0xF8, 0xB3, 0x84, 0xF2 }, - }, - { - { 0xB6, 0x90, 0x8F, 0xAB, 0x0C, 0xA2, 0xD7, 0xD6, 0x5D, 0xCA, 0x8B, 0x10, 0xD0, 0x1F, 0x08, 0x48, - 0x13, 0x1C, 0x1C, 0x32, 0x10, 0xA2, 0x5B, 0x47, 0xC7, 0x9E, 0x33, 0xC4, 0xAC, 0x09, 0x5F, 0x7E }, - }, - { - { 0xB6, 0xCD, 0x3F, 0x77, 0x3A, 0xE4, 0x02, 0xE5, 0x2D, 0xFE, 0x4F, 0x14, 0xBD, 0x11, 0x49, 0x5C, - 0x9C, 0xA8, 0x80, 0xF5, 0x3D, 0x4F, 0x5A, 0x7A, 0x24, 0x96, 0xE4, 0xA9, 0xAE, 0x29, 0x53, 0x80 }, - }, - { - { 0xB7, 0x02, 0x1A, 0x28, 0x5D, 0x89, 0xA7, 0xE9, 0xDE, 0x1A, 0xFC, 0xFA, 0x8F, 0x66, 0x6A, 0x55, - 0x92, 0xBB, 0xA6, 0xD2, 0xAC, 0x28, 0xDD, 0x62, 0x74, 0x7E, 0xC1, 0x86, 0x19, 0x1C, 0x57, 0xF7 }, - }, - { - { 0xB7, 0x06, 0xDE, 0x1B, 0xD1, 0xEE, 0x2F, 0x4C, 0xEC, 0x6C, 0xE0, 0x92, 0x02, 0x2B, 0x49, 0x32, - 0x81, 0xE2, 0x9A, 0x21, 0x73, 0x50, 0x8C, 0x9B, 0xD0, 0xFB, 0xC2, 0xC3, 0xD9, 0x68, 0xE3, 0xE7 }, - }, - { - { 0xB7, 0x1F, 0x29, 0x1E, 0x6E, 0xC6, 0xBD, 0x6C, 0x4F, 0x2B, 0x81, 0xF7, 0xF7, 0x21, 0x06, 0x73, - 0xE9, 0x73, 0x08, 0xAF, 0xF1, 0x24, 0x3F, 0x26, 0x99, 0x5A, 0x25, 0xFA, 0x23, 0x0C, 0xFE, 0x4C }, - }, - { - { 0xB7, 0x45, 0x85, 0x05, 0xC5, 0x17, 0x90, 0x14, 0x9C, 0x5E, 0x98, 0x00, 0xFD, 0x22, 0x74, 0x8A, - 0x1D, 0x44, 0x66, 0x5F, 0x68, 0x34, 0xBA, 0x84, 0x4E, 0x9A, 0x0C, 0x32, 0x31, 0x4A, 0x57, 0x21 }, - }, - { - { 0xB7, 0x4C, 0x89, 0x90, 0x0B, 0xBC, 0x4C, 0xE2, 0x8D, 0xCA, 0x03, 0x3F, 0x80, 0x08, 0x70, 0x03, - 0xD1, 0x89, 0xEC, 0xDD, 0x54, 0xC3, 0xFD, 0x23, 0x79, 0xDA, 0x5E, 0x22, 0x17, 0x57, 0xBC, 0x73 }, - }, - { - { 0xB7, 0x65, 0xC9, 0x6B, 0x69, 0x18, 0xAB, 0x88, 0xBF, 0xBE, 0xC4, 0x32, 0xA7, 0x5B, 0x79, 0x97, - 0xDF, 0xFA, 0x55, 0x96, 0xD1, 0x13, 0xD1, 0x6F, 0x13, 0x7E, 0xFE, 0x7D, 0x76, 0x2B, 0xE1, 0x52 }, - }, - { - { 0xB7, 0x9F, 0xCA, 0x4D, 0x47, 0x92, 0xEC, 0x5E, 0x5A, 0x74, 0x06, 0x59, 0x81, 0x3A, 0x0F, 0x46, - 0x08, 0xEA, 0xF9, 0xBA, 0x9C, 0xBB, 0xA8, 0xA0, 0xF8, 0xDA, 0xE1, 0xDD, 0xBB, 0xE6, 0x1E, 0x77 }, - }, - { - { 0xB8, 0x30, 0xC5, 0x8C, 0x49, 0x50, 0x7D, 0xD9, 0x85, 0x7C, 0xC0, 0xCE, 0x37, 0xFA, 0xC7, 0xFA, - 0x3C, 0xDE, 0xA0, 0x4E, 0x9B, 0x64, 0x3E, 0x38, 0xD5, 0x3B, 0x38, 0x1D, 0xB8, 0xFB, 0x89, 0x5D }, - }, - { - { 0xB8, 0x37, 0xC3, 0x7E, 0xE9, 0x9C, 0x18, 0x2B, 0x07, 0xAD, 0x6D, 0x79, 0x1F, 0x53, 0x9E, 0x22, - 0xE0, 0x4E, 0x0D, 0xDB, 0x16, 0xF9, 0xC1, 0x57, 0xA1, 0x35, 0x20, 0xAC, 0xAE, 0xD0, 0x7D, 0xCA }, - }, - { - { 0xB8, 0x74, 0x36, 0x95, 0x1C, 0xEC, 0x37, 0x7E, 0xEF, 0x73, 0xDE, 0x4B, 0x74, 0xF2, 0x83, 0xC4, - 0x2B, 0x2C, 0xCB, 0x1C, 0xA3, 0x7C, 0x5B, 0x30, 0xAA, 0xD6, 0x55, 0xA7, 0x40, 0x1A, 0x3D, 0x2F }, - }, - { - { 0xB8, 0x8C, 0xE8, 0x1A, 0x7B, 0x4B, 0x62, 0x65, 0x71, 0x0F, 0x38, 0xD0, 0xCA, 0x3E, 0x01, 0xFF, - 0xAB, 0xDE, 0x0F, 0xC2, 0x48, 0x3E, 0x21, 0xB8, 0xF1, 0xA5, 0xFF, 0x48, 0x3B, 0x2D, 0x60, 0xCE }, - }, - { - { 0xB9, 0x42, 0x94, 0x19, 0xF2, 0x9F, 0xE3, 0x5C, 0xD8, 0xCF, 0x94, 0x92, 0xD5, 0xA9, 0xB5, 0xD2, - 0x24, 0x1D, 0xDA, 0x4E, 0x12, 0x15, 0x6F, 0x37, 0x4C, 0xEC, 0x78, 0x4F, 0x44, 0x5B, 0x43, 0xF2 }, - }, - { - { 0xB9, 0x8D, 0x83, 0x38, 0x55, 0xC3, 0x67, 0x88, 0x62, 0xB6, 0x2F, 0x36, 0x50, 0xDB, 0x00, 0xA3, - 0x45, 0xF4, 0x6A, 0x0E, 0x8E, 0x01, 0x1A, 0x20, 0x01, 0x3F, 0xD8, 0xED, 0xCE, 0x25, 0x27, 0x0D }, - }, - { - { 0xB9, 0x9C, 0xDB, 0x82, 0xA9, 0x77, 0x31, 0x12, 0xC0, 0x67, 0x17, 0xD7, 0x74, 0x50, 0x51, 0xA7, - 0x01, 0xF3, 0x00, 0xD5, 0x25, 0xD0, 0x55, 0x6E, 0x67, 0x5A, 0x04, 0xCA, 0xEF, 0x26, 0x22, 0x89 }, - }, - { - { 0xB9, 0xCC, 0x92, 0xF7, 0x8C, 0x2C, 0x19, 0x57, 0xDB, 0xB6, 0xC4, 0xA5, 0xE4, 0x25, 0x44, 0x68, - 0xFB, 0xCD, 0x88, 0xB1, 0xFD, 0x9F, 0x98, 0xFA, 0x6D, 0x76, 0x08, 0x70, 0x9E, 0xBE, 0x92, 0x8D }, - }, - { - { 0xBA, 0x0A, 0x8C, 0xC1, 0xC2, 0xF6, 0x62, 0x9B, 0x78, 0xAF, 0xEF, 0x1D, 0x22, 0xD5, 0x57, 0x7A, - 0x13, 0x81, 0x13, 0xC4, 0xC6, 0x21, 0x89, 0x48, 0x47, 0x44, 0xC2, 0x92, 0x50, 0x24, 0x49, 0x7C }, - }, - { - { 0xBA, 0x18, 0x2C, 0x1B, 0x75, 0xD8, 0xDF, 0xD1, 0x18, 0x92, 0xE4, 0x77, 0x59, 0x59, 0xAD, 0x8A, - 0x8C, 0x78, 0x2C, 0xEF, 0x60, 0xEC, 0xEA, 0xBE, 0x56, 0x19, 0x72, 0x9B, 0xB8, 0x1B, 0x4A, 0x10 }, - }, - { - { 0xBA, 0x2F, 0xDE, 0x44, 0xDD, 0xAE, 0x01, 0x8A, 0x51, 0x06, 0xC5, 0x0C, 0x36, 0xA2, 0x33, 0x0D, - 0xF4, 0x30, 0x68, 0x9E, 0x0A, 0x6D, 0xCA, 0x6A, 0xBF, 0x85, 0x7F, 0xA2, 0xFD, 0xED, 0xE8, 0xD4 }, - }, - { - { 0xBA, 0x51, 0xAF, 0xF5, 0xD5, 0xD3, 0x10, 0x5F, 0x34, 0xA2, 0xB3, 0x3A, 0x83, 0xE3, 0xAD, 0xFD, - 0x12, 0xD7, 0x9C, 0xA6, 0x05, 0x90, 0x9D, 0x96, 0x03, 0x3E, 0x32, 0xA5, 0xCF, 0x2F, 0x71, 0xF6 }, - }, - { - { 0xBA, 0xCF, 0x5E, 0x99, 0xF5, 0x7F, 0x78, 0xCC, 0x32, 0xF2, 0xAF, 0x8D, 0x4E, 0x80, 0x6A, 0x0A, - 0x36, 0xCE, 0x9B, 0x42, 0xE9, 0xC7, 0x5C, 0x54, 0x8D, 0xED, 0x55, 0xD2, 0x48, 0x62, 0xCA, 0x17 }, - }, - { - { 0xBB, 0x0B, 0xD1, 0xE6, 0x9F, 0xF4, 0xA3, 0x89, 0x51, 0x61, 0x13, 0x55, 0x2C, 0x17, 0xAB, 0x77, - 0x82, 0xA7, 0xEB, 0xBA, 0xEA, 0x0B, 0xE3, 0x9F, 0x58, 0x92, 0x84, 0x1F, 0x1F, 0x74, 0xD2, 0x98 }, - }, - { - { 0xBB, 0x13, 0xDF, 0x73, 0xB6, 0xE8, 0x89, 0x77, 0x7C, 0x4D, 0x85, 0xEC, 0x93, 0xB8, 0x3E, 0xA8, - 0xBB, 0x95, 0x43, 0xF9, 0xFC, 0x08, 0xC2, 0xB3, 0x1C, 0x02, 0xAC, 0x72, 0xB3, 0x1A, 0x09, 0x0D }, - }, - { - { 0xBB, 0x48, 0x13, 0xED, 0xFC, 0xF7, 0x4A, 0x4F, 0x12, 0xD9, 0x8F, 0x99, 0x6B, 0xF7, 0x98, 0xD4, - 0xED, 0xE3, 0xCB, 0xB7, 0x00, 0x07, 0x31, 0x7A, 0x2C, 0x6B, 0x54, 0x9D, 0xBF, 0x92, 0xA8, 0x5E }, - }, - { - { 0xBB, 0x5C, 0xB3, 0x78, 0xB7, 0xB9, 0x48, 0x7F, 0xA6, 0x1B, 0xC0, 0x91, 0x3D, 0xA1, 0xDF, 0x26, - 0xA1, 0xCF, 0xEF, 0xF7, 0x45, 0x2D, 0x9B, 0xA3, 0x6C, 0xAC, 0x47, 0xA8, 0x5C, 0x7F, 0xF3, 0x48 }, - }, - { - { 0xBB, 0x77, 0x41, 0x99, 0x17, 0x89, 0x5C, 0x74, 0x0F, 0x39, 0x61, 0x60, 0x1B, 0x99, 0xB5, 0xC2, - 0x25, 0x67, 0x37, 0xAA, 0x6C, 0x6E, 0x88, 0x27, 0x48, 0x5E, 0x44, 0x8E, 0x69, 0x74, 0xB1, 0x6B }, - }, - { - { 0xBB, 0xAA, 0x32, 0x35, 0x0E, 0x2D, 0xC5, 0x06, 0x07, 0xAA, 0xC6, 0x5B, 0x29, 0x81, 0xD3, 0x97, - 0xC8, 0xB9, 0xAF, 0x51, 0x22, 0x38, 0xCA, 0xD4, 0xCB, 0xB3, 0x10, 0x07, 0x64, 0xE7, 0xA3, 0x94 }, - }, - { - { 0xBB, 0xAD, 0x8A, 0x81, 0x54, 0xD7, 0xAB, 0x8E, 0x3F, 0x3A, 0x67, 0x09, 0x7B, 0x4D, 0xB7, 0x44, - 0x8F, 0x4B, 0x07, 0xE4, 0x7C, 0xDA, 0xA6, 0xB8, 0x36, 0xED, 0xD2, 0x67, 0x68, 0xF9, 0x64, 0x92 }, - }, - { - { 0xBB, 0xE6, 0xB5, 0x24, 0x36, 0x69, 0x0A, 0x58, 0x57, 0x74, 0x91, 0x27, 0xCC, 0xB6, 0xAB, 0x5B, - 0x16, 0xD6, 0xB3, 0x06, 0x6C, 0x71, 0x27, 0x25, 0xA2, 0xC5, 0xFC, 0x4F, 0x61, 0xB8, 0xA9, 0x88 }, - }, - { - { 0xBC, 0x14, 0x2E, 0xBA, 0xC2, 0x78, 0xA8, 0xFE, 0x8C, 0xA8, 0xBC, 0x2C, 0x62, 0xFB, 0xCC, 0x40, - 0x17, 0xFF, 0x24, 0x96, 0x98, 0xBE, 0xED, 0xFB, 0x1E, 0xF3, 0x6F, 0x37, 0x5F, 0xB3, 0x9F, 0x72 }, - }, - { - { 0xBC, 0x1A, 0x3B, 0x83, 0x46, 0xA5, 0x18, 0x4E, 0x8F, 0xE2, 0xA9, 0x36, 0xD6, 0xD9, 0xCE, 0x2C, - 0xBE, 0x3A, 0x92, 0x05, 0x54, 0xE0, 0x60, 0xF9, 0x07, 0x97, 0xF9, 0x8F, 0xEE, 0x62, 0xA8, 0x52 }, - }, - { - { 0xBC, 0x3F, 0x40, 0xAE, 0xDC, 0x2D, 0xDF, 0x00, 0x3F, 0x3A, 0x5C, 0xCA, 0x77, 0xBF, 0x3B, 0x63, - 0x26, 0xC9, 0x3C, 0xCF, 0xA1, 0x6D, 0x1C, 0xC1, 0xBC, 0xF1, 0x3D, 0x5E, 0x46, 0xEA, 0x0D, 0xB6 }, - }, - { - { 0xBC, 0x98, 0x39, 0xC8, 0xB9, 0x22, 0xF6, 0x54, 0x57, 0x67, 0xA2, 0xBA, 0x46, 0x5A, 0x5B, 0xEA, - 0x9A, 0xA1, 0x84, 0x11, 0x52, 0x99, 0x4A, 0x6C, 0xF4, 0x67, 0x83, 0xAE, 0x49, 0x98, 0xAF, 0xCC }, - }, - { - { 0xBC, 0xE9, 0x07, 0x86, 0x57, 0x91, 0xAE, 0x71, 0x57, 0x9C, 0x64, 0xEE, 0x76, 0xB1, 0xAE, 0x09, - 0xF6, 0x55, 0x22, 0x2D, 0x38, 0x7B, 0xA7, 0xC1, 0x11, 0xF6, 0xA3, 0x0B, 0x7C, 0xD3, 0x98, 0x4D }, - }, - { - { 0xBD, 0x20, 0x20, 0x24, 0x96, 0x06, 0xC0, 0x1C, 0xE7, 0x70, 0xB2, 0x56, 0xE3, 0x8E, 0x82, 0x6B, - 0x87, 0x42, 0x04, 0xCD, 0x70, 0x44, 0x69, 0x6E, 0x6F, 0xBA, 0x53, 0x58, 0xBD, 0x44, 0xD6, 0x9A }, - }, - { - { 0xBD, 0x2E, 0x2F, 0x37, 0xC9, 0x66, 0xC3, 0x86, 0xD9, 0x70, 0x44, 0xFD, 0xE3, 0xE3, 0xF9, 0x00, - 0xFB, 0x1A, 0x0B, 0x04, 0x03, 0xB5, 0x81, 0x72, 0x5F, 0x34, 0xE3, 0xC1, 0x90, 0x05, 0x60, 0x56 }, - }, - { - { 0xBD, 0x4F, 0x30, 0xA1, 0x05, 0xD4, 0xC4, 0x5A, 0x36, 0x7F, 0x55, 0xDA, 0xE7, 0x33, 0x84, 0x75, - 0x5E, 0x01, 0x67, 0x8A, 0x32, 0x1F, 0xF0, 0x4C, 0x99, 0xD2, 0xD5, 0x2A, 0x2B, 0xFD, 0x7A, 0xCF }, - }, - { - { 0xBD, 0xD5, 0x42, 0x49, 0xDD, 0xD5, 0x4B, 0xC7, 0x2A, 0xA7, 0xA7, 0x5F, 0x77, 0x63, 0xA8, 0x38, - 0xCF, 0x4B, 0xA1, 0x7F, 0xB3, 0x64, 0x72, 0xBA, 0x12, 0x69, 0x8C, 0x45, 0xDF, 0x88, 0xE8, 0x46 }, - }, - { - { 0xBE, 0x2E, 0x88, 0xC5, 0xEE, 0x30, 0x7B, 0xA5, 0x41, 0x73, 0xA6, 0x00, 0x2B, 0x99, 0x16, 0x92, - 0xC8, 0xBD, 0x1D, 0x40, 0x8A, 0x59, 0x2F, 0x70, 0x7B, 0xB1, 0xAF, 0x56, 0xF5, 0xB9, 0xD7, 0x42 }, - }, - { - { 0xBE, 0x34, 0x75, 0x8B, 0x19, 0xD4, 0x31, 0x2D, 0x65, 0xB9, 0xE0, 0x78, 0xB6, 0xF8, 0xD9, 0x27, - 0x7C, 0x5E, 0x52, 0x1B, 0xA1, 0xF0, 0xD3, 0x15, 0x20, 0x9B, 0x2B, 0x56, 0x2D, 0x73, 0x91, 0x89 }, - }, - { - { 0xBE, 0x41, 0x0A, 0x51, 0xD3, 0x44, 0x17, 0x76, 0x91, 0xB3, 0x42, 0x64, 0x10, 0xA4, 0x41, 0xAF, - 0xD1, 0xC9, 0x40, 0xB1, 0xB2, 0x7C, 0xF5, 0x29, 0xEE, 0x87, 0xA1, 0x40, 0x3B, 0xB0, 0x16, 0xF4 }, - }, - { - { 0xBE, 0x5C, 0x3C, 0xD0, 0x6E, 0x3C, 0x58, 0x1A, 0x4E, 0x67, 0xAB, 0x8F, 0x77, 0x85, 0x51, 0xBB, - 0x0F, 0x41, 0x24, 0x4C, 0x6B, 0xBB, 0x41, 0x1D, 0x9B, 0xF1, 0x27, 0x19, 0x0F, 0x60, 0x99, 0x9D }, - }, - { - { 0xBE, 0x68, 0x35, 0x4F, 0x7C, 0x36, 0x24, 0x2D, 0xB6, 0x20, 0x4F, 0x20, 0x13, 0x1B, 0x01, 0xFF, - 0x28, 0xB7, 0xDD, 0xFF, 0x36, 0x2E, 0x42, 0x9B, 0xFD, 0xF8, 0x8F, 0x36, 0x37, 0x58, 0x24, 0x51 }, - }, - { - { 0xBE, 0xAC, 0x00, 0x60, 0x68, 0x7E, 0xB2, 0x5A, 0x9B, 0xED, 0x21, 0xA1, 0x99, 0x97, 0xAF, 0xFF, - 0x67, 0x7C, 0x89, 0x61, 0xDC, 0x00, 0xE2, 0x3B, 0x4C, 0x1E, 0x27, 0x7F, 0xF8, 0x58, 0xC0, 0x92 }, - }, - { - { 0xBE, 0xB7, 0x1D, 0xAF, 0x38, 0x97, 0x76, 0xCE, 0x8B, 0x4A, 0xC8, 0x18, 0x90, 0x1E, 0x02, 0xC0, - 0x6C, 0xFE, 0xF5, 0x22, 0x34, 0xFC, 0x49, 0x20, 0x3B, 0x4A, 0xA7, 0x73, 0x35, 0xB6, 0x63, 0x9B }, - }, - { - { 0xBE, 0xB9, 0x09, 0x0C, 0x92, 0xD1, 0x6B, 0xD0, 0x5A, 0xF3, 0x91, 0x5A, 0x39, 0xCC, 0x2A, 0xFA, - 0x9F, 0x6A, 0x8A, 0x6F, 0xBE, 0xD4, 0xFE, 0x54, 0xD9, 0xDE, 0x32, 0x49, 0x23, 0xB3, 0x93, 0x5A }, - }, - { - { 0xBE, 0xD5, 0xB6, 0xAD, 0xE6, 0xC9, 0xC2, 0x15, 0xE4, 0x14, 0x53, 0x21, 0x9A, 0xF2, 0x9A, 0x8B, - 0x8D, 0x76, 0x9D, 0x36, 0x43, 0x8C, 0x3F, 0x96, 0x61, 0x76, 0xE3, 0xBC, 0xC9, 0x1F, 0x2E, 0xE8 }, - }, - { - { 0xBE, 0xD6, 0xF8, 0x1A, 0xD8, 0x5E, 0x71, 0x6B, 0x60, 0xD3, 0xE9, 0x7D, 0x8B, 0x90, 0x81, 0xE9, - 0xC1, 0xB9, 0xEC, 0x3B, 0xE8, 0xF3, 0xFD, 0x5B, 0xAD, 0x55, 0x40, 0x2B, 0x79, 0x78, 0x5B, 0x37 }, - }, - { - { 0xBE, 0xE1, 0xD6, 0x40, 0x7D, 0x2F, 0xE3, 0xDB, 0x76, 0x64, 0x4C, 0x58, 0xA4, 0xF2, 0xB6, 0x4E, - 0x62, 0xF8, 0x93, 0xF8, 0x04, 0xFB, 0x9A, 0x87, 0xFE, 0xA3, 0x2C, 0x4C, 0x76, 0x45, 0x7F, 0x3B }, - }, - { - { 0xBE, 0xE5, 0x93, 0x20, 0xCE, 0x39, 0xB6, 0xBB, 0x7A, 0xC7, 0x72, 0xCD, 0xF3, 0xD3, 0x0D, 0xFE, - 0x57, 0xE0, 0x60, 0xCC, 0xA9, 0xE5, 0x4A, 0x62, 0x99, 0x96, 0xAA, 0x4F, 0xCB, 0xD4, 0xAF, 0x0E }, - }, - { - { 0xBE, 0xE9, 0x05, 0xD6, 0xA4, 0x20, 0x55, 0x47, 0x66, 0x90, 0xD3, 0x89, 0xD4, 0x80, 0x66, 0x5D, - 0x10, 0x29, 0xD0, 0xA0, 0x24, 0x75, 0x35, 0xE0, 0xA1, 0x4A, 0x79, 0x8E, 0xE3, 0xF5, 0xA3, 0x3D }, - }, - { - { 0xBF, 0x38, 0xE6, 0xAE, 0x32, 0x0F, 0x69, 0x16, 0x16, 0x0D, 0xA6, 0x06, 0x86, 0x83, 0xBF, 0x49, - 0xF2, 0xB2, 0x2B, 0x25, 0x24, 0x84, 0x63, 0x68, 0xF5, 0x04, 0x51, 0x81, 0x52, 0x40, 0x25, 0x9A }, - }, - { - { 0xBF, 0x60, 0xAE, 0xB3, 0x91, 0xC0, 0xFB, 0xD0, 0x49, 0x53, 0x52, 0x6D, 0xA9, 0xFD, 0x59, 0x96, - 0x9A, 0x82, 0xF1, 0xEE, 0x81, 0xA7, 0x97, 0x98, 0xA4, 0x17, 0x1E, 0x14, 0x59, 0x39, 0x19, 0x67 }, - }, - { - { 0xBF, 0xC6, 0x2C, 0x0A, 0x05, 0x85, 0xBC, 0x32, 0xD4, 0x0C, 0xBC, 0x2E, 0x24, 0xA4, 0x8E, 0x26, - 0x43, 0x4A, 0xE3, 0x33, 0x27, 0xD7, 0xE9, 0x8D, 0x1C, 0x57, 0xB6, 0xC5, 0x28, 0x4B, 0x95, 0x7A }, - }, - { - { 0xBF, 0xF4, 0x3A, 0x97, 0x20, 0x48, 0x2D, 0x13, 0x4C, 0xD5, 0xEE, 0x8A, 0x88, 0x99, 0xE1, 0xA7, - 0x36, 0xBF, 0x54, 0xA2, 0xB7, 0x86, 0x26, 0x9C, 0x0D, 0xCB, 0x8B, 0xA1, 0x92, 0xA8, 0x1F, 0xA4 }, - }, - { - { 0xC0, 0x09, 0xA1, 0xBE, 0x5B, 0xE8, 0xAF, 0xB5, 0x25, 0x8E, 0x12, 0x85, 0x5C, 0x64, 0xD0, 0x4D, - 0x13, 0xE8, 0xCC, 0xC4, 0x7B, 0x02, 0xBF, 0x3B, 0x51, 0xC6, 0xE1, 0x18, 0x05, 0xAE, 0xEC, 0xEB }, - }, - { - { 0xC0, 0x52, 0xE0, 0x98, 0xDD, 0x04, 0x2B, 0x3D, 0x44, 0x0F, 0x8F, 0xFB, 0xEE, 0x31, 0x91, 0x67, - 0x1F, 0x5F, 0x78, 0x4B, 0x94, 0x9C, 0x2D, 0x23, 0x3D, 0x60, 0xDA, 0x66, 0xC5, 0xC3, 0x6C, 0xFD }, - }, - { - { 0xC0, 0x9F, 0xFA, 0x0E, 0xDD, 0x16, 0xBA, 0x55, 0xF2, 0x3C, 0xEA, 0xF7, 0x2B, 0x11, 0x34, 0xE9, - 0x28, 0xDB, 0xA1, 0xC2, 0x34, 0x5A, 0x5A, 0xB5, 0x63, 0x1E, 0x25, 0x41, 0x24, 0x05, 0x4A, 0xDB }, - }, - { - { 0xC0, 0xAB, 0xD1, 0xC3, 0x56, 0x2F, 0xBC, 0x7F, 0xF7, 0xBD, 0x38, 0x95, 0x54, 0x60, 0xC3, 0xFC, - 0x43, 0x55, 0x0D, 0x97, 0x7F, 0x25, 0xE3, 0x43, 0xD4, 0x9C, 0xD4, 0xAF, 0xAD, 0xF2, 0x09, 0x3C }, - }, - { - { 0xC0, 0xD3, 0xDC, 0x9A, 0x2D, 0x13, 0x9D, 0x38, 0xCE, 0x02, 0xC0, 0x78, 0xF3, 0xC2, 0x92, 0x5D, - 0x89, 0x1D, 0x24, 0xE4, 0x36, 0x13, 0xCB, 0xEE, 0x3F, 0x18, 0xA2, 0xC8, 0x60, 0x98, 0x84, 0xB2 }, - }, - { - { 0xC0, 0xFE, 0xB7, 0x2A, 0x5F, 0x33, 0x16, 0x5C, 0x0D, 0xC7, 0xC4, 0x24, 0x7E, 0x23, 0xF3, 0x8C, - 0xC6, 0x1F, 0x25, 0x24, 0x42, 0xB2, 0xF6, 0x13, 0x40, 0x92, 0xDE, 0x3B, 0xAD, 0x7E, 0x45, 0x0D }, - }, - { - { 0xC1, 0x36, 0x56, 0xB8, 0xB3, 0xDD, 0x77, 0xCB, 0x97, 0x0D, 0xB1, 0x38, 0x81, 0x10, 0x6F, 0xB0, - 0x99, 0x8E, 0xC5, 0x4E, 0x94, 0xF8, 0x2E, 0xE4, 0x4D, 0xEA, 0x1B, 0x1A, 0x65, 0x90, 0xFC, 0xE7 }, - }, - { - { 0xC1, 0x53, 0xE6, 0x04, 0xED, 0xD6, 0x55, 0x50, 0x5D, 0xFF, 0x3F, 0x04, 0xB4, 0xAA, 0x95, 0xA4, - 0x73, 0xCD, 0x3F, 0xAB, 0x0A, 0x4D, 0xBC, 0xB9, 0x85, 0x84, 0xCD, 0x4B, 0x66, 0x46, 0x32, 0xF9 }, - }, - { - { 0xC1, 0x63, 0x98, 0xBA, 0xC4, 0xEA, 0x08, 0x39, 0xDF, 0x12, 0xEB, 0x3D, 0x6B, 0xF3, 0x98, 0x6D, - 0x4C, 0x69, 0x78, 0x04, 0xE0, 0x2A, 0xB9, 0x78, 0x8D, 0x3C, 0xF3, 0xB0, 0x38, 0x6E, 0x64, 0x10 }, - }, - { - { 0xC1, 0x73, 0xB2, 0x9F, 0x14, 0x85, 0xEE, 0x0F, 0x3F, 0xE6, 0x24, 0xDA, 0xAE, 0xBF, 0x21, 0x45, - 0x14, 0x1F, 0x7C, 0xD0, 0xE4, 0xC5, 0xEA, 0x2F, 0x46, 0xB7, 0xAF, 0xE3, 0x74, 0x8C, 0xC5, 0x03 }, - }, - { - { 0xC1, 0x77, 0x12, 0x97, 0xA4, 0xE8, 0xDC, 0x53, 0x75, 0x19, 0x5E, 0x1B, 0x63, 0x04, 0x2B, 0x59, - 0x19, 0x09, 0xF1, 0xD7, 0xEB, 0x5D, 0x25, 0xF2, 0x97, 0xAE, 0x7A, 0x61, 0xC1, 0x53, 0x8F, 0x9E }, - }, - { - { 0xC1, 0x7C, 0xE3, 0xBE, 0xF9, 0xCC, 0x61, 0x0B, 0x71, 0x3C, 0xFF, 0x47, 0xCC, 0xBE, 0x95, 0x8A, - 0xA7, 0x78, 0x35, 0x8D, 0xCC, 0x7C, 0x52, 0x63, 0xC1, 0xAA, 0x7F, 0xE4, 0x22, 0xF3, 0x9B, 0xC6 }, - }, - { - { 0xC1, 0x86, 0xBE, 0x26, 0xE4, 0x47, 0x89, 0x7C, 0x48, 0x3C, 0x43, 0xFD, 0xC0, 0x86, 0xE2, 0x60, - 0x74, 0x17, 0xEB, 0x3E, 0xA7, 0x88, 0xEC, 0x03, 0x10, 0xA7, 0x9D, 0xA9, 0x24, 0x1D, 0x16, 0xDE }, - }, - { - { 0xC1, 0xC3, 0x03, 0x06, 0x23, 0x16, 0x38, 0xEA, 0x57, 0x60, 0xAF, 0xBE, 0xF1, 0x44, 0x50, 0x68, - 0x22, 0x6C, 0xA0, 0x25, 0xF5, 0xE0, 0x86, 0xE2, 0x21, 0x21, 0x54, 0xDA, 0xC2, 0xE5, 0x48, 0x49 }, - }, - { - { 0xC1, 0xDE, 0x5F, 0xA3, 0x92, 0x13, 0x68, 0x58, 0x11, 0xA5, 0xBA, 0x93, 0x12, 0x1D, 0xE7, 0xA3, - 0x95, 0x98, 0x4E, 0x84, 0x44, 0x4E, 0x58, 0xF1, 0x63, 0xB7, 0xA6, 0x20, 0xAE, 0x3B, 0xBF, 0xA8 }, - }, - { - { 0xC1, 0xE8, 0x95, 0xA8, 0x27, 0x96, 0x4B, 0x9C, 0x04, 0x91, 0x69, 0xAD, 0xFF, 0x9A, 0x30, 0x32, - 0xD8, 0x70, 0x6A, 0x71, 0x7A, 0xCD, 0xB6, 0xF3, 0x39, 0x44, 0xFF, 0xA9, 0x62, 0xC6, 0x0D, 0x44 }, - }, - { - { 0xC2, 0x17, 0x03, 0x01, 0xD2, 0x2F, 0x8D, 0xC0, 0x42, 0xDC, 0xED, 0xD8, 0x3A, 0x92, 0x05, 0xC6, - 0x95, 0x25, 0x6F, 0x18, 0x4E, 0xD4, 0xBD, 0x5B, 0x52, 0x98, 0x28, 0x0A, 0xA6, 0x73, 0xB3, 0x7F }, - }, - { - { 0xC2, 0x29, 0xEE, 0xBB, 0x9E, 0x1A, 0x91, 0x38, 0x80, 0x87, 0xA3, 0xE0, 0x5F, 0x0C, 0x8A, 0x6B, - 0xB6, 0x84, 0x25, 0x6E, 0x34, 0x06, 0x68, 0xEE, 0xA2, 0x14, 0x01, 0x1D, 0x75, 0x2E, 0xF6, 0xB2 }, - }, - { - { 0xC2, 0xAD, 0xDF, 0x99, 0xCF, 0xC4, 0x2C, 0xE0, 0xE5, 0xA0, 0x93, 0xBC, 0xBF, 0x87, 0x40, 0x7C, - 0x61, 0x1F, 0x9D, 0x0A, 0xBF, 0x2A, 0x35, 0xD6, 0xE8, 0x03, 0xA3, 0x8E, 0xCB, 0x92, 0xC7, 0xB3 }, - }, - { - { 0xC2, 0xE7, 0x92, 0x11, 0x6A, 0x05, 0x00, 0x00, 0xBD, 0x47, 0x59, 0x1D, 0x93, 0x04, 0x71, 0xE6, - 0x17, 0x4C, 0x93, 0x85, 0xF5, 0xDC, 0x32, 0xB7, 0x62, 0x31, 0x65, 0x5F, 0xC8, 0x5E, 0x22, 0xE2 }, - }, - { - { 0xC2, 0xE8, 0x7A, 0xF9, 0xFE, 0x26, 0x55, 0x64, 0xE1, 0x09, 0xA3, 0x9D, 0x73, 0xBC, 0xD4, 0x7A, - 0x4E, 0x98, 0x75, 0x6F, 0x76, 0xEB, 0xDF, 0xB7, 0xA6, 0x57, 0x0A, 0xDA, 0xB9, 0xDD, 0xDD, 0xFB }, - }, - { - { 0xC3, 0x3A, 0x14, 0x69, 0x59, 0xF3, 0x02, 0x8B, 0x97, 0x1A, 0x8D, 0x3B, 0xF0, 0x30, 0x38, 0x7E, - 0x33, 0xBC, 0xC5, 0xB5, 0x2B, 0xA9, 0xA6, 0x8A, 0x7F, 0x76, 0x34, 0x39, 0x23, 0x6D, 0x61, 0x1A }, - }, - { - { 0xC3, 0x79, 0x03, 0xC5, 0x3A, 0xE6, 0x02, 0xEC, 0x96, 0x9E, 0xC3, 0x3F, 0x63, 0xFE, 0x9A, 0xB2, - 0x0C, 0x39, 0x5F, 0x83, 0x0D, 0x30, 0xE4, 0xEE, 0x9D, 0x8D, 0xD9, 0x05, 0x92, 0x1E, 0xC1, 0xA0 }, - }, - { - { 0xC3, 0xCF, 0x54, 0x16, 0xA5, 0x31, 0xAF, 0x4B, 0xFA, 0xE8, 0x9C, 0x45, 0x14, 0x3F, 0x20, 0xCC, - 0x1B, 0x3E, 0x18, 0x1D, 0x29, 0xC2, 0xD0, 0xE8, 0xFF, 0x7D, 0x3F, 0x2A, 0x66, 0xB1, 0x82, 0xFE }, - }, - { - { 0xC3, 0xDE, 0xF4, 0xB0, 0xD7, 0xF0, 0x81, 0xC7, 0xFB, 0x88, 0x91, 0x0D, 0xBD, 0xA3, 0x14, 0xDE, - 0x57, 0xA9, 0xCF, 0xDB, 0x40, 0xF8, 0x64, 0x7E, 0xF2, 0x88, 0xCE, 0xC9, 0x67, 0x3E, 0x00, 0x0C }, - }, - { - { 0xC4, 0x21, 0x98, 0x61, 0x93, 0xF8, 0x62, 0xFF, 0x25, 0x8C, 0x1C, 0xCC, 0x94, 0x9D, 0x1B, 0x3A, - 0xCB, 0x67, 0xB4, 0xF6, 0x38, 0x31, 0xC6, 0x32, 0xE6, 0x9B, 0xD0, 0xFB, 0x08, 0xA2, 0x69, 0x67 }, - }, - { - { 0xC4, 0x85, 0x0E, 0x1C, 0x62, 0xB1, 0x7C, 0xEF, 0xD0, 0xDC, 0x64, 0xD4, 0xA8, 0x66, 0x95, 0x3E, - 0x11, 0x54, 0xDC, 0x88, 0xD9, 0xBD, 0x96, 0x16, 0x47, 0xB6, 0xB2, 0x34, 0x1D, 0x85, 0xD9, 0xBA }, - }, - { - { 0xC4, 0x87, 0xA2, 0x59, 0x81, 0x9B, 0x56, 0xD3, 0x15, 0x9D, 0xD1, 0x73, 0x15, 0x7E, 0x86, 0x45, - 0xB7, 0x0B, 0xCA, 0x29, 0x08, 0xCB, 0x2C, 0x5B, 0xAE, 0x34, 0x48, 0x6E, 0xA4, 0xF6, 0x14, 0xFF }, - }, - { - { 0xC4, 0x98, 0xA1, 0xB6, 0x9F, 0x54, 0x40, 0x86, 0x17, 0x47, 0x47, 0x71, 0x5A, 0x27, 0x4D, 0x3F, - 0xB5, 0x90, 0x19, 0xBE, 0x09, 0x21, 0x31, 0xBC, 0xFA, 0xA8, 0x3A, 0x39, 0x5F, 0x7E, 0x57, 0x3C }, - }, - { - { 0xC4, 0xE2, 0x8D, 0xD8, 0x3F, 0xE3, 0x0C, 0x96, 0x33, 0x8C, 0xEF, 0x77, 0x73, 0xC6, 0xDF, 0xCA, - 0x6C, 0xE4, 0xFA, 0x96, 0x41, 0xBE, 0xAB, 0x38, 0x05, 0xA8, 0xEF, 0xB6, 0xCD, 0xC3, 0xCF, 0x0A }, - }, - { - { 0xC4, 0xF4, 0x79, 0x81, 0xF4, 0x5D, 0x90, 0x3B, 0x56, 0x2F, 0x39, 0xF6, 0x17, 0x45, 0xF4, 0xE1, - 0x90, 0x48, 0x1C, 0x4B, 0x56, 0xA4, 0xBD, 0xF5, 0xA0, 0xE1, 0x61, 0xE3, 0xE9, 0x42, 0x83, 0x89 }, - }, - { - { 0xC5, 0x00, 0xB8, 0x3F, 0x3E, 0x06, 0x6C, 0xD1, 0xDD, 0x0E, 0xBC, 0xD7, 0x3D, 0xD4, 0x01, 0x61, - 0xB9, 0x25, 0x9A, 0xA7, 0x7A, 0xB8, 0xA6, 0x47, 0xE8, 0x57, 0x1F, 0xF3, 0x37, 0xCF, 0x94, 0x6D }, - }, - { - { 0xC5, 0x1E, 0x9B, 0x95, 0x9A, 0xCF, 0x0D, 0xDA, 0xFF, 0x54, 0x64, 0x9C, 0xB5, 0xFC, 0x68, 0xFC, - 0xDC, 0xB2, 0x70, 0xB2, 0x7A, 0x53, 0xD4, 0x0A, 0xDA, 0xBE, 0xD0, 0x8B, 0x79, 0x7B, 0x14, 0xB6 }, - }, - { - { 0xC5, 0x29, 0x5B, 0xA6, 0xE2, 0x7E, 0x72, 0x10, 0x22, 0xFE, 0xB2, 0x1E, 0x78, 0xEB, 0x7B, 0x03, - 0x57, 0xC9, 0xCD, 0x56, 0x5B, 0xD0, 0xE5, 0x96, 0x72, 0xF6, 0x66, 0x34, 0x2B, 0x79, 0x94, 0x9D }, - }, - { - { 0xC5, 0x82, 0x1F, 0xA0, 0x9B, 0x7A, 0x3F, 0x59, 0x65, 0xF3, 0xC6, 0x37, 0xC6, 0xDC, 0x91, 0x40, - 0xF4, 0xC4, 0x29, 0x00, 0x10, 0x78, 0xA5, 0xEE, 0x2B, 0x10, 0x6F, 0x87, 0xBF, 0xA2, 0xC3, 0x1A }, - }, - { - { 0xC5, 0x9F, 0x27, 0xDF, 0x84, 0x0B, 0xC2, 0x18, 0x71, 0x35, 0xCD, 0x17, 0xB6, 0xF4, 0x75, 0x23, - 0xB4, 0xD5, 0x5C, 0x47, 0xBD, 0x4D, 0x8C, 0x2C, 0x4B, 0x15, 0x4C, 0x14, 0x65, 0xC8, 0x06, 0xFE }, - }, - { - { 0xC6, 0x12, 0x75, 0x6B, 0xA5, 0x42, 0x34, 0x4A, 0xDC, 0x1B, 0x80, 0xE9, 0x38, 0x84, 0x5A, 0x1E, - 0xD6, 0xE9, 0x38, 0xFE, 0xF4, 0x0D, 0x04, 0xEC, 0x86, 0x55, 0x8F, 0x4B, 0x21, 0x05, 0x2F, 0xD2 }, - }, - { - { 0xC6, 0x17, 0xE0, 0x85, 0x5B, 0xF1, 0x4F, 0xBF, 0x21, 0xAF, 0x00, 0x82, 0x25, 0xCA, 0xBE, 0x40, - 0x4F, 0x73, 0x8C, 0x27, 0x8A, 0x4A, 0x42, 0x87, 0xF1, 0xEE, 0x38, 0x01, 0x27, 0xC5, 0x61, 0xFA }, - }, - { - { 0xC6, 0x41, 0x82, 0xD6, 0x05, 0xC1, 0xCB, 0xE1, 0x9B, 0xD3, 0xB7, 0xFE, 0x55, 0x7F, 0x58, 0xCD, - 0x52, 0x10, 0x30, 0x97, 0xA3, 0x3B, 0xF8, 0x4A, 0xF2, 0x22, 0xC8, 0xCE, 0x72, 0x52, 0x61, 0x15 }, - }, - { - { 0xC6, 0x48, 0x76, 0x70, 0x78, 0x83, 0x67, 0x74, 0x64, 0x11, 0xC9, 0x38, 0xBD, 0xDB, 0x5C, 0xFC, - 0x0D, 0x20, 0xAC, 0xF8, 0x29, 0xD2, 0xA1, 0x39, 0x12, 0x7A, 0x22, 0x7B, 0xC0, 0x06, 0x03, 0xDC }, - }, - { - { 0xC6, 0x67, 0x05, 0xFC, 0xA8, 0x55, 0x10, 0xFD, 0x14, 0x58, 0xE2, 0xF4, 0x51, 0xD4, 0x54, 0x43, - 0x55, 0xD0, 0xB1, 0x03, 0xFE, 0x6D, 0xB4, 0x73, 0x78, 0xE7, 0x28, 0x37, 0xED, 0x9A, 0x2E, 0x6F }, - }, - { - { 0xC6, 0x81, 0x77, 0x4B, 0x31, 0x13, 0x72, 0x97, 0x0C, 0x4E, 0xCA, 0xED, 0x00, 0x22, 0xEB, 0x5E, - 0xF9, 0xC2, 0x32, 0x80, 0x35, 0xC2, 0x5B, 0x00, 0xD8, 0xFA, 0xF0, 0x1E, 0xCF, 0x2C, 0x03, 0x9C }, - }, - { - { 0xC6, 0x89, 0xB9, 0x95, 0x6C, 0x73, 0x11, 0xD7, 0x34, 0x6A, 0x7F, 0xA3, 0x8B, 0x2C, 0xCD, 0xE3, - 0xEF, 0xEE, 0x85, 0x3D, 0x7C, 0x2C, 0x41, 0x4F, 0x81, 0xF3, 0xB0, 0x64, 0xE6, 0xAF, 0x1F, 0x49 }, - }, - { - { 0xC6, 0xA4, 0x24, 0xBF, 0x7C, 0xFE, 0x31, 0x72, 0x74, 0x7A, 0x47, 0x14, 0xA0, 0xEF, 0xB9, 0x17, - 0x93, 0x8C, 0x5E, 0xBD, 0x59, 0x12, 0x9D, 0xED, 0x7A, 0x81, 0x18, 0xC7, 0xF6, 0x59, 0xD1, 0x33 }, - }, - { - { 0xC6, 0xAD, 0x1D, 0x7A, 0x14, 0x1A, 0x91, 0x75, 0x2D, 0x31, 0xFB, 0xC1, 0x06, 0x16, 0xBF, 0x1C, - 0xA2, 0xFB, 0x5B, 0x02, 0xE8, 0x46, 0xB5, 0x9E, 0x63, 0x34, 0x6B, 0x31, 0x92, 0xA7, 0x52, 0x92 }, - }, - { - { 0xC6, 0xC6, 0xB0, 0x9A, 0xFA, 0x64, 0x6E, 0x4E, 0x1D, 0x75, 0xC9, 0x23, 0xAE, 0xB0, 0x2B, 0x39, - 0xF8, 0xF0, 0x7A, 0x74, 0x33, 0x59, 0xDD, 0x22, 0xB4, 0xB5, 0x32, 0x41, 0xB7, 0xB0, 0x3D, 0x63 }, - }, - { - { 0xC7, 0x01, 0x83, 0x64, 0x38, 0xF3, 0x7B, 0xEA, 0x8A, 0x88, 0x16, 0x10, 0x63, 0x70, 0x86, 0xF8, - 0x8D, 0x9A, 0x11, 0x5E, 0x00, 0x92, 0x46, 0xD2, 0x7F, 0x48, 0x9F, 0xA7, 0x18, 0x51, 0x88, 0xA8 }, - }, - { - { 0xC7, 0xA6, 0xF4, 0xE6, 0xAC, 0xFA, 0x70, 0x88, 0x7A, 0xEF, 0xEC, 0x5C, 0x75, 0x66, 0x9E, 0x04, - 0x43, 0xDB, 0x00, 0x2D, 0xBD, 0xB5, 0xED, 0x95, 0xFB, 0xBE, 0x52, 0xC5, 0xC9, 0xB8, 0xF2, 0x01 }, - }, - { - { 0xC7, 0xF8, 0x85, 0xE4, 0x1A, 0xA5, 0x3B, 0x8C, 0xB8, 0xE4, 0xE5, 0x59, 0xC4, 0x04, 0x3A, 0x87, - 0xDA, 0xFB, 0x78, 0x7A, 0x0D, 0x2B, 0x2E, 0xF1, 0xBC, 0xC0, 0x55, 0x71, 0xB7, 0x5D, 0x4E, 0x29 }, - }, - { - { 0xC7, 0xFF, 0x8E, 0xFD, 0xEC, 0xDF, 0x00, 0xD1, 0xFC, 0x8D, 0x55, 0x2D, 0x2A, 0x70, 0x70, 0xE5, - 0xE3, 0x3D, 0x42, 0xE5, 0x90, 0xF5, 0x86, 0xC6, 0xAE, 0xDE, 0x03, 0x2B, 0x2D, 0x86, 0x7B, 0xD5 }, - }, - { - { 0xC7, 0xFF, 0xB4, 0x9F, 0xBC, 0x94, 0x72, 0x24, 0x5C, 0x8E, 0x95, 0xDE, 0x62, 0x9A, 0xF5, 0xC1, - 0xBF, 0xEA, 0xC5, 0x50, 0x04, 0xC1, 0x54, 0x82, 0x3A, 0x58, 0xBA, 0xE8, 0x05, 0x6E, 0x3C, 0x64 }, - }, - { - { 0xC8, 0x26, 0xBE, 0xDD, 0x88, 0x6A, 0x87, 0x1D, 0xD5, 0xCF, 0x3A, 0x2A, 0xE0, 0xA5, 0x1C, 0x93, - 0xBC, 0x2C, 0xFF, 0x31, 0x90, 0xD1, 0xCB, 0x2C, 0x13, 0x13, 0x97, 0x29, 0x5A, 0x81, 0x76, 0xB5 }, - }, - { - { 0xC8, 0x37, 0xD6, 0xF2, 0xAB, 0x14, 0x79, 0x91, 0x42, 0xED, 0x3C, 0x79, 0xBE, 0xD9, 0x44, 0x1E, - 0x92, 0x50, 0xBD, 0x05, 0x20, 0x25, 0xAD, 0x8A, 0xF4, 0x40, 0x41, 0xAC, 0x19, 0xEF, 0xBB, 0x4C }, - }, - { - { 0xC8, 0xC6, 0x92, 0x81, 0xBE, 0x05, 0xC4, 0x14, 0xEA, 0xA3, 0x1C, 0x61, 0xB6, 0x52, 0x93, 0xBE, - 0x72, 0xB5, 0x89, 0xD1, 0xD5, 0xE4, 0xB7, 0x59, 0xD5, 0xED, 0xAF, 0x54, 0x63, 0x99, 0xA2, 0xEF }, - }, - { - { 0xC8, 0xF2, 0x99, 0x18, 0xD3, 0x41, 0xEE, 0x02, 0x20, 0xA4, 0x4D, 0xB0, 0xF0, 0xC2, 0xD9, 0xC4, - 0x16, 0x6E, 0x02, 0x3A, 0x66, 0xCA, 0x6D, 0x1D, 0x3F, 0x78, 0xF1, 0x58, 0x93, 0x61, 0x90, 0x8E }, - }, - { - { 0xC9, 0x43, 0x10, 0x03, 0xBB, 0xEA, 0xB5, 0x8E, 0x35, 0x2F, 0xDE, 0xB4, 0x5B, 0x7F, 0xCF, 0x15, - 0xC7, 0x3F, 0x07, 0x34, 0xA0, 0x7D, 0x6C, 0xBD, 0xF6, 0x32, 0x92, 0x92, 0xEB, 0x81, 0x2C, 0x93 }, - }, - { - { 0xC9, 0x72, 0xF4, 0xF9, 0x6E, 0x71, 0x33, 0xE1, 0x6E, 0x55, 0x57, 0xA0, 0x57, 0xB1, 0xD4, 0x2B, - 0xA9, 0x2D, 0x98, 0x5C, 0xAE, 0xE7, 0x3C, 0xAF, 0xDA, 0xEB, 0x55, 0xEC, 0xA2, 0xE4, 0xAB, 0xB0 }, - }, - { - { 0xC9, 0x78, 0x37, 0x2C, 0x9E, 0x11, 0x60, 0x71, 0xB6, 0x1B, 0x90, 0x92, 0xA9, 0xAA, 0x96, 0x81, - 0x62, 0x36, 0x55, 0xA6, 0x6F, 0x4F, 0xCB, 0xC4, 0xD3, 0xA6, 0x7E, 0xFD, 0x56, 0x72, 0x48, 0x30 }, - }, - { - { 0xC9, 0x7E, 0x4D, 0x81, 0xE7, 0x4E, 0x3D, 0x0A, 0x5E, 0xE0, 0x9C, 0x6F, 0x76, 0x9B, 0x95, 0x7E, - 0x70, 0x04, 0xAD, 0x2C, 0x9F, 0xC6, 0x66, 0x8A, 0x69, 0xD6, 0xCA, 0x29, 0xE0, 0x66, 0xE7, 0xFE }, - }, - { - { 0xC9, 0x84, 0x0B, 0xFB, 0x2C, 0x2D, 0x46, 0x82, 0x7C, 0xC7, 0x55, 0xC7, 0x5B, 0x12, 0x8A, 0x4F, - 0x0B, 0x7E, 0x06, 0xE5, 0xAC, 0x44, 0xEE, 0x8F, 0xFB, 0x92, 0x9A, 0xAC, 0xD9, 0x58, 0x3F, 0x39 }, - }, - { - { 0xC9, 0xE5, 0x7C, 0x8F, 0xE0, 0x00, 0x40, 0x58, 0x58, 0xBA, 0x46, 0xBE, 0xCB, 0x84, 0x78, 0xAA, - 0x8A, 0xD8, 0x24, 0x90, 0x8B, 0x90, 0xC4, 0xB5, 0xF4, 0x73, 0x8F, 0xEB, 0xD3, 0x11, 0x3B, 0xE0 }, - }, - { - { 0xCA, 0x18, 0x88, 0xDC, 0x1C, 0xEE, 0xC3, 0x5F, 0x92, 0x31, 0xD4, 0x1D, 0x23, 0x07, 0x77, 0x82, - 0x91, 0xDF, 0x33, 0x81, 0xAE, 0x6F, 0x3B, 0xC4, 0x17, 0xA9, 0xD9, 0x94, 0x4D, 0xE3, 0x06, 0x48 }, - }, - { - { 0xCA, 0x21, 0x0B, 0x73, 0x5D, 0xC0, 0x7F, 0xFB, 0xD2, 0x3C, 0x5B, 0x61, 0x30, 0x76, 0xE3, 0xD5, - 0x1B, 0xB3, 0xCE, 0x53, 0x52, 0x6A, 0x1A, 0xDF, 0xC7, 0x32, 0x54, 0x25, 0x49, 0xD8, 0xF9, 0xDA }, - }, - { - { 0xCA, 0x55, 0x6F, 0x82, 0xC9, 0x68, 0x4C, 0x9A, 0xF3, 0x55, 0x7D, 0x3E, 0x2D, 0x88, 0xAF, 0x92, - 0xED, 0x25, 0x9C, 0x20, 0xFF, 0xD1, 0xDD, 0xE9, 0xF7, 0x9D, 0x6B, 0x92, 0xC6, 0x1E, 0xE1, 0xB9 }, - }, - { - { 0xCA, 0x5A, 0x11, 0x99, 0xC9, 0xA7, 0xA3, 0x7F, 0xAD, 0xCF, 0x8D, 0xE9, 0x88, 0xDC, 0xFE, 0x55, - 0xBF, 0x80, 0x39, 0x38, 0x6D, 0x60, 0x34, 0xC1, 0xBD, 0xD8, 0x69, 0x2D, 0x49, 0x2F, 0x4C, 0x6C }, - }, - { - { 0xCA, 0x5F, 0x30, 0x7A, 0x0A, 0xA2, 0x8F, 0xF4, 0x33, 0x29, 0xCC, 0xFD, 0xC0, 0x0D, 0xE3, 0x5E, - 0xED, 0x83, 0xDA, 0x0E, 0x4B, 0x15, 0x1A, 0x76, 0xEC, 0x9E, 0x1E, 0x93, 0x5A, 0x5E, 0x36, 0xB0 }, - }, - { - { 0xCA, 0x5F, 0x8F, 0x8A, 0xF0, 0xD9, 0xFA, 0x3F, 0x80, 0x03, 0x88, 0x49, 0x54, 0xE8, 0xAA, 0x1B, - 0x8A, 0xAD, 0x4E, 0xE8, 0xD1, 0x4E, 0x82, 0xF3, 0x3F, 0xBA, 0xE3, 0xB4, 0x59, 0x8B, 0x5F, 0x90 }, - }, - { - { 0xCA, 0x6C, 0xC4, 0xBA, 0x92, 0x04, 0x14, 0x20, 0x7A, 0xA0, 0xE0, 0xF3, 0x3F, 0x27, 0x44, 0xC3, - 0x1A, 0x37, 0x78, 0x27, 0x50, 0x89, 0x24, 0x6E, 0x9E, 0x98, 0x4C, 0xB7, 0x2C, 0x58, 0x72, 0xFC }, - }, - { - { 0xCA, 0x91, 0x6E, 0xA3, 0xFA, 0x04, 0xFA, 0x3D, 0xA0, 0xC0, 0xB9, 0x27, 0xE8, 0x1D, 0xBD, 0x77, - 0xC0, 0xE4, 0x1C, 0xB8, 0xFF, 0x04, 0xAD, 0x95, 0x33, 0xB8, 0x5D, 0x87, 0xBD, 0x63, 0x30, 0x92 }, - }, - { - { 0xCA, 0xBE, 0x25, 0x56, 0xF1, 0xBB, 0x56, 0x57, 0x0C, 0xEF, 0x3A, 0x87, 0x03, 0x32, 0x71, 0xA1, - 0xF2, 0x1D, 0x09, 0xB7, 0xFD, 0x04, 0x12, 0x83, 0x18, 0xE5, 0xE7, 0xBC, 0xE3, 0xA2, 0x01, 0xE2 }, - }, - { - { 0xCA, 0xC4, 0xBB, 0x2C, 0x3D, 0x5F, 0xC7, 0xCB, 0x19, 0xC5, 0x41, 0x06, 0x79, 0x59, 0xD7, 0x20, - 0xEF, 0x4C, 0xBF, 0x52, 0x98, 0x01, 0xBE, 0xE1, 0xC8, 0xDE, 0xBF, 0x42, 0x75, 0xFC, 0x08, 0x3B }, - }, - { - { 0xCA, 0xDC, 0xD5, 0xAE, 0x1B, 0x75, 0x6A, 0xB7, 0x41, 0xB3, 0x56, 0x9C, 0x42, 0xA5, 0x41, 0x1F, - 0x09, 0x3E, 0x4E, 0x1F, 0x01, 0x2E, 0xC5, 0x79, 0x91, 0xCB, 0xD6, 0xDB, 0xE0, 0x8F, 0xAA, 0xC1 }, - }, - { - { 0xCB, 0x51, 0x19, 0xD5, 0x1A, 0x4E, 0xE8, 0x5D, 0x7D, 0x4B, 0xD0, 0xD7, 0xEC, 0xBA, 0xAD, 0x4E, - 0xC4, 0x43, 0x65, 0x4D, 0xA8, 0x5D, 0xD2, 0x46, 0xBB, 0x5E, 0x03, 0x7F, 0xE7, 0x70, 0x79, 0xB6 }, - }, - { - { 0xCB, 0x7A, 0x43, 0x8D, 0x16, 0xE4, 0xA5, 0xF3, 0xC5, 0x6F, 0xDF, 0x19, 0x1E, 0x1D, 0xAF, 0x9F, - 0x32, 0x5C, 0x65, 0x0B, 0xD6, 0x2F, 0x07, 0xC4, 0x67, 0x71, 0x72, 0x07, 0x35, 0x1A, 0xE3, 0x29 }, - }, - { - { 0xCB, 0x9C, 0x10, 0xF2, 0xCB, 0x7F, 0x7C, 0xDB, 0xFD, 0xB1, 0xF8, 0xED, 0x6A, 0x42, 0x32, 0xB4, - 0x4D, 0x6F, 0x7C, 0x32, 0x57, 0xA5, 0x94, 0x99, 0xE2, 0x37, 0xEC, 0x11, 0x3A, 0x2D, 0xDC, 0x1D }, - }, - { - { 0xCC, 0x2A, 0x70, 0x6F, 0xE6, 0x8F, 0x5D, 0x17, 0xF4, 0xAB, 0xAF, 0x60, 0x86, 0xE5, 0xBD, 0x97, - 0xAE, 0x35, 0xEB, 0x35, 0x9F, 0x75, 0xC0, 0x92, 0xBB, 0xA4, 0x93, 0xFE, 0x11, 0xF2, 0x69, 0xFD }, - }, - { - { 0xCC, 0x30, 0xD8, 0x19, 0xDE, 0x54, 0x05, 0xF6, 0x49, 0xC8, 0xB7, 0xA8, 0x14, 0x8F, 0x26, 0xD7, - 0x71, 0x08, 0x3E, 0xC5, 0x18, 0xF9, 0xB6, 0x6F, 0xF5, 0x47, 0xF2, 0x82, 0x2D, 0x11, 0x93, 0x6D }, - }, - { - { 0xCC, 0x4E, 0x09, 0x63, 0x13, 0xDF, 0xA0, 0xCC, 0x24, 0x77, 0xA3, 0xA5, 0xB7, 0x9A, 0xEF, 0x0A, - 0x45, 0x54, 0x58, 0x69, 0xA7, 0xF8, 0x8A, 0x29, 0x14, 0x96, 0x06, 0x4B, 0x69, 0x76, 0xE1, 0x4D }, - }, - { - { 0xCC, 0x5C, 0xBD, 0xDB, 0x14, 0x85, 0x91, 0x00, 0xF8, 0x46, 0x23, 0xAF, 0xBB, 0x00, 0x6D, 0x90, - 0x6B, 0x71, 0xBC, 0xC3, 0xAA, 0x84, 0x07, 0x44, 0x0C, 0x7F, 0x10, 0x47, 0x0C, 0xA9, 0x29, 0x21 }, - }, - { - { 0xCC, 0x65, 0xCD, 0xC5, 0x33, 0x62, 0xD4, 0x21, 0x62, 0x7E, 0xAE, 0xF5, 0xD0, 0xC8, 0xE4, 0xC4, - 0xE2, 0x40, 0xAD, 0xE0, 0xC9, 0xD4, 0x20, 0xBE, 0x67, 0x1E, 0x70, 0xF0, 0xFB, 0xAC, 0x8D, 0x0A }, - }, - { - { 0xCC, 0xA9, 0x7F, 0x5E, 0x4E, 0x65, 0xB6, 0x11, 0x97, 0x5F, 0xC4, 0x4A, 0xAC, 0xD4, 0x3F, 0x49, - 0x0E, 0xB9, 0x47, 0x4D, 0x15, 0xFF, 0x07, 0x40, 0x55, 0xB5, 0x93, 0x28, 0x81, 0xF1, 0x1F, 0x3F }, - }, - { - { 0xCC, 0xCB, 0x6F, 0xA7, 0xEF, 0x62, 0x78, 0x99, 0xFA, 0x6F, 0xCC, 0x96, 0x50, 0x9B, 0x22, 0x55, - 0x77, 0x4E, 0xD9, 0x94, 0xA0, 0xB7, 0xA5, 0x74, 0xB8, 0x4E, 0xBD, 0xC1, 0xAE, 0x59, 0xA4, 0xA8 }, - }, - { - { 0xCD, 0x12, 0x53, 0xFF, 0xC5, 0x8D, 0xC6, 0x3D, 0x0B, 0xAF, 0xBD, 0xDE, 0x1B, 0xBF, 0xF0, 0x33, - 0xAE, 0xAB, 0x63, 0x30, 0x9B, 0x4D, 0x72, 0xE7, 0x59, 0xC4, 0x79, 0xC2, 0xE5, 0x5D, 0x39, 0xBD }, - }, - { - { 0xCD, 0x51, 0xED, 0x79, 0xB6, 0x39, 0x06, 0x32, 0x75, 0x7F, 0x8A, 0xAD, 0x39, 0xD3, 0xBE, 0xBD, - 0xDC, 0x79, 0xBB, 0x90, 0xD0, 0x46, 0xFD, 0xF1, 0x46, 0xDA, 0x62, 0xF6, 0x9D, 0x28, 0x41, 0x34 }, - }, - { - { 0xCD, 0x8E, 0xA1, 0x1F, 0xF5, 0x9F, 0x00, 0x9F, 0xD3, 0x02, 0xD7, 0x90, 0xA2, 0x89, 0xB7, 0x04, - 0x76, 0x1E, 0x01, 0xCF, 0x27, 0x3F, 0xD9, 0x70, 0xD9, 0xC7, 0xC1, 0xEC, 0xA4, 0x9D, 0x48, 0x51 }, - }, - { - { 0xCD, 0xB1, 0x62, 0x53, 0xD2, 0x2E, 0xD5, 0xD4, 0x26, 0xCF, 0xA1, 0xB0, 0x5C, 0xEC, 0xD8, 0x6E, - 0xF1, 0xB7, 0xDE, 0xAA, 0x07, 0xC5, 0x70, 0x5E, 0xBB, 0xAF, 0x7D, 0x9A, 0x80, 0x7D, 0x56, 0x16 }, - }, - { - { 0xCD, 0xC0, 0x39, 0xF3, 0xA2, 0xD1, 0xBB, 0xA5, 0xE8, 0x09, 0x4E, 0x55, 0x23, 0xCF, 0x60, 0x47, - 0x09, 0x7D, 0x4B, 0x3C, 0xD4, 0xEC, 0x4E, 0xD6, 0xAA, 0x8E, 0xB7, 0xB4, 0xD8, 0xB5, 0x77, 0x7D }, - }, - { - { 0xCD, 0xC4, 0xEA, 0x92, 0x02, 0xE3, 0x3E, 0xDD, 0x0F, 0x2D, 0x3A, 0xE8, 0x6A, 0xCA, 0xC7, 0xFB, - 0x25, 0x35, 0x4B, 0x02, 0x23, 0x5B, 0x09, 0x33, 0xAA, 0x81, 0xA3, 0x13, 0xB5, 0xFD, 0xFE, 0xEC }, - }, - { - { 0xCE, 0x2C, 0xF2, 0x55, 0x72, 0x57, 0x21, 0x30, 0x71, 0x73, 0x68, 0x19, 0xB7, 0xD2, 0x88, 0xA9, - 0x30, 0x77, 0x2B, 0x9B, 0x78, 0x2E, 0x61, 0x60, 0x03, 0x8F, 0xC6, 0x7A, 0x76, 0x0D, 0x7C, 0xDC }, - }, - { - { 0xCE, 0x47, 0xD5, 0x29, 0x14, 0xEF, 0xAA, 0xBE, 0x41, 0x80, 0xD4, 0xA0, 0xF7, 0xE1, 0xBC, 0xA4, - 0x72, 0x0B, 0x35, 0xA4, 0x43, 0x11, 0x93, 0x61, 0x26, 0x57, 0x99, 0x71, 0xBF, 0x16, 0x8C, 0x71 }, - }, - { - { 0xCE, 0x4C, 0x2F, 0x8F, 0x16, 0x46, 0x8A, 0x58, 0x88, 0xE9, 0x0F, 0x73, 0x4E, 0x4D, 0x22, 0x02, - 0xDF, 0xAD, 0xBF, 0xA6, 0x6F, 0x5B, 0x35, 0x75, 0x2B, 0xAA, 0x76, 0x21, 0xA7, 0x60, 0xB0, 0x88 }, - }, - { - { 0xCE, 0x52, 0x40, 0xCB, 0xAC, 0x28, 0x6B, 0x4E, 0x87, 0x69, 0xCE, 0xDC, 0x3F, 0x79, 0xD0, 0x6D, - 0x9C, 0x8D, 0x15, 0xD3, 0xD6, 0xC6, 0x84, 0x50, 0xF7, 0xC2, 0x9D, 0x44, 0x1D, 0x02, 0xFA, 0x50 }, - }, - { - { 0xCE, 0x81, 0x44, 0x58, 0x54, 0x03, 0x1F, 0x3D, 0x0F, 0x5C, 0x88, 0x75, 0x46, 0x4D, 0xCD, 0x5B, - 0xA6, 0xC8, 0x90, 0xF4, 0x49, 0xB3, 0x20, 0x7B, 0xCA, 0x2B, 0xC9, 0x61, 0x82, 0x2D, 0x27, 0xC4 }, - }, - { - { 0xCE, 0x83, 0x25, 0x83, 0x1D, 0xA3, 0xAF, 0x4D, 0x77, 0xAC, 0x41, 0xCE, 0xD9, 0x2A, 0xED, 0x17, - 0x95, 0x8A, 0x2B, 0x27, 0xAA, 0xFD, 0xEF, 0x64, 0xDB, 0x3E, 0xA2, 0x26, 0x03, 0x2C, 0x0F, 0x87 }, - }, - { - { 0xCE, 0x84, 0x19, 0xA7, 0xC8, 0x87, 0xFD, 0x59, 0x48, 0xB1, 0x0D, 0xC2, 0x64, 0x5C, 0x05, 0xCF, - 0xA1, 0xE1, 0x69, 0x06, 0xAC, 0x83, 0x35, 0x02, 0xA3, 0x0C, 0x42, 0xAD, 0x3F, 0x00, 0x7F, 0x17 }, - }, - { - { 0xCE, 0x9D, 0xE7, 0xAC, 0x2E, 0x0B, 0x8A, 0x4F, 0x85, 0xF5, 0xB6, 0x4E, 0x65, 0x22, 0x8D, 0x03, - 0xFC, 0x77, 0x93, 0xD9, 0x49, 0x42, 0xF8, 0x8A, 0x1C, 0x72, 0xBB, 0x7B, 0x61, 0x14, 0x51, 0xD5 }, - }, - { - { 0xCF, 0x03, 0x40, 0x17, 0x5B, 0x25, 0x03, 0xC8, 0xFA, 0x5D, 0x52, 0xED, 0x42, 0x5B, 0xF3, 0x7E, - 0x69, 0xC1, 0x80, 0xE5, 0x75, 0xAD, 0xC1, 0xA2, 0x6A, 0x47, 0x81, 0x97, 0x71, 0xB6, 0x8F, 0x7D }, - }, - { - { 0xCF, 0x10, 0xFA, 0xC3, 0x54, 0x4D, 0xCE, 0xE1, 0xBB, 0x98, 0x7E, 0x92, 0xE7, 0x35, 0x48, 0xB1, - 0xC6, 0xA8, 0x65, 0xE6, 0x9C, 0xD2, 0x91, 0x8A, 0xD0, 0x1D, 0xAF, 0x89, 0xB1, 0x04, 0x6A, 0x51 }, - }, - { - { 0xCF, 0x3C, 0x62, 0x0B, 0x39, 0xA4, 0x91, 0xB1, 0xBD, 0xC0, 0x33, 0x5F, 0xA1, 0x15, 0xB4, 0xF5, - 0xAE, 0xD7, 0xD8, 0xCD, 0x8E, 0xBB, 0xF2, 0xCA, 0x73, 0x7E, 0x7C, 0x6A, 0xC2, 0x00, 0x68, 0x0E }, - }, - { - { 0xCF, 0x3E, 0xCB, 0x41, 0xA4, 0xE8, 0x1B, 0x3A, 0xC8, 0x27, 0xDC, 0xBE, 0x4E, 0xB6, 0xD1, 0xCD, - 0x4C, 0x53, 0x4A, 0xDF, 0x8C, 0x87, 0xE4, 0xAA, 0x0C, 0xB2, 0x97, 0x15, 0x74, 0x6F, 0x04, 0x0B }, - }, - { - { 0xCF, 0x55, 0x5E, 0x56, 0x05, 0xDF, 0xA7, 0x42, 0x35, 0x33, 0xDD, 0xDA, 0xF7, 0x48, 0x72, 0xD1, - 0x68, 0x46, 0xE2, 0xCB, 0xF0, 0x30, 0x7D, 0x33, 0xA1, 0x0D, 0xF5, 0x72, 0x40, 0x67, 0x2F, 0x42 }, - }, - { - { 0xCF, 0x92, 0x77, 0xCE, 0xEA, 0x50, 0x1A, 0x49, 0x66, 0x04, 0x3E, 0xF2, 0xB0, 0xF8, 0x86, 0x2A, - 0xC9, 0x00, 0x93, 0x89, 0x78, 0x08, 0x26, 0x22, 0xC5, 0x7A, 0x50, 0x07, 0xC9, 0xC6, 0x53, 0x9D }, - }, - { - { 0xCF, 0xA0, 0xC0, 0x0C, 0xB2, 0xFB, 0x4B, 0x85, 0x7A, 0xAD, 0x22, 0xB1, 0x3A, 0x90, 0xE3, 0x46, - 0xA0, 0x3E, 0x6B, 0x79, 0xAB, 0xD5, 0xD2, 0x75, 0xB5, 0x43, 0x24, 0x68, 0x17, 0x92, 0xD6, 0xD1 }, - }, - { - { 0xCF, 0xFC, 0x37, 0x2D, 0xB5, 0xDA, 0x47, 0xAC, 0xDD, 0xF3, 0x1A, 0x84, 0x9B, 0xD2, 0xE2, 0xBD, - 0x25, 0xB6, 0x58, 0xEE, 0xB8, 0xDA, 0x82, 0x51, 0x59, 0x9A, 0x97, 0x51, 0x89, 0xB5, 0xF8, 0x24 }, - }, - { - { 0xD0, 0x71, 0x14, 0xB2, 0x97, 0xB2, 0x9F, 0xA2, 0xE0, 0xEC, 0xCD, 0xF1, 0x58, 0x7C, 0x0F, 0x03, - 0xF8, 0x81, 0x63, 0x95, 0x46, 0x1D, 0x01, 0x1C, 0x47, 0x7B, 0xD7, 0xFE, 0x83, 0x8A, 0x3D, 0x0B }, - }, - { - { 0xD0, 0xC4, 0x74, 0xE4, 0x47, 0xE3, 0x38, 0xA5, 0x4D, 0x31, 0xB3, 0xA0, 0xF4, 0x47, 0x43, 0x75, - 0x1E, 0x45, 0xCB, 0x92, 0x87, 0xA0, 0x1F, 0x2B, 0x0A, 0x51, 0xE6, 0x4F, 0x16, 0xC9, 0xA7, 0x5C }, - }, - { - { 0xD0, 0xEA, 0x0E, 0x9F, 0xD1, 0x80, 0x10, 0x0D, 0xCA, 0xC8, 0xB1, 0xB3, 0xFB, 0x95, 0xCE, 0xCB, - 0x9E, 0xCB, 0x1D, 0xFD, 0xCD, 0x6D, 0xF6, 0x16, 0xD8, 0xE1, 0x17, 0x50, 0x8A, 0x5C, 0xEE, 0xFD }, - }, - { - { 0xD0, 0xF5, 0x93, 0xC1, 0xA8, 0x1B, 0x1E, 0xF8, 0x51, 0x69, 0x81, 0xEE, 0x56, 0xF1, 0xD5, 0x98, - 0xA2, 0xA6, 0x03, 0x48, 0x8C, 0x67, 0x8C, 0x1B, 0x7B, 0xBE, 0xA6, 0x44, 0x6B, 0x00, 0x83, 0xAD }, - }, - { - { 0xD1, 0x07, 0x9A, 0x99, 0xF7, 0x3A, 0x01, 0xC9, 0x6E, 0xA6, 0x78, 0x84, 0x16, 0x62, 0xDA, 0x5E, - 0x74, 0xCA, 0xB2, 0xC4, 0x1D, 0x1F, 0x83, 0x45, 0x47, 0xFE, 0x65, 0x0F, 0x28, 0x50, 0xCD, 0x27 }, - }, - { - { 0xD1, 0x24, 0xFC, 0x30, 0x54, 0x79, 0x1F, 0x76, 0xBB, 0x8B, 0xAF, 0x57, 0xF5, 0xC4, 0x5B, 0x69, - 0x16, 0x8C, 0x3A, 0x6E, 0xE3, 0xFB, 0xCD, 0xF3, 0xEC, 0x2A, 0x77, 0xE8, 0x7C, 0x7C, 0x50, 0x09 }, - }, - { - { 0xD1, 0xBA, 0x62, 0xAC, 0x65, 0x17, 0x92, 0x3B, 0x96, 0x74, 0xF6, 0xA9, 0x73, 0xA1, 0x13, 0x17, - 0xC3, 0x0C, 0x20, 0x4F, 0x63, 0x65, 0xD1, 0x03, 0x00, 0x21, 0xB6, 0xF1, 0xF7, 0xFF, 0xBA, 0xA5 }, - }, - { - { 0xD1, 0xFA, 0xD9, 0xA8, 0xE6, 0x2E, 0x06, 0xCF, 0x9B, 0x40, 0x3A, 0xDF, 0x51, 0xED, 0x60, 0x75, - 0xEC, 0xE7, 0x61, 0xA1, 0x0D, 0xD6, 0xA4, 0xD8, 0xDE, 0x08, 0x82, 0x2F, 0xBB, 0x08, 0x22, 0xFD }, - }, - { - { 0xD2, 0x29, 0x2E, 0x6F, 0x6C, 0x3A, 0xF8, 0xAE, 0xEE, 0x62, 0xA8, 0x14, 0xB3, 0x17, 0x1D, 0xE4, - 0xA6, 0xD6, 0x60, 0xED, 0x25, 0xA2, 0x01, 0xB9, 0xBA, 0x7D, 0xE8, 0x3F, 0xDB, 0xE3, 0x95, 0x5E }, - }, - { - { 0xD2, 0x3F, 0xEB, 0x93, 0x47, 0x60, 0xB8, 0xDF, 0x4E, 0xE6, 0xB0, 0xE8, 0xBB, 0x4F, 0x5D, 0x31, - 0x5D, 0x40, 0x5B, 0xF0, 0x56, 0x18, 0x2E, 0x5D, 0x5F, 0x70, 0x20, 0x31, 0x94, 0x61, 0x8A, 0x05 }, - }, - { - { 0xD2, 0x56, 0x79, 0xCB, 0x58, 0x3B, 0xA0, 0x10, 0x8F, 0x74, 0x97, 0xE3, 0x21, 0xC6, 0x5C, 0x4D, - 0xC2, 0xCA, 0x0F, 0x28, 0x20, 0xC7, 0xFC, 0xDB, 0x11, 0x3F, 0x05, 0x72, 0xDF, 0x44, 0x79, 0x34 }, - }, - { - { 0xD2, 0x90, 0x3C, 0xA2, 0x55, 0x17, 0x27, 0xED, 0x01, 0x71, 0xCC, 0x4A, 0x43, 0xB3, 0xCA, 0xE0, - 0x09, 0xB7, 0x47, 0xB9, 0xF4, 0xF8, 0x48, 0x72, 0x92, 0x27, 0xBF, 0x59, 0x02, 0xF2, 0x3E, 0x47 }, - }, - { - { 0xD2, 0xB9, 0x70, 0xF3, 0x30, 0x65, 0x03, 0xE7, 0xD4, 0xBC, 0x63, 0x04, 0x64, 0xB2, 0xAF, 0x39, - 0x20, 0x66, 0x06, 0xD3, 0x6F, 0xF0, 0x51, 0xD9, 0x7D, 0x40, 0xD5, 0x8A, 0xB5, 0x37, 0x72, 0x83 }, - }, - { - { 0xD2, 0xC7, 0x0A, 0x4C, 0x52, 0xFB, 0xFC, 0x7B, 0x4C, 0x2D, 0xFE, 0x94, 0xCB, 0x44, 0x50, 0x37, - 0x1E, 0x72, 0x36, 0xBD, 0xBD, 0x1C, 0x81, 0x13, 0xFF, 0x36, 0x0F, 0xA4, 0xA1, 0x58, 0x1E, 0xFC }, - }, - { - { 0xD2, 0xD1, 0x84, 0xCA, 0x5B, 0x97, 0xAC, 0x7B, 0xD3, 0x4E, 0x78, 0x42, 0x4C, 0xA0, 0xC2, 0xB3, - 0x9C, 0x35, 0x08, 0x52, 0xCC, 0xB1, 0x33, 0xE5, 0xA1, 0x87, 0xF7, 0x61, 0x7D, 0x00, 0xB0, 0x2C }, - }, - { - { 0xD2, 0xE8, 0xA1, 0x23, 0x7A, 0x93, 0xF5, 0x78, 0xD1, 0xBA, 0x8F, 0x09, 0xE4, 0xFF, 0x10, 0x7B, - 0x62, 0x35, 0x78, 0x85, 0x42, 0xAA, 0x61, 0x83, 0xD1, 0x76, 0xDB, 0xF1, 0xC8, 0x8D, 0xCF, 0xB6 }, - }, - { - { 0xD3, 0x10, 0x0B, 0xC8, 0x42, 0x8B, 0xA2, 0x3A, 0xE1, 0x3B, 0x41, 0xEA, 0xA2, 0x95, 0xBF, 0xBF, - 0xD6, 0x97, 0xF5, 0x0B, 0x81, 0xCA, 0xEF, 0x6A, 0x30, 0xA4, 0xD1, 0x99, 0x47, 0x1B, 0x9F, 0x32 }, - }, - { - { 0xD3, 0x22, 0xE0, 0xC4, 0x4E, 0xA7, 0x92, 0xC0, 0x00, 0x13, 0x01, 0xA6, 0x32, 0xA1, 0x1D, 0x50, - 0x6E, 0xA9, 0x17, 0xDE, 0xED, 0xCA, 0x8E, 0xD0, 0x5F, 0x9E, 0x7A, 0xF0, 0xB6, 0x08, 0x55, 0x8B }, - }, - { - { 0xD3, 0x8E, 0x25, 0x54, 0xA9, 0xEE, 0x9B, 0x6D, 0xBC, 0xC4, 0x89, 0x2D, 0x71, 0x44, 0x7E, 0xF1, - 0x78, 0x92, 0xF3, 0xBC, 0xA3, 0x33, 0x95, 0x2D, 0xAA, 0x12, 0x16, 0xC9, 0xE9, 0x56, 0x22, 0x27 }, - }, - { - { 0xD3, 0xFF, 0x14, 0xAD, 0xD8, 0x86, 0x5F, 0xAA, 0x9C, 0x30, 0x3A, 0xED, 0xF9, 0x34, 0x53, 0x85, - 0x49, 0x8D, 0x44, 0xE1, 0xCD, 0xE0, 0x45, 0x6F, 0x1F, 0x33, 0xB4, 0x54, 0xC3, 0x95, 0x04, 0x58 }, - }, - { - { 0xD4, 0xA8, 0x3C, 0x51, 0x04, 0x29, 0x4F, 0x6A, 0xEC, 0x2A, 0xA0, 0x9F, 0xA6, 0xEF, 0x5F, 0xA0, - 0xF1, 0x72, 0xFD, 0xE6, 0xC4, 0xAC, 0xD9, 0x97, 0x2F, 0x39, 0xFE, 0xE2, 0x92, 0x4B, 0xE2, 0x74 }, - }, - { - { 0xD4, 0xC3, 0xFD, 0x99, 0x41, 0x39, 0x82, 0x2A, 0xF3, 0x4D, 0xED, 0xF2, 0xC0, 0xE6, 0x2A, 0xE5, - 0xEC, 0x67, 0x28, 0xAA, 0x6E, 0xAE, 0x4B, 0x65, 0x8D, 0x93, 0xBD, 0xAF, 0x3E, 0x4A, 0x7C, 0x0C }, - }, - { - { 0xD5, 0x04, 0x88, 0x96, 0x86, 0x07, 0x29, 0xA8, 0xFA, 0x5D, 0x23, 0x57, 0x81, 0x2B, 0xA5, 0x6C, - 0xBE, 0x84, 0xC9, 0xAB, 0x7D, 0x14, 0xDF, 0x47, 0x64, 0xE0, 0xB6, 0x62, 0x0F, 0xA3, 0x20, 0x10 }, - }, - { - { 0xD5, 0x07, 0x55, 0x61, 0x65, 0x49, 0x1E, 0xB1, 0x24, 0x3D, 0x9A, 0x61, 0xE2, 0x5D, 0x20, 0x84, - 0x7C, 0x57, 0xBC, 0xB2, 0x98, 0xE6, 0xD8, 0x5B, 0x7C, 0x45, 0xBE, 0xFB, 0x3D, 0x9C, 0x7B, 0x35 }, - }, - { - { 0xD5, 0x41, 0xA7, 0x7E, 0x13, 0x6E, 0x9E, 0x70, 0x3B, 0xB9, 0x9F, 0x80, 0x68, 0xCF, 0xEE, 0x86, - 0xA4, 0xB9, 0xF0, 0x89, 0xE0, 0x2D, 0x0C, 0x6C, 0xB6, 0xD4, 0xA3, 0x94, 0x6C, 0x6B, 0x16, 0x7A }, - }, - { - { 0xD5, 0x50, 0xB9, 0xA6, 0xD5, 0xC3, 0xF5, 0x25, 0x7C, 0x99, 0xB9, 0x94, 0x43, 0x69, 0x88, 0x3D, - 0xA1, 0x1D, 0xBE, 0x23, 0xB9, 0x6E, 0x19, 0x34, 0xED, 0xED, 0x52, 0x1B, 0x73, 0x55, 0xE4, 0x44 }, - }, - { - { 0xD5, 0x83, 0x7F, 0x79, 0xAD, 0xB8, 0x27, 0x89, 0x70, 0xDF, 0x46, 0x7E, 0xDF, 0x42, 0x5B, 0x8A, - 0x31, 0xB7, 0x50, 0xBC, 0x3B, 0x9C, 0x07, 0x57, 0xD4, 0xDA, 0x14, 0xC5, 0x0F, 0xCF, 0x76, 0x88 }, - }, - { - { 0xD5, 0x83, 0x94, 0x96, 0xCD, 0xC8, 0x5B, 0xE3, 0xD1, 0xF1, 0xAC, 0x65, 0x2E, 0xFA, 0x92, 0xBE, - 0xA3, 0xB0, 0x61, 0xC1, 0x3D, 0xAD, 0x5A, 0x82, 0x11, 0x22, 0xCF, 0xE9, 0xC7, 0x1A, 0x5A, 0x32 }, - }, - { - { 0xD5, 0xA4, 0xEE, 0x46, 0x95, 0xB5, 0x65, 0xA6, 0x7E, 0x50, 0x48, 0x66, 0xFE, 0x5B, 0xA3, 0xC0, - 0xED, 0xCA, 0xEE, 0xD5, 0x2A, 0xD0, 0xAF, 0x07, 0xE6, 0x79, 0x17, 0x73, 0x85, 0x12, 0xC8, 0xF5 }, - }, - { - { 0xD5, 0xCB, 0xAB, 0xC2, 0x61, 0x1A, 0x6C, 0x55, 0xAF, 0xB0, 0x43, 0x27, 0xE2, 0x60, 0x8C, 0xEC, - 0xF3, 0x45, 0x6C, 0x9F, 0xD8, 0xC7, 0x66, 0x58, 0x18, 0xA5, 0x4D, 0x5D, 0x93, 0x24, 0x97, 0xAB }, - }, - { - { 0xD6, 0x25, 0xC0, 0x59, 0x2B, 0x25, 0xDC, 0x03, 0xAA, 0x7E, 0x87, 0x8E, 0x6A, 0x85, 0x09, 0x1B, - 0xAA, 0x07, 0x8D, 0x26, 0x8B, 0xBD, 0xB4, 0x9F, 0x09, 0x67, 0x94, 0x08, 0x61, 0x2D, 0x1E, 0xFE }, - }, - { - { 0xD6, 0x46, 0x08, 0xB1, 0x5F, 0x71, 0xFC, 0x3B, 0x91, 0x90, 0xA2, 0x00, 0xEE, 0x3C, 0xB5, 0xBC, - 0xD9, 0xFC, 0x5B, 0x99, 0xFB, 0x67, 0x74, 0x9D, 0x18, 0x87, 0xD9, 0x17, 0xD8, 0x50, 0x01, 0x0B }, - }, - { - { 0xD6, 0x83, 0xD0, 0x6E, 0xB9, 0x28, 0x74, 0x43, 0xE5, 0x01, 0xEC, 0xF7, 0x1D, 0xAD, 0xA6, 0x80, - 0x35, 0x88, 0x71, 0xD1, 0x2A, 0x53, 0xFB, 0xCC, 0x44, 0x09, 0x2E, 0x76, 0x4E, 0xE5, 0xBA, 0x08 }, - }, - { - { 0xD6, 0xD1, 0xB3, 0x5C, 0xBC, 0x12, 0xFB, 0x1C, 0x70, 0xA0, 0xB4, 0x3B, 0xA5, 0x9A, 0xB3, 0xD3, - 0x22, 0x5F, 0x37, 0x32, 0x64, 0xDD, 0x87, 0xFB, 0xCA, 0x00, 0x61, 0xEC, 0x1C, 0x4D, 0xA1, 0x1A }, - }, - { - { 0xD7, 0x0E, 0xB9, 0xB3, 0xFE, 0xAD, 0xD3, 0x05, 0x3F, 0x5B, 0xBC, 0xD5, 0xBB, 0xDE, 0x27, 0x48, - 0xCC, 0xCF, 0xB3, 0xE4, 0x41, 0x36, 0x7C, 0xE9, 0x3B, 0x76, 0xCC, 0x46, 0xCC, 0xE3, 0x76, 0xC8 }, - }, - { - { 0xD7, 0x2C, 0x0E, 0x02, 0xA8, 0x71, 0xA9, 0xC2, 0x86, 0x7D, 0xB5, 0x13, 0x63, 0x62, 0x56, 0x98, - 0x32, 0xDC, 0x3B, 0x85, 0xAA, 0x05, 0x4A, 0x6C, 0x9E, 0xCC, 0x19, 0x01, 0x0E, 0xBA, 0x39, 0x3A }, - }, - { - { 0xD7, 0x32, 0x49, 0x74, 0xB5, 0x60, 0x09, 0x62, 0x17, 0x61, 0xF7, 0xC0, 0xFF, 0x68, 0x9D, 0xDE, - 0x47, 0x74, 0x99, 0x85, 0xE1, 0xEE, 0x8B, 0x5C, 0x89, 0x61, 0xDD, 0x8F, 0x6A, 0x78, 0xBB, 0xF5 }, - }, - { - { 0xD8, 0x0D, 0x49, 0xD7, 0xC6, 0x7A, 0x19, 0x3D, 0xE4, 0x4C, 0x4A, 0xD0, 0xA2, 0xF1, 0x0D, 0x04, - 0x33, 0xBD, 0x28, 0xFF, 0x57, 0x46, 0xB4, 0x2D, 0x8D, 0x27, 0x7F, 0x60, 0x8D, 0xAB, 0x7E, 0xFD }, - }, - { - { 0xD8, 0x18, 0xA4, 0x72, 0x70, 0xFD, 0xCD, 0x56, 0x4C, 0x8C, 0xEF, 0xBC, 0x28, 0xF7, 0x6D, 0x93, - 0x0B, 0x6C, 0x0D, 0xAE, 0x09, 0xD9, 0x3D, 0x24, 0x20, 0xEB, 0x7C, 0xDE, 0x20, 0x59, 0xAD, 0xBA }, - }, - { - { 0xD8, 0x29, 0xD3, 0x8A, 0xF1, 0xC4, 0x45, 0x73, 0x8B, 0xD8, 0x12, 0xE2, 0x8E, 0x38, 0x26, 0xB3, - 0x32, 0x27, 0x32, 0xAB, 0xE0, 0x02, 0x32, 0x89, 0xFE, 0x5A, 0x9E, 0xA6, 0x15, 0xF4, 0xF8, 0x97 }, - }, - { - { 0xD8, 0x32, 0x8D, 0x2F, 0xF8, 0x7E, 0xC3, 0xE9, 0x0B, 0x84, 0xD9, 0xA1, 0x7B, 0x1E, 0x90, 0x24, - 0xF6, 0x27, 0xC1, 0xEC, 0xC3, 0x5E, 0xC7, 0xE6, 0x71, 0xC1, 0x42, 0x92, 0xA7, 0xB8, 0x8B, 0x43 }, - }, - { - { 0xD8, 0x55, 0x49, 0xFC, 0xD2, 0x4D, 0x36, 0xCB, 0x3F, 0x7C, 0x18, 0x06, 0x3F, 0x97, 0x5A, 0x16, - 0x9F, 0xE3, 0xA1, 0xFB, 0x8D, 0x0A, 0x35, 0x9F, 0xD3, 0x5C, 0x28, 0x7B, 0xB2, 0xAF, 0x50, 0xCA }, - }, - { - { 0xD8, 0x7A, 0x9D, 0xF7, 0x19, 0x1E, 0x29, 0xC8, 0x04, 0x1E, 0x4C, 0x19, 0x3C, 0x03, 0xA8, 0xA7, - 0x12, 0x5F, 0x16, 0x6E, 0xA6, 0xCB, 0x21, 0x1F, 0xFF, 0x4B, 0xEE, 0x45, 0x0D, 0x72, 0x58, 0x09 }, - }, - { - { 0xD8, 0x83, 0xDD, 0x00, 0x1C, 0x4E, 0x5C, 0x22, 0x6E, 0xE2, 0xC1, 0xF1, 0x0A, 0x66, 0x6F, 0xA1, - 0x6E, 0x5A, 0xA9, 0x12, 0x30, 0x58, 0x38, 0xED, 0x9C, 0xDD, 0xC1, 0x56, 0x4D, 0xC6, 0x49, 0x64 }, - }, - { - { 0xD8, 0xF0, 0xE4, 0x50, 0x14, 0xD7, 0x09, 0x7D, 0xB4, 0xD6, 0xF7, 0x65, 0xEF, 0xE8, 0xB2, 0xB1, - 0x3A, 0x18, 0xDD, 0xE7, 0x39, 0xDF, 0x2A, 0xF7, 0x72, 0x73, 0x50, 0x26, 0x47, 0x04, 0xF7, 0x90 }, - }, - { - { 0xD8, 0xFF, 0x73, 0x93, 0x1F, 0x89, 0x1D, 0x94, 0x70, 0xBD, 0x60, 0xF4, 0xC7, 0x4A, 0x0E, 0x28, - 0x88, 0xC8, 0x0D, 0xCB, 0x1E, 0xCF, 0xB1, 0x18, 0xC3, 0xDC, 0x81, 0x90, 0xDA, 0x99, 0x1A, 0x70 }, - }, - { - { 0xD9, 0x2E, 0x3E, 0xE3, 0x82, 0xC8, 0xDC, 0xAF, 0xA0, 0x39, 0x3D, 0x9F, 0x9A, 0x00, 0xBF, 0x4C, - 0xD9, 0xD5, 0x64, 0x26, 0x2B, 0x18, 0x0F, 0x68, 0x16, 0x0B, 0x20, 0x34, 0xC5, 0x44, 0xD1, 0x0A }, - }, - { - { 0xD9, 0x41, 0x01, 0xB0, 0xDF, 0x02, 0xCD, 0xFE, 0xEA, 0xD5, 0x21, 0xD0, 0xE2, 0xCF, 0x3A, 0x69, - 0x46, 0x1F, 0x82, 0x6B, 0xB7, 0xA4, 0xAB, 0x50, 0xBA, 0x36, 0xA3, 0xC1, 0xF8, 0x3A, 0x52, 0xC4 }, - }, - { - { 0xD9, 0x65, 0xF7, 0x41, 0x62, 0x04, 0xDA, 0x83, 0x1A, 0xF6, 0x6B, 0xFA, 0x8F, 0x90, 0xD1, 0x41, - 0xE9, 0x93, 0xF0, 0x00, 0x21, 0x33, 0xF2, 0x8D, 0xE9, 0x7F, 0x56, 0x4A, 0x1D, 0x60, 0x4E, 0xCC }, - }, - { - { 0xD9, 0x7F, 0x55, 0xB9, 0x57, 0x9B, 0x05, 0xAE, 0x4A, 0x3E, 0xD7, 0xFC, 0x55, 0x8C, 0x58, 0x45, - 0x64, 0x51, 0x60, 0xDA, 0xB3, 0x53, 0x85, 0xC1, 0x38, 0xBC, 0x89, 0x9C, 0x4D, 0xAD, 0x8B, 0x36 }, - }, - { - { 0xD9, 0x81, 0x67, 0x9E, 0x4E, 0xCD, 0xE9, 0xC5, 0xAB, 0x5B, 0xEF, 0x9D, 0x5F, 0x97, 0x7B, 0x0F, - 0x32, 0xF9, 0x25, 0x56, 0xE2, 0x06, 0xB1, 0x51, 0x09, 0xA9, 0xBB, 0xEC, 0x59, 0x16, 0xE2, 0xD7 }, - }, - { - { 0xD9, 0x89, 0x73, 0x8D, 0x2D, 0xE5, 0x06, 0x5B, 0x8E, 0x7A, 0x8C, 0x07, 0x44, 0x88, 0xBE, 0x8E, - 0x7D, 0x93, 0xAA, 0x82, 0xA8, 0x35, 0x96, 0x49, 0x24, 0xC5, 0x8F, 0x32, 0x09, 0xFB, 0x56, 0x9E }, - }, - { - { 0xD9, 0xD0, 0xD9, 0x6E, 0xB3, 0x28, 0xE0, 0xC1, 0x77, 0x8B, 0x56, 0xA9, 0x2F, 0x71, 0x24, 0x3B, - 0x6C, 0x0D, 0xB4, 0x5C, 0x62, 0x51, 0x32, 0xDD, 0x82, 0xCA, 0x11, 0xA0, 0x97, 0xE7, 0x91, 0xC6 }, - }, - { - { 0xD9, 0xE8, 0xCC, 0xDA, 0x78, 0xFB, 0x8D, 0x5D, 0xBC, 0xE6, 0x94, 0x15, 0x57, 0x61, 0xF4, 0xD0, - 0x2C, 0x30, 0xCC, 0x8D, 0x7A, 0xEA, 0x0E, 0x11, 0x88, 0x2D, 0x79, 0x37, 0x6C, 0x72, 0x90, 0xFF }, - }, - { - { 0xDA, 0x1D, 0x8C, 0x2F, 0xE5, 0x25, 0xA6, 0xAD, 0xD6, 0xCD, 0x0F, 0xB4, 0x0F, 0xCD, 0xBF, 0xCE, - 0x0D, 0x19, 0x72, 0xED, 0x61, 0xAC, 0xDD, 0x5A, 0x0F, 0xE0, 0x19, 0x7F, 0x01, 0x07, 0x8D, 0x7F }, - }, - { - { 0xDA, 0xA3, 0x09, 0xDA, 0xEF, 0xCB, 0x5C, 0xD3, 0xBD, 0xF6, 0xE1, 0x4B, 0xA6, 0x89, 0x0B, 0x4F, - 0x73, 0xF2, 0xEC, 0x1C, 0xEF, 0xC1, 0xD5, 0x1F, 0x45, 0xCD, 0x9F, 0xC2, 0x2B, 0x01, 0x9A, 0x1E }, - }, - { - { 0xDA, 0xB2, 0xF9, 0xE8, 0xB5, 0xF8, 0x56, 0x47, 0x90, 0x93, 0x2D, 0x6B, 0xDB, 0x34, 0x29, 0x16, - 0x2D, 0x5E, 0x2C, 0xB5, 0xD0, 0x10, 0x2D, 0x79, 0xD8, 0x89, 0xAD, 0x5A, 0xB6, 0xEE, 0xC4, 0x77 }, - }, - { - { 0xDA, 0xDF, 0x97, 0x13, 0x34, 0x14, 0xAD, 0x51, 0x3F, 0xC7, 0x50, 0x14, 0xE9, 0x56, 0x65, 0xDA, - 0xD7, 0x76, 0xB1, 0x50, 0x4B, 0x15, 0x67, 0x43, 0x4F, 0xD8, 0x2A, 0x79, 0xA2, 0x20, 0xE9, 0xA1 }, - }, - { - { 0xDB, 0x1B, 0x33, 0x54, 0x93, 0xBE, 0x68, 0xD2, 0x8E, 0x3C, 0x4D, 0x3D, 0x11, 0x84, 0x99, 0x42, - 0x26, 0x17, 0x93, 0x49, 0xDA, 0xF1, 0x79, 0x5B, 0x77, 0x39, 0x3E, 0x2D, 0xD9, 0x87, 0xBB, 0x43 }, - }, - { - { 0xDB, 0x1D, 0x05, 0x4E, 0xEF, 0x12, 0xBD, 0x34, 0xA5, 0xBD, 0x99, 0xCD, 0xC5, 0xB8, 0x64, 0x8D, - 0x8E, 0x10, 0xDE, 0xF9, 0xC7, 0x8A, 0xFD, 0x90, 0xA4, 0xB4, 0xAD, 0x1E, 0xD1, 0xD9, 0x09, 0x06 }, - }, - { - { 0xDB, 0x2D, 0xB8, 0x4B, 0x17, 0x3C, 0xE2, 0x83, 0xBA, 0x18, 0x0F, 0xA2, 0x2F, 0x15, 0xC5, 0x5F, - 0x6A, 0x2A, 0x27, 0x66, 0x9C, 0xA8, 0x14, 0xA0, 0x3B, 0x9E, 0xD0, 0x31, 0x90, 0xCF, 0x92, 0xF6 }, - }, - { - { 0xDB, 0x57, 0x78, 0x2A, 0x14, 0xE1, 0x3C, 0x3B, 0xE5, 0x38, 0x9A, 0x26, 0x08, 0x1C, 0x99, 0x8B, - 0x5F, 0xFA, 0x67, 0xDD, 0x45, 0x97, 0xF8, 0xCA, 0x67, 0xEF, 0x10, 0x6A, 0xD7, 0x5F, 0x34, 0x9F }, - }, - { - { 0xDB, 0xA1, 0x23, 0x67, 0x1F, 0xED, 0x4B, 0x28, 0x70, 0x33, 0xA4, 0xB0, 0x06, 0x8F, 0xC7, 0x14, - 0xA5, 0xFC, 0x9C, 0x02, 0x6E, 0xF5, 0x65, 0x0B, 0x42, 0xDE, 0x25, 0x85, 0x9A, 0x12, 0x6A, 0xD1 }, - }, - { - { 0xDB, 0xA2, 0x21, 0xC2, 0xAB, 0x44, 0xB5, 0x2C, 0x0B, 0x83, 0x36, 0xC4, 0x69, 0xFA, 0xA8, 0x56, - 0xD6, 0xC3, 0xEC, 0xDC, 0x6C, 0x24, 0x6B, 0xE3, 0xCA, 0xC7, 0xE0, 0xF6, 0x28, 0x4B, 0x5B, 0xDA }, - }, - { - { 0xDC, 0x30, 0x45, 0x1C, 0xFB, 0x1A, 0x68, 0x3F, 0xC5, 0xB2, 0xF3, 0x16, 0x56, 0x02, 0x49, 0x6A, - 0x8F, 0xC1, 0xED, 0xA7, 0xCD, 0x1E, 0x61, 0xB3, 0xE1, 0x67, 0x47, 0x71, 0xD1, 0x4F, 0x7A, 0x0E }, - }, - { - { 0xDC, 0x3D, 0x81, 0xC3, 0x01, 0xBC, 0xDE, 0xC5, 0x38, 0xEF, 0xC7, 0xFA, 0x6A, 0x4E, 0x5A, 0x13, - 0xE5, 0x17, 0xD2, 0xA4, 0x61, 0x22, 0x2D, 0xED, 0x98, 0x3E, 0x75, 0x56, 0x4D, 0x0E, 0x68, 0x84 }, - }, - { - { 0xDC, 0x42, 0x4A, 0x70, 0x87, 0x80, 0x95, 0x98, 0x7A, 0x5B, 0xCD, 0x17, 0x1A, 0xA5, 0x13, 0x67, - 0x7B, 0xDA, 0x56, 0xDF, 0x35, 0xB6, 0x81, 0xC7, 0x07, 0x84, 0x0F, 0xDC, 0xEA, 0xC5, 0xE4, 0x0F }, - }, - { - { 0xDC, 0x69, 0x58, 0x6C, 0xCD, 0x6D, 0x51, 0x0D, 0xD1, 0xCF, 0x79, 0x56, 0xA6, 0x71, 0xD0, 0x84, - 0xEE, 0x14, 0x99, 0xDA, 0x54, 0xB8, 0xBC, 0x79, 0xEB, 0x07, 0x28, 0x71, 0xA9, 0x18, 0xC4, 0x06 }, - }, - { - { 0xDC, 0x90, 0x90, 0x55, 0x0C, 0x93, 0x42, 0xE2, 0xFA, 0xE2, 0x42, 0x26, 0xA4, 0xF9, 0xB3, 0xF6, - 0x93, 0xF4, 0xD1, 0x46, 0x52, 0x79, 0xC3, 0x7B, 0x46, 0x14, 0x38, 0xF4, 0xF5, 0x3C, 0x0E, 0x0B }, - }, - { - { 0xDC, 0xB2, 0x1D, 0xEF, 0x3C, 0x26, 0x0B, 0x20, 0x50, 0xF3, 0x4C, 0x5F, 0x51, 0xBE, 0x30, 0x9C, - 0x3C, 0x76, 0x36, 0x30, 0x6D, 0x51, 0xB9, 0xBE, 0x43, 0xD8, 0x9D, 0xE0, 0x8F, 0x60, 0xD9, 0x4A }, - }, - { - { 0xDD, 0x30, 0xCB, 0x75, 0xC9, 0x3E, 0x01, 0xFC, 0xC6, 0xE8, 0x44, 0x63, 0xFD, 0x47, 0x78, 0x15, - 0x8F, 0x3A, 0x18, 0xCE, 0x89, 0x67, 0x7B, 0x01, 0xE6, 0xFF, 0x5B, 0xA7, 0x2F, 0xA4, 0xD0, 0xF6 }, - }, - { - { 0xDD, 0x9D, 0xD7, 0xC1, 0x80, 0xB2, 0x73, 0x50, 0x83, 0xF5, 0xC7, 0x29, 0x3E, 0xC8, 0x64, 0x07, - 0x4B, 0x42, 0x27, 0xFE, 0x0E, 0xAE, 0x8D, 0x4D, 0xAF, 0x66, 0x54, 0x0D, 0x82, 0x2F, 0x81, 0xA1 }, - }, - { - { 0xDE, 0x01, 0xA7, 0x27, 0x1A, 0x95, 0x3D, 0xA2, 0xF0, 0xFD, 0xDB, 0x6B, 0x37, 0xFE, 0x00, 0x28, - 0xDE, 0x8B, 0x7D, 0x3C, 0xE5, 0x79, 0x1B, 0x45, 0x0D, 0xD2, 0x83, 0xB2, 0x0A, 0xDB, 0x05, 0xD2 }, - }, - { - { 0xDE, 0x45, 0x46, 0xC0, 0x24, 0x51, 0xA5, 0xB5, 0xAD, 0x85, 0xEA, 0x53, 0x2F, 0x09, 0x6F, 0xDF, - 0x1E, 0x2B, 0x41, 0x71, 0xD9, 0x6A, 0x1D, 0xC3, 0x93, 0x6A, 0x19, 0x74, 0xF0, 0x58, 0xF0, 0xB2 }, - }, - { - { 0xDE, 0x5C, 0x3D, 0x09, 0x58, 0xA6, 0x12, 0xBD, 0x6D, 0x48, 0x09, 0x15, 0x03, 0x3D, 0x97, 0x15, - 0x58, 0xDF, 0x35, 0xCE, 0xB1, 0xC9, 0x18, 0xE6, 0x9A, 0x01, 0x34, 0x51, 0xE4, 0x50, 0x95, 0xB8 }, - }, - { - { 0xDE, 0x77, 0xEA, 0xDB, 0xCB, 0xC2, 0x05, 0xDD, 0x55, 0xA0, 0xE1, 0x18, 0xCA, 0x67, 0x74, 0xF9, - 0x58, 0x09, 0xA8, 0x2C, 0xA0, 0x1B, 0x2D, 0x5E, 0x85, 0x72, 0xE6, 0x17, 0xB6, 0xAB, 0xF4, 0x72 }, + { 0x94, 0xDC, 0x80, 0x07, 0x49, 0x1D, 0xA8, 0xBF, 0xB7, 0x39, 0x14, 0xAD, 0xCE, 0xF7, 0x1A, 0x12, + 0x41, 0x58, 0xBA, 0xD1, 0x7B, 0xA8, 0x8F, 0xA9, 0x46, 0x57, 0x9B, 0xBC, 0x2D, 0x64, 0x97, 0x8D }, }, { - { 0xDE, 0xCD, 0xB9, 0xFC, 0x1D, 0xDE, 0xC9, 0x7E, 0x09, 0xC3, 0x02, 0x6A, 0xCE, 0xB7, 0x6B, 0xDA, - 0xE9, 0xDE, 0xB6, 0x62, 0x75, 0x1D, 0xDA, 0x34, 0x9D, 0x2F, 0xA6, 0xBD, 0x75, 0xCA, 0x59, 0x14 }, + { 0x95, 0x68, 0x33, 0xAE, 0xE6, 0x61, 0x19, 0x26, 0xE9, 0x52, 0x72, 0xA1, 0xF5, 0x88, 0xF9, 0x2A, + 0xF5, 0x2C, 0xAE, 0x70, 0x7A, 0xCD, 0xCC, 0x82, 0x63, 0x99, 0x7B, 0xFA, 0x8C, 0x71, 0x9C, 0xA8 }, }, { - { 0xDE, 0xD1, 0x9A, 0xD5, 0xDE, 0x99, 0x65, 0xD9, 0x22, 0x5C, 0x1B, 0xBA, 0x5F, 0xB4, 0xD8, 0x90, - 0xC8, 0xE5, 0xC0, 0x35, 0xE4, 0x85, 0x27, 0x52, 0xB6, 0x69, 0xB0, 0x40, 0x0F, 0x24, 0xF1, 0x74 }, + { 0x95, 0x89, 0xDA, 0xC9, 0xEC, 0xE7, 0x6D, 0xF5, 0x72, 0x01, 0x96, 0xDC, 0x58, 0x6D, 0x17, 0x9D, + 0x73, 0x5D, 0xF7, 0x17, 0x92, 0x6C, 0x06, 0x1E, 0xA7, 0x0C, 0x40, 0x85, 0x64, 0x8F, 0xF3, 0x12 }, }, { - { 0xDF, 0x12, 0x39, 0x4E, 0x73, 0xCB, 0x8C, 0x95, 0xC5, 0x7E, 0x49, 0x8B, 0x96, 0xFF, 0x65, 0x2C, - 0x06, 0xAC, 0x62, 0xA9, 0xA8, 0xED, 0x83, 0x85, 0x39, 0x93, 0xDC, 0xBD, 0xEB, 0xC0, 0x16, 0xAA }, + { 0x96, 0xA4, 0x59, 0x90, 0xFC, 0xD0, 0x1C, 0x9C, 0x2A, 0xF0, 0x64, 0x5F, 0x87, 0xB9, 0x69, 0x8B, + 0x05, 0xAF, 0xE6, 0x94, 0x32, 0xEB, 0x57, 0x01, 0x08, 0x20, 0x13, 0xBA, 0xC5, 0xB0, 0x55, 0x60 }, }, { - { 0xDF, 0x30, 0xBF, 0x8D, 0x1B, 0xF9, 0x37, 0x8E, 0x43, 0x3E, 0xF9, 0xE1, 0xB3, 0xA2, 0x28, 0xA0, - 0x7E, 0x36, 0x58, 0xA5, 0xBC, 0x43, 0x88, 0x23, 0x45, 0x4D, 0xB0, 0x6A, 0x67, 0x94, 0x4C, 0x6E }, + { 0x96, 0xEB, 0x44, 0xAA, 0x6A, 0x20, 0x49, 0xE6, 0xBA, 0xFF, 0xE6, 0xB5, 0x21, 0xC4, 0xAD, 0x8C, + 0x58, 0x77, 0x26, 0xCA, 0xA0, 0x12, 0xE8, 0xFB, 0x8E, 0x8E, 0x21, 0x89, 0x77, 0xBF, 0x1D, 0xF6 }, }, { - { 0xDF, 0x51, 0x6D, 0xA3, 0xC8, 0x2D, 0x2D, 0x71, 0x17, 0x77, 0x76, 0x59, 0xCC, 0x9D, 0xBE, 0x7C, - 0xEC, 0x22, 0x70, 0x8F, 0x22, 0x59, 0x47, 0x6F, 0xFC, 0x48, 0x60, 0x34, 0x94, 0xFC, 0x87, 0xD3 }, + { 0x97, 0x4F, 0x51, 0xA6, 0x04, 0x68, 0x48, 0xFA, 0xA7, 0xB3, 0x3F, 0xD2, 0x39, 0x13, 0x86, 0x42, + 0x8B, 0xD5, 0x24, 0xEA, 0xEB, 0xA8, 0x01, 0x4E, 0x6D, 0x1F, 0xE2, 0x54, 0x38, 0x3F, 0x41, 0x79 }, }, { - { 0xDF, 0x69, 0xF9, 0x6A, 0x85, 0x67, 0x8F, 0x6C, 0xAF, 0x3F, 0xDE, 0x25, 0xEC, 0xFB, 0x5D, 0xF4, - 0x74, 0x70, 0x87, 0xC2, 0xAF, 0x3B, 0x00, 0x65, 0xFB, 0x15, 0x10, 0x55, 0xCB, 0xCB, 0xA8, 0xC1 }, + { 0x97, 0x8D, 0x6F, 0x1E, 0x9A, 0xA3, 0xA3, 0xCE, 0xB1, 0xAD, 0xA6, 0x09, 0xE2, 0x00, 0x95, 0xFB, + 0xC3, 0x3A, 0x6B, 0xBC, 0x6A, 0x21, 0xD8, 0x0A, 0x4E, 0xCB, 0x27, 0x3C, 0x60, 0xAC, 0x2A, 0xC7 }, }, { - { 0xDF, 0xE5, 0xE5, 0x4F, 0x77, 0x04, 0xBE, 0xA9, 0xCE, 0xC9, 0xC3, 0x36, 0x85, 0xE8, 0x93, 0x37, - 0x6F, 0xE0, 0x65, 0xD3, 0x3B, 0xBC, 0x23, 0x5D, 0x16, 0xA4, 0x35, 0x3D, 0x3C, 0x28, 0x41, 0xED }, + { 0x98, 0xB5, 0x92, 0x4E, 0x06, 0xCD, 0xEA, 0x1B, 0xA1, 0x7F, 0xDB, 0x1B, 0x13, 0x97, 0x90, 0x24, + 0xB1, 0xC2, 0x5B, 0x0A, 0x69, 0x0C, 0xFE, 0x87, 0x8D, 0x4C, 0xB4, 0x07, 0x76, 0xB9, 0x6F, 0xB0 }, }, { - { 0xDF, 0xFB, 0x15, 0x21, 0xAA, 0x2D, 0x83, 0x65, 0x9A, 0x85, 0x8E, 0x14, 0x62, 0x82, 0x43, 0xD7, - 0x23, 0x14, 0x5E, 0xA8, 0x13, 0x77, 0xDE, 0xD7, 0x99, 0x1A, 0x3C, 0x00, 0xA3, 0x88, 0x9B, 0xF5 }, + { 0x99, 0xA5, 0x5F, 0x76, 0xCB, 0xEA, 0x0F, 0x3E, 0x60, 0x71, 0xD3, 0x82, 0x18, 0x1A, 0xF6, 0xCB, + 0x25, 0xBD, 0xC5, 0x87, 0x5E, 0x29, 0xF0, 0xF4, 0xD7, 0x19, 0xA9, 0xD3, 0x5B, 0x5B, 0xD6, 0xBF }, }, { - { 0xE0, 0x0B, 0xD7, 0x86, 0xD1, 0xF2, 0xF4, 0x46, 0xC4, 0xBA, 0x83, 0x99, 0xD4, 0xD8, 0xD5, 0xA0, - 0xD1, 0x98, 0x57, 0x8F, 0x42, 0x99, 0xFD, 0xFD, 0xAF, 0xF7, 0x8C, 0x3F, 0x67, 0x71, 0xF3, 0x94 }, + { 0x9A, 0x4B, 0x49, 0x93, 0xB4, 0xED, 0x8C, 0x27, 0xE7, 0x7F, 0x3C, 0x8A, 0xAF, 0xDB, 0xDC, 0x11, + 0x1A, 0x36, 0xB7, 0x3C, 0xCA, 0xDB, 0x87, 0x04, 0x98, 0x25, 0x00, 0xD1, 0xB0, 0xF1, 0x09, 0xF2 }, }, { - { 0xE0, 0x65, 0x19, 0x10, 0x41, 0x74, 0x08, 0xBE, 0x2B, 0x0C, 0xFD, 0x3D, 0x9E, 0xAA, 0xEB, 0xCA, - 0x32, 0x1F, 0x61, 0x6D, 0xDA, 0x48, 0xCB, 0x4F, 0x09, 0x10, 0x9D, 0x67, 0x19, 0x45, 0xA1, 0x1C }, + { 0x9A, 0x5F, 0xAB, 0xE5, 0x8A, 0x1E, 0xAE, 0x4B, 0x20, 0xBA, 0xB3, 0xA7, 0xEB, 0x5E, 0x42, 0xA2, + 0xDA, 0x83, 0x11, 0x59, 0x25, 0x7D, 0xD4, 0xE3, 0x55, 0x2E, 0xC6, 0xF7, 0xD2, 0x67, 0xFA, 0xBA }, }, { - { 0xE0, 0x8B, 0x2C, 0xC2, 0x7A, 0xE8, 0xE2, 0xEF, 0x1A, 0x33, 0x01, 0x7A, 0x9A, 0xC2, 0x5D, 0xDA, - 0xFB, 0x5E, 0xA1, 0x12, 0xC9, 0x56, 0xB0, 0x02, 0xFE, 0x6C, 0x79, 0x80, 0x14, 0xAA, 0x90, 0x65 }, + { 0x9A, 0xAE, 0x9D, 0x45, 0xAA, 0x04, 0x03, 0x06, 0x4B, 0xC5, 0xA7, 0x4D, 0xD0, 0x32, 0x5D, 0xA4, + 0x1E, 0x12, 0xCF, 0x58, 0x6C, 0x46, 0x2E, 0xE0, 0x6C, 0x2B, 0xB4, 0x56, 0xF8, 0x44, 0x1C, 0x4F }, }, { - { 0xE0, 0xA0, 0x7B, 0x39, 0x6D, 0x25, 0x7F, 0xAB, 0xB4, 0xE3, 0x22, 0xD8, 0x79, 0x94, 0x88, 0x37, - 0x28, 0x7A, 0xAA, 0x99, 0xAD, 0x14, 0xD7, 0x8D, 0x3A, 0x2F, 0x9D, 0xFE, 0x5C, 0x97, 0x28, 0xBF }, + { 0x9B, 0x8F, 0x9F, 0xC4, 0xAF, 0xA7, 0x04, 0x0D, 0x4E, 0x59, 0x4D, 0x66, 0x7C, 0x44, 0x44, 0xB5, + 0x25, 0x88, 0x20, 0xC0, 0x8F, 0x89, 0x91, 0x0E, 0xD3, 0x42, 0x1C, 0xB4, 0xA9, 0x7B, 0xB7, 0x9E }, }, { - { 0xE0, 0xA9, 0xD9, 0x63, 0x6E, 0xFA, 0x36, 0xA7, 0x72, 0xAC, 0xB5, 0xD0, 0x22, 0xFC, 0xA9, 0x73, - 0x71, 0xB4, 0x4F, 0x7B, 0x80, 0x4B, 0x03, 0x97, 0xFB, 0x6C, 0x37, 0x1A, 0x22, 0x5B, 0xDA, 0x78 }, + { 0x9C, 0x70, 0x8D, 0x5B, 0xAB, 0x37, 0xF5, 0xB6, 0xBC, 0x8A, 0x77, 0x53, 0x12, 0x57, 0x2A, 0xB2, + 0x79, 0x21, 0x6D, 0x55, 0x6D, 0xA7, 0x4A, 0xC2, 0xA7, 0xC0, 0x41, 0xE8, 0xCE, 0xB0, 0xBE, 0x0A }, }, { - { 0xE0, 0xBB, 0xEF, 0x7E, 0xE4, 0x37, 0xB0, 0x59, 0xE0, 0x3B, 0x52, 0x9B, 0xE6, 0xB4, 0x09, 0x6D, - 0x56, 0xC7, 0x4E, 0x90, 0x67, 0xB0, 0x5F, 0x87, 0xAA, 0x6A, 0x5A, 0x61, 0x93, 0x40, 0xA7, 0xC3 }, + { 0x9C, 0xCA, 0x23, 0x7C, 0xDF, 0xCA, 0x2C, 0x72, 0xC6, 0x09, 0x25, 0x4A, 0x72, 0x57, 0xFE, 0xD5, + 0x3A, 0xF1, 0x44, 0xAB, 0xC2, 0x5E, 0xCD, 0x8E, 0xF7, 0x01, 0x30, 0x8C, 0xB1, 0x3C, 0xF7, 0x69 }, }, { - { 0xE0, 0xDD, 0xE1, 0x29, 0xD2, 0x60, 0xC3, 0xDA, 0xB6, 0x91, 0xD8, 0x1D, 0xAB, 0xAD, 0x73, 0x4C, - 0x9A, 0xDC, 0x61, 0xD2, 0x0C, 0x1A, 0xE1, 0xB6, 0x72, 0x4E, 0x7B, 0x27, 0x92, 0x75, 0xDA, 0x35 }, + { 0x9D, 0x6B, 0xDF, 0xCF, 0x0C, 0xBF, 0xFE, 0xEA, 0x3B, 0x1A, 0xC7, 0xE9, 0x63, 0xCB, 0xB5, 0xF2, + 0x7F, 0xBD, 0xA8, 0x9D, 0x27, 0x77, 0xF6, 0x0E, 0x56, 0x5B, 0x27, 0x78, 0x54, 0xEF, 0xB0, 0x19 }, }, { - { 0xE1, 0xB2, 0xE8, 0x6B, 0x0D, 0xA8, 0x69, 0xE9, 0x25, 0x26, 0x6C, 0x1B, 0x56, 0x88, 0x34, 0x5A, - 0x17, 0xB0, 0xF6, 0xE2, 0xA2, 0x14, 0x94, 0x54, 0x7E, 0xAC, 0x09, 0x7C, 0x8B, 0xF5, 0x3C, 0x5A }, + { 0x9D, 0xAC, 0x33, 0x14, 0xB2, 0x5B, 0xB7, 0x9A, 0x39, 0xCD, 0x01, 0xEC, 0x4B, 0x33, 0xA1, 0x2F, + 0x47, 0x51, 0x2F, 0x54, 0x09, 0xFF, 0x09, 0x5D, 0x40, 0xAA, 0xD6, 0x20, 0x84, 0xEF, 0x15, 0xBE }, }, { - { 0xE1, 0xD4, 0xBB, 0x78, 0x58, 0x58, 0x9E, 0x08, 0x7E, 0x01, 0xAE, 0x85, 0x99, 0x5A, 0x5C, 0x2F, - 0xD0, 0xAC, 0xED, 0xF4, 0x40, 0x55, 0xFF, 0x96, 0x73, 0x8F, 0x2B, 0x32, 0xB3, 0x31, 0x6E, 0xB0 }, + { 0x9F, 0x24, 0x5C, 0x0A, 0x0E, 0xC6, 0x3A, 0xAA, 0xCB, 0xF9, 0x69, 0xC6, 0xFC, 0x24, 0xA1, 0x07, + 0x15, 0x83, 0xB7, 0x79, 0xA5, 0x8A, 0xB6, 0x23, 0xDD, 0x15, 0x31, 0xA2, 0xCA, 0x9F, 0x87, 0x51 }, }, { - { 0xE1, 0xD6, 0x44, 0xA0, 0x96, 0xBD, 0x8A, 0x6C, 0xAC, 0xBB, 0xDA, 0x3E, 0x7F, 0xC3, 0x38, 0xEA, - 0xDD, 0xC1, 0x2F, 0x23, 0x6C, 0x72, 0x61, 0xE4, 0x5F, 0x8A, 0xD2, 0xD8, 0x42, 0x42, 0x4F, 0x72 }, + { 0x9F, 0xAF, 0x1C, 0x11, 0xA3, 0xC7, 0xE2, 0x41, 0xF8, 0x63, 0x71, 0x97, 0xE8, 0x99, 0x68, 0xDB, + 0x86, 0x6A, 0xD0, 0x1A, 0x5D, 0x4E, 0xD5, 0x34, 0x59, 0x48, 0x65, 0xB9, 0x70, 0x75, 0xF2, 0x60 }, }, { - { 0xE2, 0x24, 0x10, 0xB5, 0xA6, 0x7F, 0xED, 0xC2, 0x64, 0x69, 0x4C, 0x44, 0x9D, 0x84, 0xFA, 0x1A, - 0x02, 0xBC, 0x8B, 0x21, 0x28, 0xC1, 0x25, 0x60, 0x71, 0x58, 0xC9, 0x1B, 0x05, 0x38, 0x6C, 0x6A }, + { 0x9F, 0xFA, 0x4E, 0xF4, 0xFC, 0xF2, 0xCF, 0xD1, 0xB2, 0x7C, 0x6A, 0x62, 0xE3, 0xC4, 0x23, 0x5B, + 0xD8, 0x3C, 0xC5, 0xE0, 0x06, 0xE9, 0x2A, 0x55, 0xE4, 0xA9, 0x86, 0xE6, 0x30, 0x53, 0x57, 0xE3 }, }, { - { 0xE2, 0xA8, 0x47, 0xC3, 0xF0, 0x9B, 0xEB, 0x6F, 0x05, 0x68, 0x6F, 0x17, 0x79, 0x1B, 0x05, 0xF1, - 0xFE, 0x25, 0xF7, 0x71, 0x86, 0x9C, 0x42, 0x63, 0xA5, 0x5B, 0x94, 0x18, 0x77, 0xE4, 0x79, 0x04 }, + { 0xA0, 0xC2, 0xD2, 0x07, 0xA4, 0x7E, 0x18, 0xD0, 0x37, 0x14, 0xD5, 0xB3, 0x44, 0x5D, 0x88, 0xBE, + 0x81, 0xFF, 0x5E, 0x1D, 0x16, 0x07, 0x3D, 0xC1, 0x16, 0x6B, 0xB5, 0x44, 0x8F, 0xF6, 0x52, 0xDF }, }, { - { 0xE2, 0xB4, 0x03, 0x32, 0x0B, 0x01, 0xF6, 0x03, 0xD7, 0xB0, 0xCA, 0x1F, 0x89, 0xF0, 0x8E, 0x25, - 0xA7, 0x95, 0xE8, 0xB6, 0x04, 0x36, 0x8B, 0xA0, 0x78, 0x69, 0x68, 0x46, 0x8C, 0x18, 0xC3, 0xF0 }, + { 0xA1, 0x97, 0x7D, 0x0C, 0x92, 0x7C, 0x21, 0xEB, 0x47, 0x6F, 0x67, 0xBE, 0xFE, 0xD6, 0xCF, 0x2C, + 0x61, 0xB7, 0x45, 0xF0, 0xCE, 0x8D, 0x26, 0x58, 0x3D, 0x03, 0xB2, 0x70, 0x02, 0xD5, 0xCD, 0xAF }, }, { - { 0xE2, 0xDE, 0x18, 0x3E, 0xAE, 0x35, 0x4C, 0xCF, 0x68, 0xF2, 0x52, 0x56, 0x76, 0xD7, 0x26, 0x46, - 0x06, 0x01, 0x38, 0x43, 0xAC, 0xB1, 0xFB, 0xFF, 0xA0, 0x22, 0x99, 0xA7, 0x4E, 0xA0, 0xDF, 0x62 }, + { 0xA2, 0x6C, 0x37, 0x5E, 0xB3, 0x19, 0x6E, 0x28, 0x3B, 0xEC, 0x60, 0x3D, 0xB6, 0xBB, 0xDA, 0xE2, + 0x49, 0x55, 0xE4, 0xBA, 0x91, 0x0C, 0xD4, 0x2D, 0x9E, 0xAC, 0x55, 0xCA, 0xC6, 0x10, 0x3A, 0xB9 }, }, { - { 0xE2, 0xF3, 0x9A, 0x9D, 0x48, 0xA3, 0x22, 0x10, 0x55, 0xB3, 0xC8, 0xA3, 0xEB, 0x14, 0x39, 0xD6, - 0xB8, 0x73, 0x01, 0x3E, 0xE4, 0xD0, 0x97, 0x12, 0x20, 0x64, 0xF2, 0x7E, 0xC0, 0x3D, 0xD4, 0xDA }, + { 0xA3, 0xA4, 0xFC, 0x03, 0xE1, 0x75, 0xF2, 0x68, 0x02, 0x57, 0x46, 0x34, 0xDE, 0x70, 0x7D, 0x2F, + 0x92, 0xF4, 0xD0, 0xCB, 0x90, 0xCD, 0xB6, 0x1D, 0xD1, 0x95, 0x8B, 0xCF, 0x0C, 0x55, 0x20, 0x86 }, }, { - { 0xE2, 0xF5, 0xDE, 0x57, 0xCD, 0x67, 0x24, 0x9A, 0x7E, 0x1F, 0x45, 0x5B, 0x85, 0xC0, 0x6F, 0x0D, - 0x80, 0x9E, 0x75, 0xA5, 0x5C, 0x6B, 0x05, 0x48, 0x16, 0xE0, 0x19, 0x89, 0x9A, 0x3A, 0x02, 0xFF }, + { 0xA6, 0x62, 0xFC, 0x81, 0xC9, 0x09, 0x34, 0xB9, 0xB4, 0xD6, 0x30, 0xB5, 0xD8, 0x2E, 0x86, 0xF2, + 0x36, 0x3E, 0xC1, 0x5C, 0xCF, 0xCD, 0xAF, 0xA7, 0xA2, 0x0C, 0x9B, 0x4E, 0x3A, 0x90, 0x0D, 0xD1 }, }, { - { 0xE3, 0x1F, 0xA0, 0xBD, 0xE8, 0x58, 0x9E, 0xDD, 0xDA, 0x1C, 0x5D, 0x1A, 0xA9, 0xC5, 0x81, 0x86, - 0xC3, 0x14, 0x36, 0x85, 0x67, 0xBD, 0xF9, 0xDC, 0xD5, 0x37, 0xAA, 0xE3, 0xCF, 0xF8, 0x77, 0x52 }, + { 0xA6, 0xA4, 0xA3, 0xF6, 0x1F, 0xA5, 0x8C, 0xE9, 0x70, 0xB4, 0x58, 0xB7, 0xC3, 0x7C, 0x05, 0x2E, + 0xAD, 0x1E, 0xB2, 0x0B, 0x85, 0x67, 0xE3, 0x51, 0xAD, 0x8E, 0x6F, 0xBA, 0x49, 0xC2, 0x69, 0x2C }, }, { - { 0xE3, 0xC8, 0xFC, 0x63, 0x7B, 0x7B, 0xB0, 0xCC, 0x67, 0x4A, 0x5A, 0x4C, 0x3B, 0x4D, 0x35, 0x62, - 0xEB, 0x8A, 0xA0, 0x0D, 0x7A, 0xD2, 0xC8, 0xA9, 0xC6, 0x37, 0x09, 0xE4, 0x51, 0x06, 0x52, 0xD5 }, + { 0xA6, 0xDE, 0x6C, 0x3B, 0x8C, 0x14, 0x05, 0xCB, 0xE1, 0x2D, 0xB4, 0x09, 0x97, 0x61, 0x71, 0xAC, + 0xB5, 0x1F, 0xB3, 0xDC, 0xFB, 0xB7, 0x6E, 0xE3, 0x84, 0x95, 0x39, 0xCD, 0x8A, 0xB0, 0x66, 0xDF }, }, { - { 0xE4, 0x6C, 0x8D, 0x7E, 0x4D, 0x59, 0x76, 0x83, 0x0B, 0xE3, 0x7A, 0x22, 0x25, 0x75, 0x55, 0x42, - 0x20, 0x81, 0xE1, 0xA8, 0x4B, 0x72, 0x6B, 0xCF, 0x17, 0xB0, 0x43, 0x54, 0x1E, 0x7C, 0xA7, 0x15 }, + { 0xA8, 0x53, 0xAD, 0xC1, 0xC2, 0x18, 0x59, 0xAF, 0x7C, 0x46, 0x2B, 0x4A, 0xA0, 0xA5, 0x74, 0xCA, + 0x9F, 0xEE, 0xFB, 0x18, 0x5A, 0x1F, 0xDB, 0xB6, 0xC1, 0x0E, 0x17, 0xD6, 0x01, 0xB7, 0x09, 0x8F }, }, { - { 0xE5, 0x3C, 0x7E, 0xA6, 0xB1, 0x2D, 0x3E, 0xCA, 0xBF, 0xB0, 0x2F, 0xE4, 0x88, 0x56, 0xE6, 0x38, - 0xBD, 0x0C, 0x6F, 0xEB, 0x35, 0x75, 0x7C, 0x19, 0xAE, 0xFA, 0x3D, 0x51, 0x92, 0x17, 0xE2, 0x9E }, + { 0xA8, 0xDF, 0xF0, 0x6A, 0x17, 0x35, 0xB4, 0x6D, 0x17, 0xDA, 0xEB, 0xC3, 0x43, 0x43, 0x18, 0x31, + 0x3B, 0x2D, 0x9E, 0x7C, 0x3E, 0xF4, 0x8F, 0x28, 0x53, 0x75, 0x35, 0x13, 0xE1, 0xB2, 0x53, 0xA8 }, }, { - { 0xE5, 0x6B, 0xF9, 0xFA, 0xF8, 0xEE, 0x91, 0xD8, 0x2F, 0xAF, 0xDF, 0x9B, 0x51, 0x20, 0x64, 0x7F, - 0x0D, 0x67, 0xF7, 0x18, 0xD7, 0x55, 0x49, 0x87, 0xFA, 0x06, 0x4B, 0xB2, 0x38, 0xCB, 0xE3, 0x9A }, + { 0xA8, 0xE3, 0x8C, 0x6E, 0xC0, 0x93, 0xF5, 0xAF, 0x53, 0x88, 0xF1, 0xE7, 0x66, 0xD7, 0x5F, 0xFB, + 0x57, 0xDD, 0xBE, 0x3E, 0x9D, 0xC2, 0xE0, 0xBE, 0x57, 0xBB, 0x88, 0x36, 0x46, 0xC5, 0xC0, 0x32 }, }, { - { 0xE5, 0x70, 0x93, 0x54, 0xAF, 0x05, 0x47, 0x26, 0x95, 0x3F, 0xC5, 0xC3, 0xBB, 0x13, 0x3E, 0x16, - 0xC7, 0xBB, 0xB7, 0xC3, 0x5A, 0xFC, 0xC3, 0x21, 0xCD, 0xA0, 0x35, 0x0B, 0xEB, 0x57, 0x17, 0x77 }, + { 0xA9, 0x0B, 0x8D, 0xE1, 0x7F, 0x6B, 0x68, 0x37, 0x56, 0x21, 0x2D, 0xB3, 0xAB, 0x34, 0x89, 0x6E, + 0x91, 0x70, 0x93, 0x11, 0x3E, 0x47, 0xCA, 0x35, 0x96, 0x2E, 0xAC, 0xCA, 0x9C, 0xB3, 0x86, 0xF0 }, }, { - { 0xE5, 0x9A, 0x43, 0xB8, 0x41, 0x20, 0x26, 0x84, 0x36, 0xC3, 0x5E, 0xD8, 0x6D, 0x73, 0x21, 0x38, - 0x5F, 0xB9, 0x1F, 0x89, 0x82, 0x83, 0x3E, 0x5F, 0x54, 0xD2, 0xAE, 0xE2, 0x09, 0x56, 0x2F, 0x2F }, + { 0xA9, 0x71, 0x2F, 0x85, 0xED, 0x2E, 0x25, 0xAD, 0xA5, 0x7D, 0xC1, 0xF0, 0xF8, 0x6D, 0xE1, 0x07, + 0xB5, 0xE2, 0xF0, 0x36, 0x09, 0x53, 0xF1, 0xED, 0x12, 0x5E, 0x37, 0x07, 0x59, 0x47, 0x1D, 0x09 }, }, { - { 0xE5, 0xAF, 0x76, 0xA5, 0xA0, 0xCC, 0x06, 0x75, 0x0E, 0x8C, 0x17, 0x76, 0x9A, 0xF3, 0x4D, 0x72, - 0x43, 0x76, 0x7F, 0xBE, 0x2A, 0x9F, 0x4A, 0xBC, 0x17, 0x08, 0xEA, 0x1C, 0x86, 0x2A, 0x38, 0xEB }, + { 0xAA, 0xEB, 0xFE, 0x2D, 0x21, 0xB7, 0xE5, 0x35, 0x1B, 0xB9, 0x99, 0x69, 0x44, 0x44, 0x19, 0xEF, + 0x21, 0xC9, 0x68, 0x8C, 0xE0, 0x53, 0x24, 0x88, 0x84, 0xCA, 0xB0, 0xB8, 0x95, 0x10, 0x30, 0xFF }, }, { - { 0xE5, 0xF1, 0x20, 0xB8, 0x78, 0x63, 0x43, 0x1A, 0xD8, 0x34, 0xD8, 0x47, 0x94, 0x86, 0x4A, 0x90, - 0x0E, 0x39, 0x30, 0xE0, 0xCE, 0xCE, 0xA1, 0x4B, 0x0D, 0x31, 0x33, 0xA9, 0x87, 0x74, 0x48, 0x89 }, + { 0xAB, 0x41, 0x28, 0x10, 0x9C, 0xAB, 0x8A, 0x58, 0x7C, 0x8F, 0xF4, 0xC7, 0xF6, 0x87, 0x34, 0x49, + 0x98, 0x18, 0xD1, 0x3F, 0x52, 0x26, 0x76, 0xD0, 0x66, 0xB3, 0x52, 0x17, 0x6F, 0xD2, 0x35, 0x96 }, }, { - { 0xE6, 0x17, 0x7C, 0x86, 0xB8, 0x35, 0x58, 0x0A, 0x7A, 0x09, 0x50, 0x34, 0x78, 0x98, 0xAB, 0x63, - 0xAF, 0x11, 0xEC, 0x99, 0x60, 0x64, 0x45, 0x4C, 0x04, 0x62, 0xBE, 0x5D, 0x4E, 0xD5, 0x22, 0x48 }, + { 0xAB, 0x80, 0xD9, 0xBA, 0x0A, 0xEF, 0xAD, 0x7B, 0xEC, 0xCE, 0x7F, 0x5E, 0x61, 0x59, 0x9A, 0xF5, + 0x26, 0x69, 0xBF, 0x59, 0x50, 0x7F, 0x8E, 0xF1, 0x99, 0x13, 0xC4, 0x2E, 0xE1, 0x29, 0xDA, 0xF0 }, }, { - { 0xE6, 0x44, 0xD1, 0x1C, 0x37, 0x07, 0x0F, 0x89, 0x69, 0x33, 0x08, 0x17, 0x8D, 0x6B, 0xE4, 0x95, - 0x94, 0x96, 0x92, 0xC1, 0xFB, 0xEB, 0x30, 0xED, 0x32, 0x9B, 0x74, 0x02, 0x7F, 0xCF, 0xFD, 0x48 }, + { 0xAB, 0xEB, 0x6A, 0xA0, 0xD1, 0xB0, 0xE0, 0x49, 0xD6, 0x9D, 0xF8, 0x3A, 0xDD, 0x19, 0xF7, 0x26, + 0x8A, 0x38, 0xDE, 0x6C, 0x00, 0x72, 0x60, 0x68, 0xC2, 0xEE, 0xE4, 0x55, 0x44, 0xF6, 0xD6, 0x7A }, }, { - { 0xE6, 0x7E, 0x9D, 0xC8, 0x17, 0x8E, 0x8D, 0xAD, 0x62, 0x91, 0x40, 0x22, 0xAE, 0x76, 0xD4, 0x75, - 0x1E, 0x9E, 0x26, 0xC6, 0x32, 0x68, 0xD3, 0xB9, 0xDF, 0xC8, 0x86, 0xE6, 0x7A, 0xAA, 0x9E, 0xEB }, + { 0xAC, 0x1B, 0x4C, 0x64, 0x6C, 0xAE, 0xFB, 0x10, 0x8A, 0x54, 0xCA, 0xB5, 0x4A, 0x96, 0xE9, 0x66, + 0x6E, 0x72, 0xA8, 0x20, 0x22, 0x44, 0xEF, 0x3D, 0x7C, 0xA9, 0x34, 0xDF, 0xCC, 0x24, 0xFC, 0xA7 }, }, { - { 0xE6, 0xA7, 0x10, 0x85, 0x6E, 0x43, 0x3D, 0x4F, 0x5F, 0xAA, 0xD2, 0xAE, 0xF4, 0x38, 0x6F, 0x17, - 0x46, 0x02, 0xC8, 0xFA, 0xE4, 0x50, 0x0F, 0x34, 0x40, 0xDD, 0x3C, 0x78, 0xF6, 0xE8, 0xDA, 0x6C }, + { 0xAC, 0x7C, 0x14, 0xB9, 0x56, 0x8F, 0x92, 0x07, 0x5A, 0xD4, 0xA3, 0xBA, 0x3D, 0x4B, 0x01, 0x84, + 0x91, 0xF3, 0x66, 0x1A, 0x37, 0x9B, 0x3D, 0xFE, 0xDD, 0x6F, 0xD3, 0xC3, 0x2E, 0xFA, 0x84, 0x7D }, }, { - { 0xE6, 0xB0, 0xF2, 0xE2, 0x5B, 0xD5, 0x16, 0xE4, 0xBB, 0xA3, 0x7A, 0x2B, 0xF2, 0xE2, 0xC7, 0x2A, - 0x1E, 0x53, 0x9C, 0x60, 0x30, 0xF3, 0xCF, 0x9B, 0xBE, 0x5E, 0x79, 0x72, 0x8D, 0x68, 0x64, 0x78 }, + { 0xAD, 0x69, 0x54, 0x5F, 0x9F, 0x85, 0x25, 0x5F, 0xE4, 0x16, 0x51, 0x3D, 0x94, 0xDB, 0x31, 0x50, + 0x5F, 0x38, 0x4B, 0x52, 0x3C, 0x2C, 0xA2, 0x6E, 0xDC, 0x0A, 0x54, 0x9A, 0x8F, 0x16, 0x26, 0xF9 }, }, { - { 0xE6, 0xC9, 0x32, 0x43, 0x98, 0x7B, 0x3B, 0xB2, 0x8A, 0xB8, 0x6F, 0xDD, 0x6B, 0xF4, 0xD9, 0xA5, - 0x94, 0xF8, 0xD5, 0xBC, 0xE3, 0xB2, 0xF6, 0xAF, 0x51, 0x97, 0x15, 0x53, 0x08, 0xC6, 0x03, 0x2D }, + { 0xAE, 0x03, 0x19, 0xFE, 0xA6, 0xA6, 0x5E, 0x84, 0xE8, 0x54, 0xB5, 0x15, 0x50, 0xEA, 0x44, 0x4F, + 0xA3, 0xB8, 0xBB, 0x50, 0xAE, 0x93, 0x74, 0x01, 0x3C, 0xFE, 0xF3, 0x88, 0x73, 0x5D, 0x0B, 0xD3 }, }, { - { 0xE6, 0xE5, 0x4D, 0xE7, 0xB4, 0x97, 0x54, 0xD3, 0x57, 0xB0, 0xA8, 0xD9, 0x4A, 0x4D, 0x4F, 0x80, - 0xAC, 0xD1, 0x99, 0x4C, 0xCC, 0x1C, 0x99, 0x08, 0xE9, 0xF0, 0xD9, 0x21, 0xE4, 0x28, 0xB8, 0x38 }, + { 0xAE, 0x4D, 0xF3, 0x97, 0x9B, 0x74, 0x27, 0x34, 0xA3, 0x39, 0xC4, 0x70, 0x1D, 0x5E, 0x13, 0x21, + 0x26, 0x3F, 0xF4, 0x4E, 0x67, 0x56, 0x49, 0x05, 0xF4, 0x9E, 0x25, 0x34, 0x62, 0xB8, 0x02, 0x25 }, }, { - { 0xE7, 0x0C, 0xBB, 0x7A, 0xF7, 0xAA, 0x20, 0xB9, 0x89, 0x0B, 0xC1, 0xF9, 0xFA, 0x00, 0xD8, 0x09, - 0x0B, 0x5A, 0xC9, 0x82, 0x5E, 0xA9, 0xD2, 0xFD, 0xF7, 0x7C, 0xA4, 0xDA, 0xE9, 0x44, 0x51, 0xB2 }, + { 0xAF, 0x1F, 0x37, 0x1F, 0x34, 0x84, 0x57, 0x51, 0x65, 0x2D, 0xC7, 0x48, 0x23, 0xF3, 0x01, 0x5C, + 0x5A, 0x11, 0xCA, 0x65, 0x3F, 0x28, 0x70, 0x1E, 0xDD, 0x4A, 0x7E, 0x0D, 0x23, 0x17, 0x1B, 0xBB }, }, { - { 0xE7, 0x5D, 0x32, 0x90, 0xA6, 0x9A, 0xB5, 0x96, 0xEE, 0x17, 0x9D, 0xC1, 0x34, 0xAA, 0x07, 0x1E, - 0x69, 0xFD, 0x98, 0x25, 0xFC, 0x06, 0x2E, 0x33, 0x8B, 0xA2, 0x23, 0x5E, 0xE3, 0x25, 0x56, 0xD2 }, + { 0xAF, 0x6B, 0x80, 0x51, 0x47, 0x14, 0x0A, 0x0E, 0x41, 0x81, 0xD8, 0x6A, 0x7E, 0x8F, 0x07, 0x69, + 0xB6, 0x1D, 0x46, 0xD7, 0xB6, 0xFA, 0xC6, 0xE6, 0xF9, 0x59, 0x6D, 0xE9, 0x4A, 0xA8, 0xE2, 0xE8 }, }, { - { 0xE7, 0xD5, 0x73, 0x8A, 0xCD, 0x7F, 0x56, 0x3D, 0xD6, 0x8E, 0x86, 0x75, 0xC8, 0x78, 0xC6, 0xC6, - 0x80, 0x02, 0xD6, 0x40, 0x60, 0x46, 0xAF, 0x40, 0x56, 0x01, 0x3A, 0xA4, 0x6E, 0xA0, 0x37, 0x54 }, + { 0xB0, 0x5C, 0x14, 0x33, 0x61, 0x75, 0x9B, 0xE1, 0x52, 0xFD, 0x76, 0xA5, 0xFF, 0xA4, 0x87, 0x2D, + 0xD4, 0x2E, 0xA0, 0x60, 0xAE, 0x40, 0xA3, 0x83, 0x13, 0xB7, 0xB5, 0x4A, 0xEC, 0x06, 0x73, 0xC2 }, }, { - { 0xE7, 0xFD, 0x58, 0x39, 0x86, 0x80, 0xFA, 0xBD, 0x43, 0x21, 0xCD, 0xBE, 0x23, 0x33, 0xCB, 0xC2, - 0xC5, 0x4A, 0x32, 0xFF, 0x76, 0x6C, 0x4A, 0x94, 0x43, 0xC3, 0x6E, 0x2C, 0xEB, 0x46, 0xC5, 0xF0 }, + { 0xB0, 0xE0, 0xE1, 0x6C, 0x5F, 0x69, 0x1F, 0x66, 0xA9, 0x57, 0x3B, 0xD3, 0xCF, 0x43, 0xF9, 0xDF, + 0xD2, 0xAD, 0x3E, 0x56, 0x15, 0x54, 0x63, 0x7F, 0x1E, 0x7B, 0x71, 0x91, 0x4D, 0x62, 0x73, 0x38 }, }, { - { 0xE8, 0x02, 0xCB, 0x32, 0x13, 0x85, 0x51, 0xE5, 0x57, 0x44, 0xD4, 0x11, 0xC4, 0x8C, 0x7D, 0x5F, - 0x47, 0xB8, 0x15, 0x47, 0xB1, 0x23, 0x47, 0x90, 0xDA, 0x5D, 0xA4, 0x33, 0x97, 0x2E, 0x57, 0x27 }, + { 0xB2, 0xDC, 0x86, 0x25, 0x6C, 0xCF, 0xF4, 0xBB, 0x14, 0xFD, 0x70, 0x27, 0x9F, 0xCC, 0x3C, 0xE9, + 0x25, 0xC5, 0x1F, 0xB7, 0x17, 0xE5, 0x87, 0x6F, 0x29, 0x1B, 0xA1, 0x70, 0x73, 0x43, 0x85, 0x68 }, }, { - { 0xE8, 0x16, 0xF9, 0x92, 0x94, 0xA1, 0x3A, 0xC2, 0xFA, 0x2B, 0xFB, 0x76, 0xC2, 0x2D, 0xFA, 0x71, - 0xBC, 0x3D, 0xA4, 0x8F, 0x67, 0x1E, 0xF7, 0x7C, 0x00, 0xAA, 0x8E, 0x45, 0x9B, 0x7C, 0xC8, 0x2A }, + { 0xB3, 0x0D, 0x88, 0x44, 0x30, 0x43, 0xF5, 0xF3, 0x72, 0x32, 0xBB, 0x9B, 0xAC, 0xB9, 0x94, 0xC5, + 0xBA, 0xE9, 0x3A, 0x46, 0xFC, 0x87, 0xF1, 0x51, 0x29, 0xC9, 0x74, 0x69, 0xA5, 0x81, 0x4E, 0xCA }, }, { - { 0xE8, 0x1A, 0x87, 0x45, 0xAD, 0x86, 0xF6, 0x5F, 0xA0, 0xD8, 0x51, 0xFC, 0xB7, 0x2E, 0x3E, 0xF5, - 0x4D, 0x51, 0xBC, 0x60, 0xB9, 0x68, 0x0C, 0xB2, 0x5E, 0xB2, 0xF3, 0xAC, 0x44, 0xEA, 0xA7, 0xA4 }, + { 0xB3, 0x1A, 0xF0, 0xC2, 0xE5, 0x1E, 0xA2, 0x1C, 0x91, 0x04, 0xF9, 0x4F, 0xAA, 0x66, 0xE0, 0xCC, + 0xC0, 0x41, 0x34, 0xD5, 0x80, 0x9A, 0x2A, 0x26, 0x70, 0xA3, 0xB7, 0xBC, 0x7D, 0xD9, 0x64, 0xF8 }, }, { - { 0xE8, 0x21, 0x3C, 0x45, 0x51, 0x81, 0x61, 0xBC, 0x36, 0x37, 0x3D, 0xCD, 0x2D, 0x4B, 0x21, 0xB7, - 0x6A, 0x7C, 0x06, 0x6D, 0xF5, 0x52, 0x6E, 0x88, 0x8B, 0x6E, 0xED, 0x09, 0xA9, 0xEE, 0xD0, 0x62 }, + { 0xB3, 0xE6, 0x42, 0x06, 0x6E, 0x41, 0x78, 0x67, 0xD9, 0x0F, 0xB9, 0xB2, 0xBA, 0x15, 0x41, 0x98, + 0xA5, 0xC5, 0xF6, 0xCC, 0x82, 0x9B, 0x51, 0x39, 0xDF, 0xD6, 0x91, 0xE5, 0x1A, 0xD3, 0x74, 0xAD }, }, { - { 0xE8, 0x68, 0xE4, 0xE2, 0x52, 0xDC, 0x95, 0x87, 0x75, 0x75, 0x6E, 0xC0, 0x10, 0xFA, 0xCF, 0xB8, - 0x79, 0x63, 0x6A, 0x35, 0x27, 0xB3, 0xB8, 0xDB, 0x9B, 0xF9, 0x26, 0x03, 0x6A, 0xD4, 0x0E, 0x92 }, + { 0xB3, 0xF4, 0xB1, 0x6F, 0x8E, 0xCE, 0xBB, 0x41, 0x47, 0x4F, 0x92, 0x4F, 0xEE, 0xF9, 0xB0, 0xBD, + 0x97, 0x9B, 0x36, 0x36, 0xC3, 0x4F, 0xF2, 0x72, 0x3F, 0x67, 0x3C, 0x8E, 0xEE, 0x2A, 0xF1, 0x52 }, }, { - { 0xE8, 0x6E, 0xE6, 0x9D, 0x51, 0xBE, 0x64, 0xF8, 0x28, 0xFC, 0x22, 0xCC, 0xE5, 0xBC, 0xC1, 0x1D, - 0x24, 0xA5, 0xF1, 0x77, 0xF9, 0xBA, 0x99, 0x51, 0x92, 0x71, 0xA4, 0xF3, 0x9F, 0x0C, 0x51, 0x7C }, + { 0xB4, 0xD4, 0x67, 0xFC, 0x5E, 0x97, 0xDB, 0x25, 0xA1, 0xFD, 0xB0, 0x06, 0xD2, 0x77, 0x66, 0xB9, + 0x99, 0x5B, 0xB9, 0xC7, 0x7B, 0x66, 0x43, 0x97, 0x08, 0xA4, 0x59, 0xB0, 0x43, 0xD0, 0x33, 0x24 }, }, { - { 0xE8, 0xA6, 0x09, 0xEC, 0x44, 0xF9, 0x3C, 0x12, 0xE0, 0x81, 0xE5, 0x94, 0x3B, 0x5E, 0xA0, 0x48, - 0x68, 0x14, 0x48, 0x33, 0x32, 0x5D, 0xAA, 0x64, 0x4F, 0x3F, 0x9F, 0xB7, 0x6A, 0xA2, 0x77, 0xC8 }, + { 0xB4, 0xED, 0xCD, 0x6F, 0x8A, 0x01, 0x82, 0xB7, 0x17, 0xF0, 0x6F, 0xE1, 0xD7, 0xAC, 0x9C, 0x62, + 0x33, 0xD4, 0x38, 0x22, 0xE9, 0xFD, 0x14, 0xDB, 0x98, 0xF7, 0xF8, 0x4E, 0x32, 0x79, 0x6D, 0x08 }, }, { - { 0xE9, 0x52, 0x76, 0x76, 0x30, 0x2F, 0xFB, 0x14, 0x91, 0x15, 0x65, 0x19, 0x28, 0xF0, 0x4D, 0x9C, - 0x96, 0xAF, 0xEF, 0x18, 0xB5, 0x72, 0x12, 0x37, 0x52, 0x75, 0x4B, 0x38, 0xA9, 0x7C, 0x8E, 0xF0 }, + { 0xB5, 0xE5, 0xDC, 0xDE, 0xCB, 0x8D, 0xEB, 0x27, 0x13, 0x4F, 0x02, 0xA5, 0x18, 0x79, 0x43, 0x16, + 0xF0, 0x8F, 0xAF, 0x9C, 0x2B, 0x1F, 0xDA, 0xD6, 0xD4, 0x86, 0x61, 0xF5, 0x7E, 0xA6, 0x45, 0xD9 }, }, { - { 0xE9, 0x65, 0xDB, 0x91, 0x44, 0x8E, 0xFF, 0xC5, 0x3D, 0xEF, 0x1B, 0x72, 0x68, 0xA2, 0xF5, 0xAB, - 0x95, 0xB1, 0x4A, 0x2A, 0x90, 0x2C, 0x6A, 0xC9, 0xB2, 0x54, 0xEC, 0xAF, 0xC7, 0x9F, 0x08, 0xD8 }, + { 0xB5, 0xEF, 0x42, 0xC4, 0xBC, 0xED, 0xF1, 0x7B, 0xEC, 0xC7, 0x5B, 0xF4, 0x63, 0x66, 0x49, 0xCE, + 0xBF, 0xF8, 0x71, 0x1B, 0xCE, 0xFF, 0xFA, 0x69, 0x5C, 0xC2, 0x52, 0xFA, 0x57, 0x4D, 0x42, 0x18 }, }, { - { 0xE9, 0xC2, 0x8F, 0x7A, 0x33, 0xFB, 0xC5, 0xB4, 0x49, 0xC9, 0x5A, 0x88, 0x47, 0x1D, 0x3F, 0x71, - 0xFB, 0x34, 0x7A, 0x02, 0xCE, 0xB0, 0x5E, 0xB0, 0xE7, 0x1C, 0x7B, 0xB7, 0x46, 0x45, 0xC8, 0x92 }, + { 0xB6, 0x82, 0x3C, 0x9D, 0xBC, 0x8E, 0x8C, 0x05, 0x4B, 0xCF, 0x60, 0xF2, 0x38, 0x21, 0xAC, 0x6C, + 0x58, 0x19, 0x73, 0x51, 0xEA, 0xCF, 0xA5, 0x57, 0x4C, 0xF0, 0x41, 0xB4, 0xCE, 0x6B, 0x84, 0x04 }, }, { - { 0xE9, 0xF5, 0x71, 0xC7, 0x71, 0x64, 0xAB, 0xEA, 0xE1, 0x85, 0x28, 0x37, 0x5C, 0xFD, 0xC7, 0x21, - 0x9A, 0x6B, 0xDE, 0x46, 0x1B, 0x19, 0x73, 0xBE, 0x2B, 0xB8, 0xBD, 0xF0, 0xDA, 0x78, 0xB2, 0xB4 }, + { 0xB7, 0x06, 0xDE, 0x1B, 0xD1, 0xEE, 0x2F, 0x4C, 0xEC, 0x6C, 0xE0, 0x92, 0x02, 0x2B, 0x49, 0x32, + 0x81, 0xE2, 0x9A, 0x21, 0x73, 0x50, 0x8C, 0x9B, 0xD0, 0xFB, 0xC2, 0xC3, 0xD9, 0x68, 0xE3, 0xE7 }, }, { - { 0xEA, 0x2E, 0x8C, 0x23, 0xAA, 0x7C, 0xC3, 0x7D, 0x64, 0xCF, 0xC3, 0x03, 0xDD, 0x9F, 0x3F, 0x92, - 0x1B, 0xAE, 0x11, 0x8C, 0xA3, 0xDF, 0x81, 0xE5, 0x92, 0xE3, 0x0B, 0xBB, 0x03, 0x71, 0x4D, 0x96 }, + { 0xB8, 0x74, 0x36, 0x95, 0x1C, 0xEC, 0x37, 0x7E, 0xEF, 0x73, 0xDE, 0x4B, 0x74, 0xF2, 0x83, 0xC4, + 0x2B, 0x2C, 0xCB, 0x1C, 0xA3, 0x7C, 0x5B, 0x30, 0xAA, 0xD6, 0x55, 0xA7, 0x40, 0x1A, 0x3D, 0x2F }, }, { - { 0xEA, 0x51, 0x8B, 0x42, 0x91, 0x89, 0x39, 0xA6, 0x22, 0x63, 0xA7, 0xCC, 0xD2, 0xA9, 0xB5, 0x44, - 0x9C, 0x58, 0x1C, 0x2E, 0xA9, 0x9C, 0x2B, 0x74, 0x3F, 0x6F, 0x18, 0x3D, 0xFC, 0x19, 0xED, 0xFF }, + { 0xB9, 0x8D, 0x83, 0x38, 0x55, 0xC3, 0x67, 0x88, 0x62, 0xB6, 0x2F, 0x36, 0x50, 0xDB, 0x00, 0xA3, + 0x45, 0xF4, 0x6A, 0x0E, 0x8E, 0x01, 0x1A, 0x20, 0x01, 0x3F, 0xD8, 0xED, 0xCE, 0x25, 0x27, 0x0D }, }, { - { 0xEA, 0x5A, 0xB6, 0x6C, 0xAF, 0xDE, 0x63, 0x38, 0xC0, 0x67, 0x8D, 0x74, 0x54, 0xD0, 0x79, 0x6D, - 0xDE, 0xA0, 0xD2, 0x84, 0xDD, 0xAA, 0x79, 0x4D, 0x04, 0x42, 0x0E, 0xDA, 0x97, 0x71, 0xC5, 0x1A }, + { 0xBA, 0x51, 0xAF, 0xF5, 0xD5, 0xD3, 0x10, 0x5F, 0x34, 0xA2, 0xB3, 0x3A, 0x83, 0xE3, 0xAD, 0xFD, + 0x12, 0xD7, 0x9C, 0xA6, 0x05, 0x90, 0x9D, 0x96, 0x03, 0x3E, 0x32, 0xA5, 0xCF, 0x2F, 0x71, 0xF6 }, }, { - { 0xEA, 0x76, 0x8A, 0xF7, 0x9B, 0x07, 0xCE, 0x21, 0xC2, 0x64, 0x90, 0xE9, 0x4B, 0xC0, 0x7A, 0x2A, - 0xAE, 0x96, 0xBD, 0x60, 0xA4, 0x19, 0xE9, 0x8B, 0x03, 0x63, 0x87, 0xF2, 0x10, 0x2D, 0x28, 0xF6 }, + { 0xBB, 0x5C, 0xB3, 0x78, 0xB7, 0xB9, 0x48, 0x7F, 0xA6, 0x1B, 0xC0, 0x91, 0x3D, 0xA1, 0xDF, 0x26, + 0xA1, 0xCF, 0xEF, 0xF7, 0x45, 0x2D, 0x9B, 0xA3, 0x6C, 0xAC, 0x47, 0xA8, 0x5C, 0x7F, 0xF3, 0x48 }, }, { - { 0xEA, 0x81, 0xEE, 0xEB, 0x60, 0x6B, 0xC9, 0x1C, 0x0E, 0x07, 0xDA, 0x1F, 0x86, 0x04, 0x89, 0x3C, - 0x1D, 0x17, 0x84, 0x60, 0xDE, 0xE8, 0x7E, 0xD5, 0x37, 0xFF, 0x8D, 0x85, 0xE4, 0x00, 0x02, 0xF5 }, + { 0xBC, 0x14, 0x2E, 0xBA, 0xC2, 0x78, 0xA8, 0xFE, 0x8C, 0xA8, 0xBC, 0x2C, 0x62, 0xFB, 0xCC, 0x40, + 0x17, 0xFF, 0x24, 0x96, 0x98, 0xBE, 0xED, 0xFB, 0x1E, 0xF3, 0x6F, 0x37, 0x5F, 0xB3, 0x9F, 0x72 }, }, { - { 0xEA, 0xC1, 0x29, 0xDC, 0x3A, 0xE7, 0xF5, 0xCC, 0x0F, 0x13, 0x46, 0x57, 0x0D, 0x06, 0x92, 0x6A, - 0x85, 0x01, 0xB0, 0xD2, 0x06, 0x9B, 0xF7, 0x17, 0xAF, 0x69, 0xD1, 0xBE, 0x0E, 0x3E, 0x30, 0xDE }, + { 0xBD, 0x2E, 0x2F, 0x37, 0xC9, 0x66, 0xC3, 0x86, 0xD9, 0x70, 0x44, 0xFD, 0xE3, 0xE3, 0xF9, 0x00, + 0xFB, 0x1A, 0x0B, 0x04, 0x03, 0xB5, 0x81, 0x72, 0x5F, 0x34, 0xE3, 0xC1, 0x90, 0x05, 0x60, 0x56 }, }, { - { 0xEB, 0x11, 0x63, 0xAA, 0xEF, 0xE8, 0xFD, 0x88, 0xE1, 0x32, 0x7B, 0x48, 0xA9, 0xC0, 0x06, 0x2E, - 0x06, 0xF0, 0xA6, 0xEA, 0xA0, 0xA0, 0x18, 0x24, 0x7F, 0x9F, 0xA4, 0xE3, 0x4E, 0x3A, 0x47, 0x4C }, + { 0xBE, 0xB9, 0x09, 0x0C, 0x92, 0xD1, 0x6B, 0xD0, 0x5A, 0xF3, 0x91, 0x5A, 0x39, 0xCC, 0x2A, 0xFA, + 0x9F, 0x6A, 0x8A, 0x6F, 0xBE, 0xD4, 0xFE, 0x54, 0xD9, 0xDE, 0x32, 0x49, 0x23, 0xB3, 0x93, 0x5A }, }, { - { 0xEB, 0x43, 0x76, 0xB1, 0xD2, 0x38, 0x2A, 0xC1, 0xC3, 0xEE, 0x27, 0xBE, 0x86, 0x67, 0xEC, 0xF5, - 0xAB, 0x36, 0x25, 0x5A, 0x3C, 0x36, 0xC7, 0x22, 0x74, 0x33, 0x8A, 0xD7, 0x17, 0x56, 0x25, 0x11 }, + { 0xBF, 0x38, 0xE6, 0xAE, 0x32, 0x0F, 0x69, 0x16, 0x16, 0x0D, 0xA6, 0x06, 0x86, 0x83, 0xBF, 0x49, + 0xF2, 0xB2, 0x2B, 0x25, 0x24, 0x84, 0x63, 0x68, 0xF5, 0x04, 0x51, 0x81, 0x52, 0x40, 0x25, 0x9A }, }, { - { 0xEB, 0x5B, 0x21, 0x0F, 0x76, 0xA3, 0xC4, 0x5E, 0x5A, 0x76, 0x07, 0x64, 0x3E, 0x15, 0x26, 0x0D, - 0x1C, 0x93, 0xFD, 0x9B, 0xE0, 0xFA, 0xB1, 0x0B, 0x76, 0xDC, 0x96, 0x86, 0xF6, 0x54, 0xC6, 0xE5 }, + { 0xBF, 0x60, 0xAE, 0xB3, 0x91, 0xC0, 0xFB, 0xD0, 0x49, 0x53, 0x52, 0x6D, 0xA9, 0xFD, 0x59, 0x96, + 0x9A, 0x82, 0xF1, 0xEE, 0x81, 0xA7, 0x97, 0x98, 0xA4, 0x17, 0x1E, 0x14, 0x59, 0x39, 0x19, 0x67 }, }, { - { 0xEB, 0x89, 0x84, 0xD1, 0xA9, 0xFE, 0x26, 0x7C, 0x07, 0x9A, 0xE2, 0xF2, 0xF1, 0x6F, 0x01, 0xE6, - 0x0C, 0x4C, 0xEA, 0x94, 0x34, 0xC5, 0x29, 0x7A, 0x71, 0x88, 0xAA, 0x09, 0x25, 0x1D, 0x03, 0xE0 }, + { 0xBF, 0xF4, 0x3A, 0x97, 0x20, 0x48, 0x2D, 0x13, 0x4C, 0xD5, 0xEE, 0x8A, 0x88, 0x99, 0xE1, 0xA7, + 0x36, 0xBF, 0x54, 0xA2, 0xB7, 0x86, 0x26, 0x9C, 0x0D, 0xCB, 0x8B, 0xA1, 0x92, 0xA8, 0x1F, 0xA4 }, }, { - { 0xEB, 0xB7, 0xC4, 0x12, 0x58, 0x17, 0x82, 0x26, 0xAD, 0x37, 0xCC, 0xAF, 0x01, 0x1F, 0xCF, 0xF0, - 0x54, 0xB7, 0x7A, 0xC4, 0x9F, 0xCE, 0x28, 0x13, 0x5F, 0x5A, 0xFC, 0x51, 0x63, 0x15, 0xEA, 0x4D }, + { 0xC0, 0x09, 0xA1, 0xBE, 0x5B, 0xE8, 0xAF, 0xB5, 0x25, 0x8E, 0x12, 0x85, 0x5C, 0x64, 0xD0, 0x4D, + 0x13, 0xE8, 0xCC, 0xC4, 0x7B, 0x02, 0xBF, 0x3B, 0x51, 0xC6, 0xE1, 0x18, 0x05, 0xAE, 0xEC, 0xEB }, }, { - { 0xEC, 0x01, 0x78, 0xD1, 0xCA, 0x3B, 0x94, 0x52, 0xAA, 0x5C, 0xD5, 0xD3, 0x75, 0x45, 0x6B, 0xAB, - 0xF0, 0xDC, 0x0E, 0xD2, 0x29, 0x91, 0x5D, 0x1A, 0x8F, 0x49, 0x6D, 0xF2, 0xA2, 0xA0, 0x98, 0x71 }, + { 0xC0, 0x9F, 0xFA, 0x0E, 0xDD, 0x16, 0xBA, 0x55, 0xF2, 0x3C, 0xEA, 0xF7, 0x2B, 0x11, 0x34, 0xE9, + 0x28, 0xDB, 0xA1, 0xC2, 0x34, 0x5A, 0x5A, 0xB5, 0x63, 0x1E, 0x25, 0x41, 0x24, 0x05, 0x4A, 0xDB }, }, { - { 0xEC, 0x27, 0x05, 0x63, 0xB0, 0x5A, 0x06, 0xE5, 0xAA, 0xA5, 0xE6, 0xD5, 0xBB, 0xCC, 0x17, 0xCD, - 0x1C, 0xB5, 0xB2, 0xA9, 0x4D, 0x93, 0x84, 0x75, 0xF1, 0x58, 0x17, 0x6F, 0x4D, 0x84, 0xF4, 0x53 }, + { 0xC0, 0xAB, 0xD1, 0xC3, 0x56, 0x2F, 0xBC, 0x7F, 0xF7, 0xBD, 0x38, 0x95, 0x54, 0x60, 0xC3, 0xFC, + 0x43, 0x55, 0x0D, 0x97, 0x7F, 0x25, 0xE3, 0x43, 0xD4, 0x9C, 0xD4, 0xAF, 0xAD, 0xF2, 0x09, 0x3C }, }, { - { 0xEC, 0x4B, 0xBD, 0xEB, 0x15, 0x12, 0x1D, 0x96, 0x76, 0x4D, 0x6C, 0x01, 0xB2, 0x7E, 0xD5, 0xAE, - 0x86, 0x46, 0x5C, 0x46, 0xD5, 0xA4, 0x0E, 0x34, 0xAE, 0xFC, 0x09, 0x2D, 0x3E, 0x8B, 0xB1, 0x76 }, + { 0xC0, 0xFE, 0xB7, 0x2A, 0x5F, 0x33, 0x16, 0x5C, 0x0D, 0xC7, 0xC4, 0x24, 0x7E, 0x23, 0xF3, 0x8C, + 0xC6, 0x1F, 0x25, 0x24, 0x42, 0xB2, 0xF6, 0x13, 0x40, 0x92, 0xDE, 0x3B, 0xAD, 0x7E, 0x45, 0x0D }, }, { - { 0xEC, 0x5F, 0xA4, 0x73, 0x12, 0x1E, 0x3F, 0x49, 0xF0, 0x95, 0x3A, 0x2A, 0x91, 0x83, 0x39, 0xE3, - 0x6F, 0x3C, 0xB6, 0xB8, 0xD8, 0xB8, 0x9E, 0x91, 0x74, 0x23, 0xDA, 0xCE, 0xAC, 0xE6, 0xD5, 0x8A }, + { 0xC1, 0x77, 0x12, 0x97, 0xA4, 0xE8, 0xDC, 0x53, 0x75, 0x19, 0x5E, 0x1B, 0x63, 0x04, 0x2B, 0x59, + 0x19, 0x09, 0xF1, 0xD7, 0xEB, 0x5D, 0x25, 0xF2, 0x97, 0xAE, 0x7A, 0x61, 0xC1, 0x53, 0x8F, 0x9E }, }, { - { 0xEC, 0x79, 0x76, 0xC2, 0xB8, 0x10, 0x31, 0xF5, 0x88, 0x49, 0x5B, 0xC1, 0x9F, 0x51, 0xB0, 0x36, - 0xF8, 0x4F, 0x48, 0x1D, 0x9B, 0x15, 0x73, 0xD9, 0x8A, 0x7C, 0x32, 0x67, 0xC0, 0x63, 0x1E, 0x00 }, + { 0xC1, 0x86, 0xBE, 0x26, 0xE4, 0x47, 0x89, 0x7C, 0x48, 0x3C, 0x43, 0xFD, 0xC0, 0x86, 0xE2, 0x60, + 0x74, 0x17, 0xEB, 0x3E, 0xA7, 0x88, 0xEC, 0x03, 0x10, 0xA7, 0x9D, 0xA9, 0x24, 0x1D, 0x16, 0xDE }, }, { - { 0xEC, 0xCE, 0x4E, 0x52, 0x82, 0xFD, 0x2E, 0xE0, 0x03, 0xA4, 0x03, 0x2C, 0x80, 0xD3, 0x32, 0x1A, - 0x69, 0x47, 0x25, 0x98, 0x94, 0x59, 0x09, 0xCB, 0x25, 0x55, 0x7A, 0xA8, 0x47, 0x74, 0x2D, 0xDF }, + { 0xC1, 0xDE, 0x5F, 0xA3, 0x92, 0x13, 0x68, 0x58, 0x11, 0xA5, 0xBA, 0x93, 0x12, 0x1D, 0xE7, 0xA3, + 0x95, 0x98, 0x4E, 0x84, 0x44, 0x4E, 0x58, 0xF1, 0x63, 0xB7, 0xA6, 0x20, 0xAE, 0x3B, 0xBF, 0xA8 }, }, { - { 0xED, 0x2B, 0x81, 0xA0, 0xF8, 0xF1, 0x46, 0x5E, 0xA2, 0xF4, 0x17, 0xA4, 0xE8, 0x34, 0xC2, 0x2A, - 0x22, 0xEE, 0x7A, 0x9D, 0xDF, 0x59, 0xA8, 0x3B, 0x89, 0x82, 0xB0, 0xE1, 0x07, 0x19, 0x64, 0x42 }, + { 0xC2, 0xAD, 0xDF, 0x99, 0xCF, 0xC4, 0x2C, 0xE0, 0xE5, 0xA0, 0x93, 0xBC, 0xBF, 0x87, 0x40, 0x7C, + 0x61, 0x1F, 0x9D, 0x0A, 0xBF, 0x2A, 0x35, 0xD6, 0xE8, 0x03, 0xA3, 0x8E, 0xCB, 0x92, 0xC7, 0xB3 }, }, { - { 0xED, 0x50, 0xC1, 0x22, 0xAA, 0x2A, 0x49, 0x53, 0xF0, 0x51, 0xB7, 0x81, 0x41, 0x33, 0xAB, 0xBC, - 0x37, 0xA0, 0xC2, 0x21, 0x1B, 0xF7, 0x44, 0x0D, 0x75, 0xB3, 0x5E, 0xE5, 0x4E, 0x5A, 0x98, 0x86 }, + { 0xC2, 0xE7, 0x92, 0x11, 0x6A, 0x05, 0x00, 0x00, 0xBD, 0x47, 0x59, 0x1D, 0x93, 0x04, 0x71, 0xE6, + 0x17, 0x4C, 0x93, 0x85, 0xF5, 0xDC, 0x32, 0xB7, 0x62, 0x31, 0x65, 0x5F, 0xC8, 0x5E, 0x22, 0xE2 }, }, { - { 0xED, 0x57, 0xFB, 0x37, 0xD8, 0x73, 0xD5, 0x26, 0xB1, 0xB6, 0xFD, 0xC3, 0x38, 0x0F, 0xA9, 0x30, - 0x0D, 0xA6, 0x25, 0x81, 0x4C, 0x35, 0xF1, 0x0A, 0x04, 0x93, 0xEE, 0x19, 0xFF, 0x09, 0x60, 0x29 }, + { 0xC3, 0x79, 0x03, 0xC5, 0x3A, 0xE6, 0x02, 0xEC, 0x96, 0x9E, 0xC3, 0x3F, 0x63, 0xFE, 0x9A, 0xB2, + 0x0C, 0x39, 0x5F, 0x83, 0x0D, 0x30, 0xE4, 0xEE, 0x9D, 0x8D, 0xD9, 0x05, 0x92, 0x1E, 0xC1, 0xA0 }, }, { - { 0xED, 0x5B, 0xB8, 0x6A, 0x95, 0xA5, 0xFE, 0x2B, 0x17, 0x08, 0xF2, 0x56, 0x75, 0x4A, 0x89, 0xC4, - 0x29, 0x67, 0x9B, 0x30, 0x75, 0x8E, 0xE0, 0x12, 0x2B, 0x9E, 0x50, 0x85, 0x8D, 0xE2, 0x10, 0x4B }, + { 0xC3, 0xCF, 0x54, 0x16, 0xA5, 0x31, 0xAF, 0x4B, 0xFA, 0xE8, 0x9C, 0x45, 0x14, 0x3F, 0x20, 0xCC, + 0x1B, 0x3E, 0x18, 0x1D, 0x29, 0xC2, 0xD0, 0xE8, 0xFF, 0x7D, 0x3F, 0x2A, 0x66, 0xB1, 0x82, 0xFE }, }, { - { 0xED, 0x6D, 0xDA, 0xE4, 0xF4, 0xAF, 0xCE, 0x6B, 0xAF, 0x3A, 0x63, 0x7D, 0x89, 0x0A, 0x0D, 0x65, - 0x75, 0x3E, 0x45, 0x97, 0x14, 0x5A, 0xF8, 0x97, 0x53, 0x9B, 0xF9, 0xF7, 0xD3, 0x42, 0xA1, 0xD1 }, + { 0xC4, 0x98, 0xA1, 0xB6, 0x9F, 0x54, 0x40, 0x86, 0x17, 0x47, 0x47, 0x71, 0x5A, 0x27, 0x4D, 0x3F, + 0xB5, 0x90, 0x19, 0xBE, 0x09, 0x21, 0x31, 0xBC, 0xFA, 0xA8, 0x3A, 0x39, 0x5F, 0x7E, 0x57, 0x3C }, }, { - { 0xED, 0xC1, 0xBF, 0x3E, 0xFB, 0xF7, 0xE1, 0xD9, 0x5E, 0x19, 0xC5, 0x5E, 0xCA, 0xE7, 0x7E, 0x83, - 0x69, 0x46, 0xAB, 0x0A, 0x26, 0xA7, 0x8E, 0x32, 0xA4, 0x72, 0xC9, 0xD3, 0x6C, 0x69, 0xCE, 0xCD }, + { 0xC4, 0xE2, 0x8D, 0xD8, 0x3F, 0xE3, 0x0C, 0x96, 0x33, 0x8C, 0xEF, 0x77, 0x73, 0xC6, 0xDF, 0xCA, + 0x6C, 0xE4, 0xFA, 0x96, 0x41, 0xBE, 0xAB, 0x38, 0x05, 0xA8, 0xEF, 0xB6, 0xCD, 0xC3, 0xCF, 0x0A }, }, { - { 0xED, 0xF4, 0xDF, 0x97, 0x2C, 0xAD, 0x6C, 0x47, 0x0B, 0xAB, 0x5D, 0x66, 0x42, 0xF6, 0x60, 0xB8, - 0x42, 0xD6, 0xC9, 0x73, 0x07, 0x44, 0x93, 0xE4, 0xEF, 0x1B, 0xBF, 0x31, 0x1A, 0x92, 0x79, 0x95 }, + { 0xC5, 0x00, 0xB8, 0x3F, 0x3E, 0x06, 0x6C, 0xD1, 0xDD, 0x0E, 0xBC, 0xD7, 0x3D, 0xD4, 0x01, 0x61, + 0xB9, 0x25, 0x9A, 0xA7, 0x7A, 0xB8, 0xA6, 0x47, 0xE8, 0x57, 0x1F, 0xF3, 0x37, 0xCF, 0x94, 0x6D }, }, { - { 0xEE, 0x0C, 0xF6, 0x2B, 0x9D, 0x8E, 0x42, 0xA2, 0x23, 0xB9, 0xA9, 0x60, 0xB5, 0xE9, 0x67, 0x0C, - 0xCC, 0x34, 0x6D, 0x89, 0x93, 0x8F, 0xFA, 0x5D, 0xF7, 0x98, 0x65, 0xE4, 0x13, 0xD6, 0x31, 0x54 }, + { 0xC5, 0x29, 0x5B, 0xA6, 0xE2, 0x7E, 0x72, 0x10, 0x22, 0xFE, 0xB2, 0x1E, 0x78, 0xEB, 0x7B, 0x03, + 0x57, 0xC9, 0xCD, 0x56, 0x5B, 0xD0, 0xE5, 0x96, 0x72, 0xF6, 0x66, 0x34, 0x2B, 0x79, 0x94, 0x9D }, }, { - { 0xEE, 0x1A, 0x2F, 0xA9, 0x58, 0x37, 0x5E, 0x11, 0x06, 0xE2, 0xC9, 0x05, 0xED, 0x8A, 0x26, 0x4F, - 0x28, 0x19, 0xCB, 0xB5, 0x26, 0x11, 0x8D, 0x30, 0x68, 0x9D, 0x17, 0x90, 0x42, 0x9A, 0x46, 0xA1 }, + { 0xC6, 0x12, 0x75, 0x6B, 0xA5, 0x42, 0x34, 0x4A, 0xDC, 0x1B, 0x80, 0xE9, 0x38, 0x84, 0x5A, 0x1E, + 0xD6, 0xE9, 0x38, 0xFE, 0xF4, 0x0D, 0x04, 0xEC, 0x86, 0x55, 0x8F, 0x4B, 0x21, 0x05, 0x2F, 0xD2 }, }, { - { 0xEE, 0x34, 0xE1, 0xA1, 0x9B, 0xC8, 0x89, 0xF8, 0x5F, 0x7F, 0x0F, 0x5B, 0xF8, 0x72, 0xB1, 0xAC, - 0x56, 0x5E, 0xC6, 0xF1, 0x9D, 0xB5, 0x17, 0xBA, 0x4E, 0xD7, 0x55, 0xC4, 0x18, 0x5F, 0x69, 0xE8 }, + { 0xC6, 0x17, 0xE0, 0x85, 0x5B, 0xF1, 0x4F, 0xBF, 0x21, 0xAF, 0x00, 0x82, 0x25, 0xCA, 0xBE, 0x40, + 0x4F, 0x73, 0x8C, 0x27, 0x8A, 0x4A, 0x42, 0x87, 0xF1, 0xEE, 0x38, 0x01, 0x27, 0xC5, 0x61, 0xFA }, }, { - { 0xEE, 0x35, 0x71, 0x37, 0x61, 0x52, 0x7A, 0xE4, 0x8E, 0x7E, 0x40, 0x94, 0xB2, 0xB9, 0x1D, 0x3D, - 0xD2, 0x64, 0x3F, 0x38, 0xE2, 0x6D, 0x34, 0x36, 0x36, 0x52, 0xFE, 0x5C, 0x2B, 0xBC, 0x41, 0x6B }, + { 0xC6, 0xA4, 0x24, 0xBF, 0x7C, 0xFE, 0x31, 0x72, 0x74, 0x7A, 0x47, 0x14, 0xA0, 0xEF, 0xB9, 0x17, + 0x93, 0x8C, 0x5E, 0xBD, 0x59, 0x12, 0x9D, 0xED, 0x7A, 0x81, 0x18, 0xC7, 0xF6, 0x59, 0xD1, 0x33 }, }, { - { 0xEE, 0x3D, 0x0B, 0xC5, 0xA6, 0x5A, 0xF5, 0x8D, 0x43, 0x2D, 0x08, 0x63, 0x7B, 0xE0, 0xB7, 0xBA, - 0x49, 0xC2, 0x32, 0x61, 0x8D, 0xA9, 0xC8, 0x97, 0x3F, 0x88, 0x56, 0x8C, 0x88, 0x89, 0xD1, 0xAD }, + { 0xC6, 0xAD, 0x1D, 0x7A, 0x14, 0x1A, 0x91, 0x75, 0x2D, 0x31, 0xFB, 0xC1, 0x06, 0x16, 0xBF, 0x1C, + 0xA2, 0xFB, 0x5B, 0x02, 0xE8, 0x46, 0xB5, 0x9E, 0x63, 0x34, 0x6B, 0x31, 0x92, 0xA7, 0x52, 0x92 }, }, { - { 0xEE, 0xE4, 0x9F, 0xCF, 0x29, 0x63, 0x9E, 0xD8, 0x82, 0xE0, 0x1A, 0xD1, 0xF0, 0xF5, 0xA1, 0xC5, - 0x55, 0x09, 0x26, 0xAF, 0xD4, 0x23, 0x4E, 0xF1, 0x46, 0xBC, 0x47, 0x09, 0xFE, 0x5D, 0x90, 0xE8 }, + { 0xC7, 0x01, 0x83, 0x64, 0x38, 0xF3, 0x7B, 0xEA, 0x8A, 0x88, 0x16, 0x10, 0x63, 0x70, 0x86, 0xF8, + 0x8D, 0x9A, 0x11, 0x5E, 0x00, 0x92, 0x46, 0xD2, 0x7F, 0x48, 0x9F, 0xA7, 0x18, 0x51, 0x88, 0xA8 }, }, { - { 0xEF, 0x36, 0xA2, 0x29, 0x89, 0x65, 0xE4, 0x98, 0x84, 0x59, 0xB9, 0x21, 0x6A, 0xB3, 0x3C, 0x3C, - 0xA8, 0x42, 0xD2, 0x16, 0x83, 0xB6, 0x2A, 0x2B, 0xF1, 0x53, 0x0D, 0x30, 0xB0, 0xAE, 0x78, 0x25 }, + { 0xC7, 0xFF, 0x8E, 0xFD, 0xEC, 0xDF, 0x00, 0xD1, 0xFC, 0x8D, 0x55, 0x2D, 0x2A, 0x70, 0x70, 0xE5, + 0xE3, 0x3D, 0x42, 0xE5, 0x90, 0xF5, 0x86, 0xC6, 0xAE, 0xDE, 0x03, 0x2B, 0x2D, 0x86, 0x7B, 0xD5 }, }, { - { 0xEF, 0x6D, 0xE0, 0xC4, 0x85, 0x70, 0xBD, 0x71, 0x51, 0x6B, 0xF6, 0x39, 0x5D, 0xBD, 0x29, 0x33, - 0x7C, 0xFC, 0xB7, 0xD4, 0x26, 0x64, 0x10, 0xA1, 0xF5, 0xDA, 0x08, 0x08, 0xE0, 0x96, 0xF4, 0x55 }, + { 0xC7, 0xFF, 0xB4, 0x9F, 0xBC, 0x94, 0x72, 0x24, 0x5C, 0x8E, 0x95, 0xDE, 0x62, 0x9A, 0xF5, 0xC1, + 0xBF, 0xEA, 0xC5, 0x50, 0x04, 0xC1, 0x54, 0x82, 0x3A, 0x58, 0xBA, 0xE8, 0x05, 0x6E, 0x3C, 0x64 }, }, { - { 0xEF, 0x7E, 0x8C, 0xCD, 0x7B, 0xCF, 0xB7, 0x1D, 0x2A, 0xA7, 0xBC, 0xDD, 0x8F, 0xD2, 0xD2, 0xD1, - 0x55, 0x77, 0x9D, 0xE8, 0x68, 0x43, 0x20, 0x44, 0x35, 0x1E, 0x98, 0x02, 0xCC, 0xA2, 0x90, 0xAF }, + { 0xC8, 0x37, 0xD6, 0xF2, 0xAB, 0x14, 0x79, 0x91, 0x42, 0xED, 0x3C, 0x79, 0xBE, 0xD9, 0x44, 0x1E, + 0x92, 0x50, 0xBD, 0x05, 0x20, 0x25, 0xAD, 0x8A, 0xF4, 0x40, 0x41, 0xAC, 0x19, 0xEF, 0xBB, 0x4C }, }, { - { 0xEF, 0xAF, 0xCA, 0x84, 0x90, 0x30, 0x7B, 0x0F, 0x62, 0x2B, 0xF4, 0x3A, 0x0E, 0xB3, 0xC5, 0x1A, - 0xCB, 0xDD, 0xDE, 0xDC, 0x23, 0x92, 0xF1, 0x61, 0xAC, 0xED, 0x16, 0x71, 0xA6, 0x53, 0x60, 0x7E }, + { 0xC9, 0x43, 0x10, 0x03, 0xBB, 0xEA, 0xB5, 0x8E, 0x35, 0x2F, 0xDE, 0xB4, 0x5B, 0x7F, 0xCF, 0x15, + 0xC7, 0x3F, 0x07, 0x34, 0xA0, 0x7D, 0x6C, 0xBD, 0xF6, 0x32, 0x92, 0x92, 0xEB, 0x81, 0x2C, 0x93 }, }, { - { 0xEF, 0xB5, 0xBE, 0x9F, 0xA2, 0xC6, 0xEE, 0x48, 0x9F, 0x9E, 0xB3, 0xDD, 0x55, 0x42, 0xA7, 0x0C, - 0x22, 0x57, 0xB5, 0x6B, 0x24, 0x0B, 0x3B, 0x4B, 0x29, 0xF3, 0xB4, 0xE6, 0xBA, 0x8A, 0xED, 0xE3 }, + { 0xC9, 0x72, 0xF4, 0xF9, 0x6E, 0x71, 0x33, 0xE1, 0x6E, 0x55, 0x57, 0xA0, 0x57, 0xB1, 0xD4, 0x2B, + 0xA9, 0x2D, 0x98, 0x5C, 0xAE, 0xE7, 0x3C, 0xAF, 0xDA, 0xEB, 0x55, 0xEC, 0xA2, 0xE4, 0xAB, 0xB0 }, }, { - { 0xEF, 0xC1, 0x72, 0xEE, 0xAB, 0xE2, 0xAE, 0x26, 0xBC, 0xBF, 0x0E, 0xDD, 0x22, 0x19, 0xE6, 0x62, - 0xE4, 0x63, 0xF9, 0x58, 0x03, 0x40, 0xF3, 0x47, 0x3D, 0xAD, 0x35, 0xE7, 0x50, 0xB0, 0x70, 0x68 }, + { 0xC9, 0x78, 0x37, 0x2C, 0x9E, 0x11, 0x60, 0x71, 0xB6, 0x1B, 0x90, 0x92, 0xA9, 0xAA, 0x96, 0x81, + 0x62, 0x36, 0x55, 0xA6, 0x6F, 0x4F, 0xCB, 0xC4, 0xD3, 0xA6, 0x7E, 0xFD, 0x56, 0x72, 0x48, 0x30 }, }, { - { 0xEF, 0xCE, 0x18, 0x13, 0x67, 0x41, 0x03, 0xC4, 0x43, 0xAF, 0x12, 0x8F, 0x84, 0x81, 0x8E, 0x33, - 0x85, 0x3E, 0x3B, 0x69, 0x03, 0x55, 0x35, 0x36, 0x57, 0x98, 0xEA, 0xF7, 0x5F, 0x7E, 0xAF, 0x79 }, + { 0xCA, 0x55, 0x6F, 0x82, 0xC9, 0x68, 0x4C, 0x9A, 0xF3, 0x55, 0x7D, 0x3E, 0x2D, 0x88, 0xAF, 0x92, + 0xED, 0x25, 0x9C, 0x20, 0xFF, 0xD1, 0xDD, 0xE9, 0xF7, 0x9D, 0x6B, 0x92, 0xC6, 0x1E, 0xE1, 0xB9 }, }, { - { 0xEF, 0xD1, 0xE0, 0xE7, 0x3F, 0xA8, 0x71, 0x00, 0xB7, 0x6A, 0x93, 0x23, 0x49, 0xC4, 0x5D, 0x09, - 0xB2, 0x8B, 0x2D, 0x8A, 0x00, 0x17, 0x19, 0xA5, 0x8D, 0xFA, 0xCC, 0x74, 0x84, 0xC7, 0xCF, 0x42 }, + { 0xCA, 0xBE, 0x25, 0x56, 0xF1, 0xBB, 0x56, 0x57, 0x0C, 0xEF, 0x3A, 0x87, 0x03, 0x32, 0x71, 0xA1, + 0xF2, 0x1D, 0x09, 0xB7, 0xFD, 0x04, 0x12, 0x83, 0x18, 0xE5, 0xE7, 0xBC, 0xE3, 0xA2, 0x01, 0xE2 }, }, { - { 0xF0, 0x11, 0xAD, 0x9E, 0xDD, 0x4F, 0xE7, 0x18, 0x8D, 0x77, 0x2E, 0xBA, 0xFA, 0x5B, 0xF5, 0x32, - 0x92, 0x47, 0x77, 0x88, 0xDC, 0x12, 0x80, 0x32, 0x76, 0xB0, 0x00, 0xC4, 0x41, 0x91, 0x03, 0xF0 }, + { 0xCA, 0xDC, 0xD5, 0xAE, 0x1B, 0x75, 0x6A, 0xB7, 0x41, 0xB3, 0x56, 0x9C, 0x42, 0xA5, 0x41, 0x1F, + 0x09, 0x3E, 0x4E, 0x1F, 0x01, 0x2E, 0xC5, 0x79, 0x91, 0xCB, 0xD6, 0xDB, 0xE0, 0x8F, 0xAA, 0xC1 }, }, { - { 0xF0, 0x15, 0x95, 0xF5, 0xA4, 0x66, 0x88, 0x78, 0xF6, 0xC7, 0x98, 0xA5, 0xD2, 0xF1, 0x35, 0x23, - 0xF3, 0xAF, 0xB2, 0x0E, 0xF7, 0x6F, 0xE5, 0x77, 0x6F, 0xCE, 0x47, 0xD3, 0x40, 0x9D, 0xF3, 0xC2 }, + { 0xCB, 0x7A, 0x43, 0x8D, 0x16, 0xE4, 0xA5, 0xF3, 0xC5, 0x6F, 0xDF, 0x19, 0x1E, 0x1D, 0xAF, 0x9F, + 0x32, 0x5C, 0x65, 0x0B, 0xD6, 0x2F, 0x07, 0xC4, 0x67, 0x71, 0x72, 0x07, 0x35, 0x1A, 0xE3, 0x29 }, }, { - { 0xF0, 0x2F, 0x9D, 0xA4, 0x5D, 0x9E, 0xB9, 0x86, 0x19, 0x4E, 0x06, 0xF5, 0xE6, 0x18, 0x95, 0x45, - 0x12, 0xC9, 0x02, 0x6E, 0x7C, 0xA7, 0xB5, 0x1E, 0x66, 0x5D, 0xB6, 0xAD, 0xBA, 0xC1, 0xF6, 0x00 }, + { 0xCC, 0x2A, 0x70, 0x6F, 0xE6, 0x8F, 0x5D, 0x17, 0xF4, 0xAB, 0xAF, 0x60, 0x86, 0xE5, 0xBD, 0x97, + 0xAE, 0x35, 0xEB, 0x35, 0x9F, 0x75, 0xC0, 0x92, 0xBB, 0xA4, 0x93, 0xFE, 0x11, 0xF2, 0x69, 0xFD }, }, { - { 0xF0, 0x6B, 0x35, 0x95, 0x36, 0xD1, 0x34, 0x32, 0x8B, 0x36, 0x00, 0x4D, 0xA9, 0xA9, 0x19, 0x0C, - 0x3A, 0x76, 0x69, 0xE8, 0x27, 0x8D, 0xB9, 0xF7, 0x58, 0x57, 0xC4, 0x8D, 0x64, 0x4B, 0xE2, 0x03 }, + { 0xCC, 0x30, 0xD8, 0x19, 0xDE, 0x54, 0x05, 0xF6, 0x49, 0xC8, 0xB7, 0xA8, 0x14, 0x8F, 0x26, 0xD7, + 0x71, 0x08, 0x3E, 0xC5, 0x18, 0xF9, 0xB6, 0x6F, 0xF5, 0x47, 0xF2, 0x82, 0x2D, 0x11, 0x93, 0x6D }, }, { - { 0xF0, 0xCF, 0xC7, 0x79, 0x13, 0x39, 0x7D, 0xE2, 0x38, 0xED, 0xB5, 0x9F, 0x0F, 0x99, 0x23, 0xC6, - 0xD4, 0x11, 0x0A, 0x4B, 0x3A, 0xC8, 0xAC, 0x76, 0x55, 0x6A, 0x0C, 0x92, 0x44, 0xF0, 0x3F, 0xC1 }, + { 0xCC, 0x65, 0xCD, 0xC5, 0x33, 0x62, 0xD4, 0x21, 0x62, 0x7E, 0xAE, 0xF5, 0xD0, 0xC8, 0xE4, 0xC4, + 0xE2, 0x40, 0xAD, 0xE0, 0xC9, 0xD4, 0x20, 0xBE, 0x67, 0x1E, 0x70, 0xF0, 0xFB, 0xAC, 0x8D, 0x0A }, }, { - { 0xF1, 0x13, 0x93, 0xAF, 0xAA, 0xCB, 0x50, 0x3A, 0xE4, 0xAC, 0xCC, 0x3E, 0xDF, 0xC5, 0x8F, 0x9A, - 0xD8, 0xA9, 0x6A, 0x01, 0x2E, 0x3A, 0xC3, 0x8E, 0xCB, 0xAA, 0x28, 0x62, 0xB8, 0x05, 0x69, 0x8B }, + { 0xCD, 0xB1, 0x62, 0x53, 0xD2, 0x2E, 0xD5, 0xD4, 0x26, 0xCF, 0xA1, 0xB0, 0x5C, 0xEC, 0xD8, 0x6E, + 0xF1, 0xB7, 0xDE, 0xAA, 0x07, 0xC5, 0x70, 0x5E, 0xBB, 0xAF, 0x7D, 0x9A, 0x80, 0x7D, 0x56, 0x16 }, }, { - { 0xF1, 0x46, 0x85, 0xC4, 0xC1, 0x0C, 0x79, 0xFC, 0x97, 0xE1, 0x84, 0xEA, 0x7D, 0x22, 0xF8, 0xEE, - 0x4A, 0x81, 0xD0, 0x56, 0x95, 0xAB, 0x08, 0xD2, 0x5D, 0x4A, 0x73, 0x3B, 0x60, 0xB4, 0x70, 0xDF }, + { 0xCD, 0xC0, 0x39, 0xF3, 0xA2, 0xD1, 0xBB, 0xA5, 0xE8, 0x09, 0x4E, 0x55, 0x23, 0xCF, 0x60, 0x47, + 0x09, 0x7D, 0x4B, 0x3C, 0xD4, 0xEC, 0x4E, 0xD6, 0xAA, 0x8E, 0xB7, 0xB4, 0xD8, 0xB5, 0x77, 0x7D }, }, { - { 0xF1, 0x4B, 0xF7, 0x41, 0x19, 0x15, 0xEF, 0x83, 0x96, 0xCC, 0x04, 0x0A, 0x6F, 0x30, 0x12, 0xBD, - 0x81, 0x8C, 0x11, 0x9D, 0x03, 0x98, 0xCE, 0xD6, 0x1D, 0x80, 0x9E, 0xF9, 0x4B, 0xD8, 0x62, 0xD8 }, + { 0xCD, 0xC4, 0xEA, 0x92, 0x02, 0xE3, 0x3E, 0xDD, 0x0F, 0x2D, 0x3A, 0xE8, 0x6A, 0xCA, 0xC7, 0xFB, + 0x25, 0x35, 0x4B, 0x02, 0x23, 0x5B, 0x09, 0x33, 0xAA, 0x81, 0xA3, 0x13, 0xB5, 0xFD, 0xFE, 0xEC }, }, { - { 0xF1, 0x9A, 0xE4, 0x7D, 0x93, 0x67, 0x16, 0x52, 0x78, 0xE1, 0x66, 0xED, 0x44, 0xFF, 0xC3, 0x7E, - 0x5B, 0x28, 0x19, 0x6C, 0x01, 0x4B, 0xF1, 0x18, 0xCF, 0xC6, 0x4E, 0xD5, 0xFA, 0x18, 0x19, 0x4D }, + { 0xCE, 0x4C, 0x2F, 0x8F, 0x16, 0x46, 0x8A, 0x58, 0x88, 0xE9, 0x0F, 0x73, 0x4E, 0x4D, 0x22, 0x02, + 0xDF, 0xAD, 0xBF, 0xA6, 0x6F, 0x5B, 0x35, 0x75, 0x2B, 0xAA, 0x76, 0x21, 0xA7, 0x60, 0xB0, 0x88 }, }, { - { 0xF1, 0xB5, 0xF4, 0xB2, 0x1E, 0xA3, 0x2D, 0x06, 0x26, 0xAA, 0x5A, 0x6B, 0xF5, 0xC4, 0xDE, 0x59, - 0x1C, 0xF1, 0x65, 0x0F, 0xA8, 0x22, 0xF1, 0x34, 0xD9, 0x2D, 0x54, 0x8F, 0x15, 0x77, 0x73, 0xD6 }, + { 0xCE, 0x81, 0x44, 0x58, 0x54, 0x03, 0x1F, 0x3D, 0x0F, 0x5C, 0x88, 0x75, 0x46, 0x4D, 0xCD, 0x5B, + 0xA6, 0xC8, 0x90, 0xF4, 0x49, 0xB3, 0x20, 0x7B, 0xCA, 0x2B, 0xC9, 0x61, 0x82, 0x2D, 0x27, 0xC4 }, }, { - { 0xF2, 0x06, 0x59, 0x72, 0x49, 0x8D, 0x5E, 0x12, 0x79, 0x8E, 0x1E, 0x1F, 0xF3, 0xE1, 0x1D, 0xE4, - 0x23, 0x3A, 0xBB, 0xBD, 0x30, 0x8A, 0x58, 0x07, 0x60, 0x58, 0x48, 0x18, 0x6E, 0x44, 0x11, 0x7F }, + { 0xCF, 0xA0, 0xC0, 0x0C, 0xB2, 0xFB, 0x4B, 0x85, 0x7A, 0xAD, 0x22, 0xB1, 0x3A, 0x90, 0xE3, 0x46, + 0xA0, 0x3E, 0x6B, 0x79, 0xAB, 0xD5, 0xD2, 0x75, 0xB5, 0x43, 0x24, 0x68, 0x17, 0x92, 0xD6, 0xD1 }, }, { - { 0xF2, 0x54, 0x76, 0xF3, 0xAB, 0x8E, 0x5E, 0x0B, 0x9B, 0xB6, 0x1D, 0x4C, 0xE4, 0x50, 0x7F, 0xA3, - 0x52, 0x93, 0xC6, 0x64, 0x15, 0xD7, 0xD1, 0x91, 0x9B, 0x29, 0xBB, 0x8C, 0xBF, 0xFD, 0xA5, 0x00 }, + { 0xD0, 0xF5, 0x93, 0xC1, 0xA8, 0x1B, 0x1E, 0xF8, 0x51, 0x69, 0x81, 0xEE, 0x56, 0xF1, 0xD5, 0x98, + 0xA2, 0xA6, 0x03, 0x48, 0x8C, 0x67, 0x8C, 0x1B, 0x7B, 0xBE, 0xA6, 0x44, 0x6B, 0x00, 0x83, 0xAD }, }, { - { 0xF2, 0x6F, 0x08, 0x73, 0x87, 0xBC, 0x9B, 0x62, 0xF5, 0x38, 0xB0, 0x76, 0xD6, 0xBD, 0xFD, 0x15, - 0x87, 0x36, 0xDE, 0x71, 0x61, 0xC6, 0xBC, 0xA3, 0x86, 0xF5, 0x7D, 0xD2, 0xB0, 0x0B, 0x8F, 0xE0 }, + { 0xD2, 0x90, 0x3C, 0xA2, 0x55, 0x17, 0x27, 0xED, 0x01, 0x71, 0xCC, 0x4A, 0x43, 0xB3, 0xCA, 0xE0, + 0x09, 0xB7, 0x47, 0xB9, 0xF4, 0xF8, 0x48, 0x72, 0x92, 0x27, 0xBF, 0x59, 0x02, 0xF2, 0x3E, 0x47 }, }, { - { 0xF2, 0xB1, 0x95, 0x84, 0x6E, 0xE2, 0xB9, 0xAB, 0x5F, 0x18, 0xE6, 0x80, 0x21, 0xF8, 0xDF, 0x7C, - 0x0B, 0x60, 0x58, 0xDE, 0xDE, 0x86, 0xC5, 0xD5, 0x90, 0xF2, 0xE8, 0x64, 0x3A, 0xFE, 0x04, 0x52 }, + { 0xD2, 0xE8, 0xA1, 0x23, 0x7A, 0x93, 0xF5, 0x78, 0xD1, 0xBA, 0x8F, 0x09, 0xE4, 0xFF, 0x10, 0x7B, + 0x62, 0x35, 0x78, 0x85, 0x42, 0xAA, 0x61, 0x83, 0xD1, 0x76, 0xDB, 0xF1, 0xC8, 0x8D, 0xCF, 0xB6 }, }, { - { 0xF2, 0xE3, 0x0F, 0xB6, 0xCD, 0x91, 0x67, 0x54, 0x84, 0x72, 0xCC, 0xDF, 0x58, 0x9F, 0x3D, 0x00, - 0x43, 0x0C, 0x22, 0xB8, 0x33, 0x44, 0xA1, 0x16, 0x5B, 0x64, 0xE6, 0x87, 0x4D, 0xF3, 0x5E, 0xDC }, + { 0xD5, 0x04, 0x88, 0x96, 0x86, 0x07, 0x29, 0xA8, 0xFA, 0x5D, 0x23, 0x57, 0x81, 0x2B, 0xA5, 0x6C, + 0xBE, 0x84, 0xC9, 0xAB, 0x7D, 0x14, 0xDF, 0x47, 0x64, 0xE0, 0xB6, 0x62, 0x0F, 0xA3, 0x20, 0x10 }, }, { - { 0xF2, 0xE5, 0x30, 0x0C, 0x39, 0xF2, 0x86, 0xC6, 0x78, 0x99, 0x90, 0x9C, 0x7C, 0xE7, 0x35, 0x9B, - 0x09, 0x45, 0xD2, 0xAF, 0xD3, 0x4A, 0x6D, 0xD6, 0x9E, 0x08, 0xCD, 0xA5, 0x44, 0xC8, 0x7B, 0x3A }, + { 0xD5, 0x41, 0xA7, 0x7E, 0x13, 0x6E, 0x9E, 0x70, 0x3B, 0xB9, 0x9F, 0x80, 0x68, 0xCF, 0xEE, 0x86, + 0xA4, 0xB9, 0xF0, 0x89, 0xE0, 0x2D, 0x0C, 0x6C, 0xB6, 0xD4, 0xA3, 0x94, 0x6C, 0x6B, 0x16, 0x7A }, }, { - { 0xF3, 0x0C, 0x0A, 0xED, 0x70, 0x6D, 0x22, 0x55, 0x5F, 0x07, 0x09, 0x6A, 0xF4, 0xB8, 0xBE, 0xDC, - 0x16, 0x3C, 0x0F, 0x6E, 0xD5, 0x34, 0x6E, 0xFC, 0x28, 0xE8, 0xCF, 0xAF, 0x84, 0x2F, 0xA5, 0xD9 }, + { 0xD5, 0x83, 0x94, 0x96, 0xCD, 0xC8, 0x5B, 0xE3, 0xD1, 0xF1, 0xAC, 0x65, 0x2E, 0xFA, 0x92, 0xBE, + 0xA3, 0xB0, 0x61, 0xC1, 0x3D, 0xAD, 0x5A, 0x82, 0x11, 0x22, 0xCF, 0xE9, 0xC7, 0x1A, 0x5A, 0x32 }, }, { - { 0xF3, 0x25, 0x58, 0x52, 0x53, 0xD2, 0x8E, 0x72, 0x02, 0x3F, 0x04, 0xDA, 0x0A, 0x2C, 0xB5, 0x0F, - 0xBD, 0x4B, 0x75, 0xC2, 0x5A, 0x3A, 0x80, 0x25, 0x3F, 0x70, 0x36, 0xCE, 0x71, 0x74, 0x1B, 0x9B }, + { 0xD5, 0xA4, 0xEE, 0x46, 0x95, 0xB5, 0x65, 0xA6, 0x7E, 0x50, 0x48, 0x66, 0xFE, 0x5B, 0xA3, 0xC0, + 0xED, 0xCA, 0xEE, 0xD5, 0x2A, 0xD0, 0xAF, 0x07, 0xE6, 0x79, 0x17, 0x73, 0x85, 0x12, 0xC8, 0xF5 }, }, { - { 0xF3, 0x48, 0x7E, 0x13, 0xEA, 0xB9, 0x5D, 0xA9, 0xAF, 0xED, 0xE0, 0x74, 0x84, 0x4B, 0xDE, 0x4C, - 0xA0, 0x31, 0x48, 0x26, 0xCC, 0xBD, 0x06, 0x96, 0x29, 0x8C, 0x35, 0x32, 0x4A, 0x91, 0xCB, 0xEB }, + { 0xD6, 0x25, 0xC0, 0x59, 0x2B, 0x25, 0xDC, 0x03, 0xAA, 0x7E, 0x87, 0x8E, 0x6A, 0x85, 0x09, 0x1B, + 0xAA, 0x07, 0x8D, 0x26, 0x8B, 0xBD, 0xB4, 0x9F, 0x09, 0x67, 0x94, 0x08, 0x61, 0x2D, 0x1E, 0xFE }, }, { - { 0xF3, 0x5F, 0xE6, 0x61, 0xD1, 0x88, 0x65, 0x29, 0x35, 0xE2, 0xC0, 0xE5, 0x19, 0x11, 0x8F, 0x7C, - 0x4E, 0x45, 0x7B, 0x0C, 0x65, 0xC8, 0xE1, 0x4B, 0xCE, 0xDC, 0x7D, 0x4C, 0xC5, 0x1E, 0x81, 0xD0 }, + { 0xD6, 0xD1, 0xB3, 0x5C, 0xBC, 0x12, 0xFB, 0x1C, 0x70, 0xA0, 0xB4, 0x3B, 0xA5, 0x9A, 0xB3, 0xD3, + 0x22, 0x5F, 0x37, 0x32, 0x64, 0xDD, 0x87, 0xFB, 0xCA, 0x00, 0x61, 0xEC, 0x1C, 0x4D, 0xA1, 0x1A }, }, { - { 0xF3, 0xCB, 0x8E, 0xA4, 0xE8, 0xF2, 0xA7, 0x00, 0x9C, 0x23, 0x3A, 0x64, 0x88, 0x71, 0xDB, 0x46, - 0x04, 0xD5, 0x45, 0x4B, 0xC5, 0x55, 0x9E, 0x9B, 0xF1, 0xBB, 0x2E, 0xB0, 0x00, 0x99, 0x3B, 0xDF }, + { 0xD7, 0x32, 0x49, 0x74, 0xB5, 0x60, 0x09, 0x62, 0x17, 0x61, 0xF7, 0xC0, 0xFF, 0x68, 0x9D, 0xDE, + 0x47, 0x74, 0x99, 0x85, 0xE1, 0xEE, 0x8B, 0x5C, 0x89, 0x61, 0xDD, 0x8F, 0x6A, 0x78, 0xBB, 0xF5 }, }, { - { 0xF4, 0x0C, 0x5A, 0x4F, 0xE5, 0xA7, 0x08, 0x81, 0x08, 0x7E, 0x61, 0x6A, 0xAD, 0x68, 0x23, 0x09, - 0x21, 0xDA, 0xF0, 0x31, 0x01, 0xEB, 0x91, 0x2F, 0x13, 0x3A, 0x8B, 0xD1, 0xC5, 0xCF, 0x0A, 0xD0 }, + { 0xD9, 0x2E, 0x3E, 0xE3, 0x82, 0xC8, 0xDC, 0xAF, 0xA0, 0x39, 0x3D, 0x9F, 0x9A, 0x00, 0xBF, 0x4C, + 0xD9, 0xD5, 0x64, 0x26, 0x2B, 0x18, 0x0F, 0x68, 0x16, 0x0B, 0x20, 0x34, 0xC5, 0x44, 0xD1, 0x0A }, }, { - { 0xF4, 0x2A, 0x12, 0xA1, 0x43, 0x57, 0xC0, 0xCF, 0x12, 0x2B, 0xBD, 0x82, 0x77, 0x69, 0xFB, 0x56, - 0xDB, 0xF5, 0xB6, 0xEE, 0x89, 0x4F, 0x02, 0x5B, 0x9A, 0xDE, 0x25, 0x88, 0xA9, 0xB5, 0x5D, 0x9B }, + { 0xD9, 0x65, 0xF7, 0x41, 0x62, 0x04, 0xDA, 0x83, 0x1A, 0xF6, 0x6B, 0xFA, 0x8F, 0x90, 0xD1, 0x41, + 0xE9, 0x93, 0xF0, 0x00, 0x21, 0x33, 0xF2, 0x8D, 0xE9, 0x7F, 0x56, 0x4A, 0x1D, 0x60, 0x4E, 0xCC }, }, { - { 0xF4, 0x83, 0x3E, 0x73, 0x82, 0x42, 0x02, 0x18, 0xFF, 0xA7, 0x8D, 0xFA, 0x23, 0x50, 0x0E, 0x7D, - 0x34, 0x8F, 0x80, 0xFB, 0x87, 0xE9, 0x82, 0x48, 0x61, 0x3B, 0x59, 0x24, 0x2D, 0x99, 0x1A, 0x78 }, + { 0xD9, 0x7F, 0x55, 0xB9, 0x57, 0x9B, 0x05, 0xAE, 0x4A, 0x3E, 0xD7, 0xFC, 0x55, 0x8C, 0x58, 0x45, + 0x64, 0x51, 0x60, 0xDA, 0xB3, 0x53, 0x85, 0xC1, 0x38, 0xBC, 0x89, 0x9C, 0x4D, 0xAD, 0x8B, 0x36 }, }, { - { 0xF4, 0x91, 0x32, 0x07, 0xAD, 0xC7, 0x68, 0xEC, 0x7C, 0xA6, 0xB1, 0xFE, 0x03, 0xEF, 0x9C, 0xF1, - 0x0B, 0x7D, 0xB6, 0x01, 0xD7, 0xF6, 0x6C, 0x10, 0x2C, 0x84, 0xE4, 0x70, 0x92, 0x9E, 0xE4, 0xA1 }, + { 0xDA, 0xDF, 0x97, 0x13, 0x34, 0x14, 0xAD, 0x51, 0x3F, 0xC7, 0x50, 0x14, 0xE9, 0x56, 0x65, 0xDA, + 0xD7, 0x76, 0xB1, 0x50, 0x4B, 0x15, 0x67, 0x43, 0x4F, 0xD8, 0x2A, 0x79, 0xA2, 0x20, 0xE9, 0xA1 }, }, { - { 0xF4, 0xCC, 0xA7, 0x7F, 0x70, 0x42, 0xD6, 0x78, 0x8A, 0x04, 0x5E, 0xAD, 0x54, 0x95, 0x1A, 0x25, - 0x4A, 0x26, 0x9E, 0xD9, 0x85, 0x4A, 0x62, 0x06, 0xB4, 0xAA, 0x5B, 0xE9, 0x9F, 0xC7, 0xD9, 0xAC }, + { 0xDE, 0xCD, 0xB9, 0xFC, 0x1D, 0xDE, 0xC9, 0x7E, 0x09, 0xC3, 0x02, 0x6A, 0xCE, 0xB7, 0x6B, 0xDA, + 0xE9, 0xDE, 0xB6, 0x62, 0x75, 0x1D, 0xDA, 0x34, 0x9D, 0x2F, 0xA6, 0xBD, 0x75, 0xCA, 0x59, 0x14 }, }, { - { 0xF4, 0xD1, 0xD1, 0x3C, 0xFD, 0x04, 0x31, 0x16, 0x09, 0x38, 0xE8, 0xE9, 0xB2, 0xE3, 0x80, 0x61, - 0x97, 0xCA, 0x7F, 0xFD, 0xEC, 0x7A, 0xAD, 0xFE, 0xAF, 0xFB, 0x4D, 0xA4, 0x72, 0x92, 0x4E, 0xDF }, + { 0xDE, 0xD1, 0x9A, 0xD5, 0xDE, 0x99, 0x65, 0xD9, 0x22, 0x5C, 0x1B, 0xBA, 0x5F, 0xB4, 0xD8, 0x90, + 0xC8, 0xE5, 0xC0, 0x35, 0xE4, 0x85, 0x27, 0x52, 0xB6, 0x69, 0xB0, 0x40, 0x0F, 0x24, 0xF1, 0x74 }, }, { - { 0xF5, 0x12, 0x02, 0xF2, 0xDD, 0x4C, 0x4A, 0xD1, 0x04, 0x3A, 0xF5, 0xA3, 0x75, 0xAD, 0xD0, 0x69, - 0xE7, 0x4B, 0x4C, 0x3E, 0xFA, 0xB5, 0xE0, 0xF6, 0xDD, 0xA9, 0x20, 0xD2, 0x3D, 0xB7, 0xCC, 0x73 }, + { 0xDF, 0x30, 0xBF, 0x8D, 0x1B, 0xF9, 0x37, 0x8E, 0x43, 0x3E, 0xF9, 0xE1, 0xB3, 0xA2, 0x28, 0xA0, + 0x7E, 0x36, 0x58, 0xA5, 0xBC, 0x43, 0x88, 0x23, 0x45, 0x4D, 0xB0, 0x6A, 0x67, 0x94, 0x4C, 0x6E }, }, { - { 0xF5, 0x82, 0xF1, 0x66, 0xB8, 0x2B, 0xED, 0x47, 0xEF, 0xE3, 0x66, 0x1A, 0xA8, 0x02, 0x32, 0xFA, - 0x81, 0x67, 0xD2, 0xE8, 0x97, 0x96, 0xA3, 0x66, 0xEA, 0x35, 0xAD, 0x40, 0xA1, 0xBA, 0x2F, 0x66 }, + { 0xDF, 0x69, 0xF9, 0x6A, 0x85, 0x67, 0x8F, 0x6C, 0xAF, 0x3F, 0xDE, 0x25, 0xEC, 0xFB, 0x5D, 0xF4, + 0x74, 0x70, 0x87, 0xC2, 0xAF, 0x3B, 0x00, 0x65, 0xFB, 0x15, 0x10, 0x55, 0xCB, 0xCB, 0xA8, 0xC1 }, }, { - { 0xF5, 0x98, 0x77, 0xC3, 0xC9, 0x03, 0xF2, 0x02, 0xDD, 0xB7, 0x2C, 0xE9, 0x9B, 0x18, 0x02, 0x63, - 0x9A, 0xA6, 0x53, 0x9B, 0x08, 0x6E, 0xAA, 0x74, 0xCA, 0xAB, 0x16, 0xAB, 0x9B, 0xF3, 0x0D, 0x95 }, + { 0xE0, 0x0B, 0xD7, 0x86, 0xD1, 0xF2, 0xF4, 0x46, 0xC4, 0xBA, 0x83, 0x99, 0xD4, 0xD8, 0xD5, 0xA0, + 0xD1, 0x98, 0x57, 0x8F, 0x42, 0x99, 0xFD, 0xFD, 0xAF, 0xF7, 0x8C, 0x3F, 0x67, 0x71, 0xF3, 0x94 }, }, { - { 0xF5, 0xCA, 0x51, 0xE5, 0xB2, 0x72, 0xD3, 0x77, 0x52, 0x4A, 0x38, 0xD1, 0xA0, 0x3B, 0x51, 0x23, - 0x7C, 0xA0, 0x89, 0x47, 0x24, 0x19, 0xE5, 0x61, 0x9F, 0xFD, 0x71, 0x7A, 0x09, 0x8B, 0x5B, 0x42 }, + { 0xE0, 0x8B, 0x2C, 0xC2, 0x7A, 0xE8, 0xE2, 0xEF, 0x1A, 0x33, 0x01, 0x7A, 0x9A, 0xC2, 0x5D, 0xDA, + 0xFB, 0x5E, 0xA1, 0x12, 0xC9, 0x56, 0xB0, 0x02, 0xFE, 0x6C, 0x79, 0x80, 0x14, 0xAA, 0x90, 0x65 }, }, { - { 0xF5, 0xE1, 0xF7, 0xDA, 0x24, 0x9D, 0xB8, 0x7D, 0x6B, 0xB8, 0xF9, 0x6E, 0xE7, 0x3D, 0xD1, 0x31, - 0xBD, 0xDF, 0xAF, 0x62, 0xCC, 0x0B, 0x46, 0x5F, 0x3A, 0x47, 0x4F, 0x91, 0xD3, 0xE3, 0xB5, 0xEC }, + { 0xE1, 0xB2, 0xE8, 0x6B, 0x0D, 0xA8, 0x69, 0xE9, 0x25, 0x26, 0x6C, 0x1B, 0x56, 0x88, 0x34, 0x5A, + 0x17, 0xB0, 0xF6, 0xE2, 0xA2, 0x14, 0x94, 0x54, 0x7E, 0xAC, 0x09, 0x7C, 0x8B, 0xF5, 0x3C, 0x5A }, }, { - { 0xF6, 0x13, 0xD5, 0x90, 0x46, 0xD1, 0x66, 0x71, 0xD3, 0xC5, 0x60, 0x17, 0x6F, 0x3D, 0x77, 0xFD, - 0xC5, 0x1E, 0x5F, 0x57, 0xB5, 0xE4, 0x8A, 0xE7, 0xA4, 0xB9, 0x70, 0x0A, 0x11, 0xD4, 0x69, 0x3A }, + { 0xE1, 0xD6, 0x44, 0xA0, 0x96, 0xBD, 0x8A, 0x6C, 0xAC, 0xBB, 0xDA, 0x3E, 0x7F, 0xC3, 0x38, 0xEA, + 0xDD, 0xC1, 0x2F, 0x23, 0x6C, 0x72, 0x61, 0xE4, 0x5F, 0x8A, 0xD2, 0xD8, 0x42, 0x42, 0x4F, 0x72 }, }, { - { 0xF6, 0x1E, 0x88, 0xE4, 0x31, 0x76, 0x13, 0x50, 0x00, 0x62, 0x99, 0x19, 0xD9, 0x39, 0x82, 0xDB, - 0x67, 0xE9, 0xD1, 0x77, 0x4E, 0x7E, 0xD0, 0xB4, 0xFA, 0x03, 0x8E, 0x1B, 0x24, 0xEC, 0x0A, 0xCF }, + { 0xE2, 0x24, 0x10, 0xB5, 0xA6, 0x7F, 0xED, 0xC2, 0x64, 0x69, 0x4C, 0x44, 0x9D, 0x84, 0xFA, 0x1A, + 0x02, 0xBC, 0x8B, 0x21, 0x28, 0xC1, 0x25, 0x60, 0x71, 0x58, 0xC9, 0x1B, 0x05, 0x38, 0x6C, 0x6A }, }, { - { 0xF6, 0x41, 0xE7, 0xE0, 0x1B, 0xF4, 0xF2, 0xB0, 0xD0, 0xC4, 0x8B, 0xA6, 0x38, 0xA0, 0x2E, 0x26, - 0xBD, 0xDB, 0xD7, 0x7B, 0xC5, 0xE9, 0x72, 0x61, 0x94, 0xDB, 0x1A, 0xEA, 0x4F, 0x2F, 0xD7, 0x71 }, + { 0xE2, 0xA8, 0x47, 0xC3, 0xF0, 0x9B, 0xEB, 0x6F, 0x05, 0x68, 0x6F, 0x17, 0x79, 0x1B, 0x05, 0xF1, + 0xFE, 0x25, 0xF7, 0x71, 0x86, 0x9C, 0x42, 0x63, 0xA5, 0x5B, 0x94, 0x18, 0x77, 0xE4, 0x79, 0x04 }, }, { - { 0xF6, 0x54, 0x6B, 0x2F, 0xFE, 0x2B, 0xAE, 0xF7, 0x35, 0xE8, 0x25, 0x67, 0xA6, 0xE2, 0x36, 0x75, - 0x03, 0x94, 0xC1, 0x19, 0x14, 0x09, 0x87, 0x0C, 0x6F, 0xBE, 0x95, 0x2D, 0x08, 0xA3, 0x3A, 0xBA }, + { 0xE2, 0xF3, 0x9A, 0x9D, 0x48, 0xA3, 0x22, 0x10, 0x55, 0xB3, 0xC8, 0xA3, 0xEB, 0x14, 0x39, 0xD6, + 0xB8, 0x73, 0x01, 0x3E, 0xE4, 0xD0, 0x97, 0x12, 0x20, 0x64, 0xF2, 0x7E, 0xC0, 0x3D, 0xD4, 0xDA }, }, { - { 0xF6, 0x6E, 0xDF, 0xF6, 0xA3, 0x94, 0xC6, 0x6D, 0xF5, 0xBF, 0x9F, 0xE7, 0x84, 0xE6, 0x31, 0xF7, - 0x9A, 0xF3, 0x9C, 0xB1, 0x4F, 0x3A, 0xC5, 0x16, 0x11, 0xF6, 0xFE, 0x1D, 0x9D, 0x1E, 0x1C, 0xE9 }, + { 0xE2, 0xF5, 0xDE, 0x57, 0xCD, 0x67, 0x24, 0x9A, 0x7E, 0x1F, 0x45, 0x5B, 0x85, 0xC0, 0x6F, 0x0D, + 0x80, 0x9E, 0x75, 0xA5, 0x5C, 0x6B, 0x05, 0x48, 0x16, 0xE0, 0x19, 0x89, 0x9A, 0x3A, 0x02, 0xFF }, }, { - { 0xF6, 0x93, 0x79, 0x9B, 0xBD, 0xF1, 0xFF, 0x89, 0xBA, 0x48, 0xF2, 0xBF, 0xE2, 0x8F, 0x89, 0x36, - 0x6A, 0xC3, 0xB4, 0x13, 0x54, 0x7D, 0xB8, 0x06, 0x0D, 0xB5, 0x07, 0xAB, 0xC9, 0x42, 0x0B, 0xA8 }, + { 0xE6, 0x44, 0xD1, 0x1C, 0x37, 0x07, 0x0F, 0x89, 0x69, 0x33, 0x08, 0x17, 0x8D, 0x6B, 0xE4, 0x95, + 0x94, 0x96, 0x92, 0xC1, 0xFB, 0xEB, 0x30, 0xED, 0x32, 0x9B, 0x74, 0x02, 0x7F, 0xCF, 0xFD, 0x48 }, }, { - { 0xF6, 0x9D, 0x95, 0x42, 0xDB, 0x97, 0xEC, 0x65, 0xBF, 0xF8, 0x45, 0x23, 0x0A, 0xDC, 0x76, 0xB0, - 0x3C, 0x15, 0x91, 0x2F, 0x6F, 0x09, 0x97, 0x32, 0x9D, 0x5C, 0x2D, 0x14, 0xF6, 0xB2, 0x5E, 0xDF }, + { 0xE6, 0xB0, 0xF2, 0xE2, 0x5B, 0xD5, 0x16, 0xE4, 0xBB, 0xA3, 0x7A, 0x2B, 0xF2, 0xE2, 0xC7, 0x2A, + 0x1E, 0x53, 0x9C, 0x60, 0x30, 0xF3, 0xCF, 0x9B, 0xBE, 0x5E, 0x79, 0x72, 0x8D, 0x68, 0x64, 0x78 }, }, { - { 0xF6, 0xA8, 0x1F, 0x59, 0xB1, 0x13, 0xBA, 0xB9, 0x52, 0xD6, 0x2B, 0xDA, 0xB9, 0x70, 0xC8, 0xEE, - 0xD9, 0xF7, 0x26, 0x22, 0xFA, 0x8A, 0xC6, 0xD8, 0x48, 0xC3, 0xE2, 0xC6, 0x14, 0x62, 0xEF, 0x95 }, + { 0xE6, 0xE5, 0x4D, 0xE7, 0xB4, 0x97, 0x54, 0xD3, 0x57, 0xB0, 0xA8, 0xD9, 0x4A, 0x4D, 0x4F, 0x80, + 0xAC, 0xD1, 0x99, 0x4C, 0xCC, 0x1C, 0x99, 0x08, 0xE9, 0xF0, 0xD9, 0x21, 0xE4, 0x28, 0xB8, 0x38 }, }, { - { 0xF6, 0xAA, 0xEF, 0x12, 0xFC, 0x25, 0x2D, 0xD9, 0xE7, 0xF7, 0x75, 0x2C, 0x2F, 0x74, 0x5D, 0x59, - 0xD6, 0x37, 0x57, 0xC6, 0xCC, 0x14, 0xD2, 0x25, 0x3A, 0x64, 0x7C, 0xD1, 0x81, 0x49, 0x39, 0x93 }, + { 0xE7, 0x0C, 0xBB, 0x7A, 0xF7, 0xAA, 0x20, 0xB9, 0x89, 0x0B, 0xC1, 0xF9, 0xFA, 0x00, 0xD8, 0x09, + 0x0B, 0x5A, 0xC9, 0x82, 0x5E, 0xA9, 0xD2, 0xFD, 0xF7, 0x7C, 0xA4, 0xDA, 0xE9, 0x44, 0x51, 0xB2 }, }, { - { 0xF6, 0xE3, 0x03, 0x5A, 0xEC, 0xC9, 0xC9, 0x6B, 0x03, 0xE9, 0x73, 0x71, 0xF3, 0x60, 0xF5, 0xBA, - 0x02, 0x14, 0x13, 0x81, 0x27, 0x5D, 0x71, 0xC1, 0x41, 0xEA, 0xF6, 0x3A, 0x06, 0x55, 0x23, 0x07 }, + { 0xE8, 0x16, 0xF9, 0x92, 0x94, 0xA1, 0x3A, 0xC2, 0xFA, 0x2B, 0xFB, 0x76, 0xC2, 0x2D, 0xFA, 0x71, + 0xBC, 0x3D, 0xA4, 0x8F, 0x67, 0x1E, 0xF7, 0x7C, 0x00, 0xAA, 0x8E, 0x45, 0x9B, 0x7C, 0xC8, 0x2A }, }, { - { 0xF6, 0xFE, 0xB3, 0x88, 0x25, 0xE6, 0xEE, 0x7B, 0xA5, 0xBF, 0xD9, 0x4B, 0xB5, 0x77, 0x12, 0xA4, - 0x14, 0x1E, 0xB8, 0xD0, 0x92, 0xBB, 0x2D, 0x5D, 0xD1, 0x64, 0xF6, 0x74, 0xA2, 0xE5, 0xB0, 0x64 }, + { 0xE8, 0x21, 0x3C, 0x45, 0x51, 0x81, 0x61, 0xBC, 0x36, 0x37, 0x3D, 0xCD, 0x2D, 0x4B, 0x21, 0xB7, + 0x6A, 0x7C, 0x06, 0x6D, 0xF5, 0x52, 0x6E, 0x88, 0x8B, 0x6E, 0xED, 0x09, 0xA9, 0xEE, 0xD0, 0x62 }, }, { - { 0xF7, 0x22, 0xE3, 0x21, 0x67, 0xF0, 0x0D, 0x96, 0xEB, 0x35, 0xF9, 0xB9, 0x43, 0xD2, 0x56, 0x26, - 0x5B, 0xA5, 0x5E, 0x70, 0x34, 0x6D, 0x8C, 0xEE, 0x54, 0x48, 0x29, 0xC2, 0xB0, 0x9B, 0x95, 0x90 }, + { 0xE9, 0xF5, 0x71, 0xC7, 0x71, 0x64, 0xAB, 0xEA, 0xE1, 0x85, 0x28, 0x37, 0x5C, 0xFD, 0xC7, 0x21, + 0x9A, 0x6B, 0xDE, 0x46, 0x1B, 0x19, 0x73, 0xBE, 0x2B, 0xB8, 0xBD, 0xF0, 0xDA, 0x78, 0xB2, 0xB4 }, }, { - { 0xF7, 0x76, 0x3B, 0xE8, 0x7E, 0x67, 0x8B, 0x31, 0x18, 0x66, 0x11, 0x9A, 0xD5, 0xAC, 0xDF, 0x8F, - 0xDB, 0x3B, 0xBB, 0x46, 0x5B, 0x83, 0x40, 0x61, 0x64, 0xAC, 0x21, 0x30, 0x34, 0xE8, 0xAD, 0x0E }, + { 0xEB, 0x11, 0x63, 0xAA, 0xEF, 0xE8, 0xFD, 0x88, 0xE1, 0x32, 0x7B, 0x48, 0xA9, 0xC0, 0x06, 0x2E, + 0x06, 0xF0, 0xA6, 0xEA, 0xA0, 0xA0, 0x18, 0x24, 0x7F, 0x9F, 0xA4, 0xE3, 0x4E, 0x3A, 0x47, 0x4C }, }, { - { 0xF7, 0x77, 0x35, 0xCE, 0xE3, 0x38, 0x5C, 0xEC, 0xBC, 0x88, 0x4A, 0x54, 0xCE, 0x7F, 0xB1, 0x78, - 0xA0, 0x40, 0x3C, 0x3E, 0x2B, 0x16, 0x9E, 0x49, 0xF9, 0x38, 0xA8, 0x1D, 0xAD, 0x15, 0xDC, 0x1C }, + { 0xEC, 0x4B, 0xBD, 0xEB, 0x15, 0x12, 0x1D, 0x96, 0x76, 0x4D, 0x6C, 0x01, 0xB2, 0x7E, 0xD5, 0xAE, + 0x86, 0x46, 0x5C, 0x46, 0xD5, 0xA4, 0x0E, 0x34, 0xAE, 0xFC, 0x09, 0x2D, 0x3E, 0x8B, 0xB1, 0x76 }, }, { - { 0xF7, 0xB5, 0x97, 0x11, 0xCA, 0xE9, 0x11, 0xEF, 0x56, 0xC8, 0x1B, 0x54, 0x03, 0x6F, 0x21, 0x32, - 0xEC, 0xFA, 0x0F, 0x09, 0x08, 0x90, 0xAF, 0xCA, 0x7E, 0x16, 0x39, 0x4E, 0xD4, 0x99, 0xE8, 0x0C }, + { 0xEC, 0x5F, 0xA4, 0x73, 0x12, 0x1E, 0x3F, 0x49, 0xF0, 0x95, 0x3A, 0x2A, 0x91, 0x83, 0x39, 0xE3, + 0x6F, 0x3C, 0xB6, 0xB8, 0xD8, 0xB8, 0x9E, 0x91, 0x74, 0x23, 0xDA, 0xCE, 0xAC, 0xE6, 0xD5, 0x8A }, }, { - { 0xF7, 0xD9, 0x10, 0xBC, 0xE2, 0xAB, 0x1A, 0xCA, 0xA6, 0x7B, 0x66, 0x3A, 0x8A, 0xDD, 0xBD, 0xA2, - 0x93, 0xB5, 0x1C, 0xED, 0xE7, 0x86, 0x8B, 0x69, 0xA3, 0xCE, 0xA7, 0xFF, 0xD0, 0x10, 0xB3, 0xA8 }, + { 0xEC, 0xCE, 0x4E, 0x52, 0x82, 0xFD, 0x2E, 0xE0, 0x03, 0xA4, 0x03, 0x2C, 0x80, 0xD3, 0x32, 0x1A, + 0x69, 0x47, 0x25, 0x98, 0x94, 0x59, 0x09, 0xCB, 0x25, 0x55, 0x7A, 0xA8, 0x47, 0x74, 0x2D, 0xDF }, }, { - { 0xF8, 0x0C, 0x71, 0x5B, 0x84, 0x49, 0x5D, 0xBE, 0xDA, 0xBF, 0xEB, 0x1B, 0x05, 0x7F, 0xA0, 0x80, - 0x93, 0x10, 0x5D, 0x74, 0x6F, 0x8D, 0x4F, 0x10, 0x35, 0xD4, 0xE1, 0xD8, 0x6B, 0xE2, 0xB4, 0x80 }, + { 0xED, 0x5B, 0xB8, 0x6A, 0x95, 0xA5, 0xFE, 0x2B, 0x17, 0x08, 0xF2, 0x56, 0x75, 0x4A, 0x89, 0xC4, + 0x29, 0x67, 0x9B, 0x30, 0x75, 0x8E, 0xE0, 0x12, 0x2B, 0x9E, 0x50, 0x85, 0x8D, 0xE2, 0x10, 0x4B }, }, { - { 0xF8, 0x24, 0x21, 0x09, 0xF2, 0x80, 0xE3, 0x51, 0xBF, 0xD6, 0x11, 0x95, 0xF8, 0x84, 0x52, 0x5D, - 0xC8, 0xE0, 0x64, 0xD6, 0x85, 0x07, 0x57, 0x49, 0x52, 0x08, 0x3F, 0xAD, 0xCD, 0xCB, 0x91, 0x4B }, + { 0xED, 0xC1, 0xBF, 0x3E, 0xFB, 0xF7, 0xE1, 0xD9, 0x5E, 0x19, 0xC5, 0x5E, 0xCA, 0xE7, 0x7E, 0x83, + 0x69, 0x46, 0xAB, 0x0A, 0x26, 0xA7, 0x8E, 0x32, 0xA4, 0x72, 0xC9, 0xD3, 0x6C, 0x69, 0xCE, 0xCD }, }, { - { 0xF8, 0x2C, 0xC3, 0xC4, 0x5E, 0x9F, 0x62, 0x42, 0x7D, 0xFF, 0xE7, 0x8F, 0x48, 0x8D, 0x5B, 0x5F, - 0x79, 0x2A, 0xF0, 0xBE, 0x06, 0x5D, 0xDD, 0x59, 0xCA, 0x2C, 0x28, 0x61, 0xFB, 0x32, 0xC3, 0x2A }, + { 0xED, 0xF4, 0xDF, 0x97, 0x2C, 0xAD, 0x6C, 0x47, 0x0B, 0xAB, 0x5D, 0x66, 0x42, 0xF6, 0x60, 0xB8, + 0x42, 0xD6, 0xC9, 0x73, 0x07, 0x44, 0x93, 0xE4, 0xEF, 0x1B, 0xBF, 0x31, 0x1A, 0x92, 0x79, 0x95 }, }, { - { 0xF8, 0x64, 0x44, 0x3E, 0x2F, 0x63, 0x9E, 0x7C, 0xFF, 0xD2, 0x42, 0x21, 0xF6, 0x1B, 0xBF, 0xF0, - 0x7C, 0xCE, 0x5C, 0x61, 0xDD, 0xB1, 0x68, 0xB3, 0xB4, 0x04, 0xD7, 0xC8, 0xCD, 0xCA, 0x18, 0xB2 }, + { 0xEE, 0x0C, 0xF6, 0x2B, 0x9D, 0x8E, 0x42, 0xA2, 0x23, 0xB9, 0xA9, 0x60, 0xB5, 0xE9, 0x67, 0x0C, + 0xCC, 0x34, 0x6D, 0x89, 0x93, 0x8F, 0xFA, 0x5D, 0xF7, 0x98, 0x65, 0xE4, 0x13, 0xD6, 0x31, 0x54 }, }, { - { 0xF8, 0x76, 0xC7, 0x3F, 0xAE, 0x72, 0x52, 0x5D, 0x4A, 0xD5, 0x26, 0x69, 0xBC, 0x5A, 0x34, 0xDC, - 0x8D, 0x46, 0x14, 0xE9, 0x3B, 0xFD, 0xEE, 0xEC, 0xA3, 0xD9, 0xBE, 0xCA, 0x97, 0x2E, 0xC6, 0xB8 }, + { 0xEE, 0x34, 0xE1, 0xA1, 0x9B, 0xC8, 0x89, 0xF8, 0x5F, 0x7F, 0x0F, 0x5B, 0xF8, 0x72, 0xB1, 0xAC, + 0x56, 0x5E, 0xC6, 0xF1, 0x9D, 0xB5, 0x17, 0xBA, 0x4E, 0xD7, 0x55, 0xC4, 0x18, 0x5F, 0x69, 0xE8 }, }, { - { 0xF8, 0x81, 0x51, 0xC3, 0xD8, 0x91, 0x6B, 0x1D, 0x03, 0xA0, 0x5F, 0x55, 0x85, 0xEC, 0x38, 0xAD, - 0x1C, 0xC0, 0x3A, 0x36, 0x2E, 0x68, 0x60, 0x8E, 0x39, 0x13, 0xED, 0xDF, 0xB1, 0xFD, 0xF1, 0x27 }, + { 0xEF, 0x36, 0xA2, 0x29, 0x89, 0x65, 0xE4, 0x98, 0x84, 0x59, 0xB9, 0x21, 0x6A, 0xB3, 0x3C, 0x3C, + 0xA8, 0x42, 0xD2, 0x16, 0x83, 0xB6, 0x2A, 0x2B, 0xF1, 0x53, 0x0D, 0x30, 0xB0, 0xAE, 0x78, 0x25 }, }, { - { 0xF8, 0x94, 0xF9, 0x67, 0x36, 0x9C, 0xE7, 0xCF, 0xA3, 0x1A, 0xC1, 0x9A, 0x66, 0x65, 0xB0, 0xC4, - 0x24, 0xBA, 0x40, 0x8A, 0xD5, 0xD3, 0x65, 0xF1, 0x68, 0xD8, 0xBE, 0xEB, 0x79, 0xF4, 0x89, 0xF3 }, + { 0xEF, 0xAF, 0xCA, 0x84, 0x90, 0x30, 0x7B, 0x0F, 0x62, 0x2B, 0xF4, 0x3A, 0x0E, 0xB3, 0xC5, 0x1A, + 0xCB, 0xDD, 0xDE, 0xDC, 0x23, 0x92, 0xF1, 0x61, 0xAC, 0xED, 0x16, 0x71, 0xA6, 0x53, 0x60, 0x7E }, }, { - { 0xF8, 0xCF, 0x1E, 0x08, 0x6A, 0x6A, 0x06, 0x3F, 0xAD, 0x25, 0x74, 0x25, 0xAA, 0xE7, 0x20, 0x01, - 0x40, 0x05, 0xB4, 0x15, 0x91, 0x2D, 0xBB, 0x8C, 0x0B, 0xC9, 0x99, 0xAF, 0x48, 0x48, 0xCF, 0xE5 }, + { 0xEF, 0xD1, 0xE0, 0xE7, 0x3F, 0xA8, 0x71, 0x00, 0xB7, 0x6A, 0x93, 0x23, 0x49, 0xC4, 0x5D, 0x09, + 0xB2, 0x8B, 0x2D, 0x8A, 0x00, 0x17, 0x19, 0xA5, 0x8D, 0xFA, 0xCC, 0x74, 0x84, 0xC7, 0xCF, 0x42 }, }, { - { 0xF9, 0x0E, 0x7C, 0x21, 0x81, 0xBA, 0x53, 0x4D, 0xCF, 0x5B, 0xB6, 0xDB, 0xF7, 0xF9, 0xAD, 0xA3, - 0xFF, 0x98, 0xDE, 0x50, 0x0C, 0xBD, 0x42, 0x12, 0xC0, 0xD1, 0xFA, 0x05, 0x82, 0x80, 0xFD, 0x57 }, + { 0xF0, 0x11, 0xAD, 0x9E, 0xDD, 0x4F, 0xE7, 0x18, 0x8D, 0x77, 0x2E, 0xBA, 0xFA, 0x5B, 0xF5, 0x32, + 0x92, 0x47, 0x77, 0x88, 0xDC, 0x12, 0x80, 0x32, 0x76, 0xB0, 0x00, 0xC4, 0x41, 0x91, 0x03, 0xF0 }, }, { - { 0xF9, 0x29, 0xC1, 0x0E, 0x66, 0x15, 0xB3, 0xE7, 0x1F, 0xDA, 0x31, 0xF1, 0xB7, 0x1A, 0x44, 0x47, - 0x00, 0x7E, 0xE3, 0x7A, 0x39, 0x3C, 0x32, 0xE0, 0xFB, 0x34, 0xFC, 0xF1, 0x05, 0x5D, 0x51, 0x8F }, + { 0xF0, 0x2F, 0x9D, 0xA4, 0x5D, 0x9E, 0xB9, 0x86, 0x19, 0x4E, 0x06, 0xF5, 0xE6, 0x18, 0x95, 0x45, + 0x12, 0xC9, 0x02, 0x6E, 0x7C, 0xA7, 0xB5, 0x1E, 0x66, 0x5D, 0xB6, 0xAD, 0xBA, 0xC1, 0xF6, 0x00 }, }, { - { 0xF9, 0x8B, 0x43, 0x93, 0xF7, 0xC3, 0x1D, 0x37, 0x03, 0x49, 0x81, 0x63, 0xE7, 0x77, 0x9F, 0x75, - 0xDE, 0xF6, 0xAF, 0x44, 0x10, 0x44, 0x6A, 0x03, 0x4D, 0x52, 0x8C, 0xB7, 0x14, 0x3A, 0xA0, 0x13 }, + { 0xF0, 0x6B, 0x35, 0x95, 0x36, 0xD1, 0x34, 0x32, 0x8B, 0x36, 0x00, 0x4D, 0xA9, 0xA9, 0x19, 0x0C, + 0x3A, 0x76, 0x69, 0xE8, 0x27, 0x8D, 0xB9, 0xF7, 0x58, 0x57, 0xC4, 0x8D, 0x64, 0x4B, 0xE2, 0x03 }, }, { - { 0xF9, 0xA7, 0xDD, 0xD3, 0xFF, 0x51, 0xAF, 0x30, 0x7F, 0x95, 0x4F, 0x7B, 0x44, 0xDB, 0xD2, 0x42, - 0x83, 0xCF, 0x97, 0xB6, 0x25, 0xBE, 0x76, 0x6B, 0x43, 0x5E, 0x6C, 0x26, 0xD9, 0xCC, 0xAC, 0xC3 }, + { 0xF0, 0xCF, 0xC7, 0x79, 0x13, 0x39, 0x7D, 0xE2, 0x38, 0xED, 0xB5, 0x9F, 0x0F, 0x99, 0x23, 0xC6, + 0xD4, 0x11, 0x0A, 0x4B, 0x3A, 0xC8, 0xAC, 0x76, 0x55, 0x6A, 0x0C, 0x92, 0x44, 0xF0, 0x3F, 0xC1 }, }, { - { 0xF9, 0xAF, 0xE7, 0x1B, 0xF1, 0xF4, 0x1B, 0xCD, 0xE6, 0x4F, 0x3F, 0x35, 0x82, 0x60, 0xE7, 0x74, - 0x18, 0x76, 0x18, 0x8D, 0xE6, 0x99, 0x04, 0xA6, 0xD0, 0xB6, 0x3A, 0x32, 0x93, 0x02, 0xFA, 0x3D }, + { 0xF2, 0xB1, 0x95, 0x84, 0x6E, 0xE2, 0xB9, 0xAB, 0x5F, 0x18, 0xE6, 0x80, 0x21, 0xF8, 0xDF, 0x7C, + 0x0B, 0x60, 0x58, 0xDE, 0xDE, 0x86, 0xC5, 0xD5, 0x90, 0xF2, 0xE8, 0x64, 0x3A, 0xFE, 0x04, 0x52 }, }, { - { 0xF9, 0xF5, 0xFD, 0xAE, 0x79, 0x59, 0x07, 0x40, 0xB3, 0x85, 0xA8, 0x33, 0x12, 0x7A, 0x28, 0x21, - 0xFB, 0x9D, 0x03, 0xC0, 0xC6, 0xA1, 0xBE, 0x42, 0xEB, 0x2A, 0xBF, 0xD2, 0x0D, 0xF6, 0xB7, 0xB9 }, + { 0xF2, 0xE5, 0x30, 0x0C, 0x39, 0xF2, 0x86, 0xC6, 0x78, 0x99, 0x90, 0x9C, 0x7C, 0xE7, 0x35, 0x9B, + 0x09, 0x45, 0xD2, 0xAF, 0xD3, 0x4A, 0x6D, 0xD6, 0x9E, 0x08, 0xCD, 0xA5, 0x44, 0xC8, 0x7B, 0x3A }, }, { - { 0xF9, 0xFB, 0xFD, 0xD0, 0x91, 0x50, 0x4F, 0x93, 0x08, 0xBC, 0xA0, 0xE3, 0x03, 0x1B, 0xDE, 0x76, - 0x36, 0x62, 0x6B, 0x1E, 0x53, 0x6E, 0xCF, 0xAE, 0x7B, 0xB7, 0x34, 0xC2, 0xE6, 0xD0, 0xE9, 0xDE }, + { 0xF3, 0x0C, 0x0A, 0xED, 0x70, 0x6D, 0x22, 0x55, 0x5F, 0x07, 0x09, 0x6A, 0xF4, 0xB8, 0xBE, 0xDC, + 0x16, 0x3C, 0x0F, 0x6E, 0xD5, 0x34, 0x6E, 0xFC, 0x28, 0xE8, 0xCF, 0xAF, 0x84, 0x2F, 0xA5, 0xD9 }, }, { - { 0xFA, 0x2A, 0x2F, 0x77, 0x8C, 0xBE, 0xF9, 0xF1, 0xB4, 0xA8, 0xFC, 0x57, 0xBF, 0x79, 0x5F, 0x1F, - 0x8C, 0xF6, 0x23, 0xDB, 0x15, 0xBE, 0x65, 0x81, 0xEB, 0xA3, 0x6B, 0x2A, 0x86, 0x49, 0xD2, 0x1E }, + { 0xF6, 0x13, 0xD5, 0x90, 0x46, 0xD1, 0x66, 0x71, 0xD3, 0xC5, 0x60, 0x17, 0x6F, 0x3D, 0x77, 0xFD, + 0xC5, 0x1E, 0x5F, 0x57, 0xB5, 0xE4, 0x8A, 0xE7, 0xA4, 0xB9, 0x70, 0x0A, 0x11, 0xD4, 0x69, 0x3A }, }, { - { 0xFA, 0x50, 0x6B, 0xD0, 0x69, 0x4B, 0x92, 0x94, 0xB9, 0x9F, 0x7B, 0x5C, 0x90, 0x07, 0xCE, 0x13, - 0xA6, 0x03, 0x07, 0xF4, 0xC5, 0x94, 0xEB, 0xFB, 0xE7, 0xB3, 0x4A, 0x05, 0x50, 0xAE, 0x3D, 0x4F }, + { 0xF6, 0x54, 0x6B, 0x2F, 0xFE, 0x2B, 0xAE, 0xF7, 0x35, 0xE8, 0x25, 0x67, 0xA6, 0xE2, 0x36, 0x75, + 0x03, 0x94, 0xC1, 0x19, 0x14, 0x09, 0x87, 0x0C, 0x6F, 0xBE, 0x95, 0x2D, 0x08, 0xA3, 0x3A, 0xBA }, }, { - { 0xFA, 0x83, 0xFB, 0xD3, 0x29, 0x80, 0xB9, 0x55, 0x23, 0xDA, 0xFA, 0xED, 0xFE, 0x15, 0x0E, 0x91, - 0xFF, 0x80, 0xEB, 0xDC, 0xB2, 0xB7, 0x8D, 0x9E, 0x9C, 0x3A, 0x70, 0xFD, 0x79, 0x85, 0x1B, 0x69 }, + { 0xF6, 0xAA, 0xEF, 0x12, 0xFC, 0x25, 0x2D, 0xD9, 0xE7, 0xF7, 0x75, 0x2C, 0x2F, 0x74, 0x5D, 0x59, + 0xD6, 0x37, 0x57, 0xC6, 0xCC, 0x14, 0xD2, 0x25, 0x3A, 0x64, 0x7C, 0xD1, 0x81, 0x49, 0x39, 0x93 }, }, { - { 0xFA, 0x95, 0xB3, 0xF9, 0x6F, 0xC9, 0xC2, 0xD3, 0xA7, 0x9B, 0x05, 0x48, 0x67, 0x6C, 0x18, 0x48, - 0x5A, 0xF1, 0x10, 0x4C, 0xCA, 0x9B, 0xB6, 0xB8, 0xDD, 0x9B, 0x5A, 0x54, 0x3C, 0xB6, 0xC6, 0x2E }, + { 0xF8, 0x64, 0x44, 0x3E, 0x2F, 0x63, 0x9E, 0x7C, 0xFF, 0xD2, 0x42, 0x21, 0xF6, 0x1B, 0xBF, 0xF0, + 0x7C, 0xCE, 0x5C, 0x61, 0xDD, 0xB1, 0x68, 0xB3, 0xB4, 0x04, 0xD7, 0xC8, 0xCD, 0xCA, 0x18, 0xB2 }, }, { - { 0xFA, 0xE4, 0x72, 0x1E, 0x39, 0x47, 0xA5, 0x0D, 0xD0, 0x4D, 0x16, 0xAC, 0xEF, 0xF3, 0x55, 0xC0, - 0x87, 0xB7, 0xE2, 0x24, 0x6B, 0xE6, 0x0F, 0xBC, 0x26, 0x2A, 0x53, 0x52, 0xAD, 0xAC, 0x18, 0x01 }, + { 0xF8, 0x94, 0xF9, 0x67, 0x36, 0x9C, 0xE7, 0xCF, 0xA3, 0x1A, 0xC1, 0x9A, 0x66, 0x65, 0xB0, 0xC4, + 0x24, 0xBA, 0x40, 0x8A, 0xD5, 0xD3, 0x65, 0xF1, 0x68, 0xD8, 0xBE, 0xEB, 0x79, 0xF4, 0x89, 0xF3 }, }, { - { 0xFB, 0x44, 0x15, 0x70, 0x4C, 0x1D, 0x61, 0x55, 0x10, 0x6D, 0x88, 0xF3, 0xB2, 0x0F, 0xEC, 0x9F, - 0x6E, 0x82, 0x0C, 0x82, 0x24, 0xFE, 0xE3, 0x5E, 0x45, 0x22, 0x85, 0x19, 0x05, 0xF3, 0x28, 0xD7 }, + { 0xF8, 0xCF, 0x1E, 0x08, 0x6A, 0x6A, 0x06, 0x3F, 0xAD, 0x25, 0x74, 0x25, 0xAA, 0xE7, 0x20, 0x01, + 0x40, 0x05, 0xB4, 0x15, 0x91, 0x2D, 0xBB, 0x8C, 0x0B, 0xC9, 0x99, 0xAF, 0x48, 0x48, 0xCF, 0xE5 }, }, { { 0xFB, 0x9A, 0xF7, 0x9D, 0xEA, 0x18, 0xAF, 0x62, 0x99, 0x85, 0x0E, 0x25, 0x15, 0x9B, 0x4F, 0xB2, @@ -5592,10 +1588,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0xFB, 0xC4, 0xC9, 0xBA, 0xCF, 0xE3, 0xDA, 0x64, 0x13, 0x18, 0x26, 0x6B, 0x72, 0x58, 0x56, 0x00, 0x35, 0xBC, 0x64, 0x60, 0x8E, 0x34, 0xB9, 0x90, 0xCA, 0x92, 0xA5, 0x52, 0xF3, 0x14, 0x21, 0x61 }, }, - { - { 0xFB, 0xDD, 0x65, 0xD5, 0x6E, 0x48, 0x0C, 0xD2, 0x53, 0x1B, 0xAB, 0xFB, 0x98, 0xAD, 0x6E, 0x35, - 0x22, 0x1E, 0xB9, 0x8A, 0xE4, 0x63, 0x2C, 0x43, 0x12, 0xDB, 0x75, 0x17, 0xB1, 0x36, 0x54, 0x72 }, - }, { { 0xFB, 0xED, 0xD3, 0x88, 0x89, 0xF0, 0xB4, 0x1F, 0x73, 0x4D, 0xE2, 0xF4, 0xC9, 0xD6, 0xF2, 0x7C, 0x8D, 0x4A, 0xA9, 0xAB, 0x73, 0x64, 0x91, 0xE1, 0x64, 0xE1, 0x21, 0xB7, 0xBC, 0xAF, 0x44, 0xE8 }, @@ -5604,26 +1596,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0xFC, 0x01, 0xA5, 0x5A, 0x36, 0xCC, 0x8B, 0x7B, 0x7C, 0xA2, 0xEA, 0xB0, 0x84, 0x60, 0xC2, 0x8D, 0x1D, 0x6C, 0xD8, 0x9C, 0x57, 0x59, 0x94, 0x05, 0xD5, 0x37, 0x4B, 0x91, 0xAA, 0xEB, 0xC8, 0x79 }, }, - { - { 0xFC, 0x11, 0xD0, 0x51, 0xC2, 0x7A, 0x33, 0xA2, 0xE8, 0x1C, 0xB7, 0x20, 0xA9, 0xE6, 0xD8, 0xA7, - 0xFE, 0x3C, 0x5D, 0x94, 0x13, 0x9C, 0xBA, 0x0F, 0x5E, 0xAA, 0x61, 0xBA, 0xBE, 0x34, 0x1A, 0x8B }, - }, - { - { 0xFC, 0x2F, 0x1E, 0x84, 0x29, 0x82, 0xC9, 0x3B, 0x85, 0xD2, 0x79, 0xA8, 0x3D, 0xF2, 0x13, 0xC1, - 0xA3, 0x33, 0x29, 0x7D, 0x42, 0xA3, 0x1A, 0x8C, 0xC7, 0x8A, 0x3F, 0x73, 0xCD, 0xF8, 0xAF, 0x9A }, - }, { { 0xFC, 0x4D, 0x9A, 0x37, 0xE5, 0xF7, 0x32, 0x72, 0xD0, 0xA9, 0xDF, 0xCC, 0xE9, 0x03, 0x12, 0xC7, 0x52, 0xE1, 0xB5, 0x2E, 0xB6, 0x54, 0xC4, 0x2C, 0x36, 0x94, 0x4B, 0x90, 0x2A, 0x30, 0x41, 0x07 }, }, - { - { 0xFC, 0x53, 0x0D, 0x33, 0x87, 0x60, 0xB5, 0x92, 0x47, 0x55, 0xE1, 0x55, 0x62, 0x34, 0xF0, 0x2D, - 0x84, 0x04, 0x71, 0x11, 0x08, 0xF1, 0xB7, 0xC8, 0xE4, 0x8C, 0x05, 0xDB, 0x84, 0xF8, 0xBA, 0x7F }, - }, - { - { 0xFC, 0x55, 0x86, 0x91, 0xDA, 0xFF, 0xE1, 0xE3, 0x53, 0x8D, 0x38, 0xA6, 0xD3, 0xA9, 0xE6, 0xE7, - 0xC9, 0x9D, 0x24, 0x0C, 0x86, 0x89, 0x66, 0x73, 0x56, 0x27, 0x99, 0x72, 0xFB, 0x4F, 0x30, 0x85 }, - }, { { 0xFC, 0x56, 0xDB, 0xA1, 0xE7, 0xAF, 0xBD, 0xAA, 0x07, 0x33, 0xC6, 0x91, 0x1C, 0x5F, 0x1F, 0x18, 0x28, 0xCB, 0x12, 0x98, 0x31, 0x40, 0x1A, 0x3C, 0xFD, 0xEA, 0xA7, 0x24, 0x62, 0x95, 0x35, 0x94 }, @@ -5636,30 +1612,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0xFC, 0xA6, 0x23, 0x5D, 0x2A, 0xA4, 0xB1, 0xB2, 0x51, 0x50, 0x78, 0x57, 0xB4, 0xF0, 0x08, 0xDF, 0xD5, 0x27, 0x04, 0x2C, 0xE0, 0x45, 0x01, 0xAA, 0xE2, 0x9D, 0xD2, 0x05, 0xBB, 0xEF, 0xCE, 0x0D }, }, - { - { 0xFC, 0xB7, 0xFE, 0x6D, 0x32, 0x2D, 0x87, 0xC7, 0x51, 0x59, 0x47, 0x79, 0x50, 0x88, 0x95, 0x8A, - 0x5F, 0x75, 0xBF, 0xF1, 0x18, 0x40, 0x21, 0xEF, 0x05, 0xD6, 0xF4, 0xD3, 0xC4, 0x3B, 0x85, 0xC5 }, - }, - { - { 0xFC, 0xE5, 0x47, 0xE1, 0x43, 0x54, 0x87, 0x7F, 0xED, 0x93, 0x0B, 0x19, 0xFD, 0xE7, 0xC6, 0xF9, - 0xCB, 0xF5, 0xD4, 0xB5, 0x7B, 0xA5, 0x34, 0x4A, 0x0D, 0x40, 0x10, 0xFF, 0x70, 0x5A, 0x03, 0xDE }, - }, { { 0xFC, 0xE7, 0x34, 0xE1, 0x2B, 0x8E, 0xFB, 0x43, 0x12, 0x71, 0xBF, 0xF6, 0x7A, 0x7A, 0x0A, 0x93, 0xB2, 0x19, 0xDD, 0x5E, 0x5D, 0xCC, 0x12, 0x58, 0x59, 0x4D, 0x96, 0xFC, 0xE1, 0x93, 0xB8, 0x60 }, }, - { - { 0xFC, 0xF6, 0x81, 0x39, 0x64, 0x2F, 0x8D, 0x79, 0xA4, 0x86, 0x15, 0xE4, 0x44, 0xCE, 0xD6, 0x90, - 0xFA, 0x60, 0xEB, 0xFD, 0x0A, 0x06, 0x0A, 0x49, 0x93, 0x89, 0x98, 0x8A, 0x2C, 0x2C, 0x05, 0xCE }, - }, - { - { 0xFD, 0x44, 0x89, 0xF0, 0x27, 0x27, 0xDB, 0x36, 0xC1, 0x84, 0x35, 0xE5, 0xC4, 0xA9, 0xF8, 0x63, - 0xAC, 0xD8, 0x04, 0xAE, 0x1B, 0x39, 0x7F, 0xBB, 0x83, 0xD4, 0x27, 0x5A, 0xF5, 0x6D, 0xF8, 0x9F }, - }, - { - { 0xFD, 0x85, 0xCC, 0x72, 0x1B, 0x77, 0xC4, 0x41, 0xC8, 0xB1, 0xF1, 0x4A, 0xDE, 0x34, 0x8A, 0x3E, - 0xC9, 0xFA, 0xA6, 0x26, 0x4A, 0x91, 0x3F, 0xB8, 0xD3, 0x4C, 0x98, 0x3B, 0x43, 0x60, 0xE9, 0x7B }, - }, { { 0xFD, 0x9C, 0xFE, 0x14, 0xDA, 0xD8, 0x97, 0x8C, 0x5B, 0xC8, 0x88, 0x93, 0x8F, 0x16, 0xF3, 0xB3, 0x98, 0xF7, 0x63, 0xA3, 0xAD, 0xAF, 0xAA, 0x4A, 0xD9, 0x41, 0xB7, 0xE3, 0x87, 0xEB, 0x4F, 0x4A }, @@ -5668,10 +1624,6 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0xFD, 0xED, 0x92, 0xCB, 0x40, 0x91, 0x66, 0x82, 0x3A, 0x35, 0xE2, 0x17, 0xF3, 0x0B, 0x38, 0xC4, 0x86, 0xF8, 0x3E, 0xF2, 0xD4, 0xF2, 0x7B, 0x05, 0xF1, 0x8C, 0x74, 0x49, 0x81, 0x33, 0x9A, 0x1C }, }, - { - { 0xFE, 0x0F, 0x6A, 0xDC, 0x4C, 0xB9, 0xA1, 0x3F, 0xCB, 0xAF, 0xD8, 0x98, 0xC1, 0xBB, 0x53, 0xB3, - 0xD9, 0x33, 0x74, 0x49, 0x9D, 0xF3, 0x47, 0xB7, 0x1F, 0x13, 0x4C, 0x94, 0x3C, 0x4F, 0xF1, 0x20 }, - }, { { 0xFE, 0x26, 0xB2, 0xA6, 0x45, 0xA3, 0x1A, 0x91, 0x11, 0x00, 0x09, 0x9A, 0xA9, 0xA2, 0x93, 0x9F, 0x49, 0xE9, 0xFB, 0xEA, 0x64, 0x48, 0x7B, 0xDF, 0x68, 0xA5, 0x23, 0x70, 0x32, 0x92, 0xD6, 0xA0 }, @@ -5684,42 +1636,10 @@ static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = { { 0xFE, 0x4F, 0x35, 0x6C, 0x7F, 0x9B, 0xFC, 0x17, 0xFF, 0xCB, 0x68, 0xD0, 0x76, 0x4E, 0xCB, 0x2A, 0x87, 0xCA, 0xA0, 0xAE, 0x4C, 0xB5, 0x66, 0x62, 0x21, 0x04, 0xD3, 0x6F, 0xFB, 0x52, 0xCB, 0x29 }, }, - { - { 0xFE, 0xAA, 0xBD, 0xD7, 0x92, 0xA4, 0x31, 0x68, 0x99, 0x98, 0x3E, 0xF5, 0x7B, 0xEA, 0x99, 0xBE, - 0x81, 0x15, 0x6D, 0x47, 0x9C, 0xDF, 0x7B, 0x81, 0xF5, 0x58, 0x49, 0x60, 0x92, 0xD3, 0x17, 0x16 }, - }, - { - { 0xFE, 0xB8, 0xF0, 0x0C, 0x83, 0xEA, 0x05, 0xBD, 0xA2, 0x85, 0x0E, 0xC5, 0xBB, 0x77, 0x43, 0xE4, - 0x42, 0xEB, 0xF4, 0x31, 0xE3, 0xBA, 0x75, 0x4A, 0xA2, 0xD9, 0x47, 0x5E, 0x98, 0x0B, 0x6E, 0x3A }, - }, - { - { 0xFE, 0xC5, 0xFF, 0x1D, 0x4E, 0x56, 0x49, 0xB0, 0x1F, 0xBA, 0xAB, 0xD9, 0x02, 0x2D, 0xBF, 0x86, - 0xA7, 0x60, 0x2D, 0x89, 0x04, 0x45, 0x1B, 0xF4, 0x93, 0xC4, 0xAF, 0xE1, 0x1C, 0x99, 0xAE, 0x07 }, - }, - { - { 0xFE, 0xFF, 0x60, 0xF2, 0xDA, 0x22, 0xC9, 0xDB, 0xBC, 0x3D, 0x10, 0x13, 0x1E, 0xE4, 0x39, 0xBA, - 0xE3, 0xE0, 0x0E, 0x58, 0xCC, 0xE0, 0xBD, 0x07, 0x4F, 0x55, 0xF7, 0x7C, 0x3B, 0x00, 0xF9, 0x35 }, - }, - { - { 0xFF, 0x0E, 0x31, 0x58, 0x55, 0x2A, 0x28, 0x10, 0xA9, 0x71, 0x3D, 0xE8, 0x3B, 0x03, 0x25, 0xA1, - 0x16, 0x4A, 0xA6, 0x0E, 0x9C, 0xE5, 0x74, 0x20, 0x1D, 0x6B, 0x9B, 0x8B, 0xEA, 0xBA, 0x1F, 0x47 }, - }, - { - { 0xFF, 0x4C, 0x40, 0xA0, 0x13, 0xA4, 0x1E, 0x5A, 0xDB, 0x23, 0x1A, 0x14, 0xA9, 0x77, 0xB5, 0x8C, - 0x4F, 0xE7, 0x8D, 0x0C, 0xA3, 0x5C, 0x59, 0x35, 0xE2, 0x22, 0x07, 0x21, 0xCC, 0x54, 0x14, 0xF3 }, - }, { { 0xFF, 0x82, 0x6E, 0x2D, 0x0C, 0xB7, 0x71, 0x68, 0x68, 0x67, 0x5A, 0xE4, 0xB4, 0x31, 0xB6, 0x37, 0x1E, 0x9F, 0x0C, 0xDF, 0xCC, 0xB4, 0x9D, 0x43, 0xBA, 0x30, 0x49, 0xBF, 0xDD, 0x2C, 0x41, 0xB1 }, }, - { - { 0xFF, 0xC9, 0x74, 0x1A, 0x5E, 0x6A, 0x5A, 0x7C, 0xC3, 0xBB, 0x10, 0xCA, 0x31, 0x3F, 0x97, 0x7A, - 0xA9, 0xCC, 0xC1, 0x92, 0x28, 0xDB, 0xE1, 0x39, 0xB0, 0xC2, 0xD9, 0xF1, 0xF4, 0x1D, 0x83, 0x1B }, - }, - { - { 0xFF, 0xD5, 0x3F, 0x73, 0x6D, 0x4E, 0x0D, 0xC3, 0xBE, 0x8E, 0x43, 0xD9, 0x15, 0x09, 0xE0, 0x44, - 0x79, 0x1D, 0x36, 0xD4, 0x49, 0x12, 0xA6, 0xFA, 0xBA, 0x52, 0x28, 0x25, 0x10, 0x0E, 0x0A, 0x7C }, - }, { { 0xFF, 0xDC, 0x6B, 0x85, 0xFE, 0x7B, 0x10, 0x83, 0xB5, 0x41, 0x6F, 0x80, 0x6F, 0xC2, 0x44, 0xB9, 0xE4, 0xDF, 0x42, 0x99, 0xFB, 0xE3, 0xF6, 0x81, 0xAF, 0x3F, 0x5C, 0xF4, 0x22, 0x5A, 0x8E, 0xAF }, diff --git a/src/StartComAndWoSignData.inc b/src/StartComAndWoSignData.inc new file mode 100644 index 00000000000000..3ba643397c7ff9 --- /dev/null +++ b/src/StartComAndWoSignData.inc @@ -0,0 +1,89 @@ +// /C=CN/O=WoSign CA Limited/CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6 +// Using a consistent naming convention, this would actually be called +// 'CA沃通根证书DN', but since GCC 6.2.1 apparently can't handle UTF-8 +// identifiers, this will have to do. +static const uint8_t CAWoSignRootDN[72] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x12, 0x43, 0x41, 0x20, 0xE6, 0xB2, 0x83, 0xE9, 0x80, 0x9A, 0xE6, 0xA0, + 0xB9, 0xE8, 0xAF, 0x81, 0xE4, 0xB9, 0xA6, +}; + +// /C=CN/O=WoSign CA Limited/CN=CA WoSign ECC Root +static const uint8_t CAWoSignECCRootDN[72] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x12, 0x43, 0x41, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, + 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, +}; + +// /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +static const uint8_t CertificationAuthorityofWoSignDN[87] = { + 0x30, 0x55, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, +}; + +// /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign G2 +static const uint8_t CertificationAuthorityofWoSignG2DN[90] = { + 0x30, 0x58, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x24, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, 0x32, +}; + +// /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority +static const uint8_t StartComCertificationAuthorityDN[127] = { + 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E, + 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, + 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, +}; + +// /C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +static const uint8_t StartComCertificationAuthorityG2DN[85] = { + 0x30, 0x53, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E, + 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32, +}; + +struct DataAndLength { + const uint8_t* data; + uint32_t len; +}; + +static const DataAndLength StartComAndWoSignDNs[]= { + { CAWoSignRootDN, + sizeof(CAWoSignRootDN) }, + { CAWoSignECCRootDN, + sizeof(CAWoSignECCRootDN) }, + { CertificationAuthorityofWoSignDN, + sizeof(CertificationAuthorityofWoSignDN) }, + { CertificationAuthorityofWoSignG2DN, + sizeof(CertificationAuthorityofWoSignG2DN) }, + { StartComCertificationAuthorityDN, + sizeof(StartComCertificationAuthorityDN) }, + { StartComCertificationAuthorityG2DN, + sizeof(StartComCertificationAuthorityG2DN) }, +}; diff --git a/src/connection_wrap.cc b/src/connection_wrap.cc index 41571946b22e4f..020fe8b4c9508c 100644 --- a/src/connection_wrap.cc +++ b/src/connection_wrap.cc @@ -99,11 +99,10 @@ void ConnectionWrap::AfterConnect(uv_connect_t* req, writable = uv_is_writable(req->handle) != 0; } - Local req_wrap_obj = req_wrap->object(); Local argv[5] = { Integer::New(env->isolate(), status), wrap->object(), - req_wrap_obj, + req_wrap->object(), Boolean::New(env->isolate(), readable), Boolean::New(env->isolate(), writable) }; diff --git a/src/env-inl.h b/src/env-inl.h index 0981a09aeb4bed..002683f89095ca 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -396,22 +396,22 @@ inline std::vector* Environment::destroy_ids_list() { return &destroy_ids_list_; } -inline uint32_t* Environment::heap_statistics_buffer() const { +inline double* Environment::heap_statistics_buffer() const { CHECK_NE(heap_statistics_buffer_, nullptr); return heap_statistics_buffer_; } -inline void Environment::set_heap_statistics_buffer(uint32_t* pointer) { +inline void Environment::set_heap_statistics_buffer(double* pointer) { CHECK_EQ(heap_statistics_buffer_, nullptr); // Should be set only once. heap_statistics_buffer_ = pointer; } -inline uint32_t* Environment::heap_space_statistics_buffer() const { +inline double* Environment::heap_space_statistics_buffer() const { CHECK_NE(heap_space_statistics_buffer_, nullptr); return heap_space_statistics_buffer_; } -inline void Environment::set_heap_space_statistics_buffer(uint32_t* pointer) { +inline void Environment::set_heap_space_statistics_buffer(double* pointer) { CHECK_EQ(heap_space_statistics_buffer_, nullptr); // Should be set only once. heap_space_statistics_buffer_ = pointer; } diff --git a/src/env.h b/src/env.h index 3b6c42064fa59b..a10e699e0a73c3 100644 --- a/src/env.h +++ b/src/env.h @@ -105,7 +105,6 @@ namespace node { V(exponent_string, "exponent") \ V(exports_string, "exports") \ V(ext_key_usage_string, "ext_key_usage") \ - V(external_string, "external") \ V(external_stream_string, "_externalStream") \ V(family_string, "family") \ V(fatal_exception_string, "_fatalException") \ @@ -115,8 +114,6 @@ namespace node { V(flags_string, "flags") \ V(gid_string, "gid") \ V(handle_string, "handle") \ - V(heap_total_string, "heapTotal") \ - V(heap_used_string, "heapUsed") \ V(homedir_string, "homedir") \ V(hostmaster_string, "hostmaster") \ V(ignore_string, "ignore") \ @@ -184,7 +181,6 @@ namespace node { V(rename_string, "rename") \ V(replacement_string, "replacement") \ V(retry_string, "retry") \ - V(rss_string, "rss") \ V(serial_string, "serial") \ V(scopeid_string, "scopeid") \ V(sent_shutdown_string, "sentShutdown") \ @@ -458,11 +454,11 @@ class Environment { // List of id's that have been destroyed and need the destroy() cb called. inline std::vector* destroy_ids_list(); - inline uint32_t* heap_statistics_buffer() const; - inline void set_heap_statistics_buffer(uint32_t* pointer); + inline double* heap_statistics_buffer() const; + inline void set_heap_statistics_buffer(double* pointer); - inline uint32_t* heap_space_statistics_buffer() const; - inline void set_heap_space_statistics_buffer(uint32_t* pointer); + inline double* heap_space_statistics_buffer() const; + inline void set_heap_space_statistics_buffer(double* pointer); inline char* http_parser_buffer() const; inline void set_http_parser_buffer(char* buffer); @@ -578,8 +574,8 @@ class Environment { &HandleCleanup::handle_cleanup_queue_> handle_cleanup_queue_; int handle_cleanup_waiting_; - uint32_t* heap_statistics_buffer_ = nullptr; - uint32_t* heap_space_statistics_buffer_ = nullptr; + double* heap_statistics_buffer_ = nullptr; + double* heap_space_statistics_buffer_ = nullptr; char* http_parser_buffer_; diff --git a/src/node.cc b/src/node.cc index 4ecfc0489c94ee..fe2fc2a6a4eda6 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2248,7 +2248,7 @@ static void WaitForInspectorDisconnect(Environment* env) { if (env->inspector_agent()->IsConnected()) { // Restore signal dispositions, the app is done and is no longer // capable of handling signals. -#ifdef __POSIX__ +#if defined(__POSIX__) && !defined(NODE_SHARED_MODE) struct sigaction act; memset(&act, 0, sizeof(act)); for (unsigned nr = 1; nr < kMaxSignal; nr += 1) { @@ -2290,25 +2290,22 @@ void MemoryUsage(const FunctionCallbackInfo& args) { return env->ThrowUVException(err, "uv_resident_set_memory"); } + Isolate* isolate = env->isolate(); // V8 memory usage HeapStatistics v8_heap_stats; - env->isolate()->GetHeapStatistics(&v8_heap_stats); - - Local heap_total = - Number::New(env->isolate(), v8_heap_stats.total_heap_size()); - Local heap_used = - Number::New(env->isolate(), v8_heap_stats.used_heap_size()); - Local external_mem = - Number::New(env->isolate(), - env->isolate()->AdjustAmountOfExternalAllocatedMemory(0)); + isolate->GetHeapStatistics(&v8_heap_stats); - Local info = Object::New(env->isolate()); - info->Set(env->rss_string(), Number::New(env->isolate(), rss)); - info->Set(env->heap_total_string(), heap_total); - info->Set(env->heap_used_string(), heap_used); - info->Set(env->external_string(), external_mem); + // Get the double array pointer from the Float64Array argument. + CHECK(args[0]->IsFloat64Array()); + Local array = args[0].As(); + CHECK_EQ(array->Length(), 4); + Local ab = array->Buffer(); + double* fields = static_cast(ab->GetContents().Data()); - args.GetReturnValue().Set(info); + fields[0] = rss; + fields[1] = v8_heap_stats.total_heap_size(); + fields[2] = v8_heap_stats.used_heap_size(); + fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0); } @@ -2420,8 +2417,6 @@ struct node_module* get_linked_module(const char* name) { return mp; } -typedef void (UV_DYNAMIC* extInit)(Local exports); - // DLOpen is process.dlopen(module, filename). // Used to load 'module.node' dynamically shared objects. // @@ -3709,7 +3704,14 @@ static void PrintHelp() { " (will extend linked-in data)\n" #endif #endif - "NODE_REPL_HISTORY path to the persistent REPL history file\n" + "NODE_NO_WARNINGS set to 1 to silence process warnings\n" +#ifdef _WIN32 + "NODE_PATH ';'-separated list of directories\n" +#else + "NODE_PATH ':'-separated list of directories\n" +#endif + " prefixed to the module search path\n" + "NODE_REPL_HISTORY path to the persistent REPL history file\n" "\n" "Documentation can be found at https://nodejs.org/\n"); } @@ -4256,6 +4258,7 @@ inline void PlatformInit() { CHECK_EQ(err, 0); +#ifndef NODE_SHARED_MODE // Restore signal dispositions, the parent process may have changed them. struct sigaction act; memset(&act, 0, sizeof(act)); @@ -4269,6 +4272,7 @@ inline void PlatformInit() { act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL; CHECK_EQ(0, sigaction(nr, &act, nullptr)); } +#endif // !NODE_SHARED_MODE RegisterSignalHandler(SIGINT, SignalExit, true); RegisterSignalHandler(SIGTERM, SignalExit, true); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 47d7d6194e6a9d..b8b60e97adcd17 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -254,7 +254,8 @@ class ContextifyContext { Environment* env = Environment::GetCurrent(args); if (debug_context.IsEmpty()) { // Force-load the debug context. - Debug::GetMirror(args.GetIsolate()->GetCurrentContext(), args[0]); + auto dummy_event_listener = [] (const Debug::EventDetails&) {}; + Debug::SetDebugEventListener(args.GetIsolate(), dummy_event_listener); debug_context = Debug::GetDebugContext(args.GetIsolate()); CHECK(!debug_context.IsEmpty()); // Ensure that the debug context has an Environment assigned in case @@ -440,8 +441,12 @@ class ContextifyContext { Maybe success = ctx->sandbox()->Delete(ctx->context(), property); - if (success.IsJust()) - args.GetReturnValue().Set(success.FromJust()); + if (success.FromMaybe(false)) + return; + + // Delete failed on the sandbox, intercept and do not delete on + // the global object. + args.GetReturnValue().Set(false); } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 482ec230c0f450..580da8820c9a56 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -17,6 +17,10 @@ // https://hg.mozilla.org/mozilla-central/raw-file/98820360ab66/security/ // certverifier/CNNICHashWhitelist.inc #include "CNNICHashWhitelist.inc" +// StartCom and WoSign root CA list is taken from +// https://hg.mozilla.org/mozilla-central/file/tip/security/certverifier/ +// StartComAndWoSignData.inc +#include "StartComAndWoSignData.inc" #include #include // INT_MAX @@ -698,11 +702,8 @@ static X509_STORE* NewRootCertStore() { X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr); BIO_free(bp); - if (x509 == nullptr) { - // Parse errors from the built-in roots are fatal. - abort(); - return nullptr; - } + // Parse errors from the built-in roots are fatal. + CHECK_NE(x509, nullptr); root_certs_vector->push_back(x509); } @@ -1147,10 +1148,14 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo& args) { void SecureContext::SetFreeListLength(const FunctionCallbackInfo& args) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(OPENSSL_IS_BORINGSSL) + // |freelist_max_len| was removed in OpenSSL 1.1.0. In that version OpenSSL + // mallocs and frees buffers directly, without the use of a freelist. SecureContext* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); wrap->ctx_->freelist_max_len = args[0]->Int32Value(); +#endif } @@ -2756,9 +2761,40 @@ inline X509* FindRoot(STACK_OF(X509)* sk) { } -// Whitelist check for certs issued by CNNIC. See +inline bool CertIsStartComOrWoSign(X509_NAME* name) { + const unsigned char* startcom_wosign_data; + X509_NAME* startcom_wosign_name; + + for (const auto& dn : StartComAndWoSignDNs) { + startcom_wosign_data = dn.data; + startcom_wosign_name = d2i_X509_NAME(nullptr, &startcom_wosign_data, + dn.len); + if (X509_NAME_cmp(name, startcom_wosign_name) == 0) + return true; + } + + return false; +} + +// Revoke the certificates issued by StartCom or WoSign that has +// notBefore after 00:00:00 on October 21, 2016 (1477008000 in epoch). +inline bool CheckStartComOrWoSign(X509_NAME* root_name, X509* cert) { + if (!CertIsStartComOrWoSign(root_name)) + return true; + + time_t october_21_2016 = static_cast(1477008000); + if (X509_cmp_time(X509_get_notBefore(cert), &october_21_2016) < 0) + return true; + + return false; +} + + +// Whitelist check for certs issued by CNNIC, StartCom and WoSign. See // https://blog.mozilla.org/security/2015/04/02 -// /distrusting-new-cnnic-certificates/ +// /distrusting-new-cnnic-certificates/ and +// https://blog.mozilla.org/security/2016/10/24/ +// distrusting-new-wosign-and-startcom-certificates inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) { unsigned char hash[CNNIC_WHITELIST_HASH_LEN]; unsigned int hashlen = CNNIC_WHITELIST_HASH_LEN; @@ -2777,11 +2813,14 @@ inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) { root_name = X509_get_subject_name(root_cert); } + X509* leaf_cert = sk_X509_value(chain, 0); + if (!CheckStartComOrWoSign(root_name, leaf_cert)) + return CHECK_CERT_REVOKED; + // When the cert is issued from either CNNNIC ROOT CA or CNNNIC EV // ROOT CA, check a hash of its leaf cert if it is in the whitelist. if (X509_NAME_cmp(root_name, cnnic_name) == 0 || X509_NAME_cmp(root_name, cnnic_ev_name) == 0) { - X509* leaf_cert = sk_X509_value(chain, 0); int ret = X509_digest(leaf_cert, EVP_sha256(), hash, &hashlen); CHECK(ret); @@ -3689,8 +3728,8 @@ void Hmac::HmacInit(const FunctionCallbackInfo& args) { bool Hmac::HmacUpdate(const char* data, int len) { if (!initialised_) return false; - HMAC_Update(&ctx_, reinterpret_cast(data), len); - return true; + int r = HMAC_Update(&ctx_, reinterpret_cast(data), len); + return r == 1; } diff --git a/src/node_file.cc b/src/node_file.cc index 70f99c09f6f23a..90c88e5cb33e8b 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -27,8 +27,10 @@ namespace node { using v8::Array; +using v8::ArrayBuffer; using v8::Context; using v8::EscapableHandleScope; +using v8::Float64Array; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -528,6 +530,37 @@ Local BuildStatsObject(Environment* env, const uv_stat_t* s) { return handle_scope.Escape(stats); } +void FillStatsArray(double* fields, const uv_stat_t* s) { + fields[0] = s->st_dev; + fields[1] = s->st_mode; + fields[2] = s->st_nlink; + fields[3] = s->st_uid; + fields[4] = s->st_gid; + fields[5] = s->st_rdev; +#if defined(__POSIX__) + fields[6] = s->st_blksize; +#else + fields[6] = -1; +#endif + fields[7] = s->st_ino; + fields[8] = s->st_size; +#if defined(__POSIX__) + fields[9] = s->st_blocks; +#else + fields[9] = -1; +#endif + // Dates. +#define X(idx, name) \ + fields[idx] = (static_cast(s->st_##name.tv_sec) * 1000) + \ + (static_cast(s->st_##name.tv_nsec / 1000000)); \ + + X(10, atim) + X(11, mtim) + X(12, ctim) + X(13, birthtim) +#undef X +} + // Used to speed up module loading. Returns the contents of the file as // a string or undefined when the file cannot be opened. The speedup // comes from not creating Error objects on failure. @@ -618,12 +651,15 @@ static void Stat(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); ASSERT_PATH(path) - if (args[1]->IsObject()) { - ASYNC_CALL(stat, args[1], UTF8, *path) - } else { + if (args[1]->IsFloat64Array()) { + Local array = args[1].As(); + CHECK_EQ(array->Length(), 14); + Local ab = array->Buffer(); + double* fields = static_cast(ab->GetContents().Data()); SYNC_CALL(stat, *path, *path) - args.GetReturnValue().Set( - BuildStatsObject(env, static_cast(SYNC_REQ.ptr))); + FillStatsArray(fields, static_cast(SYNC_REQ.ptr)); + } else if (args[1]->IsObject()) { + ASYNC_CALL(stat, args[1], UTF8, *path) } } @@ -636,12 +672,15 @@ static void LStat(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); ASSERT_PATH(path) - if (args[1]->IsObject()) { - ASYNC_CALL(lstat, args[1], UTF8, *path) - } else { + if (args[1]->IsFloat64Array()) { + Local array = args[1].As(); + CHECK_EQ(array->Length(), 14); + Local ab = array->Buffer(); + double* fields = static_cast(ab->GetContents().Data()); SYNC_CALL(lstat, *path, *path) - args.GetReturnValue().Set( - BuildStatsObject(env, static_cast(SYNC_REQ.ptr))); + FillStatsArray(fields, static_cast(SYNC_REQ.ptr)); + } else if (args[1]->IsObject()) { + ASYNC_CALL(lstat, args[1], UTF8, *path) } } @@ -655,12 +694,15 @@ static void FStat(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - if (args[1]->IsObject()) { - ASYNC_CALL(fstat, args[1], UTF8, fd) - } else { + if (args[1]->IsFloat64Array()) { + Local array = args[1].As(); + CHECK_EQ(array->Length(), 14); + Local ab = array->Buffer(); + double* fields = static_cast(ab->GetContents().Data()); SYNC_CALL(fstat, 0, fd) - args.GetReturnValue().Set( - BuildStatsObject(env, static_cast(SYNC_REQ.ptr))); + FillStatsArray(fields, static_cast(SYNC_REQ.ptr)); + } else if (args[1]->IsObject()) { + ASYNC_CALL(fstat, args[1], UTF8, fd) } } diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index f757cd6797058d..bc9b5d953e8ebf 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -15,7 +15,7 @@ #include // free() #include // strdup() -// This is a binding to http_parser (https://github.com/joyent/http-parser) +// This is a binding to http_parser (https://github.com/nodejs/http-parser) // The goal is to decouple sockets from parsing for more javascript-level // agility. A Buffer is read from a socket and passed to parser.execute(). // The parser then issues callbacks with slices of the data diff --git a/src/node_javascript.cc b/src/node_javascript.cc deleted file mode 100644 index 3f6d6c82a85269..00000000000000 --- a/src/node_javascript.cc +++ /dev/null @@ -1,51 +0,0 @@ -#include "node.h" -#include "node_natives.h" -#include "v8.h" -#include "env.h" -#include "env-inl.h" - -namespace node { - -using v8::Local; -using v8::NewStringType; -using v8::Object; -using v8::String; - -// id##_data is defined in node_natives.h. -#define V(id) \ - static struct : public String::ExternalOneByteStringResource { \ - const char* data() const override { \ - return reinterpret_cast(id##_data); \ - } \ - size_t length() const override { return sizeof(id##_data); } \ - void Dispose() override { /* Default calls `delete this`. */ } \ - } id##_external_data; -NODE_NATIVES_MAP(V) -#undef V - -Local MainSource(Environment* env) { - auto maybe_string = - String::NewExternalOneByte( - env->isolate(), - &internal_bootstrap_node_external_data); - return maybe_string.ToLocalChecked(); -} - -void DefineJavaScript(Environment* env, Local target) { - auto context = env->context(); -#define V(id) \ - do { \ - auto key = \ - String::NewFromOneByte( \ - env->isolate(), id##_name, NewStringType::kNormal, \ - sizeof(id##_name)).ToLocalChecked(); \ - auto value = \ - String::NewExternalOneByte( \ - env->isolate(), &id##_external_data).ToLocalChecked(); \ - CHECK(target->Set(context, key, value).FromJust()); \ - } while (0); - NODE_NATIVES_MAP(V) -#undef V -} - -} // namespace node diff --git a/src/node_os.cc b/src/node_os.cc index f8b53e45d8e669..211ac3d01dd8b2 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -28,8 +28,10 @@ namespace node { namespace os { using v8::Array; +using v8::ArrayBuffer; using v8::Boolean; using v8::Context; +using v8::Float64Array; using v8::FunctionCallbackInfo; using v8::Integer; using v8::Local; @@ -69,7 +71,7 @@ static void GetOSType(const FunctionCallbackInfo& args) { } rval = info.sysname; #else // __MINGW32__ - rval ="Windows_NT"; + rval = "Windows_NT"; #endif // __POSIX__ args.GetReturnValue().Set(OneByteString(env->isolate(), rval)); @@ -182,14 +184,12 @@ static void GetUptime(const FunctionCallbackInfo& args) { static void GetLoadAvg(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - double loadavg[3]; + CHECK(args[0]->IsFloat64Array()); + Local array = args[0].As(); + CHECK_EQ(array->Length(), 3); + Local ab = array->Buffer(); + double* loadavg = static_cast(ab->GetContents().Data()); uv_loadavg(loadavg); - Local loads = Array::New(env->isolate(), 3); - loads->Set(0, Number::New(env->isolate(), loadavg[0])); - loads->Set(1, Number::New(env->isolate(), loadavg[1])); - loads->Set(2, Number::New(env->isolate(), loadavg[2])); - args.GetReturnValue().Set(loads); } diff --git a/src/node_v8.cc b/src/node_v8.cc index 43dd86c7574b4b..2d44da42a44b0e 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -54,8 +54,8 @@ void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); HeapStatistics s; env->isolate()->GetHeapStatistics(&s); - uint32_t* const buffer = env->heap_statistics_buffer(); -#define V(index, name, _) buffer[index] = static_cast(s.name()); + double* const buffer = env->heap_statistics_buffer(); +#define V(index, name, _) buffer[index] = static_cast(s.name()); HEAP_STATISTICS_PROPERTIES(V) #undef V } @@ -65,13 +65,13 @@ void UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); HeapSpaceStatistics s; Isolate* const isolate = env->isolate(); - uint32_t* buffer = env->heap_space_statistics_buffer(); + double* buffer = env->heap_space_statistics_buffer(); for (size_t i = 0; i < number_of_heap_spaces; i++) { isolate->GetHeapSpaceStatistics(&s, i); size_t const property_offset = i * kHeapSpaceStatisticsPropertiesCount; #define V(index, name, _) buffer[property_offset + index] = \ - static_cast(s.name()); + static_cast(s.name()); HEAP_SPACE_STATISTICS_PROPERTIES(V) #undef V } @@ -100,7 +100,7 @@ void InitializeV8Bindings(Local target, "updateHeapStatisticsArrayBuffer", UpdateHeapStatisticsArrayBuffer); - env->set_heap_statistics_buffer(new uint32_t[kHeapStatisticsPropertiesCount]); + env->set_heap_statistics_buffer(new double[kHeapStatisticsPropertiesCount]); const size_t heap_statistics_buffer_byte_length = sizeof(*env->heap_statistics_buffer()) * kHeapStatisticsPropertiesCount; @@ -146,7 +146,7 @@ void InitializeV8Bindings(Local target, UpdateHeapSpaceStatisticsBuffer); env->set_heap_space_statistics_buffer( - new uint32_t[kHeapSpaceStatisticsPropertiesCount * number_of_heap_spaces]); + new double[kHeapSpaceStatisticsPropertiesCount * number_of_heap_spaces]); const size_t heap_space_statistics_buffer_byte_length = sizeof(*env->heap_space_statistics_buffer()) * diff --git a/src/node_version.h b/src/node_version.h index d88c27fa479152..80d1559dc5b53a 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -8,7 +8,7 @@ #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Boron" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 8fd2f8f5f3bbce..5f47dadddb4d96 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -53,7 +53,11 @@ void PipeWrap::Initialize(Local target, env->SetProtoMethod(t, "ref", HandleWrap::Ref); env->SetProtoMethod(t, "hasRef", HandleWrap::HasRef); +#ifdef _WIN32 StreamWrap::AddMethods(env, t); +#else + StreamWrap::AddMethods(env, t, StreamBase::kFlagHasWritev); +#endif env->SetProtoMethod(t, "bind", Bind); env->SetProtoMethod(t, "listen", Listen); diff --git a/src/spawn_sync.cc b/src/spawn_sync.cc index 79f10a0ea2594d..3fcd61f22a4614 100644 --- a/src/spawn_sync.cc +++ b/src/spawn_sync.cc @@ -645,12 +645,17 @@ Local SyncProcessRunner::BuildResultObject() { Integer::New(env()->isolate(), GetError())); } - if (exit_status_ >= 0) - js_result->Set(env()->status_string(), - Number::New(env()->isolate(), static_cast(exit_status_))); - else + if (exit_status_ >= 0) { + if (term_signal_ > 0) { + js_result->Set(env()->status_string(), Null(env()->isolate())); + } else { + js_result->Set(env()->status_string(), + Number::New(env()->isolate(), static_cast(exit_status_))); + } + } else { // If exit_status_ < 0 the process was never started because of some error. js_result->Set(env()->status_string(), Null(env()->isolate())); + } if (term_signal_ > 0) js_result->Set(env()->signal_string(), diff --git a/test/.eslintrc b/test/.eslintrc.yaml similarity index 100% rename from test/.eslintrc rename to test/.eslintrc.yaml diff --git a/test/README.md b/test/README.md index 8d8cec44919720..0e8c13235da349 100644 --- a/test/README.md +++ b/test/README.md @@ -1,147 +1,154 @@ -# Table of Contents -* [Test directories](#test-directories) -* [Common module API](#common-module-api) - -## Test Directories - -### abort - -Tests for when the `--abort-on-uncaught-exception` flag is used. - -| Runs on CI | -|:----------:| -| No | - -### addons - -Tests for [addon](https://nodejs.org/api/addons.html) functionality along with -some tests that require an addon to function properly. - - -| Runs on CI | -|:----------:| -| Yes | - -### cctest - -C++ test that is run as part of the build process. - -| Runs on CI | -|:----------:| -| Yes | - -### debugger - -Tests for [debugger](https://nodejs.org/api/debugger.html) functionality. - -| Runs on CI | -|:----------:| -| No | - -### disabled - -Tests that have been disabled from running for various reasons. - -| Runs on CI | -|:----------:| -| No | - -### fixtures - -Test fixtures used in various tests throughout the test suite. - -### gc - -Tests for garbage collection related functionality. - -| Runs on CI | -|:----------:| -| No | - +# Node.js Core Tests -### inspector +This folder contains code and data used to test the Node.js implementation. -Tests for the V8 inspector integration. +For a detailed guide on how to write tests in this +directory, see [the guide on writing tests](../doc/guides/writing-tests.md). -| Runs on CI | -|:----------:| -| Yes | +On how to run tests in this direcotry, see +[the contributing guide](../CONTRIBUTING.md#step-5-test). -### internet +## Table of Contents -Tests that make real outbound connections (mainly networking related modules). -Tests for networking related modules may also be present in other directories, -but those tests do not make outbound connections. - -| Runs on CI | -|:----------:| -| No | - -### known_issues - -Tests reproducing known issues within the system. - -| Runs on CI | -|:----------:| -| No | - -### message - -Tests for messages that are output for various conditions (`console.log`, -error messages etc.) - -| Runs on CI | -|:----------:| -| Yes | - -### parallel - -Various tests that are able to be run in parallel. - -| Runs on CI | -|:----------:| -| Yes | - -### pummel - -Various tests for various modules / system functionality operating under load. - -| Runs on CI | -|:----------:| -| No | - -### sequential - -Various tests that are run sequentially. - -| Runs on CI | -|:----------:| -| Yes | - -### testpy - -Test configuration utility used by various test suites. - -### tick-processor - -Tests for the V8 tick processor integration. The tests are for the logic in -`lib/internal/v8_prof_processor.js` and `lib/internal/v8_prof_polyfill.js`. The -tests confirm that the profile processor packages the correct set of scripts -from V8 and introduces the correct platform specific logic. - -| Runs on CI | -|:----------:| -| No | - -### timers - -Tests for [timing utilities](https://nodejs.org/api/timers.html) (`setTimeout` -and `setInterval`). +* [Test directories](#test-directories) +* [Common module API](#common-module-api) -| Runs on CI | -|:----------:| -| No | +## Test Directories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectoryRuns on CIPurpose
abortNo + Tests for when the --abort-on-uncaught-exception + flag is used. +
addonsYes + Tests for addon + functionality along with some tests that require an addon to function + properly. +
cctestYes + C++ test that is run as part of the build process. +
debuggerNo + Tests for debugger + functionality along with some tests that require an addon to function + properly. +
disabledNo + Tests that have been disabled from running for various reasons. +
fixturesTest fixtures used in various tests throughout the test suite.
gcNoTests for garbage collection related functionality.
inspectorYesTests for the V8 inspector integration.
internetNo + Tests that make real outbound connections (mainly networking related + modules). Tests for networking related modules may also be present in + other directories, but those tests do not make outbound connections. +
known_issuesNoTests reproducing known issues within the system.
messageYes + Tests for messages that are output for various conditions + (console.log, error messages etc.)
parallelYesVarious tests that are able to be run in parallel.
pummelNo + Various tests for various modules / system functionality operating + under load. +
sequentialYes + Various tests that are run sequentially. +
testpy + Test configuration utility used by various test suites. +
tick-processorNo + Tests for the V8 tick processor integration. The tests are for the + logic in lib/internal/v8_prof_processor.js and + lib/internal/v8_prof_polyfill.js. The tests confirm that + the profile processor packages the correct set of scripts from V8 and + introduces the correct platform specific logic. +
timersNo + Tests for + timing utilities + (setTimeout and setInterval). +
## Common module API @@ -366,7 +373,7 @@ Synchronous version of `spawnPwd`. ### tmpDir * return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) -Path to the 'tmp' directory. +The realpath of the 'tmp' directory. ### tmpDirName * return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) diff --git a/test/addons/new-target/binding.cc b/test/addons/new-target/binding.cc new file mode 100644 index 00000000000000..a7e18eff70ea0d --- /dev/null +++ b/test/addons/new-target/binding.cc @@ -0,0 +1,16 @@ +#include +#include + +namespace { + +inline void NewClass(const v8::FunctionCallbackInfo&) {} + +inline void Initialize(v8::Local binding) { + auto isolate = binding->GetIsolate(); + binding->Set(v8::String::NewFromUtf8(isolate, "Class"), + v8::FunctionTemplate::New(isolate, NewClass)->GetFunction()); +} + +NODE_MODULE(binding, Initialize) + +} // anonymous namespace diff --git a/test/addons/new-target/binding.gyp b/test/addons/new-target/binding.gyp new file mode 100644 index 00000000000000..7ede63d94a0d77 --- /dev/null +++ b/test/addons/new-target/binding.gyp @@ -0,0 +1,9 @@ +{ + 'targets': [ + { + 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], + 'sources': [ 'binding.cc' ] + } + ] +} diff --git a/test/addons/new-target/test.js b/test/addons/new-target/test.js new file mode 100644 index 00000000000000..e4864adb1c24f3 --- /dev/null +++ b/test/addons/new-target/test.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../../common'); +const assert = require('assert'); +const binding = require(`./build/${common.buildType}/binding`); + +class Class extends binding.Class { + constructor() { + super(); + this.method(); + } + method() { + this.ok = true; + } +} + +assert.ok(new Class() instanceof binding.Class); +assert.ok(new Class().ok); diff --git a/test/common.js b/test/common.js index c15042c8ee89a4..0721ad94ec7c2b 100644 --- a/test/common.js +++ b/test/common.js @@ -10,7 +10,7 @@ const util = require('util'); const Timer = process.binding('timer_wrap').Timer; const testRoot = process.env.NODE_TEST_DIR ? - path.resolve(process.env.NODE_TEST_DIR) : __dirname; + fs.realpathSync(process.env.NODE_TEST_DIR) : __dirname; exports.fixturesDir = path.join(__dirname, 'fixtures'); exports.tmpDirName = 'tmp'; @@ -202,6 +202,28 @@ exports.hasIPv6 = Object.keys(ifaces).some(function(name) { }); }); +/* + * Check that when running a test with + * `$node --abort-on-uncaught-exception $file child` + * the process aborts. + */ +exports.childShouldThrowAndAbort = function() { + var testCmd = ''; + if (!exports.isWindows) { + // Do not create core files, as it can take a lot of disk space on + // continuous testing and developers' machines + testCmd += 'ulimit -c 0 && '; + } + testCmd += `${process.argv[0]} --abort-on-uncaught-exception `; + testCmd += `${process.argv[1]} child`; + const child = child_process.exec(testCmd); + child.on('exit', function onExit(exitCode, signal) { + const errMsg = 'Test should have aborted ' + + `but instead exited with exit code ${exitCode}` + + ` and signal ${signal}`; + assert(exports.nodeProcessAborted(exitCode, signal), errMsg); + }); +}; exports.ddCommand = function(filename, kilobytes) { if (exports.isWindows) { @@ -369,8 +391,7 @@ process.on('exit', function() { if (!exports.globalCheck) return; const leaked = leakedGlobals(); if (leaked.length > 0) { - console.error('Unknown globals: %s', leaked); - fail('Unknown global found'); + fail(`Unexpected global(s) found: ${leaked.join(', ')}`); } }); @@ -398,7 +419,10 @@ function runCallChecks(exitCode) { exports.mustCall = function(fn, expected) { - if (typeof expected !== 'number') expected = 1; + if (expected === undefined) + expected = 1; + else if (typeof expected !== 'number') + throw new TypeError(`Invalid expected value: ${expected}`); const context = { expected: expected, diff --git a/test/debugger/test-debug-break-on-uncaught.js b/test/debugger/test-debug-break-on-uncaught.js index dc380fa0193fb1..cfe72bb67b4f02 100644 --- a/test/debugger/test-debug-break-on-uncaught.js +++ b/test/debugger/test-debug-break-on-uncaught.js @@ -73,6 +73,7 @@ function runScenario(scriptName, throwsOnLine, next) { client.connect(port); } + let interval; function runTest(client) { client.req( { @@ -91,19 +92,22 @@ function runScenario(scriptName, throwsOnLine, next) { client.reqContinue(function(error) { assert.ifError(error); - setTimeout(assertHasPaused.bind(null, client), 100); + interval = setInterval(assertHasPaused.bind(null, client), 10); }); } ); } function assertHasPaused(client) { - assert(exceptions.length, 'no exceptions thrown, race condition in test?'); - assert.equal(exceptions.length, 1, 'debugger did not pause on exception'); - assert.equal(exceptions[0].uncaught, true); - assert.equal(exceptions[0].script.name, testScript); - assert.equal(exceptions[0].sourceLine + 1, throwsOnLine); + if (!exceptions.length) return; + + assert.strictEqual(exceptions.length, 1, + 'debugger did not pause on exception'); + assert.strictEqual(exceptions[0].uncaught, true); + assert.strictEqual(exceptions[0].script.name, testScript); + assert.strictEqual(exceptions[0].sourceLine + 1, throwsOnLine); asserted = true; client.reqContinue(assert.ifError); + clearInterval(interval); } } diff --git a/test/debugger/test-debugger-client.js b/test/debugger/test-debugger-client.js index 04823113ec32c1..869dabc6ef0c43 100644 --- a/test/debugger/test-debugger-client.js +++ b/test/debugger/test-debugger-client.js @@ -16,7 +16,7 @@ setTimeout(function() { var resCount = 0; var p = new debug.Protocol(); -p.onResponse = function(res) { +p.onResponse = function() { resCount++; }; @@ -89,7 +89,7 @@ function addTest(cb) { addTest(function(client, done) { console.error('requesting version'); client.reqVersion(function(err, v) { - assert.ok(!err); + assert.ifError(err); console.log('version: %s', v); assert.strictEqual(process.versions.v8, v); done(); @@ -99,13 +99,13 @@ addTest(function(client, done) { addTest(function(client, done) { console.error('requesting scripts'); client.reqScripts(function(err) { - assert.ok(!err); + assert.ifError(err); console.error('got %d scripts', Object.keys(client.scripts).length); var foundMainScript = false; for (var k in client.scripts) { var script = client.scripts[k]; - if (script && script.name === 'node.js') { + if (script && script.name === 'bootstrap_node.js') { foundMainScript = true; break; } @@ -119,7 +119,7 @@ addTest(function(client, done) { console.error('eval 2+2'); client.reqEval('2+2', function(err, res) { console.error(res); - assert.ok(!err); + assert.ifError(err); assert.strictEqual(res.text, '4'); assert.strictEqual(res.value, 4); done(); @@ -137,7 +137,7 @@ function doTest(cb, done) { var args = ['--debug=' + debugPort, '-e', script]; nodeProcess = spawn(process.execPath, args); - nodeProcess.stdout.once('data', function(c) { + nodeProcess.stdout.once('data', function() { console.log('>>> new node process: %d', nodeProcess.pid); var failed = true; try { @@ -158,7 +158,7 @@ function doTest(cb, done) { console.error('got stderr data %j', data); nodeProcess.stderr.resume(); b += data; - if (didTryConnect === false && b.match(/Debugger listening on port/)) { + if (didTryConnect === false && b.match(/Debugger listening on /)) { didTryConnect = true; // The timeout is here to expose a race in the bootstrap process. @@ -168,10 +168,10 @@ function doTest(cb, done) { function tryConnect() { // Wait for some data before trying to connect - var c = new debug.Client(); + const c = new debug.Client(); console.error('>>> connecting...'); c.connect(debug.port); - c.on('break', function(brk) { + c.on('break', function() { c.reqContinue(function() {}); }); c.on('ready', function() { @@ -199,7 +199,7 @@ function doTest(cb, done) { function run() { - var t = tests[0]; + const t = tests[0]; if (!t) return; doTest(t, function() { diff --git a/test/debugger/test-debugger-remote.js b/test/debugger/test-debugger-remote.js index f5232dce9c8df4..fb79fb83ee733f 100644 --- a/test/debugger/test-debugger-remote.js +++ b/test/debugger/test-debugger-remote.js @@ -1,25 +1,31 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var spawn = require('child_process').spawn; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; +const path = require('path'); -var buffer = ''; -var scriptToDebug = common.fixturesDir + '/empty.js'; - -function fail() { - assert(0); // `--debug-brk script.js` should not quit -} +const PORT = common.PORT; +const scriptToDebug = path.join(common.fixturesDir, 'empty.js'); // running with debug agent -var child = spawn(process.execPath, ['--debug-brk=5959', scriptToDebug]); - -console.error(process.execPath, '--debug-brk=5959', scriptToDebug); +const child = spawn(process.execPath, [`--debug-brk=${PORT}`, scriptToDebug]); // connect to debug agent -var interfacer = spawn(process.execPath, ['debug', 'localhost:5959']); - -console.error(process.execPath, 'debug', 'localhost:5959'); +const interfacer = spawn(process.execPath, ['debug', `localhost:${PORT}`]); interfacer.stdout.setEncoding('utf-8'); + +// fail the test if either of the processes exit normally +const debugBreakExit = common.fail.bind(null, 'child should not exit normally'); +const debugExit = common.fail.bind(null, 'interfacer should not exit normally'); +child.on('exit', debugBreakExit); +interfacer.on('exit', debugExit); + +let buffer = ''; +const expected = [ + `\bconnecting to localhost:${PORT} ... ok`, + '\bbreak in test/fixtures/empty.js:2' +]; +const actual = []; interfacer.stdout.on('data', function(data) { data = (buffer + data).split('\n'); buffer = data.pop(); @@ -30,22 +36,26 @@ interfacer.stdout.on('data', function(data) { interfacer.on('line', function(line) { line = line.replace(/^(debug> *)+/, ''); - console.log(line); - var expected = '\bconnecting to localhost:5959 ... ok'; - assert.ok(expected == line, 'Got unexpected line: ' + line); + if (expected.includes(line)) { + actual.push(line); + } }); // allow time to start up the debugger setTimeout(function() { - child.removeListener('exit', fail); + // remove the exit handlers before killing the processes + child.removeListener('exit', debugBreakExit); + interfacer.removeListener('exit', debugExit); + child.kill(); - interfacer.removeListener('exit', fail); interfacer.kill(); -}, 2000); +}, common.platformTimeout(2000)); process.on('exit', function() { + // additional checks to ensure that both the processes were actually killed assert(child.killed); assert(interfacer.killed); + assert.deepStrictEqual(actual, expected); }); interfacer.stderr.pipe(process.stderr); diff --git a/test/debugger/test-debugger-repl.js b/test/debugger/test-debugger-repl.js index 8a87d40d163af7..ab0468448bef4d 100644 --- a/test/debugger/test-debugger-repl.js +++ b/test/debugger/test-debugger-repl.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +var common = require('../common'); var repl = require('./helper-debugger-repl.js'); repl.startDebugger('breakpoints.js'); @@ -57,7 +57,7 @@ addTest('c', [ // Execute addTest('exec process.title', [ - /node/ + common.isFreeBSD || common.isOSX || common.isLinux ? /node/ : '' ]); // Execute diff --git a/test/doctool/test-doctool-html.js b/test/doctool/test-doctool-html.js index bd21e21d9563d2..442381b54d7b72 100644 --- a/test/doctool/test-doctool-html.js +++ b/test/doctool/test-doctool-html.js @@ -72,11 +72,18 @@ const testData = [ '

I exist and am being linked to.

' + '' }, + { + file: path.join(common.fixturesDir, 'sample_document.md'), + html: '
  1. fish
  2. fish

  3. Redfish

  4. ' + + '
  5. Bluefish
', + analyticsId: 'UA-67020396-1' + }, ]; -testData.forEach(function(item) { +testData.forEach((item) => { // Normalize expected data by stripping whitespace const expected = item.html.replace(/\s/g, ''); + const includeAnalytics = typeof item.analyticsId !== 'undefined'; fs.readFile(item.file, 'utf8', common.mustCall((err, input) => { assert.ifError(err); @@ -89,6 +96,7 @@ testData.forEach(function(item) { filename: 'foo', template: 'doc/template.html', nodeVersion: process.version, + analytics: item.analyticsId, }, common.mustCall((err, output) => { assert.ifError(err); @@ -96,7 +104,17 @@ testData.forEach(function(item) { const actual = output.replace(/\s/g, ''); // Assert that the input stripped of all whitespace contains the // expected list - assert.notEqual(actual.indexOf(expected), -1); + assert.notStrictEqual(actual.indexOf(expected), -1); + + // Testing the insertion of Google Analytics script when + // an analytics id is provided. Should not be present by default + if (includeAnalytics) { + assert.notStrictEqual(actual.indexOf('google-analytics.com'), -1, + 'Google Analytics script was not present'); + } else { + assert.strictEqual(actual.indexOf('google-analytics.com'), -1, + 'Google Analytics script was present'); + } })); })); })); diff --git a/test/doctool/test-doctool-json.js b/test/doctool/test-doctool-json.js index 520c79bef8bcda..ae7b2007b7d2ef 100644 --- a/test/doctool/test-doctool-json.js +++ b/test/doctool/test-doctool-json.js @@ -18,7 +18,7 @@ const json = require('../../tools/doc/json.js'); // Test data is a list of objects with two properties. // The file property is the file path. // The json property is some json which will be generated by the doctool. -var testData = [ +const testData = [ { file: path.join(common.fixturesDir, 'sample_document.md'), json: { @@ -136,10 +136,10 @@ var testData = [ } ]; -testData.forEach(function(item) { - fs.readFile(item.file, 'utf8', common.mustCall(function(err, input) { +testData.forEach((item) => { + fs.readFile(item.file, 'utf8', common.mustCall((err, input) => { assert.ifError(err); - json(input, 'foo', common.mustCall(function(err, output) { + json(input, 'foo', common.mustCall((err, output) => { assert.ifError(err); assert.deepStrictEqual(output, item.json); })); diff --git a/test/fixtures/cluster-preload.js b/test/fixtures/cluster-preload.js index 6637b418babb0d..f62bc20551c1f4 100644 --- a/test/fixtures/cluster-preload.js +++ b/test/fixtures/cluster-preload.js @@ -4,8 +4,8 @@ var assert = require('assert'); // this module is used as a preload module. It should have a parent with the // module search paths initialized from the current working directory assert.ok(module.parent); -var expectedPaths = require('module')._nodeModulePaths(process.cwd()); -assert.deepEqual(module.parent.paths, expectedPaths); +const expectedPaths = require('module')._nodeModulePaths(process.cwd()); +assert.deepStrictEqual(module.parent.paths, expectedPaths); var cluster = require('cluster'); cluster.isMaster || process.exit(42 + cluster.worker.id); // +42 to distinguish diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile index 277734aa174562..c7390eda0eefc4 100644 --- a/test/fixtures/keys/Makefile +++ b/test/fixtures/keys/Makefile @@ -57,6 +57,20 @@ fake-cnnic-root-cert.pem: fake-cnnic-root.cnf fake-cnnic-root-key.pem -out fake-cnnic-root-cert.pem \ -config fake-cnnic-root.cnf +# +# Create Fake StartCom Root Certificate Authority: fake-startcom-root +# +fake-startcom-root-key.pem: + openssl genrsa -out fake-startcom-root-key.pem 2048 + +fake-startcom-root-cert.pem: fake-startcom-root.cnf \ + fake-startcom-root-key.pem + openssl req -new -x509 -days 9999 -config \ + fake-startcom-root.cnf -key fake-startcom-root-key.pem -out \ + fake-startcom-root-cert.pem + echo '01' > fake-startcom-root-serial + touch fake-startcom-root-database.txt + # # agent1 is signed by ca1. # @@ -254,6 +268,60 @@ agent7-cert.pem: agent7-csr.pem fake-cnnic-root-cert.pem fake-cnnic-root-key.pem agent7-verify: agent7-cert.pem fake-cnnic-root-cert.pem openssl verify -CAfile fake-cnnic-root-cert.pem agent7-cert.pem +# +# agent8 is signed by fake-startcom-root with notBefore +# of Oct 20 23:59:59 2016 GMT +# + +agent8-key.pem: + openssl genrsa -out agent8-key.pem 2048 + +agent8-csr.pem: agent8.cnf agent8-key.pem + openssl req -new -config agent8.cnf -key agent8-key.pem \ + -out agent8-csr.pem + +agent8-cert.pem: agent8-csr.pem + openssl ca \ + -config fake-startcom-root.cnf \ + -keyfile fake-startcom-root-key.pem \ + -cert fake-startcom-root-cert.pem \ + -batch \ + -days 9999 \ + -passin "pass:password" \ + -in agent8-csr.pem \ + -startdate 20161020235959Z \ + -notext -out agent8-cert.pem + + +agent8-verify: agent8-cert.pem fake-startcom-root-cert.pem + openssl verify -CAfile fake-startcom-root-cert.pem \ + agent8-cert.pem + + +# +# agent9 is signed by fake-startcom-root with notBefore +# of Oct 21 00:00:01 2016 GMT +# +agent9-key.pem: + openssl genrsa -out agent9-key.pem 2048 + +agent9-csr.pem: agent9.cnf agent9-key.pem + openssl req -new -config agent9.cnf -key agent9-key.pem \ + -out agent9-csr.pem + + +agent9-cert.pem: agent9-csr.pem + openssl ca \ + -config fake-startcom-root.cnf \ + -keyfile fake-startcom-root-key.pem \ + -cert fake-startcom-root-cert.pem \ + -batch \ + -days 9999 \ + -passin "pass:password" \ + -in agent9-csr.pem \ + -startdate 20161021000001Z \ + -notext -out agent9-cert.pem + ec-key.pem: openssl ecparam -genkey -out ec-key.pem -name prime256v1 diff --git a/test/fixtures/keys/agent8-cert.pem b/test/fixtures/keys/agent8-cert.pem new file mode 100644 index 00000000000000..86de1d44a64a98 --- /dev/null +++ b/test/fixtures/keys/agent8-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjgCAQEwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNV +BAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRp +ZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MCAYDzIwMTYxMDIwMjM1OTU5WhcNNDQwMzIxMTAwNjM5WjBdMQsw +CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZO +T0RFSlMxDzANBgNVBAsTBmFnZW50ODESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzkVSP6XxWpBlSjqqavwOhpp36aFJ +qLK7fRpxR+f0PdQ9WJajDEicxwKWGFqQBE+d5BjqrAD59L2QGZQ2VOF9VLZyFz3F +9TIlkd4yt9Od0qE98yIouDBNWu7UZqvNynAe5caD5i1MgyIUQqIUOnZwM21hwqYN +N/OESf38A8Tfuvh3ALUn7zBEVyUPWIWTYPhFHSCWIsS2URZ/qDLk8GavphkqXdFB +ii3V8Th5niPtpIsRF6Qhwh8SK+s0zh53o0qkmCNpXLd/PJQQAwC70WRq7ncL4D+U +C1gnDL0j9SzojXQu31kXs8UZTa7RFnx5r+gDiA/gGrLs4IiwDJhVHMx0nQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQA7iMlm+rgZnlps+LFsoXG4dGNPaOhKI9t/XBrO +6O64LLyx/FPIQSaYi130QNB7Zy0uw8xqrH6cGRTJ9RCfBFFP4rzgIX3wEAHnmwMr +i4dGEixBUIIjhw6fAVxAhrkzmgUpUt0qIP9otGgESEYXIg7bFkXIHit0Im1VOdvf ++LnUKZw9o7UEesKIDVkuAsjoKKkrsO0kdf0dgAj6Ix5xmAtBsDvkH0aOSdPfTZG6 +LQrnZf/quBotog3NmDzrvQaH8GNpTJcYNjKlxD2z0PvQUyp0FD8oCC+oD+EGv2zZ +65scEXU/n8kTmdJkCjx4nb39HttYzOlNlTgMxAfxgL7A/PcT +-----END CERTIFICATE----- diff --git a/test/fixtures/keys/agent8-csr.pem b/test/fixtures/keys/agent8-csr.pem new file mode 100644 index 00000000000000..af749bcd1c8287 --- /dev/null +++ b/test/fixtures/keys/agent8-csr.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICxzCCAa8CAQAwXTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQswCQYDVQQH +EwJTRjEPMA0GA1UEChMGTk9ERUpTMQ8wDQYDVQQLEwZhZ2VudDgxEjAQBgNVBAMT +CWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM5FUj+l +8VqQZUo6qmr8Doaad+mhSaiyu30acUfn9D3UPViWowxInMcClhhakARPneQY6qwA ++fS9kBmUNlThfVS2chc9xfUyJZHeMrfTndKhPfMiKLgwTVru1GarzcpwHuXGg+Yt +TIMiFEKiFDp2cDNtYcKmDTfzhEn9/APE37r4dwC1J+8wRFclD1iFk2D4RR0gliLE +tlEWf6gy5PBmr6YZKl3RQYot1fE4eZ4j7aSLERekIcIfEivrNM4ed6NKpJgjaVy3 +fzyUEAMAu9Fkau53C+A/lAtYJwy9I/Us6I10Lt9ZF7PFGU2u0RZ8ea/oA4gP4Bqy +7OCIsAyYVRzMdJ0CAwEAAaAlMCMGCSqGSIb3DQEJBzEWExRBIGNoYWxsZW5nZSBw +YXNzd29yZDANBgkqhkiG9w0BAQUFAAOCAQEAykAWr5pOZh1BMc7NZgc66J16VkjN +KM2deMQNl7r3BFB336At+zmpudnjdT/tPaH34FT/Idh/DPfiSdpuDQWDA+E7xady +S7KoKfNesPFjV4rR1WgNtoix0B5EaaNxdR8ljwL30N/LbsMDWxIK7rWyhvuw3DXr +C90PbsOTCLbW1HGItgYCQFJnpXK1O1Vx0Bo55F//oxDGVTzkUqb0lsVGHLLCg0s2 +DxX3++FqFy/NjzZ5R/k1o+WIom1PzhLXJ+cqQsqYT9kBIVHTtvTAnDM70dZ8EeSW +/O4w+gb+OSJjClz7p4DuX4idDG+0cISxBOYFPyTFlGrXQ0ZXULP4pihsUA== +-----END CERTIFICATE REQUEST----- diff --git a/test/fixtures/keys/agent8-key.pem b/test/fixtures/keys/agent8-key.pem new file mode 100644 index 00000000000000..c1773f7cff4d02 --- /dev/null +++ b/test/fixtures/keys/agent8-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzkVSP6XxWpBlSjqqavwOhpp36aFJqLK7fRpxR+f0PdQ9WJaj +DEicxwKWGFqQBE+d5BjqrAD59L2QGZQ2VOF9VLZyFz3F9TIlkd4yt9Od0qE98yIo +uDBNWu7UZqvNynAe5caD5i1MgyIUQqIUOnZwM21hwqYNN/OESf38A8Tfuvh3ALUn +7zBEVyUPWIWTYPhFHSCWIsS2URZ/qDLk8GavphkqXdFBii3V8Th5niPtpIsRF6Qh +wh8SK+s0zh53o0qkmCNpXLd/PJQQAwC70WRq7ncL4D+UC1gnDL0j9SzojXQu31kX +s8UZTa7RFnx5r+gDiA/gGrLs4IiwDJhVHMx0nQIDAQABAoIBAHHp5KdT3Ht4XQfm +aDEXLGp3qhtzQDuTIWnQjZj5Z3Ax4wMmhbsF6tcY/Y1LjldjJL5QaGE/VMstWQRX +Tr4HnXCIJW/iZI2p+Qean4XXr0QgWhcI2VYHDuFWHiTpYogW7WlV/YfDooqU6n12 +BxfWStaL5L5bd9dbe8ZlJqVqN2iISfqGNIz9YKM04rHycTcicNmf0J0smkHlnHJE +ROQR73IXjDDOmkwdG75qyGRBQ0j0KEDu//n1axcOKf48F+8BQk2PFMq+RhkGGqJD +zTQK3kB33HRWeNWbykLPzYGcPtSlvaecCTc/q9wbbxh5AFlvSrPz3VzdRHECocM3 +v/o2vqECgYEA/uZib1ZYczuihcvLKxo8e/IBNYUKUcyosHDqAmJ5q8Y+Vg35ACfM +mJAhT1SXXAmm2tHuTnztfLDMQAOGVItuf5U8nuJYuWrvhMCtBT40XPeUVPD8b2D1 +9y5EipiB7huH8kMb1aAPUNgQhmqT93+4qcGf6PcNTkk6uHCCXFZEc7UCgYEAzyk1 +/T+Ah3p9+c1s+AjqkWj3Qa9lOKclJOT2O88AG+4fGQhSdUvkLDAMX3L6ri3gVZzr +wH3DJIwJx1uCW4eNJFVmh8AyP4SkfzQp1FqsIzBMQuPz6Hqtclh/UPx1yOe3NseO +xVM6Z5RbOOWyDaWxxbQHZnHkqSKcTB8K1lJ/XkkCgYAaStlMcrOc70HMW0ERqRsk +DcpiIt71oQ6lZIA+zrmOJly3s6lDgtdvxS4qaKdULwqu94iFQA2fFv16fOKWReuX +7WTbXq2YMpeSMe2m5Mux6ze5q0HemznDzVn0kdaVIPHc418zodbyl9bchpHMrbf2 +iqpb9V/B+3u7Gp/Xtm5JIQKBgBFrjr2wBFfgJg3Gh35ICamWoQwl+qYL8CStGEOp +QYIXwQey2nRAoHxSwgeYvJm/A9lPK8fxC2LcX8oi2NBnkqfWgpuxvsf2mHqV4VqZ +EVaYLiGF17HZ9xHhfTtLL4Boc9CocUoImKWzJQSg1BsvrsZIQEMOGsNaRLhl99xT +7Z/5AoGBAIxgzOGLVVrIv8vRc4YouPf0OGBmUawnEZxYVD1Mo4Tt97XjxH93B1iz +hof62zDCL7WEdKuwnOs1towBmLjC7qrAbkUgNVYmI5sG9c8+1NKClTOJGsHHiMLF +n8GxnsNU5FVTmJ/PZfOU+eru7uDYZHTkii0tkaHWUzg13pkhka5E +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/keys/agent8.cnf b/test/fixtures/keys/agent8.cnf new file mode 100644 index 00000000000000..bb50a0e7199283 --- /dev/null +++ b/test/fixtures/keys/agent8.cnf @@ -0,0 +1,17 @@ +[ req ] +default_bits = 2048 +days = 999 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +C = US +ST = CA +L = SF +O = NODEJS +OU = agent8 +CN = localhost + +[ req_attributes ] +challengePassword = A challenge password diff --git a/test/fixtures/keys/agent9-cert.pem b/test/fixtures/keys/agent9-cert.pem new file mode 100644 index 00000000000000..196922986cdb6e --- /dev/null +++ b/test/fixtures/keys/agent9-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjgCAQIwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNV +BAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRp +ZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MCAYDzIwMTYxMDIxMDAwMDAxWhcNNDQwMzIxMTAwNzAyWjBdMQsw +CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZO +T0RFSlMxDzANBgNVBAsTBmFnZW50OTESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApT6nASSx9e2i/t0aHSd9BxMRD92o +33/iaiXWzBOKMJp7jxCWAg6SnpjrFsyjTxaAqg+e1zlm10YBT6DholstffzQqK2x +TKGVOQK4jxX23wJlrn5mDk0fagBtY49L1KFy8DxJqKgt7uxz61GGUWwKWXG7Vnga +bkqDd9o3ZF7bOq7mMQvfDzPrwYI8uTjTxR8R19uxNNOGtHMTnwvDeczTmtTox8U+ +4N2hN2scDZvRBx5aQAtnXRyZhAokAJMYojinx9iqlVFQi3ct52LIhsca6ympfDc2 +0yA4aSVfoW7NlqsnvrTOV4nt3UbrxGGpiE7Em8Hdcw2EMF+jqCTLGtsqYQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQCMjKFycVQh7Puz/FpQh3NhJ99Ic3rzr+3nAKFD +4Kcl3L8szH3zjLCw46/y2jqPiAbg2zg9miYkI/2W/G+m2VQEQvp2SwjVr/Rj2Soe +iTonruUpDFF7LG01q3kpZ7nYWRGvVgn5D9BGk4/SWuzxiWRdwlzJf2e8cXLExVS0 +0CgRsb5nRoZ+RZmVIrGMfIi8CI7uTlcHtQzD7B7gpHtOSMlQoSSeqOy6F498duvl +QhhQhJBxmjSegw/lawWQSDFArJimK/rwyb6ZFbRfBgg6o/k5W9G5l0oG5abQMp+/ +u8Fd+QUNwR6OovE0AqL6wNHCnqzNnihTL6/hRVer6i5Hfxmb +-----END CERTIFICATE----- diff --git a/test/fixtures/keys/agent9-csr.pem b/test/fixtures/keys/agent9-csr.pem new file mode 100644 index 00000000000000..bba87d631f15b3 --- /dev/null +++ b/test/fixtures/keys/agent9-csr.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICxzCCAa8CAQAwXTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQswCQYDVQQH +EwJTRjEPMA0GA1UEChMGTk9ERUpTMQ8wDQYDVQQLEwZhZ2VudDkxEjAQBgNVBAMT +CWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKU+pwEk +sfXtov7dGh0nfQcTEQ/dqN9/4mol1swTijCae48QlgIOkp6Y6xbMo08WgKoPntc5 +ZtdGAU+g4aJbLX380KitsUyhlTkCuI8V9t8CZa5+Zg5NH2oAbWOPS9ShcvA8Saio +Le7sc+tRhlFsCllxu1Z4Gm5Kg3faN2Re2zqu5jEL3w8z68GCPLk408UfEdfbsTTT +hrRzE58Lw3nM05rU6MfFPuDdoTdrHA2b0QceWkALZ10cmYQKJACTGKI4p8fYqpVR +UIt3LediyIbHGuspqXw3NtMgOGklX6FuzZarJ760zleJ7d1G68RhqYhOxJvB3XMN +hDBfo6gkyxrbKmECAwEAAaAlMCMGCSqGSIb3DQEJBzEWExRBIGNoYWxsZW5nZSBw +YXNzd29yZDANBgkqhkiG9w0BAQUFAAOCAQEAKlz52i1TpqNFQQu2YCl2YlTKbu2s ++92Qq+9b8wKoTweEFxDYtfq8d6rgYtetDbJDh+CDSjG3REINHtbPB0BjFdmZq/Q6 +7JHLjmWKacmhaZJIp6xtrAX93qXYfbqH2S/DNSAO1e1sUa/gKL+wuVcrM8My7mzo +cMEgc7mHJCbSjYIcYPELas+rADoCE4mgiX8wwYQjFqxj/cdlcMzVS3ZuARAiPzA7 +60Zk3/NnbXd/OBOcf/FvbrYIQ45eV4JlMowtcdLtxP91N5/X3BBMFsXt4mPoXETC +V78wipSWtfiKTox1Ze7PSJsYm9E9TOYYPh9kSGizIFzrgnk9H15+Iy5Ixg== +-----END CERTIFICATE REQUEST----- diff --git a/test/fixtures/keys/agent9-key.pem b/test/fixtures/keys/agent9-key.pem new file mode 100644 index 00000000000000..1156fddfa68d4b --- /dev/null +++ b/test/fixtures/keys/agent9-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEApT6nASSx9e2i/t0aHSd9BxMRD92o33/iaiXWzBOKMJp7jxCW +Ag6SnpjrFsyjTxaAqg+e1zlm10YBT6DholstffzQqK2xTKGVOQK4jxX23wJlrn5m +Dk0fagBtY49L1KFy8DxJqKgt7uxz61GGUWwKWXG7VngabkqDd9o3ZF7bOq7mMQvf +DzPrwYI8uTjTxR8R19uxNNOGtHMTnwvDeczTmtTox8U+4N2hN2scDZvRBx5aQAtn +XRyZhAokAJMYojinx9iqlVFQi3ct52LIhsca6ympfDc20yA4aSVfoW7NlqsnvrTO +V4nt3UbrxGGpiE7Em8Hdcw2EMF+jqCTLGtsqYQIDAQABAoIBAE7FXAUOggry2hVW +PuGQ9mfN7f87MgpAwyTInukvk1tx+N6NEIUwfzI9QSvgJyVHW9Q1mAmO4nhSdcOI +tKaZgkkhoDIYgoE+MY04v9Ptq35JfUE+HdZJa2UziPHB2Gsm/0yH4LEWYrcXXnbZ +qQbdUt2qepxQqoDS4nLawjcFhMom24ns24eMCsFW7yrxhyvQwFKqGOKXauCpClp2 +oPXhd2wljutuIGJjMmeqMw7CuyfZMee6BsuXNWWr/kso0NaQwxKoFnGlyaOl6oUV +ypr5ADXv0NNaSqDgyfEfJedsGQul+WWnkjz6PFbWZtbG5SIKb5PCJ2aWD7mvcHdI +85BL4jUCgYEA0yPogvmlK/hSpckk/AkRtHWwjUdkgdoZzxiJV/D01y8EtB+yL46t +Gzl23Y1VtLXxn+CZdj2putS5z1Rg1LA0oMZ+TwhxGskURBPP7mym83Qn1huRcnWw +df9flCg4IwRLqI6QfsQ2Q6j549j5u8P+tqVi/yZQY0V2SGcXTXaqIksCgYEAyFpy +24+AW33ypNxr9sOIx2YQyn0UDK2K6LQYRmjwhpCZEtBdoUqKGP/9UUycM4TN9D32 +p0le+3TJVk9tVqyvwFeGBkguO/3dXD6KTsqrCfMFNj/R6QRYFEaLWjkG8EI5TXOK +a/CbhtyGaRY5QzwLRjLdEYIph3r1d2uedVzwGoMCgYEAvPV59R2u8LcAYFavvs/v +BG3/X7DxBjVGu8zdvdJrjNkLgJiNQ3qQ+bhn5MfEWEIsyESdkvCEoiwXTrHZJv+7 +WdfK2rhXYP1sIbEJefvLPj5KGJf7h1BEaJXv2AxWkSAbBfLw5kJ7vfnQClX4yk4R ++yvweSC0+OMFhK6ecDku8hkCgYAJPRJ6yV0z2tTrgTaBRHb0KuKvU6EvDHmRTWyp +IoGk0tocIfuPSm6fxH4b15qETaVpk8nh4OI+Wh5GmpcCHihkiCSn+YAYSBaDAGdE +RtgoN0qQO9UkF40wMiiO2n5VadhWl/NUEt45E8Ym5l1xmj0y2XmUKxpbIvJatV2z +L7vqnQKBgCuV47rGYLaPz+gVgwIz0PvNFgp2fdSBYYQUf70XsaEU1bQtim6q5jxd ++ePUiT65k42Iw7oLWyGtxdyxmmKgQ18i5aDNjT2SLr3RAC2BSR5Fs1W1PLi24nV6 +QW7fepI9tOBTbwbLG8ARRzx2YXrBf9PqvmDbrMiTi0WGFGlVJatX +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/keys/agent9.cnf b/test/fixtures/keys/agent9.cnf new file mode 100644 index 00000000000000..a9f5a5f16a3a10 --- /dev/null +++ b/test/fixtures/keys/agent9.cnf @@ -0,0 +1,17 @@ +[ req ] +default_bits = 2048 +days = 999 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +C = US +ST = CA +L = SF +O = NODEJS +OU = agent9 +CN = localhost + +[ req_attributes ] +challengePassword = A challenge password diff --git a/test/fixtures/keys/fake-startcom-root-cert.pem b/test/fixtures/keys/fake-startcom-root-cert.pem new file mode 100644 index 00000000000000..b3ebbacf753d6a --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjTCCAnWgAwIBAgIJAKDrU4iaFPb+MA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNV +BAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUg +RGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBTdGFydENvbSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNjExMDQwOTUwMTNaFw00NDAzMjEw +OTUwMTNaMH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSsw +KQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYD +VQQDEyBTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALvhAZtGU3u3uyB4lHn5X85XJdyPAnOY0hGc +SVMzfQ/BBEvBPkcdhJvZPLqcWTnJplsJXH+GHz9q73DbyLekdF/f6dNVcRmDjvZq +pZ6KgT8D4GmudNPMEuHs9+bqI+l5p7Mh1mEmot5JYtXvGD3UiN2ZUQ/trhf5xiJq +MEaiQHBxhJESkY+RYV2GK0njCJ2ypmtAAzyGUlNgHqxBy1PrBBqh0xbSOa2pwRyz +9u7EkYN4BCQKNCBJbOaX9rH+j836YlEHEymutjYDuYiHaOve0yJCHsQqsx7+p9aB +UxCS9mTj9q9bz9GJR9tfT04+HmQRjtSZYt7fHIixgS0vT4/6QlsCAwEAAaMQMA4w +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAiIgJ9EGWepY/Qk6n6Kcj +YQFZXeV6ugnWz96sxYc0xmo/XNkYQFLxVneyWanlUxAbvScEdC8rJ5rUrwVMhfaS +goneP2Otjcg0XcMrsf5RaJk0H8uGUdvdgWUHO85pseMOFgqXxJgEux7wcFS41qhw +thc/obZ5keOPJf3tsOffV5OJc6owwgaviz3RNFRJUleZU5r3swjWIEDK89sz9q+S +qcwostbKRrEcjyltblhFKR9s4Qyn9FYWntPApFHq7M0/jA/4iiHRcltFfc19mslb +lhRBZZ/vds3VEtfs7uPhcodXBTv5d5xUk6pybSSFhKTTtHc8OpdvbM+5LchzTc23 +pA== +-----END CERTIFICATE----- diff --git a/test/fixtures/keys/fake-startcom-root-csr.pem b/test/fixtures/keys/fake-startcom-root-csr.pem new file mode 100644 index 00000000000000..56da4e65b4a4fe --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-csr.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIC5zCCAc8CAQAwfTELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0 +ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcx +KTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAww1iG1Oq6uIEN5u4W0jWnDFvaKGp +R6XSYPK3D1VJTqr7XUfzbVG2Acc5B7WTmerFsxOADXe8kpC3U6QxcyLvMv90Bpju +dasttLnoBU2XqJxWTpmJyM8RfbSZEKfNIdKzG2uQQVHIJOV/bm6yhQIT2cDKNZDx +M0OPiCeeQMezD4/Y98zFDyWjTI2zW6kyBzdjPSLJ3DMJs+4EC6LJhKrp9kBbJHhU +QdIrQ1C3ycJ0lKv8uV8xWsgz/CsPkp92H/iUDxBnFgMcdFmgt/XgPDf1Q9ipfq7B +5Ef8RlQuDsqer+/UPOXLHWHtE+5QbkL4hzCjJEszkl5QbSPdiK1rcIkEvQIDAQAB +oCUwIwYJKoZIhvcNAQkHMRYTFEEgY2hhbGxlbmdlIHBhc3N3b3JkMA0GCSqGSIb3 +DQEBCwUAA4IBAQCwvK3cFAA9ShrFNhSuZ//xFgrXxqQXS4o571jDCLYh+QAgcRUU +ATPM0GQ4CKUR3gWD14Ji922PiVZCpKgvkEVrvMYq6jgydT2urki0hL/po7msdnLQ +2FWMwgpINaTmhmUNBxHBQbopW4HWDzcCfSQwGN/iCElNmawXGIN1LRcDAl08h/cW +hTP9agZXpmoZ2wHg+ZRHcJwJm4QL4Rm7JfyNN3fZWUFgn3Pfkwgiu9PMhU92KRU/ +5PJ3tcyw9qSQJsw6CPuijRI9kaKdFIj6BsOGmsSyYq9OoqtlfqXqgXXv3XfKQmmh +Hntg6KSQhReXDHCSTgtBZFa6+kwg3mgr8I7N +-----END CERTIFICATE REQUEST----- diff --git a/test/fixtures/keys/fake-startcom-root-database.txt b/test/fixtures/keys/fake-startcom-root-database.txt new file mode 100644 index 00000000000000..b1f582201ae32d --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-database.txt @@ -0,0 +1,2 @@ +V 440321100639Z 01 unknown /C=US/ST=CA/L=SF/O=NODEJS/OU=agent8/CN=localhost +V 440321100702Z 02 unknown /C=US/ST=CA/L=SF/O=NODEJS/OU=agent9/CN=localhost diff --git a/test/fixtures/keys/fake-startcom-root-database.txt.attr b/test/fixtures/keys/fake-startcom-root-database.txt.attr new file mode 100644 index 00000000000000..8f7e63a3475ce8 --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-database.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/test/fixtures/keys/fake-startcom-root-database.txt.attr.old b/test/fixtures/keys/fake-startcom-root-database.txt.attr.old new file mode 100644 index 00000000000000..8f7e63a3475ce8 --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-database.txt.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/test/fixtures/keys/fake-startcom-root-database.txt.old b/test/fixtures/keys/fake-startcom-root-database.txt.old new file mode 100644 index 00000000000000..66c1d034dd47cd --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-database.txt.old @@ -0,0 +1 @@ +V 440321100639Z 01 unknown /C=US/ST=CA/L=SF/O=NODEJS/OU=agent8/CN=localhost diff --git a/test/fixtures/keys/fake-startcom-root-issued-certs/01.pem b/test/fixtures/keys/fake-startcom-root-issued-certs/01.pem new file mode 100644 index 00000000000000..86de1d44a64a98 --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-issued-certs/01.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjgCAQEwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNV +BAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRp +ZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MCAYDzIwMTYxMDIwMjM1OTU5WhcNNDQwMzIxMTAwNjM5WjBdMQsw +CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZO +T0RFSlMxDzANBgNVBAsTBmFnZW50ODESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzkVSP6XxWpBlSjqqavwOhpp36aFJ +qLK7fRpxR+f0PdQ9WJajDEicxwKWGFqQBE+d5BjqrAD59L2QGZQ2VOF9VLZyFz3F +9TIlkd4yt9Od0qE98yIouDBNWu7UZqvNynAe5caD5i1MgyIUQqIUOnZwM21hwqYN +N/OESf38A8Tfuvh3ALUn7zBEVyUPWIWTYPhFHSCWIsS2URZ/qDLk8GavphkqXdFB +ii3V8Th5niPtpIsRF6Qhwh8SK+s0zh53o0qkmCNpXLd/PJQQAwC70WRq7ncL4D+U +C1gnDL0j9SzojXQu31kXs8UZTa7RFnx5r+gDiA/gGrLs4IiwDJhVHMx0nQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQA7iMlm+rgZnlps+LFsoXG4dGNPaOhKI9t/XBrO +6O64LLyx/FPIQSaYi130QNB7Zy0uw8xqrH6cGRTJ9RCfBFFP4rzgIX3wEAHnmwMr +i4dGEixBUIIjhw6fAVxAhrkzmgUpUt0qIP9otGgESEYXIg7bFkXIHit0Im1VOdvf ++LnUKZw9o7UEesKIDVkuAsjoKKkrsO0kdf0dgAj6Ix5xmAtBsDvkH0aOSdPfTZG6 +LQrnZf/quBotog3NmDzrvQaH8GNpTJcYNjKlxD2z0PvQUyp0FD8oCC+oD+EGv2zZ +65scEXU/n8kTmdJkCjx4nb39HttYzOlNlTgMxAfxgL7A/PcT +-----END CERTIFICATE----- diff --git a/test/fixtures/keys/fake-startcom-root-issued-certs/02.pem b/test/fixtures/keys/fake-startcom-root-issued-certs/02.pem new file mode 100644 index 00000000000000..196922986cdb6e --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-issued-certs/02.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjgCAQIwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNV +BAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRp +ZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5MCAYDzIwMTYxMDIxMDAwMDAxWhcNNDQwMzIxMTAwNzAyWjBdMQsw +CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZO +T0RFSlMxDzANBgNVBAsTBmFnZW50OTESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApT6nASSx9e2i/t0aHSd9BxMRD92o +33/iaiXWzBOKMJp7jxCWAg6SnpjrFsyjTxaAqg+e1zlm10YBT6DholstffzQqK2x +TKGVOQK4jxX23wJlrn5mDk0fagBtY49L1KFy8DxJqKgt7uxz61GGUWwKWXG7Vnga +bkqDd9o3ZF7bOq7mMQvfDzPrwYI8uTjTxR8R19uxNNOGtHMTnwvDeczTmtTox8U+ +4N2hN2scDZvRBx5aQAtnXRyZhAokAJMYojinx9iqlVFQi3ct52LIhsca6ympfDc2 +0yA4aSVfoW7NlqsnvrTOV4nt3UbrxGGpiE7Em8Hdcw2EMF+jqCTLGtsqYQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQCMjKFycVQh7Puz/FpQh3NhJ99Ic3rzr+3nAKFD +4Kcl3L8szH3zjLCw46/y2jqPiAbg2zg9miYkI/2W/G+m2VQEQvp2SwjVr/Rj2Soe +iTonruUpDFF7LG01q3kpZ7nYWRGvVgn5D9BGk4/SWuzxiWRdwlzJf2e8cXLExVS0 +0CgRsb5nRoZ+RZmVIrGMfIi8CI7uTlcHtQzD7B7gpHtOSMlQoSSeqOy6F498duvl +QhhQhJBxmjSegw/lawWQSDFArJimK/rwyb6ZFbRfBgg6o/k5W9G5l0oG5abQMp+/ +u8Fd+QUNwR6OovE0AqL6wNHCnqzNnihTL6/hRVer6i5Hfxmb +-----END CERTIFICATE----- diff --git a/test/fixtures/keys/fake-startcom-root-key.pem b/test/fixtures/keys/fake-startcom-root-key.pem new file mode 100644 index 00000000000000..d8f727d2be6780 --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAu+EBm0ZTe7e7IHiUeflfzlcl3I8Cc5jSEZxJUzN9D8EES8E+ +Rx2Em9k8upxZOcmmWwlcf4YfP2rvcNvIt6R0X9/p01VxGYOO9mqlnoqBPwPgaa50 +08wS4ez35uoj6XmnsyHWYSai3kli1e8YPdSI3ZlRD+2uF/nGImowRqJAcHGEkRKR +j5FhXYYrSeMInbKma0ADPIZSU2AerEHLU+sEGqHTFtI5ranBHLP27sSRg3gEJAo0 +IEls5pf2sf6PzfpiUQcTKa62NgO5iIdo697TIkIexCqzHv6n1oFTEJL2ZOP2r1vP +0YlH219PTj4eZBGO1Jli3t8ciLGBLS9Pj/pCWwIDAQABAoIBAFOQL2O9stH7FTrL +Btb9iJRBBLEF1oRNu1lj1uUvqHdCVUPQbn+47EtZIv6pHbJrMxeYoVCC+hD94gOj +bbHobm5aLCj3/rbnYcXOB13torDBa6X1lzbAtMFR4a0OBO0KVAGDklNhmN0fbNtU +XcbaagmN8JUSFPXK/Uo/SruP3PNldfPVtf/EnBlK4LOI5/WDyiwLQxlVf389poKp +wXwhVgL9Kh0uzxD31HH0NOL+D1KOI6j7gNrOAOZFFGTwVAtQFI28wIwftKf3qicQ +TZvV/O+Aw+oIZsOfX9Pg6dNehhEC25F6UcGrX7b7fI/Rbx6L/VxfjMHfbvsUtTxz +iwW1H5ECgYEA85U2LiBicAB4QkclUHjLPrPl7W0bDvKFKJkxXJ44y/ziFjOhksuF +J1xYXhVhP7mdXwGVlt2X9PSjkW06I+DFqi2IbGDBqJ/0hJrAr/+5J5OySCFlx2kC +TwIAYJIud0Vgk8FdToijOKq8I3KFmUsc6k0UMmCdCy4HXz0Qy3RqsekCgYEAxXTZ +3orr/ItfjVFz9bkcNUMutRVvsyewYJOemgaejdSHLYl8lTcLQDLSnA/Sd7JtXOyS +3M7GVpiBZqW15UJry5fpkRNhqOXqXz6/Hp9E3hG9RnS2EkZDR2vIrRwa3o6zKq8P +XYOOOzjdYq881khhRhafXCon0XvLdZAsOKfDQ6MCgYEAqsDw6Ej/eLB7nUqul8j2 +AZCvIE+Z5lKQkjNB7UFlY2p1O0cafwN45mzP7bRjJf8CmPVNXiMdQTS17V56oWgS +aQfeWMtDNuhayxKI/Vfw/hOFqRbweGfenHA0v336YNYbq7ijpkgW08SsetTvXtTP +AljiTaZ4sLulo1f1jAqiOPECgYA1CgJL6P0ixT1RdIO1iZeuJvGw6qUqdorGJmD/ +9q84YdI9xSSV4EdBY2V3Tji2tlLyFwoMDe7w6942eGS3xHO4KIIw2gftmnSuSOiF +jTqufA1fk5IkroL7+FPbTCVbivFNkeCKuf/GoKu3CmNJHAAlF4aO9zPi7WHlnmiC +f23QCQKBgET2u4cPsUAZJ8utCyQ+ZhKJUTcYDN/Nlpd/yVC+dS9BZAc2tH1EfRN2 +pxSzm9Qgd6Cjc7cVJ/T745b85nbPjd1MsOgvPCKr0TFARmlGpu4RtKEHrROSaahX +7vR7HiYqhbeYlVRz9lZ5N+J1BT7sq7+Rond89UtL/O7g0wEs/N3V +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/keys/fake-startcom-root-serial b/test/fixtures/keys/fake-startcom-root-serial new file mode 100644 index 00000000000000..75016ea3625245 --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-serial @@ -0,0 +1 @@ +03 diff --git a/test/fixtures/keys/fake-startcom-root-serial.old b/test/fixtures/keys/fake-startcom-root-serial.old new file mode 100644 index 00000000000000..9e22bcb8e34408 --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root-serial.old @@ -0,0 +1 @@ +02 diff --git a/test/fixtures/keys/fake-startcom-root.cnf b/test/fixtures/keys/fake-startcom-root.cnf new file mode 100644 index 00000000000000..d6a9557bc8778d --- /dev/null +++ b/test/fixtures/keys/fake-startcom-root.cnf @@ -0,0 +1,46 @@ +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = . +name_opt = CA_default +cert_opt = CA_default +default_crl_days = 999 +default_md = sha256 +database = fake-startcom-root-database.txt +serial = fake-startcom-root-serial +private_key = fake-startcom-root-key.pem +certificate = fake-startcom-root-cert.pem +new_certs_dir = fake-startcom-root-issued-certs +email_in_dn = no +policy = policy_anything + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +default_bits = 2048 +days = 999 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +output_password = password +x509_extensions = v3_ca + +[ req_distinguished_name ] +C = IL +O = StartCom Ltd. +OU = Secure Digital Certificate Signing +CN = StartCom Certification Authority + +[ req_attributes ] +challengePassword = A challenge password + +[ v3_ca ] +basicConstraints = CA:TRUE diff --git a/test/gc/test-net-timeout.js b/test/gc/test-net-timeout.js index 2d9bc134a30347..9bc19a04256108 100644 --- a/test/gc/test-net-timeout.js +++ b/test/gc/test-net-timeout.js @@ -36,7 +36,7 @@ function getall() { if (count >= todo) return; - const req = net.connect(server.address().port, server.address().address); + const req = net.connect(server.address().port); req.resume(); req.setTimeout(10, function() { req.destroy(); diff --git a/test/inspector/test-inspector.js b/test/inspector/test-inspector.js index 46b3323b0784ba..08c0938c87e832 100644 --- a/test/inspector/test-inspector.js +++ b/test/inspector/test-inspector.js @@ -114,10 +114,10 @@ function testSetBreakpointAndResume(session) { const commands = [ { 'method': 'Debugger.setBreakpointByUrl', 'params': { 'lineNumber': 5, - 'url': session.mainScriptPath, - 'columnNumber': 0, - 'condition': '' - } + 'url': session.mainScriptPath, + 'columnNumber': 0, + 'condition': '' + } }, { 'method': 'Debugger.resume'}, [ { 'method': 'Debugger.getScriptSource', diff --git a/test/internet/test-dgram-multicast-multi-process.js b/test/internet/test-dgram-multicast-multi-process.js index 307549bba870b6..36b429d6cf3f68 100644 --- a/test/internet/test-dgram-multicast-multi-process.js +++ b/test/internet/test-dgram-multicast-multi-process.js @@ -21,14 +21,14 @@ if (common.inFreeBSDJail) { return; } -function launchChildProcess(index) { +function launchChildProcess() { const worker = fork(__filename, ['child']); workers[worker.pid] = worker; worker.messagesReceived = []; // Handle the death of workers. - worker.on('exit', function(code, signal) { + worker.on('exit', function(code) { // Don't consider this the true death if the worker has finished // successfully or if the exit code is 0. if (worker.isDone || code === 0) { @@ -188,7 +188,7 @@ if (process.argv[2] === 'child') { process.send({ message: buf.toString() }); - if (receivedMessages.length == messages.length) { + if (receivedMessages.length === messages.length) { // .dropMembership() not strictly needed but here as a sanity check. listenSocket.dropMembership(LOCAL_BROADCAST_HOST); process.nextTick(function() { diff --git a/test/internet/test-dns-ipv4.js b/test/internet/test-dns-ipv4.js index a86c863cc443c9..c4f2d00df886d9 100644 --- a/test/internet/test-dns-ipv4.js +++ b/test/internet/test-dns-ipv4.js @@ -36,61 +36,61 @@ function checkWrap(req) { TEST(function test_resolve4(done) { const req = dns.resolve4('www.google.com', - common.mustCall((err, ips) => { - assert.ifError(err); + common.mustCall((err, ips) => { + assert.ifError(err); - assert.ok(ips.length > 0); + assert.ok(ips.length > 0); - for (let i = 0; i < ips.length; i++) { - assert.ok(isIPv4(ips[i])); - } + for (let i = 0; i < ips.length; i++) { + assert.ok(isIPv4(ips[i])); + } - done(); - })); + done(); + })); checkWrap(req); }); TEST(function test_reverse_ipv4(done) { const req = dns.reverse('8.8.8.8', - common.mustCall((err, domains) => { - assert.ifError(err); + common.mustCall((err, domains) => { + assert.ifError(err); - assert.ok(domains.length > 0); + assert.ok(domains.length > 0); - for (let i = 0; i < domains.length; i++) { - assert.ok(domains[i]); - assert.ok(typeof domains[i] === 'string'); - } + for (let i = 0; i < domains.length; i++) { + assert.ok(domains[i]); + assert.ok(typeof domains[i] === 'string'); + } - done(); - })); + done(); + })); checkWrap(req); }); TEST(function test_lookup_ipv4_explicit(done) { const req = dns.lookup('www.google.com', 4, - common.mustCall((err, ip, family) => { - assert.ifError(err); - assert.ok(net.isIPv4(ip)); - assert.strictEqual(family, 4); + common.mustCall((err, ip, family) => { + assert.ifError(err); + assert.ok(net.isIPv4(ip)); + assert.strictEqual(family, 4); - done(); - })); + done(); + })); checkWrap(req); }); TEST(function test_lookup_ipv4_implicit(done) { const req = dns.lookup('www.google.com', - common.mustCall((err, ip, family) => { - assert.ifError(err); - assert.ok(net.isIPv4(ip)); - assert.strictEqual(family, 4); + common.mustCall((err, ip, family) => { + assert.ifError(err); + assert.ok(net.isIPv4(ip)); + assert.strictEqual(family, 4); - done(); - })); + done(); + })); checkWrap(req); }); @@ -125,26 +125,26 @@ TEST(function test_lookup_ipv4_hint_addrconfig(done) { TEST(function test_lookup_ip_ipv4(done) { const req = dns.lookup('127.0.0.1', - common.mustCall((err, ip, family) => { - assert.ifError(err); - assert.strictEqual(ip, '127.0.0.1'); - assert.strictEqual(family, 4); + common.mustCall((err, ip, family) => { + assert.ifError(err); + assert.strictEqual(ip, '127.0.0.1'); + assert.strictEqual(family, 4); - done(); - })); + done(); + })); checkWrap(req); }); TEST(function test_lookup_localhost_ipv4(done) { const req = dns.lookup('localhost', 4, - common.mustCall((err, ip, family) => { - assert.ifError(err); - assert.strictEqual(ip, '127.0.0.1'); - assert.strictEqual(family, 4); + common.mustCall((err, ip, family) => { + assert.ifError(err); + assert.strictEqual(ip, '127.0.0.1'); + assert.strictEqual(family, 4); - done(); - })); + done(); + })); checkWrap(req); }); @@ -164,21 +164,23 @@ TEST(function test_lookup_all_ipv4(done) { }); done(); - } - )); + }) + ); checkWrap(req); }); TEST(function test_lookupservice_ip_ipv4(done) { - const req = dns.lookupService('127.0.0.1', 80, + const req = dns.lookupService( + '127.0.0.1', 80, common.mustCall((err, host, service) => { assert.ifError(err); assert.strictEqual(typeof host, 'string'); assert(host); assert(['http', 'www', '80'].includes(service)); done(); - })); + }) + ); checkWrap(req); }); diff --git a/test/internet/test-dns-ipv6.js b/test/internet/test-dns-ipv6.js index b2cdd14c53a60c..b872af746bf25d 100644 --- a/test/internet/test-dns-ipv6.js +++ b/test/internet/test-dns-ipv6.js @@ -41,45 +41,45 @@ function checkWrap(req) { TEST(function test_resolve6(done) { const req = dns.resolve6('ipv6.google.com', - common.mustCall((err, ips) => { - assert.ifError(err); + common.mustCall((err, ips) => { + assert.ifError(err); - assert.ok(ips.length > 0); + assert.ok(ips.length > 0); - for (let i = 0; i < ips.length; i++) - assert.ok(isIPv6(ips[i])); + for (let i = 0; i < ips.length; i++) + assert.ok(isIPv6(ips[i])); - done(); - })); + done(); + })); checkWrap(req); }); TEST(function test_reverse_ipv6(done) { const req = dns.reverse('2001:4860:4860::8888', - common.mustCall((err, domains) => { - assert.ifError(err); + common.mustCall((err, domains) => { + assert.ifError(err); - assert.ok(domains.length > 0); + assert.ok(domains.length > 0); - for (let i = 0; i < domains.length; i++) - assert.ok(typeof domains[i] === 'string'); + for (let i = 0; i < domains.length; i++) + assert.ok(typeof domains[i] === 'string'); - done(); - })); + done(); + })); checkWrap(req); }); TEST(function test_lookup_ipv6_explicit(done) { const req = dns.lookup('ipv6.google.com', 6, - common.mustCall((err, ip, family) => { - assert.ifError(err); - assert.ok(isIPv6(ip)); - assert.strictEqual(family, 6); + common.mustCall((err, ip, family) => { + assert.ifError(err); + assert.ok(isIPv6(ip)); + assert.strictEqual(family, 6); - done(); - })); + done(); + })); checkWrap(req); }); @@ -142,13 +142,13 @@ TEST(function test_lookup_ipv6_hint(done) { TEST(function test_lookup_ip_ipv6(done) { const req = dns.lookup('::1', - common.mustCall((err, ip, family) => { - assert.ifError(err); - assert.ok(isIPv6(ip)); - assert.strictEqual(family, 6); + common.mustCall((err, ip, family) => { + assert.ifError(err); + assert.ok(isIPv6(ip)); + assert.strictEqual(family, 6); - done(); - })); + done(); + })); checkWrap(req); }); @@ -169,14 +169,15 @@ TEST(function test_lookup_all_ipv6(done) { }); done(); - } - )); + }) + ); checkWrap(req); }); TEST(function test_lookupservice_ip_ipv6(done) { - const req = dns.lookupService('::1', 80, + const req = dns.lookupService( + '::1', 80, common.mustCall((err, host, service) => { if (err) { // Not skipping the test, rather checking an alternative result, @@ -188,7 +189,8 @@ TEST(function test_lookupservice_ip_ipv6(done) { assert(host); assert(['http', 'www', '80'].includes(service)); done(); - })); + }) + ); checkWrap(req); }); diff --git a/test/known_issues/test-repl-require-context.js b/test/known_issues/test-repl-require-context.js index 2c9195d940e2e4..e7a27f2ca68f6b 100644 --- a/test/known_issues/test-repl-require-context.js +++ b/test/known_issues/test-repl-require-context.js @@ -19,9 +19,7 @@ outputStream.setEncoding('utf8'); outputStream.on('data', (data) => output += data); r.on('exit', common.mustCall(() => { - const results = output.split('\n').map((line) => { - return line.replace(/\w*>\w*/, '').trim(); - }); + const results = output.replace(/^> /mg, '').split('\n'); assert.deepStrictEqual(results, ['undefined', 'true', 'true', '']); })); diff --git a/test/known_issues/test-vm-attributes-property-not-on-sandbox.js b/test/known_issues/test-vm-attributes-property-not-on-sandbox.js new file mode 100644 index 00000000000000..d9534c3d4393a9 --- /dev/null +++ b/test/known_issues/test-vm-attributes-property-not-on-sandbox.js @@ -0,0 +1,25 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const vm = require('vm'); + +// The QueryCallback explicitly calls GetRealNamedPropertyAttributes +// on the global proxy if the property is not found on the sandbox. +// +// foo is not defined on the sandbox until we call CopyProperties(). +// In the QueryCallback, we do not find the property on the sandbox +// and look up its PropertyAttributes on the global_proxy(). +// PropertyAttributes are always flattened to a value +// descriptor. +const sandbox = {}; +vm.createContext(sandbox); +const code = `Object.defineProperty( + this, + 'foo', + { get: function() {return 17} } + ); + var desc = Object.getOwnPropertyDescriptor(this, 'foo');`; + +vm.runInContext(code, sandbox); +// The descriptor is flattened. We wrongly have typeof desc.value = 'number'. +assert.strictEqual(typeof sandbox.desc.get, 'function'); diff --git a/test/known_issues/test-vm-data-property-writable.js b/test/known_issues/test-vm-data-property-writable.js new file mode 100644 index 00000000000000..f29052a73a7b6b --- /dev/null +++ b/test/known_issues/test-vm-data-property-writable.js @@ -0,0 +1,17 @@ +'use strict'; +// Refs: https://github.com/nodejs/node/issues/10223 + +require('../common'); +const vm = require('vm'); +const assert = require('assert'); + +const context = vm.createContext({}); + +const code = ` + Object.defineProperty(this, 'foo', {value: 5}); + Object.getOwnPropertyDescriptor(this, 'foo'); +`; + +const desc = vm.runInContext(code, context); + +assert.strictEqual(desc.writable, false); diff --git a/test/message/eval_messages.out b/test/message/eval_messages.out index 44965be374bac5..ba0c35431c6907 100644 --- a/test/message/eval_messages.out +++ b/test/message/eval_messages.out @@ -3,7 +3,8 @@ with(this){__filename} ^^^^ SyntaxError: Strict mode code may not include a with statement - at Object.exports.runInThisContext (vm.js:*) + at createScript (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) @@ -15,10 +16,11 @@ SyntaxError: Strict mode code may not include a with statement [eval]:1 throw new Error("hello") ^ + Error: hello at [eval]:1:7 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) @@ -28,10 +30,11 @@ Error: hello [eval]:1 throw new Error("hello") ^ + Error: hello at [eval]:1:7 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) @@ -42,20 +45,23 @@ Error: hello [eval]:1 var x = 100; y = x; ^ + ReferenceError: y is not defined at [eval]:1:16 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) at runCallback (timers.js:*:*) at tryOnImmediate (timers.js:*:*) at processImmediate [as _immediateCallback] (timers.js:*:*) + [eval]:1 var ______________________________________________; throw 10 ^ 10 + [eval]:1 var ______________________________________________; throw 10 ^ diff --git a/test/message/stdin_messages.out b/test/message/stdin_messages.out index 828bee92cb6f7f..b4c51d7ad567f0 100644 --- a/test/message/stdin_messages.out +++ b/test/message/stdin_messages.out @@ -1,10 +1,10 @@ [stdin] - [stdin]:1 with(this){__filename} ^^^^ SyntaxError: Strict mode code may not include a with statement - at Object.exports.runInThisContext (vm.js:*) + at createScript (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([stdin]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) @@ -13,28 +13,28 @@ SyntaxError: Strict mode code may not include a with statement at processImmediate [as _immediateCallback] (timers.js:*:*) 42 42 - [stdin]:1 throw new Error("hello") ^ + Error: hello - at [stdin]:1:* + at [stdin]:1:7 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([stdin]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) at runCallback (timers.js:*:*) at tryOnImmediate (timers.js:*:*) at processImmediate [as _immediateCallback] (timers.js:*:*) - [stdin]:1 throw new Error("hello") ^ + Error: hello at [stdin]:1:* at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([stdin]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) @@ -42,14 +42,14 @@ Error: hello at tryOnImmediate (timers.js:*:*) at processImmediate [as _immediateCallback] (timers.js:*:*) 100 - [stdin]:1 var x = 100; y = x; ^ + ReferenceError: y is not defined at [stdin]:1:16 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. ([stdin]-wrapper:*:*) at Module._compile (module.js:*:*) at Immediate. (bootstrap_node.js:*:*) diff --git a/test/message/timeout_throw.js b/test/message/timeout_throw.js index 14291fabd12565..4008f306fe58be 100644 --- a/test/message/timeout_throw.js +++ b/test/message/timeout_throw.js @@ -4,4 +4,4 @@ require('../common'); setTimeout(function() { // eslint-disable-next-line no-undef undefined_reference_error_maker; -}); +}, 1); diff --git a/test/message/undefined_reference_in_new_context.out b/test/message/undefined_reference_in_new_context.out index 04b9a21acdeb1f..93bc1dcc99c3e1 100644 --- a/test/message/undefined_reference_in_new_context.out +++ b/test/message/undefined_reference_in_new_context.out @@ -1,13 +1,13 @@ before - evalmachine.:1 foo.bar = 5; ^ + ReferenceError: foo is not defined at evalmachine.:1:1 at ContextifyScript.Script.runInContext (vm.js:*) at ContextifyScript.Script.runInNewContext (vm.js:*) - at Object.exports.runInNewContext (vm.js:*) + at Object.runInNewContext (vm.js:*) at Object. (*test*message*undefined_reference_in_new_context.js:*) at Module._compile (module.js:*) at *..js (module.js:*) diff --git a/test/message/unhandled_promise_trace_warnings.out b/test/message/unhandled_promise_trace_warnings.out index c2c7b91f47e11d..d77b54c4e3b2e7 100644 --- a/test/message/unhandled_promise_trace_warnings.out +++ b/test/message/unhandled_promise_trace_warnings.out @@ -13,8 +13,8 @@ at getAsynchronousRejectionWarningObject (internal/process/promises.js:*) at rejectionHandled (internal/process/promises.js:*) at * - at Promise.then (native) - at Promise.catch (native) + at Promise.then * + at Promise.catch * at Immediate.setImmediate (*test*message*unhandled_promise_trace_warnings.js:*) at * at * diff --git a/test/message/vm_display_runtime_error.out b/test/message/vm_display_runtime_error.out index b7fe798cd29adb..d5cf1d3ee50dbb 100644 --- a/test/message/vm_display_runtime_error.out +++ b/test/message/vm_display_runtime_error.out @@ -1,12 +1,12 @@ beginning - test.vm:1 throw new Error("boo!") ^ + Error: boo! at test.vm:1:7 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. (*test*message*vm_display_runtime_error.js:*) at Module._compile (module.js:*) at Object.Module._extensions..js (module.js:*) diff --git a/test/message/vm_display_syntax_error.out b/test/message/vm_display_syntax_error.out index 8917f2f9d0cbb7..9ec62eacb895f0 100644 --- a/test/message/vm_display_syntax_error.out +++ b/test/message/vm_display_syntax_error.out @@ -1,10 +1,10 @@ beginning - foo.vm:1 var 4; ^ SyntaxError: Unexpected number - at Object.exports.runInThisContext (vm.js:*) + at createScript (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. (*test*message*vm_display_syntax_error.js:*) at Module._compile (module.js:*) at Object.Module._extensions..js (module.js:*) @@ -13,12 +13,12 @@ SyntaxError: Unexpected number at Function.Module._load (module.js:*) at Module.runMain (module.js:*) at run (bootstrap_node.js:*) - at startup (bootstrap_node.js:*) test.vm:1 var 5; ^ SyntaxError: Unexpected number - at Object.exports.runInThisContext (vm.js:*) + at createScript (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. (*test*message*vm_display_syntax_error.js:*) at Module._compile (module.js:*) at Object.Module._extensions..js (module.js:*) @@ -27,4 +27,3 @@ SyntaxError: Unexpected number at Function.Module._load (module.js:*) at Module.runMain (module.js:*) at run (bootstrap_node.js:*) - at startup (bootstrap_node.js:*) diff --git a/test/message/vm_dont_display_runtime_error.out b/test/message/vm_dont_display_runtime_error.out index e0795d1f535e35..a60bde2a8c29ea 100644 --- a/test/message/vm_dont_display_runtime_error.out +++ b/test/message/vm_dont_display_runtime_error.out @@ -3,10 +3,11 @@ middle test.vm:1 throw new Error("boo!") ^ + Error: boo! at test.vm:1:7 at ContextifyScript.Script.runInThisContext (vm.js:*) - at Object.exports.runInThisContext (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. (*test*message*vm_dont_display_runtime_error.js:*) at Module._compile (module.js:*) at Object.Module._extensions..js (module.js:*) diff --git a/test/message/vm_dont_display_syntax_error.out b/test/message/vm_dont_display_syntax_error.out index de3daab301890e..bc5b180dc1fa2a 100644 --- a/test/message/vm_dont_display_syntax_error.out +++ b/test/message/vm_dont_display_syntax_error.out @@ -3,8 +3,10 @@ middle test.vm:1 var 5; ^ + SyntaxError: Unexpected number - at Object.exports.runInThisContext (vm.js:*) + at createScript (vm.js:*) + at Object.runInThisContext (vm.js:*) at Object. (*test*message*vm_dont_display_syntax_error.js:*) at Module._compile (module.js:*) at Object.Module._extensions..js (module.js:*) @@ -13,4 +15,3 @@ SyntaxError: Unexpected number at Function.Module._load (module.js:*) at Module.runMain (module.js:*) at run (bootstrap_node.js:*) - at startup (bootstrap_node.js:*) diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index eb983345418637..003cbdcc90d4e7 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -64,7 +64,7 @@ assert.doesNotThrow(makeBlock(a.notStrictEqual, 2, '2'), // deepEqual joy! // 7.2 assert.doesNotThrow(makeBlock(a.deepEqual, new Date(2000, 3, 14), - new Date(2000, 3, 14)), + new Date(2000, 3, 14)), 'deepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14))'); assert.throws(makeBlock(a.deepEqual, new Date(), new Date(2000, 3, 14)), @@ -81,7 +81,7 @@ assert.doesNotThrow(makeBlock( a.notDeepEqual, new Date(), new Date(2000, 3, 14)), - 'notDeepEqual(new Date(), new Date(2000, 3, 14))' + 'notDeepEqual(new Date(), new Date(2000, 3, 14))' ); // 7.3 @@ -90,16 +90,23 @@ assert.doesNotThrow(makeBlock(a.deepEqual, /a/g, /a/g)); assert.doesNotThrow(makeBlock(a.deepEqual, /a/i, /a/i)); assert.doesNotThrow(makeBlock(a.deepEqual, /a/m, /a/m)); assert.doesNotThrow(makeBlock(a.deepEqual, /a/igm, /a/igm)); -assert.throws(makeBlock(a.deepEqual, /ab/, /a/)); -assert.throws(makeBlock(a.deepEqual, /a/g, /a/)); -assert.throws(makeBlock(a.deepEqual, /a/i, /a/)); -assert.throws(makeBlock(a.deepEqual, /a/m, /a/)); -assert.throws(makeBlock(a.deepEqual, /a/igm, /a/im)); +assert.throws(makeBlock(a.deepEqual, /ab/, /a/), + /^AssertionError: \/ab\/ deepEqual \/a\/$/); +assert.throws(makeBlock(a.deepEqual, /a/g, /a/), + /^AssertionError: \/a\/g deepEqual \/a\/$/); +assert.throws(makeBlock(a.deepEqual, /a/i, /a/), + /^AssertionError: \/a\/i deepEqual \/a\/$/); +assert.throws(makeBlock(a.deepEqual, /a/m, /a/), + /^AssertionError: \/a\/m deepEqual \/a\/$/); +assert.throws(makeBlock(a.deepEqual, /a/igm, /a/im), + /^AssertionError: \/a\/gim deepEqual \/a\/im$/); { - const re1 = /a/; + const re1 = /a/g; re1.lastIndex = 3; - assert.throws(makeBlock(a.deepEqual, re1, /a/)); + + assert.throws(makeBlock(a.deepEqual, re1, /a/g), + /^AssertionError: \/a\/g deepEqual \/a\/g$/); } @@ -209,11 +216,26 @@ assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/g, /a/g)); assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/i, /a/i)); assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/m, /a/m)); assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/igm, /a/igm)); -assert.throws(makeBlock(a.deepStrictEqual, /ab/, /a/)); -assert.throws(makeBlock(a.deepStrictEqual, /a/g, /a/)); -assert.throws(makeBlock(a.deepStrictEqual, /a/i, /a/)); -assert.throws(makeBlock(a.deepStrictEqual, /a/m, /a/)); -assert.throws(makeBlock(a.deepStrictEqual, /a/igm, /a/im)); +assert.throws( + makeBlock(a.deepStrictEqual, /ab/, /a/), + /^AssertionError: \/ab\/ deepStrictEqual \/a\/$/ +); +assert.throws( + makeBlock(a.deepStrictEqual, /a/g, /a/), + /^AssertionError: \/a\/g deepStrictEqual \/a\/$/ +); +assert.throws( + makeBlock(a.deepStrictEqual, /a/i, /a/), + /^AssertionError: \/a\/i deepStrictEqual \/a\/$/ +); +assert.throws( + makeBlock(a.deepStrictEqual, /a/m, /a/), + /^AssertionError: \/a\/m deepStrictEqual \/a\/$/ +); +assert.throws( + makeBlock(a.deepStrictEqual, /a/igm, /a/im), + /^AssertionError: \/a\/gim deepStrictEqual \/a\/im$/ +); { const re1 = /a/; @@ -358,14 +380,15 @@ try { assert.equal(true, threw, 'a.doesNotThrow is not catching type matching errors'); -assert.throws(function() { assert.ifError(new Error('test error')); }); +assert.throws(function() { assert.ifError(new Error('test error')); }, + /^Error: test error$/); assert.doesNotThrow(function() { assert.ifError(null); }); assert.doesNotThrow(function() { assert.ifError(); }); assert.throws(() => { assert.doesNotThrow(makeBlock(thrower, Error), 'user message'); }, /Got unwanted exception. user message/, - 'a.doesNotThrow ignores user message'); + 'a.doesNotThrow ignores user message'); // make sure that validating using constructor really works threw = false; @@ -489,7 +512,7 @@ testAssertionMessage({}, '{}'); testAssertionMessage(circular, '{ y: 1, x: [Circular] }'); testAssertionMessage({a: undefined, b: null}, '{ a: undefined, b: null }'); testAssertionMessage({a: NaN, b: Infinity, c: -Infinity}, - '{ a: NaN, b: Infinity, c: -Infinity }'); + '{ a: NaN, b: Infinity, c: -Infinity }'); // #2893 try { diff --git a/test/parallel/test-buffer-alloc.js b/test/parallel/test-buffer-alloc.js index ba5379ad45fbea..1332a16a3cc807 100644 --- a/test/parallel/test-buffer-alloc.js +++ b/test/parallel/test-buffer-alloc.js @@ -830,94 +830,16 @@ assert.throws(() => Buffer.alloc(8).writeFloatLE(0, 5), RangeError); assert.throws(() => Buffer.alloc(16).writeDoubleLE(0, 9), RangeError); // attempt to overflow buffers, similar to previous bug in array buffers -assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), - RangeError); assert.throws(() => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff), RangeError); -assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), - RangeError); assert.throws(() => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff), RangeError); // ensure negative values can't get past offset -assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); assert.throws(() => Buffer.allocUnsafe(8).writeFloatLE(0.0, -1), RangeError); -assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); assert.throws(() => Buffer.allocUnsafe(8).writeFloatLE(0.0, -1), RangeError); -// offset checks -{ - const buf = Buffer.allocUnsafe(0); - - assert.throws(() => buf.readUInt8(0), RangeError); - assert.throws(() => buf.readInt8(0), RangeError); -} - -{ - const buf = Buffer.from([0xFF]); - - assert.strictEqual(buf.readUInt8(0), 255); - assert.strictEqual(buf.readInt8(0), -1); -} - -[16, 32].forEach((bits) => { - const buf = Buffer.allocUnsafe(bits / 8 - 1); - - assert.throws(() => buf[`readUInt${bits}BE`](0), - RangeError, - `readUInt${bits}BE()`); - - assert.throws(() => buf[`readUInt${bits}LE`](0), - RangeError, - `readUInt${bits}LE()`); - - assert.throws(() => buf[`readInt${bits}BE`](0), - RangeError, - `readInt${bits}BE()`); - - assert.throws(() => buf[`readInt${bits}LE`](0), - RangeError, - `readInt${bits}LE()`); -}); - -[16, 32].forEach((bits) => { - const buf = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF]); - - assert.strictEqual(buf[`readUInt${bits}BE`](0), - (0xFFFFFFFF >>> (32 - bits))); - - assert.strictEqual(buf[`readUInt${bits}LE`](0), - (0xFFFFFFFF >>> (32 - bits))); - - assert.strictEqual(buf[`readInt${bits}BE`](0), - (0xFFFFFFFF >> (32 - bits))); - - assert.strictEqual(buf[`readInt${bits}LE`](0), - (0xFFFFFFFF >> (32 - bits))); -}); - -// test for common read(U)IntLE/BE -{ - const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); - - assert.strictEqual(buf.readUIntLE(0, 1), 0x01); - assert.strictEqual(buf.readUIntBE(0, 1), 0x01); - assert.strictEqual(buf.readUIntLE(0, 3), 0x030201); - assert.strictEqual(buf.readUIntBE(0, 3), 0x010203); - assert.strictEqual(buf.readUIntLE(0, 5), 0x0504030201); - assert.strictEqual(buf.readUIntBE(0, 5), 0x0102030405); - assert.strictEqual(buf.readUIntLE(0, 6), 0x060504030201); - assert.strictEqual(buf.readUIntBE(0, 6), 0x010203040506); - assert.strictEqual(buf.readIntLE(0, 1), 0x01); - assert.strictEqual(buf.readIntBE(0, 1), 0x01); - assert.strictEqual(buf.readIntLE(0, 3), 0x030201); - assert.strictEqual(buf.readIntBE(0, 3), 0x010203); - assert.strictEqual(buf.readIntLE(0, 5), 0x0504030201); - assert.strictEqual(buf.readIntBE(0, 5), 0x0102030405); - assert.strictEqual(buf.readIntLE(0, 6), 0x060504030201); - assert.strictEqual(buf.readIntBE(0, 6), 0x010203040506); -} // test for common write(U)IntLE/BE { @@ -1018,9 +940,7 @@ assert.throws(() => Buffer.from('', 'buffer'), TypeError); // Regression test for #6111. Constructing a buffer from another buffer // should a) work, and b) not corrupt the source buffer. { - let a = [0]; - for (let i = 0; i < 7; ++i) a = a.concat(a); - a = a.map((_, i) => { return i; }); + const a = [...Array(128).keys()]; // [0, 1, 2, 3, ... 126, 127] const b = Buffer.from(a); const c = Buffer.from(b); assert.strictEqual(b.length, a.length); diff --git a/test/parallel/test-buffer-copy.js b/test/parallel/test-buffer-copy.js index fef4acf7df286b..0fb37cc0b41cf7 100644 --- a/test/parallel/test-buffer-copy.js +++ b/test/parallel/test-buffer-copy.js @@ -118,3 +118,29 @@ assert.strictEqual(b.copy(c, 0, 100, 10), 0); // when targetStart > targetLength, zero copied assert.strictEqual(b.copy(c, 512, 0, 10), 0); + +// Test that the `target` can be a Uint8Array. +{ + const d = new Uint8Array(c); + // copy 512 bytes, from 0 to 512. + b.fill(++cntr); + d.fill(++cntr); + const copied = b.copy(d, 0, 0, 512); + assert.strictEqual(512, copied); + for (let i = 0; i < d.length; i++) { + assert.strictEqual(b[i], d[i]); + } +} + +// Test that the source can be a Uint8Array, too. +{ + const e = new Uint8Array(b); + // copy 512 bytes, from 0 to 512. + e.fill(++cntr); + c.fill(++cntr); + const copied = Buffer.prototype.copy.call(e, c, 0, 0, 512); + assert.strictEqual(512, copied); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(e[i], c[i]); + } +} diff --git a/test/parallel/test-buffer-fill.js b/test/parallel/test-buffer-fill.js index eecb14abb06001..8cfeeabe91eebe 100644 --- a/test/parallel/test-buffer-fill.js +++ b/test/parallel/test-buffer-fill.js @@ -184,20 +184,20 @@ deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, -1]), [0, 0, 0, 0]); assert.throws(() => buf1.fill(0, -1), /^RangeError: Out of range index$/); assert.throws(() => buf1.fill(0, 0, buf1.length + 1), - /^RangeError: Out of range index$/); + /^RangeError: Out of range index$/); assert.throws(() => buf1.fill('', -1), /^RangeError: Out of range index$/); assert.throws(() => buf1.fill('', 0, buf1.length + 1), - /^RangeError: Out of range index$/); + /^RangeError: Out of range index$/); assert.throws(() => buf1.fill('a', 0, buf1.length, 'node rocks!'), - /^TypeError: Unknown encoding: node rocks!$/); + /^TypeError: Unknown encoding: node rocks!$/); assert.throws(() => buf1.fill('a', 0, 0, NaN), - /^TypeError: encoding must be a string$/); + /^TypeError: encoding must be a string$/); assert.throws(() => buf1.fill('a', 0, 0, null), - /^TypeError: encoding must be a string$/); + /^TypeError: encoding must be a string$/); assert.throws(() => buf1.fill('a', 0, 0, 'foo'), /^TypeError: Unknown encoding: foo$/); @@ -271,10 +271,10 @@ function testBufs(string, offset, length, encoding) { // Make sure these throw. assert.throws(() => Buffer.allocUnsafe(8).fill('a', -1), - /^RangeError: Out of range index$/); + /^RangeError: Out of range index$/); assert.throws(() => Buffer.allocUnsafe(8).fill('a', 0, 9), - /^RangeError: Out of range index$/); + /^RangeError: Out of range index$/); // Make sure this doesn't hang indefinitely. Buffer.allocUnsafe(8).fill(''); diff --git a/test/parallel/test-buffer-includes.js b/test/parallel/test-buffer-includes.js index 22ba1e6b7e1735..15e1eedeb54d15 100644 --- a/test/parallel/test-buffer-includes.js +++ b/test/parallel/test-buffer-includes.js @@ -159,10 +159,10 @@ assert( 6, mixedByteStringUcs2.includes(Buffer.from('bc', 'ucs2'), 0, 'ucs2')); assert( 10, mixedByteStringUcs2.includes(Buffer.from('\u03a3', 'ucs2'), - 0, 'ucs2')); + 0, 'ucs2')); assert( -1, mixedByteStringUcs2.includes(Buffer.from('\u0396', 'ucs2'), - 0, 'ucs2')); + 0, 'ucs2')); twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); diff --git a/test/parallel/test-buffer-indexof.js b/test/parallel/test-buffer-indexof.js index 746a2723167a60..d0379ec17162e9 100644 --- a/test/parallel/test-buffer-indexof.js +++ b/test/parallel/test-buffer-indexof.js @@ -11,6 +11,8 @@ const buf_f = Buffer.from('f'); const buf_z = Buffer.from('z'); const buf_empty = Buffer.from(''); +const s = 'abcdef'; + assert.strictEqual(b.indexOf('a'), 0); assert.strictEqual(b.indexOf('a', 1), -1); assert.strictEqual(b.indexOf('a', -1), -1); @@ -347,6 +349,37 @@ assert.throws(function() { b.indexOf([]); }); +// Test weird offset arguments. +// The following offsets coerce to NaN or 0, searching the whole Buffer +assert.strictEqual(b.indexOf('b', undefined), 1); +assert.strictEqual(b.indexOf('b', {}), 1); +assert.strictEqual(b.indexOf('b', 0), 1); +assert.strictEqual(b.indexOf('b', null), 1); +assert.strictEqual(b.indexOf('b', []), 1); + +// The following offset coerces to 2, in other words +[2] === 2 +assert.strictEqual(b.indexOf('b', [2]), -1); + +// Behavior should match String.indexOf() +assert.strictEqual( + b.indexOf('b', undefined), + s.indexOf('b', undefined)); +assert.strictEqual( + b.indexOf('b', {}), + s.indexOf('b', {})); +assert.strictEqual( + b.indexOf('b', 0), + s.indexOf('b', 0)); +assert.strictEqual( + b.indexOf('b', null), + s.indexOf('b', null)); +assert.strictEqual( + b.indexOf('b', []), + s.indexOf('b', [])); +assert.strictEqual( + b.indexOf('b', [2]), + s.indexOf('b', [2])); + // All code for handling encodings is shared between Buffer.indexOf and // Buffer.lastIndexOf, so only testing the separate lastIndexOf semantics. @@ -401,13 +434,37 @@ assert.equal(b.lastIndexOf(0x61, Infinity), 0); assert.equal(b.lastIndexOf(0x0), -1); // Test weird offset arguments. -// Behaviour should match String.lastIndexOf: -assert.equal(b.lastIndexOf('b', 0), -1); -assert.equal(b.lastIndexOf('b', undefined), 1); -assert.equal(b.lastIndexOf('b', null), -1); -assert.equal(b.lastIndexOf('b', {}), 1); -assert.equal(b.lastIndexOf('b', []), -1); -assert.equal(b.lastIndexOf('b', [2]), 1); +// The following offsets coerce to NaN, searching the whole Buffer +assert.strictEqual(b.lastIndexOf('b', undefined), 1); +assert.strictEqual(b.lastIndexOf('b', {}), 1); + +// The following offsets coerce to 0 +assert.strictEqual(b.lastIndexOf('b', 0), -1); +assert.strictEqual(b.lastIndexOf('b', null), -1); +assert.strictEqual(b.lastIndexOf('b', []), -1); + +// The following offset coerces to 2, in other words +[2] === 2 +assert.strictEqual(b.lastIndexOf('b', [2]), 1); + +// Behavior should match String.lastIndexOf() +assert.strictEqual( + b.lastIndexOf('b', undefined), + s.lastIndexOf('b', undefined)); +assert.strictEqual( + b.lastIndexOf('b', {}), + s.lastIndexOf('b', {})); +assert.strictEqual( + b.lastIndexOf('b', 0), + s.lastIndexOf('b', 0)); +assert.strictEqual( + b.lastIndexOf('b', null), + s.lastIndexOf('b', null)); +assert.strictEqual( + b.lastIndexOf('b', []), + s.lastIndexOf('b', [])); +assert.strictEqual( + b.lastIndexOf('b', [2]), + s.lastIndexOf('b', [2])); // Test needles longer than the haystack. assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'ucs2'), -1); diff --git a/test/parallel/test-buffer-read-noassert.js b/test/parallel/test-buffer-read-noassert.js new file mode 100644 index 00000000000000..83d533a32031cb --- /dev/null +++ b/test/parallel/test-buffer-read-noassert.js @@ -0,0 +1,59 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// testing basic buffer read functions +const buf = Buffer.from([0xa4, 0xfd, 0x48, 0xea, 0xcf, 0xff, 0xd9, 0x01, 0xde]); + +function read(buff, funx, args, expected) { + + assert.strictEqual(buff[funx](...args), expected); + assert.throws( + () => buff[funx](-1), + /^RangeError: Index out of range$/ + ); + + assert.doesNotThrow( + () => assert.strictEqual(buff[funx](...args, true), expected), + 'noAssert does not change return value for valid ranges' +); + +} + +// testing basic functionality of readDoubleBE() and readDOubleLE() +read(buf, 'readDoubleBE', [1], -3.1827727774563287e+295); +read(buf, 'readDoubleLE', [1], -6.966010051009108e+144); + +// testing basic functionality of readFLoatBE() and readFloatLE() +read(buf, 'readFloatBE', [1], -1.6691549692541768e+37); +read(buf, 'readFloatLE', [1], -7861303808); + +// testing basic functionality of readInt8() +read(buf, 'readInt8', [1], -3); + +// testing basic functionality of readInt16BE() and readInt16LE() +read(buf, 'readInt16BE', [1], -696); +read(buf, 'readInt16LE', [1], 0x48fd); + +// testing basic functionality of readInt32BE() and readInt32LE() +read(buf, 'readInt32BE', [1], -45552945); +read(buf, 'readInt32LE', [1], -806729475); + +// testing basic functionality of readIntBE() and readIntLE() +read(buf, 'readIntBE', [1, 1], -3); +read(buf, 'readIntLE', [2, 1], 0x48); + +// testing basic functionality of readUInt8() +read(buf, 'readUInt8', [1], 0xfd); + +// testing basic functionality of readUInt16BE() and readUInt16LE() +read(buf, 'readUInt16BE', [2], 0x48ea); +read(buf, 'readUInt16LE', [2], 0xea48); + +// testing basic functionality of readUInt32BE() and readUInt32LE() +read(buf, 'readUInt32BE', [1], 0xfd48eacf); +read(buf, 'readUInt32LE', [1], 0xcfea48fd); + +// testing basic functionality of readUIntBE() and readUIntLE() +read(buf, 'readUIntBE', [2, 0], 0xfd); +read(buf, 'readUIntLE', [2, 0], 0x48); diff --git a/test/parallel/test-buffer-read.js b/test/parallel/test-buffer-read.js new file mode 100644 index 00000000000000..53e53dd49e2a84 --- /dev/null +++ b/test/parallel/test-buffer-read.js @@ -0,0 +1,142 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// testing basic buffer read functions +const buf = Buffer.from([0xa4, 0xfd, 0x48, 0xea, 0xcf, 0xff, 0xd9, 0x01, 0xde]); + +function read(buff, funx, args, expected) { + + assert.strictEqual(buff[funx](...args), expected); + assert.throws( + () => buff[funx](-1), + /^RangeError: Index out of range$/ + ); + + assert.doesNotThrow( + () => assert.strictEqual(buff[funx](...args, true), expected), + 'noAssert does not change return value for valid ranges' +); + +} + +// testing basic functionality of readDoubleBE() and readDOubleLE() +read(buf, 'readDoubleBE', [1], -3.1827727774563287e+295); +read(buf, 'readDoubleLE', [1], -6.966010051009108e+144); + +// testing basic functionality of readFLoatBE() and readFloatLE() +read(buf, 'readFloatBE', [1], -1.6691549692541768e+37); +read(buf, 'readFloatLE', [1], -7861303808); + +// testing basic functionality of readInt8() +read(buf, 'readInt8', [1], -3); + +// testing basic functionality of readInt16BE() and readInt16LE() +read(buf, 'readInt16BE', [1], -696); +read(buf, 'readInt16LE', [1], 0x48fd); + +// testing basic functionality of readInt32BE() and readInt32LE() +read(buf, 'readInt32BE', [1], -45552945); +read(buf, 'readInt32LE', [1], -806729475); + +// testing basic functionality of readIntBE() and readIntLE() +read(buf, 'readIntBE', [1, 1], -3); +read(buf, 'readIntLE', [2, 1], 0x48); + +// testing basic functionality of readUInt8() +read(buf, 'readUInt8', [1], 0xfd); + +// testing basic functionality of readUInt16BE() and readUInt16LE() +read(buf, 'readUInt16BE', [2], 0x48ea); +read(buf, 'readUInt16LE', [2], 0xea48); + +// testing basic functionality of readUInt32BE() and readUInt32LE() +read(buf, 'readUInt32BE', [1], 0xfd48eacf); +read(buf, 'readUInt32LE', [1], 0xcfea48fd); + +// testing basic functionality of readUIntBE() and readUIntLE() +read(buf, 'readUIntBE', [2, 0], 0xfd); +read(buf, 'readUIntLE', [2, 0], 0x48); + +// attempt to overflow buffers, similar to previous bug in array buffers +assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), + RangeError); +assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), + RangeError); + +// ensure negative values can't get past offset +assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); +assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); + +// offset checks +{ + const buf = Buffer.allocUnsafe(0); + + assert.throws(() => buf.readUInt8(0), RangeError); + assert.throws(() => buf.readInt8(0), RangeError); +} + +{ + const buf = Buffer.from([0xFF]); + + assert.strictEqual(buf.readUInt8(0), 255); + assert.strictEqual(buf.readInt8(0), -1); +} + +[16, 32].forEach((bits) => { + const buf = Buffer.allocUnsafe(bits / 8 - 1); + + assert.throws(() => buf[`readUInt${bits}BE`](0), + RangeError, + `readUInt${bits}BE()`); + + assert.throws(() => buf[`readUInt${bits}LE`](0), + RangeError, + `readUInt${bits}LE()`); + + assert.throws(() => buf[`readInt${bits}BE`](0), + RangeError, + `readInt${bits}BE()`); + + assert.throws(() => buf[`readInt${bits}LE`](0), + RangeError, + `readInt${bits}LE()`); +}); + +[16, 32].forEach((bits) => { + const buf = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF]); + + assert.strictEqual(buf[`readUInt${bits}BE`](0), + (0xFFFFFFFF >>> (32 - bits))); + + assert.strictEqual(buf[`readUInt${bits}LE`](0), + (0xFFFFFFFF >>> (32 - bits))); + + assert.strictEqual(buf[`readInt${bits}BE`](0), + (0xFFFFFFFF >> (32 - bits))); + + assert.strictEqual(buf[`readInt${bits}LE`](0), + (0xFFFFFFFF >> (32 - bits))); +}); + +// test for common read(U)IntLE/BE +{ + const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); + + assert.strictEqual(buf.readUIntLE(0, 1), 0x01); + assert.strictEqual(buf.readUIntBE(0, 1), 0x01); + assert.strictEqual(buf.readUIntLE(0, 3), 0x030201); + assert.strictEqual(buf.readUIntBE(0, 3), 0x010203); + assert.strictEqual(buf.readUIntLE(0, 5), 0x0504030201); + assert.strictEqual(buf.readUIntBE(0, 5), 0x0102030405); + assert.strictEqual(buf.readUIntLE(0, 6), 0x060504030201); + assert.strictEqual(buf.readUIntBE(0, 6), 0x010203040506); + assert.strictEqual(buf.readIntLE(0, 1), 0x01); + assert.strictEqual(buf.readIntBE(0, 1), 0x01); + assert.strictEqual(buf.readIntLE(0, 3), 0x030201); + assert.strictEqual(buf.readIntBE(0, 3), 0x010203); + assert.strictEqual(buf.readIntLE(0, 5), 0x0504030201); + assert.strictEqual(buf.readIntBE(0, 5), 0x0102030405); + assert.strictEqual(buf.readIntLE(0, 6), 0x060504030201); + assert.strictEqual(buf.readIntBE(0, 6), 0x010203040506); +} diff --git a/test/parallel/test-buffer-readuintbe.js b/test/parallel/test-buffer-readuintbe.js deleted file mode 100644 index 162e9fea27a14f..00000000000000 --- a/test/parallel/test-buffer-readuintbe.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; -require('../common'); -const assert = require('assert'); - -// testing basic functionality of readUIntBE() - -const buf = Buffer.from([42, 84, 168, 127]); -const result = buf.readUIntBE(2); - -assert.strictEqual(result, 84); - -assert.throws( - () => { - buf.readUIntBE(5); - }, - /Index out of range/ -); - -assert.doesNotThrow( - () => { - buf.readUIntBE(5, 0, true); - }, - 'readUIntBE() should not throw if noAssert is true' -); diff --git a/test/parallel/test-buffer-readuintle.js b/test/parallel/test-buffer-readuintle.js deleted file mode 100644 index 982adb8607eaa1..00000000000000 --- a/test/parallel/test-buffer-readuintle.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; -require('../common'); -const assert = require('assert'); - -// testing basic functionality of readUIntLE() - -const buf = Buffer.from([42, 84, 168, 127]); -const result = buf.readUIntLE(2); - -assert.strictEqual(result, 168); - -assert.throws( - () => { - buf.readUIntLE(5); - }, - /Index out of range/ -); - -assert.doesNotThrow( - () => { - buf.readUIntLE(5, 0, true); - }, - 'readUIntLE() should not throw if noAssert is true' -); diff --git a/test/parallel/test-buffer-slice.js b/test/parallel/test-buffer-slice.js index 2489420c33e6e9..b43654b952de0b 100644 --- a/test/parallel/test-buffer-slice.js +++ b/test/parallel/test-buffer-slice.js @@ -8,54 +8,54 @@ assert.strictEqual(0, Buffer('hello', 'utf8').slice(0, 0).length); const buf = Buffer.from('0123456789', 'utf8'); assert.strictEqual(0, Buffer.compare(buf.slice(-10, 10), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(-20, 10), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(-20, -10), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(0), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(0, 0), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(undefined), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('foobar'), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(undefined, undefined), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(2), - Buffer.from('23456789', 'utf8'))); + Buffer.from('23456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(5), - Buffer.from('56789', 'utf8'))); + Buffer.from('56789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(10), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(5, 8), - Buffer.from('567', 'utf8'))); + Buffer.from('567', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(8, -1), - Buffer.from('8', 'utf8'))); + Buffer.from('8', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(-10), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(0, -9), - Buffer.from('0', 'utf8'))); + Buffer.from('0', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(0, -10), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(0, -1), - Buffer.from('012345678', 'utf8'))); + Buffer.from('012345678', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(2, -2), - Buffer.from('234567', 'utf8'))); + Buffer.from('234567', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(0, 65536), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(65536, 0), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(-5, -8), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(-5, -3), - Buffer.from('56', 'utf8'))); + Buffer.from('56', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice(-10, 10), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); for (let i = 0, s = buf; i < buf.length; ++i) { assert.strictEqual(0, Buffer.compare(buf.slice(i), s.slice(i))); assert.strictEqual(0, Buffer.compare(buf.slice(0, i), s.slice(0, i))); @@ -67,19 +67,19 @@ const utf16Buf = Buffer.from('0123456789', 'utf16le'); assert.deepStrictEqual(utf16Buf.slice(0, 6), Buffer.from('012', 'utf16le')); assert.strictEqual(0, Buffer.compare(buf.slice('0', '1'), - Buffer.from('0', 'utf8'))); + Buffer.from('0', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('-5', '10'), - Buffer.from('56789', 'utf8'))); + Buffer.from('56789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('-10', '10'), - Buffer.from('0123456789', 'utf8'))); + Buffer.from('0123456789', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('-10', '-5'), - Buffer.from('01234', 'utf8'))); + Buffer.from('01234', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('-10', '-0'), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('111'), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); assert.strictEqual(0, Buffer.compare(buf.slice('0', '-111'), - Buffer.from('', 'utf8'))); + Buffer.from('', 'utf8'))); // try to slice a zero length Buffer // see https://github.com/joyent/node/issues/5881 diff --git a/test/parallel/test-buffer-write-noassert.js b/test/parallel/test-buffer-write-noassert.js new file mode 100644 index 00000000000000..c0054733b85bb2 --- /dev/null +++ b/test/parallel/test-buffer-write-noassert.js @@ -0,0 +1,48 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// testing buffer write functions + +function write(funx, args, result, res) { + { + const buf = Buffer.alloc(9); + assert.strictEqual(buf[funx](...args), result); + assert.deepStrictEqual(buf, res); + } + + { + const invalidArgs = Array.from(args); + invalidArgs[1] = -1; + assert.throws( + () => Buffer.alloc(9)[funx](...invalidArgs), + /^RangeError: (?:Index )?out of range(?: index)?$/ + ); + } + + { + const buf2 = Buffer.alloc(9); + assert.strictEqual(buf2[funx](...args, true), result); + assert.deepStrictEqual(buf2, res); + } + +} + +write('writeInt8', [1, 0], 1, Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0])); +write('writeIntBE', [1, 1, 4], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); +write('writeIntLE', [1, 1, 4], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); +write('writeInt16LE', [1, 1], 3, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); +write('writeInt16BE', [1, 1], 3, Buffer.from([0, 0, 1, 0, 0, 0, 0, 0, 0])); +write('writeInt32LE', [1, 1], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); +write('writeInt32BE', [1, 1], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); +write('writeUInt8', [1, 0], 1, Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0])); +write('writeUIntLE', [1, 1, 4], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); +write('writeUIntBE', [1, 1, 4], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); +write('writeUInt16LE', [1, 1], 3, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); +write('writeUInt16BE', [1, 1], 3, Buffer.from([0, 0, 1, 0, 0, 0, 0, 0, 0])); +write('writeUInt32LE', [1, 1], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); +write('writeUInt32BE', [1, 1], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); +write('writeDoubleBE', [1, 1], 9, Buffer.from([0, 63, 240, 0, 0, 0, 0, 0, 0])); +write('writeDoubleLE', [1, 1], 9, Buffer.from([0, 0, 0, 0, 0, 0, 0, 240, 63])); +write('writeFloatBE', [1, 1], 5, Buffer.from([0, 63, 128, 0, 0, 0, 0, 0, 0])); +write('writeFloatLE', [1, 1], 5, Buffer.from([0, 0, 0, 128, 63, 0, 0, 0, 0])); diff --git a/test/parallel/test-child-process-exec-buffer.js b/test/parallel/test-child-process-exec-buffer.js deleted file mode 100644 index 092304879ec48c..00000000000000 --- a/test/parallel/test-child-process-exec-buffer.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const exec = require('child_process').exec; -const os = require('os'); -const str = 'hello'; - -// default encoding -exec('echo ' + str, common.mustCall(function(err, stdout, stderr) { - assert.strictEqual(typeof stdout, 'string', 'Expected stdout to be a string'); - assert.strictEqual(typeof stderr, 'string', 'Expected stderr to be a string'); - assert.strictEqual(str + os.EOL, stdout); -})); - -// no encoding (Buffers expected) -exec('echo ' + str, { - encoding: null -}, common.mustCall(function(err, stdout, stderr) { - assert.strictEqual(stdout instanceof Buffer, true, - 'Expected stdout to be a Buffer'); - assert.strictEqual(stderr instanceof Buffer, true, - 'Expected stderr to be a Buffer'); - assert.strictEqual(str + os.EOL, stdout.toString()); -})); diff --git a/test/parallel/test-child-process-exec-encoding.js b/test/parallel/test-child-process-exec-encoding.js new file mode 100644 index 00000000000000..ba80ccda8c6aee --- /dev/null +++ b/test/parallel/test-child-process-exec-encoding.js @@ -0,0 +1,49 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const stdoutData = 'foo'; +const stderrData = 'bar'; +const expectedStdout = `${stdoutData}\n`; +const expectedStderr = `${stderrData}\n`; + +if (process.argv[2] === 'child') { + // The following console calls are part of the test. + console.log(stdoutData); + console.error(stderrData); +} else { + function run(options, callback) { + const cmd = `${process.execPath} ${__filename} child`; + + cp.exec(cmd, options, common.mustCall((err, stdout, stderr) => { + assert.ifError(err); + callback(stdout, stderr); + })); + } + + // Test default encoding, which should be utf8. + run({}, (stdout, stderr) => { + assert.strictEqual(typeof stdout, 'string'); + assert.strictEqual(typeof stderr, 'string'); + assert.strictEqual(stdout, expectedStdout); + assert.strictEqual(stderr, expectedStderr); + }); + + // Test explicit utf8 encoding. + run({ encoding: 'utf8' }, (stdout, stderr) => { + assert.strictEqual(typeof stdout, 'string'); + assert.strictEqual(typeof stderr, 'string'); + assert.strictEqual(stdout, expectedStdout); + assert.strictEqual(stderr, expectedStderr); + }); + + // Test cases that result in buffer encodings. + [undefined, null, 'buffer', 'invalid'].forEach((encoding) => { + run({ encoding }, (stdout, stderr) => { + assert(stdout instanceof Buffer); + assert(stdout instanceof Buffer); + assert.strictEqual(stdout.toString(), expectedStdout); + assert.strictEqual(stderr.toString(), expectedStderr); + }); + }); +} diff --git a/test/parallel/test-child-process-exec-timeout.js b/test/parallel/test-child-process-exec-timeout.js index aef66868373e0d..3bd623ddebf3a7 100644 --- a/test/parallel/test-child-process-exec-timeout.js +++ b/test/parallel/test-child-process-exec-timeout.js @@ -39,9 +39,9 @@ cp.exec(cmd, { // Test the case where a timeout is set, but not expired. cp.exec(cmd, { timeout: Math.pow(2, 30) }, - common.mustCall((err, stdout, stderr) => { - assert.ifError(err); - assert.strictEqual(stdout.trim(), 'child stdout'); - assert.strictEqual(stderr.trim(), 'child stderr'); - }) + common.mustCall((err, stdout, stderr) => { + assert.ifError(err); + assert.strictEqual(stdout.trim(), 'child stdout'); + assert.strictEqual(stderr.trim(), 'child stderr'); + }) ); diff --git a/test/parallel/test-child-process-spawnsync-kill-signal.js b/test/parallel/test-child-process-spawnsync-kill-signal.js index 8a3c362216eac5..b0d47e0aa68f5c 100644 --- a/test/parallel/test-child-process-spawnsync-kill-signal.js +++ b/test/parallel/test-child-process-spawnsync-kill-signal.js @@ -1,12 +1,11 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const cp = require('child_process'); if (process.argv[2] === 'child') { setInterval(() => {}, 1000); } else { - const exitCode = common.isWindows ? 1 : 0; const { SIGKILL } = process.binding('constants').os.signals; function spawn(killSignal) { @@ -14,7 +13,7 @@ if (process.argv[2] === 'child') { [__filename, 'child'], {killSignal, timeout: 100}); - assert.strictEqual(child.status, exitCode); + assert.strictEqual(child.status, null); assert.strictEqual(child.error.code, 'ETIMEDOUT'); return child; } diff --git a/test/parallel/test-child-process-spawnsync-timeout.js b/test/parallel/test-child-process-spawnsync-timeout.js index 122a65825949df..c804f7502755bb 100644 --- a/test/parallel/test-child-process-spawnsync-timeout.js +++ b/test/parallel/test-child-process-spawnsync-timeout.js @@ -1,11 +1,11 @@ 'use strict'; -require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); var spawnSync = require('child_process').spawnSync; -var TIMER = 200; -var SLEEP = 5000; +const TIMER = 200; +const SLEEP = common.platformTimeout(5000); switch (process.argv[2]) { case 'child': @@ -19,8 +19,7 @@ switch (process.argv[2]) { var ret = spawnSync(process.execPath, [__filename, 'child'], {timeout: TIMER}); assert.strictEqual(ret.error.errno, 'ETIMEDOUT'); - console.log(ret); - var end = Date.now() - start; + const end = Date.now() - start; assert(end < SLEEP); assert(ret.status > 128 || ret.signal); break; diff --git a/test/parallel/test-child-process-uid-gid.js b/test/parallel/test-child-process-uid-gid.js index 1ee7661227701e..ec2cb9a31956c1 100644 --- a/test/parallel/test-child-process-uid-gid.js +++ b/test/parallel/test-child-process-uid-gid.js @@ -2,18 +2,16 @@ const common = require('../common'); const assert = require('assert'); const spawn = require('child_process').spawn; - -if (!common.isWindows && process.getuid() === 0) { - common.skip('as this test should not be run as `root`'); - return; -} - const expectedError = common.isWindows ? /\bENOTSUP\b/ : /\bEPERM\b/; -assert.throws(() => { - spawn('echo', ['fhqwhgads'], {uid: 0}); -}, expectedError); +if (common.isWindows || process.getuid() !== 0) { + assert.throws(() => { + spawn('echo', ['fhqwhgads'], {uid: 0}); + }, expectedError); +} -assert.throws(() => { - spawn('echo', ['fhqwhgads'], {gid: 0}); -}, expectedError); +if (common.isWindows || !process.getgroups().some((gid) => gid === 0)) { + assert.throws(() => { + spawn('echo', ['fhqwhgads'], {gid: 0}); + }, expectedError); +} diff --git a/test/parallel/test-cli-eval.js b/test/parallel/test-cli-eval.js index 0198a0f1beda48..8db7ad30872223 100644 --- a/test/parallel/test-cli-eval.js +++ b/test/parallel/test-cli-eval.js @@ -18,27 +18,27 @@ var filename = __filename.replace(/\\/g, '/'); // assert that nothing is written to stdout child.exec(nodejs + ' --eval 42', - function(err, stdout, stderr) { - assert.strictEqual(stdout, ''); - assert.strictEqual(stderr, ''); - }); + function(err, stdout, stderr) { + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); + }); // assert that "42\n" is written to stderr child.exec(nodejs + ' --eval "console.error(42)"', - function(err, stdout, stderr) { - assert.strictEqual(stdout, ''); - assert.strictEqual(stderr, '42\n'); - }); + function(err, stdout, stderr) { + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, '42\n'); + }); // assert that the expected output is written to stdout ['--print', '-p -e', '-pe', '-p'].forEach(function(s) { var cmd = nodejs + ' ' + s + ' '; child.exec(cmd + '42', - function(err, stdout, stderr) { - assert.strictEqual(stdout, '42\n'); - assert.strictEqual(stderr, ''); - }); + function(err, stdout, stderr) { + assert.strictEqual(stdout, '42\n'); + assert.strictEqual(stderr, ''); + }); child.exec(cmd + "'[]'", common.mustCall( function(err, stdout, stderr) { @@ -49,22 +49,22 @@ child.exec(nodejs + ' --eval "console.error(42)"', // assert that module loading works child.exec(nodejs + ' --eval "require(\'' + filename + '\')"', - function(status, stdout, stderr) { - assert.strictEqual(status.code, 42); - }); + function(status, stdout, stderr) { + assert.strictEqual(status.code, 42); + }); // Check that builtin modules are pre-defined. child.exec(nodejs + ' --print "os.platform()"', - function(status, stdout, stderr) { - assert.strictEqual(stderr, ''); - assert.strictEqual(stdout.trim(), require('os').platform()); - }); + function(status, stdout, stderr) { + assert.strictEqual(stderr, ''); + assert.strictEqual(stdout.trim(), require('os').platform()); + }); // module path resolve bug, regression test child.exec(nodejs + ' --eval "require(\'./test/parallel/test-cli-eval.js\')"', - function(status, stdout, stderr) { - assert.strictEqual(status.code, 42); - }); + function(status, stdout, stderr) { + assert.strictEqual(status.code, 42); + }); // Missing argument should not crash child.exec(nodejs + ' -e', common.mustCall(function(status, stdout, stderr) { @@ -80,24 +80,25 @@ child.exec(nodejs + ' -e ""', function(status, stdout, stderr) { // "\\-42" should be interpreted as an escaped expression, not a switch child.exec(nodejs + ' -p "\\-42"', - function(err, stdout, stderr) { - assert.strictEqual(stdout, '-42\n'); - assert.strictEqual(stderr, ''); - }); + function(err, stdout, stderr) { + assert.strictEqual(stdout, '-42\n'); + assert.strictEqual(stderr, ''); + }); child.exec(nodejs + ' --use-strict -p process.execArgv', - function(status, stdout, stderr) { - assert.strictEqual(stdout, - "[ '--use-strict', '-p', 'process.execArgv' ]\n"); - }); + function(status, stdout, stderr) { + assert.strictEqual( + stdout, "[ '--use-strict', '-p', 'process.execArgv' ]\n" + ); + }); // Regression test for https://github.com/nodejs/node/issues/3574 const emptyFile = path.join(common.fixturesDir, 'empty.js'); child.exec(nodejs + ` -e 'require("child_process").fork("${emptyFile}")'`, - function(status, stdout, stderr) { - assert.strictEqual(stdout, ''); - assert.strictEqual(stderr, ''); - }); + function(status, stdout, stderr) { + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); + }); // Regression test for https://github.com/nodejs/node/issues/8534. { diff --git a/test/parallel/test-cluster-worker-exit.js b/test/parallel/test-cluster-worker-exit.js index 1c0ec509c468ad..1cd7b1d0f222c7 100644 --- a/test/parallel/test-cluster-worker-exit.js +++ b/test/parallel/test-cluster-worker-exit.js @@ -32,8 +32,9 @@ if (cluster.isWorker) { worker_emitExit: [1, "the worker did not emit 'exit'"], worker_state: ['disconnected', 'the worker state is incorrect'], worker_suicideMode: [false, 'the worker.suicide flag is incorrect'], - worker_exitedAfterDisconnect: [false, - 'the .exitedAfterDisconnect flag is incorrect'], + worker_exitedAfterDisconnect: [ + false, 'the .exitedAfterDisconnect flag is incorrect' + ], worker_died: [true, 'the worker is still running'], worker_exitCode: [EXIT_CODE, 'the worker exited w/ incorrect exitCode'], worker_signalCode: [null, 'the worker exited w/ incorrect signalCode'] diff --git a/test/parallel/test-common.js b/test/parallel/test-common.js index 5ffe2c351503c1..59485eec4a327f 100644 --- a/test/parallel/test-common.js +++ b/test/parallel/test-common.js @@ -5,3 +5,11 @@ var assert = require('assert'); common.globalCheck = false; global.gc = 42; // Not a valid global unless --expose_gc is set. assert.deepStrictEqual(common.leakedGlobals(), ['gc']); + +assert.throws(function() { + common.mustCall(function() {}, 'foo'); +}, /^TypeError: Invalid expected value: foo$/); + +assert.throws(function() { + common.mustCall(function() {}, /foo/); +}, /^TypeError: Invalid expected value: \/foo\/$/); diff --git a/test/parallel/test-console-instance.js b/test/parallel/test-console-instance.js index 4d2727d96b1a55..ab5e5c9e6b3ce7 100644 --- a/test/parallel/test-console-instance.js +++ b/test/parallel/test-console-instance.js @@ -1,71 +1,59 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const Stream = require('stream'); const Console = require('console').Console; -var called = false; const out = new Stream(); const err = new Stream(); // ensure the Console instance doesn't write to the // process' "stdout" or "stderr" streams -process.stdout.write = process.stderr.write = function() { - throw new Error('write() should not be called!'); -}; +process.stdout.write = process.stderr.write = common.fail; // make sure that the "Console" function exists assert.strictEqual('function', typeof Console); // make sure that the Console constructor throws // when not given a writable stream instance -assert.throws(function() { +assert.throws(() => { new Console(); -}, /Console expects a writable stream/); +}, /^TypeError: Console expects a writable stream instance$/); // Console constructor should throw if stderr exists but is not writable -assert.throws(function() { - out.write = function() {}; +assert.throws(() => { + out.write = () => {}; err.write = undefined; new Console(out, err); -}, /Console expects writable stream instances/); +}, /^TypeError: Console expects writable stream instances$/); -out.write = err.write = function(d) {}; +out.write = err.write = (d) => {}; var c = new Console(out, err); -out.write = err.write = function(d) { +out.write = err.write = common.mustCall((d) => { assert.strictEqual(d, 'test\n'); - called = true; -}; +}, 2); -assert(!called); c.log('test'); -assert(called); - -called = false; c.error('test'); -assert(called); -out.write = function(d) { +out.write = common.mustCall((d) => { assert.strictEqual('{ foo: 1 }\n', d); - called = true; -}; +}); -called = false; c.dir({ foo: 1 }); -assert(called); // ensure that the console functions are bound to the console instance -called = 0; -out.write = function(d) { +let called = 0; +out.write = common.mustCall((d) => { called++; - assert.strictEqual(d, called + ' ' + (called - 1) + ' [ 1, 2, 3 ]\n'); -}; + assert.strictEqual(d, `${called} ${called - 1} [ 1, 2, 3 ]\n`); +}, 3); + [1, 2, 3].forEach(c.log); -assert.strictEqual(3, called); // Console() detects if it is called without `new` keyword -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { Console(out, err); }); diff --git a/test/parallel/test-console.js b/test/parallel/test-console.js index ee7170bd9101ac..aaa0e8259a1d22 100644 --- a/test/parallel/test-console.js +++ b/test/parallel/test-console.js @@ -22,7 +22,7 @@ assert.doesNotThrow(function() { }); // an Object with a custom .inspect() function -const custom_inspect = { foo: 'bar', inspect: () => { return 'inspect'; } }; +const custom_inspect = { foo: 'bar', inspect: () => 'inspect' }; const stdout_write = global.process.stdout.write; const stderr_write = global.process.stderr.write; @@ -130,7 +130,7 @@ assert.strictEqual(errStrings.length, 0); assert.throws(() => { console.assert(false, 'should throw'); -}, /should throw/); +}, /^AssertionError: should throw$/); assert.doesNotThrow(() => { console.assert(true, 'this should not throw'); diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js index 4bed5aa665b64d..245783fb1b4275 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -312,7 +312,7 @@ const ciphers = crypto.getCiphers(); for (const i in TEST_CASES) { const test = TEST_CASES[i]; - if (ciphers.indexOf(test.algo) === -1) { + if (!ciphers.includes(test.algo)) { common.skip('unsupported ' + test.algo + ' test'); continue; } @@ -324,7 +324,8 @@ for (const i in TEST_CASES) { { const encrypt = crypto.createCipheriv(test.algo, - Buffer.from(test.key, 'hex'), Buffer.from(test.iv, 'hex')); + Buffer.from(test.key, 'hex'), + Buffer.from(test.iv, 'hex')); if (test.aad) encrypt.setAAD(Buffer.from(test.aad, 'hex')); @@ -342,7 +343,8 @@ for (const i in TEST_CASES) { { const decrypt = crypto.createDecipheriv(test.algo, - Buffer.from(test.key, 'hex'), Buffer.from(test.iv, 'hex')); + Buffer.from(test.key, 'hex'), + Buffer.from(test.iv, 'hex')); decrypt.setAuthTag(Buffer.from(test.tag, 'hex')); if (test.aad) decrypt.setAAD(Buffer.from(test.aad, 'hex')); @@ -401,7 +403,8 @@ for (const i in TEST_CASES) { { // trying to get tag before inputting all data: const encrypt = crypto.createCipheriv(test.algo, - Buffer.from(test.key, 'hex'), Buffer.from(test.iv, 'hex')); + Buffer.from(test.key, 'hex'), + Buffer.from(test.iv, 'hex')); encrypt.update('blah', 'ascii'); assert.throws(function() { encrypt.getAuthTag(); }, / state/); } @@ -409,7 +412,8 @@ for (const i in TEST_CASES) { { // trying to set tag on encryption object: const encrypt = crypto.createCipheriv(test.algo, - Buffer.from(test.key, 'hex'), Buffer.from(test.iv, 'hex')); + Buffer.from(test.key, 'hex'), + Buffer.from(test.iv, 'hex')); assert.throws(() => { encrypt.setAuthTag(Buffer.from(test.tag, 'hex')); }, / state/); } @@ -417,7 +421,8 @@ for (const i in TEST_CASES) { { // trying to read tag from decryption object: const decrypt = crypto.createDecipheriv(test.algo, - Buffer.from(test.key, 'hex'), Buffer.from(test.iv, 'hex')); + Buffer.from(test.key, 'hex'), + Buffer.from(test.iv, 'hex')); assert.throws(function() { decrypt.getAuthTag(); }, / state/); } diff --git a/test/parallel/test-crypto-certificate.js b/test/parallel/test-crypto-certificate.js index 1dfb2c73b0eca5..8dba530fc54a45 100644 --- a/test/parallel/test-crypto-certificate.js +++ b/test/parallel/test-crypto-certificate.js @@ -37,3 +37,6 @@ assert.strictEqual(certificate.exportChallenge(spkacFail), ''); function stripLineEndings(obj) { return obj.replace(/\n/g, ''); } + +// direct call Certificate() should return instance +assert(crypto.Certificate() instanceof crypto.Certificate); diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index 6a067bef1be066..884b482fc53450 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -170,6 +170,10 @@ let firstByte = ecdh1.getPublicKey('buffer', 'compressed')[0]; assert(firstByte === 2 || firstByte === 3); firstByte = ecdh1.getPublicKey('buffer', 'hybrid')[0]; assert(firstByte === 6 || firstByte === 7); +// format value should be string +assert.throws(() => { + ecdh1.getPublicKey('buffer', 10); +}, /^TypeError: Bad format: 10$/); // ECDH should check that point is on curve const ecdh3 = crypto.createECDH('secp256k1'); @@ -262,3 +266,8 @@ ecdh5.setPrivateKey(cafebabeKey, 'hex'); // Verify object state did not change. assert.equal(ecdh5.getPrivateKey('hex'), cafebabeKey); }); + +// invalid test: curve argument is undefined +assert.throws(() => { + crypto.createECDH(); +}, /^TypeError: "curve" argument should be a string$/); diff --git a/test/parallel/test-crypto-engine.js b/test/parallel/test-crypto-engine.js new file mode 100644 index 00000000000000..8452087cc50c93 --- /dev/null +++ b/test/parallel/test-crypto-engine.js @@ -0,0 +1,18 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const assert = require('assert'); +const crypto = require('crypto'); + +assert.throws(function() { + crypto.setEngine(true); +}, /^TypeError: "id" argument should be a string$/); + +assert.throws(function() { + crypto.setEngine('/path/to/engine', 'notANumber'); +}, /^TypeError: "flags" argument should be a number, if present$/); diff --git a/test/parallel/test-crypto-hash.js b/test/parallel/test-crypto-hash.js index 9e212443453203..79353ede3b49dc 100644 --- a/test/parallel/test-crypto-hash.js +++ b/test/parallel/test-crypto-hash.js @@ -109,9 +109,9 @@ h3.digest(); assert.throws(function() { h3.digest(); }, - /Digest already called/); + /Digest already called/); assert.throws(function() { h3.update('foo'); }, - /Digest already called/); + /Digest already called/); diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index 5307ea4f6f9e05..eeb8cd152567f8 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -8,6 +8,14 @@ if (!common.hasCrypto) { } var crypto = require('crypto'); +// Test for binding layer robustness +{ + const binding = process.binding('crypto'); + const h = new binding.Hmac(); + // Fail to init the Hmac with an algorithm. + assert.throws(() => h.update('hello'), /^TypeError: HmacUpdate fail$/); +} + // Test HMAC var h1 = crypto.createHmac('sha1', 'Node') .update('some data') @@ -115,7 +123,7 @@ var rfc4231 = [ key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), data: Buffer.from('ddddddddddddddddddddddddddddddddddddddddddddddddd' + 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', - 'hex'), + 'hex'), hmac: { sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea', sha256: @@ -132,10 +140,10 @@ var rfc4231 = [ }, { key: Buffer.from('0102030405060708090a0b0c0d0e0f10111213141516171819', - 'hex'), + 'hex'), data: Buffer.from('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', - 'hex'), + 'hex'), hmac: { sha224: '6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a', sha256: @@ -256,16 +264,16 @@ var rfc2202_md5 = [ key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), data: Buffer.from('ddddddddddddddddddddddddddddddddddddddddddddddddd' + 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', - 'hex'), + 'hex'), hmac: '56be34521d144c88dbb8c733f0e8b3f6' }, { key: Buffer.from('0102030405060708090a0b0c0d0e0f10111213141516171819', - 'hex'), + 'hex'), data: Buffer.from('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + 'cdcdcdcdcd', - 'hex'), + 'hex'), hmac: '697eaf0aca3a3aea3a75164746ffaa79' }, { @@ -278,7 +286,7 @@ var rfc2202_md5 = [ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaa', - 'hex'), + 'hex'), data: 'Test Using Larger Than Block-Size Key - Hash Key First', hmac: '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd' }, @@ -287,7 +295,7 @@ var rfc2202_md5 = [ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaa', - 'hex'), + 'hex'), data: 'Test Using Larger Than Block-Size Key and Larger Than One ' + 'Block-Size Data', @@ -310,16 +318,16 @@ var rfc2202_sha1 = [ data: Buffer.from('ddddddddddddddddddddddddddddddddddddddddddddd' + 'ddddddddddddddddddddddddddddddddddddddddddddd' + 'dddddddddd', - 'hex'), + 'hex'), hmac: '125d7342b9ac11cd91a39af48aa17b4f63f175d3' }, { key: Buffer.from('0102030405060708090a0b0c0d0e0f10111213141516171819', - 'hex'), + 'hex'), data: Buffer.from('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + 'cdcdcdcdcd', - 'hex'), + 'hex'), hmac: '4c9007f4026250c6bc8414f9bf50c86c2d7235da' }, { @@ -332,7 +340,7 @@ var rfc2202_sha1 = [ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaa', - 'hex'), + 'hex'), data: 'Test Using Larger Than Block-Size Key - Hash Key First', hmac: 'aa4ae5e15272d00e95705637ce8a3b55ed402112' }, @@ -341,7 +349,7 @@ var rfc2202_sha1 = [ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'aaaaaaaaaaaaaaaaaaaaaa', - 'hex'), + 'hex'), data: 'Test Using Larger Than Block-Size Key and Larger Than One ' + 'Block-Size Data', diff --git a/test/parallel/test-crypto-padding-aes256.js b/test/parallel/test-crypto-padding-aes256.js index e835867d61d005..7fd2e98de617cf 100644 --- a/test/parallel/test-crypto-padding-aes256.js +++ b/test/parallel/test-crypto-padding-aes256.js @@ -11,18 +11,18 @@ var crypto = require('crypto'); crypto.DEFAULT_ENCODING = 'buffer'; function aes256(decipherFinal) { - var iv = Buffer.from('00000000000000000000000000000000', 'hex'); - var key = Buffer.from('0123456789abcdef0123456789abcdef' + - '0123456789abcdef0123456789abcdef', 'hex'); + const iv = Buffer.from('00000000000000000000000000000000', 'hex'); + const key = Buffer.from('0123456789abcdef0123456789abcdef' + + '0123456789abcdef0123456789abcdef', 'hex'); function encrypt(val, pad) { - var c = crypto.createCipheriv('aes256', key, iv); + const c = crypto.createCipheriv('aes256', key, iv); c.setAutoPadding(pad); return c.update(val, 'utf8', 'latin1') + c.final('latin1'); } function decrypt(val, pad) { - var c = crypto.createDecipheriv('aes256', key, iv); + const c = crypto.createDecipheriv('aes256', key, iv); c.setAutoPadding(pad); return c.update(val, 'latin1', 'utf8') + c[decipherFinal]('utf8'); } @@ -30,10 +30,10 @@ function aes256(decipherFinal) { // echo 0123456789abcdef0123456789abcdef \ // | openssl enc -e -aes256 -nopad -K -iv \ // | openssl enc -d -aes256 -nopad -K -iv - var plaintext = '0123456789abcdef0123456789abcdef'; // multiple of block size - var encrypted = encrypt(plaintext, false); - var decrypted = decrypt(encrypted, false); - assert.equal(decrypted, plaintext); + let plaintext = '0123456789abcdef0123456789abcdef'; // multiple of block size + let encrypted = encrypt(plaintext, false); + let decrypted = decrypt(encrypted, false); + assert.strictEqual(decrypted, plaintext); // echo 0123456789abcdef0123456789abcde \ // | openssl enc -e -aes256 -K -iv \ @@ -41,7 +41,7 @@ function aes256(decipherFinal) { plaintext = '0123456789abcdef0123456789abcde'; // not a multiple encrypted = encrypt(plaintext, true); decrypted = decrypt(encrypted, true); - assert.equal(decrypted, plaintext); + assert.strictEqual(decrypted, plaintext); } aes256('final'); diff --git a/test/parallel/test-crypto-rsa-dsa.js b/test/parallel/test-crypto-rsa-dsa.js index a05102320caa7c..bbc043fbc3aee2 100644 --- a/test/parallel/test-crypto-rsa-dsa.js +++ b/test/parallel/test-crypto-rsa-dsa.js @@ -14,15 +14,15 @@ var crypto = require('crypto'); var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem', - 'ascii'); + 'ascii'); var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem', - 'ascii'); + 'ascii'); var rsaKeyPemEncrypted = fs.readFileSync( common.fixturesDir + '/test_rsa_privkey_encrypted.pem', 'ascii'); var dsaPubPem = fs.readFileSync(common.fixturesDir + '/test_dsa_pubkey.pem', - 'ascii'); + 'ascii'); var dsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_dsa_privkey.pem', - 'ascii'); + 'ascii'); var dsaKeyPemEncrypted = fs.readFileSync( common.fixturesDir + '/test_dsa_privkey_encrypted.pem', 'ascii'); diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index 6df41409f0e6c1..b4ef8296282b7f 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -70,3 +70,10 @@ var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); verified = verStream.verify(certPem, s3); assert.strictEqual(verified, true, 'sign and verify (stream)'); } + +// Test throws exception when key options is null +{ + assert.throws(() => { + crypto.createSign('RSA-SHA1').update('Test123').sign(null, 'base64'); + }, /^Error: No key provided to sign$/); +} diff --git a/test/parallel/test-crypto-verify-failure.js b/test/parallel/test-crypto-verify-failure.js index fdc27215027414..415e13ff64e640 100644 --- a/test/parallel/test-crypto-verify-failure.js +++ b/test/parallel/test-crypto-verify-failure.js @@ -19,36 +19,32 @@ var options = { cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') }; -var server = tls.Server(options, function(socket) { - setImmediate(function() { - console.log('sending'); +const server = tls.Server(options, (socket) => { + setImmediate(() => { verify(); - setImmediate(function() { + setImmediate(() => { socket.destroy(); }); }); }); function verify() { - console.log('verify'); crypto.createVerify('RSA-SHA1') .update('Test') .verify(certPem, 'asdfasdfas', 'base64'); } -server.listen(0, function() { +server.listen(0, common.mustCall(() => { tls.connect({ - port: this.address().port, + port: server.address().port, rejectUnauthorized: false - }, function() { + }, common.mustCall(() => { verify(); - }).on('data', function(data) { - console.log(data); - }).on('error', function(err) { - throw err; - }).on('close', function() { - server.close(); - }).resume(); -}); + })) + .on('error', common.fail) + .on('close', common.mustCall(() => { + server.close(); + })).resume(); +})); server.unref(); diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 6d814e72e1575b..5edf748994ebdd 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -53,23 +53,33 @@ assert.throws(function() { }, /^TypeError: Data must be a string or a buffer$/); -function assertSorted(list) { +function validateList(list) { + // The list must not be empty + assert(list.length > 0); + + // The list should be sorted. // Array#sort() modifies the list in place so make a copy. - const sorted = list.slice().sort(); + const sorted = [...list].sort(); assert.deepStrictEqual(list, sorted); + + // Each element should be unique. + assert.strictEqual([...new Set(list)].length, list.length); + + // Each element should be a string. + assert(list.every((value) => typeof value === 'string')); } // Assume that we have at least AES-128-CBC. -assert.notStrictEqual(0, crypto.getCiphers().length); +const cryptoCiphers = crypto.getCiphers(); assert(crypto.getCiphers().includes('aes-128-cbc')); -assert(!crypto.getCiphers().includes('AES-128-CBC')); -assertSorted(crypto.getCiphers()); +validateList(cryptoCiphers); // Assume that we have at least AES256-SHA. -assert.notStrictEqual(0, tls.getCiphers().length); +const tlsCiphers = tls.getCiphers(); assert(tls.getCiphers().includes('aes256-sha')); -assert(!tls.getCiphers().includes('AES256-SHA')); -assertSorted(tls.getCiphers()); +// There should be no capital letters in any element. +assert(tlsCiphers.every((value) => /^[^A-Z]+$/.test(value))); +validateList(tlsCiphers); // Assert that we have sha and sha1 but not SHA and SHA1. assert.notStrictEqual(0, crypto.getHashes().length); @@ -79,13 +89,27 @@ assert(!crypto.getHashes().includes('SHA1')); assert(!crypto.getHashes().includes('SHA')); assert(crypto.getHashes().includes('RSA-SHA1')); assert(!crypto.getHashes().includes('rsa-sha1')); -assertSorted(crypto.getHashes()); +validateList(crypto.getHashes()); // Assume that we have at least secp384r1. assert.notStrictEqual(0, crypto.getCurves().length); assert(crypto.getCurves().includes('secp384r1')); assert(!crypto.getCurves().includes('SECP384R1')); -assertSorted(crypto.getCurves()); +validateList(crypto.getCurves()); + +// Modifying return value from get* functions should not mutate subsequent +// return values. +function testImmutability(fn) { + const list = fn(); + const copy = [...list]; + list.push('some-arbitrary-value'); + assert.deepStrictEqual(fn(), copy); +} + +testImmutability(crypto.getCiphers); +testImmutability(tls.getCiphers); +testImmutability(crypto.getHashes); +testImmutability(crypto.getCurves); // Regression tests for #5725: hex input that's not a power of two should // throw, not assert in C++ land. diff --git a/test/parallel/test-debugger-pid.js b/test/parallel/test-debugger-pid.js index 2b81da700f50a0..7d03b0fc5c2308 100644 --- a/test/parallel/test-debugger-pid.js +++ b/test/parallel/test-debugger-pid.js @@ -34,10 +34,6 @@ interfacer.on('line', function(line) { expected = `(node:${pid}) ${msg}`; break; - case 2: - expected = 'The parameter is incorrect.'; - break; - default: return; } diff --git a/test/parallel/test-debugger-util-regression.js b/test/parallel/test-debugger-util-regression.js index 07e52545814b14..fa5b9e8b0a0e06 100644 --- a/test/parallel/test-debugger-util-regression.js +++ b/test/parallel/test-debugger-util-regression.js @@ -4,6 +4,8 @@ const path = require('path'); const spawn = require('child_process').spawn; const assert = require('assert'); +const DELAY = common.platformTimeout(200); + const fixture = path.join( common.fixturesDir, 'debugger-util-regression-fixture.js' @@ -21,12 +23,16 @@ proc.stderr.setEncoding('utf8'); let stdout = ''; let stderr = ''; +proc.stdout.on('data', (data) => stdout += data); +proc.stderr.on('data', (data) => stderr += data); let nextCount = 0; let exit = false; -proc.stdout.on('data', (data) => { - stdout += data; +// We look at output periodically. We don't do this in the on('data') as we +// may end up processing partial output. Processing periodically ensures that +// the debugger is in a stable state before we take the next step. +const timer = setInterval(() => { if (stdout.includes('> 1') && nextCount < 1 || stdout.includes('> 2') && nextCount < 2 || stdout.includes('> 3') && nextCount < 3 || @@ -36,14 +42,14 @@ proc.stdout.on('data', (data) => { } else if (!exit && (stdout.includes('< { a: \'b\' }'))) { exit = true; proc.stdin.write('.exit\n'); + // We can cancel the timer and terminate normally. + clearInterval(timer); } else if (stdout.includes('program terminated')) { // Catch edge case present in v4.x // process will terminate after call to util.inspect common.fail('the program should not terminate'); } -}); - -proc.stderr.on('data', (data) => stderr += data); +}, DELAY); process.on('exit', (code) => { assert.strictEqual(code, 0, 'the program should exit cleanly'); diff --git a/test/parallel/test-dgram-bind.js b/test/parallel/test-dgram-bind.js index 0bca97fb294f79..2d11fba6443ad8 100644 --- a/test/parallel/test-dgram-bind.js +++ b/test/parallel/test-dgram-bind.js @@ -1,13 +1,17 @@ 'use strict'; -require('../common'); -var assert = require('assert'); -var dgram = require('dgram'); +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); var socket = dgram.createSocket('udp4'); -socket.on('listening', function() { +socket.on('listening', common.mustCall(() => { + assert.throws(() => { + socket.bind(); + }, /^Error: Socket is already bound$/); + socket.close(); -}); +})); var result = socket.bind(); // should not throw diff --git a/test/parallel/test-dgram-create-socket-handle.js b/test/parallel/test-dgram-create-socket-handle.js new file mode 100644 index 00000000000000..559d92be98d42d --- /dev/null +++ b/test/parallel/test-dgram-create-socket-handle.js @@ -0,0 +1,39 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const UDP = process.binding('udp_wrap').UDP; +const _createSocketHandle = dgram._createSocketHandle; + +// Throws if an "existing fd" is passed in. +assert.throws(() => { + _createSocketHandle(common.localhostIPv4, 0, 'udp4', 42); +}, /^AssertionError: false == true$/); + +{ + // Create a handle that is not bound. + const handle = _createSocketHandle(null, null, 'udp4'); + + assert(handle instanceof UDP); + assert.strictEqual(typeof handle.fd, 'number'); + assert(handle.fd < 0); +} + +{ + // Create a bound handle. + const handle = _createSocketHandle(common.localhostIPv4, 0, 'udp4'); + + assert(handle instanceof UDP); + assert.strictEqual(typeof handle.fd, 'number'); + + if (!common.isWindows) + assert(handle.fd > 0); +} + +{ + // Return an error if binding fails. + const err = _createSocketHandle('localhost', 0, 'udp4'); + + assert.strictEqual(typeof err, 'number'); + assert(err < 0); +} diff --git a/test/parallel/test-dgram-membership.js b/test/parallel/test-dgram-membership.js index ed5fb2897cbd3a..1543b9043f7738 100644 --- a/test/parallel/test-dgram-membership.js +++ b/test/parallel/test-dgram-membership.js @@ -5,16 +5,14 @@ const assert = require('assert'); const dgram = require('dgram'); const multicastAddress = '224.0.0.114'; -const setup = () => { - return dgram.createSocket({type: 'udp4', reuseAddr: true}); -}; +const setup = dgram.createSocket.bind(dgram, {type: 'udp4', reuseAddr: true}); // addMembership() on closed socket should throw { const socket = setup(); socket.close(common.mustCall(() => { assert.throws(() => { socket.addMembership(multicastAddress); }, - /Not running/); + /^Error: Not running$/); })); } @@ -23,7 +21,7 @@ const setup = () => { const socket = setup(); socket.close(common.mustCall(() => { assert.throws(() => { socket.dropMembership(multicastAddress); }, - /Not running/); + /^Error: Not running$/); })); } @@ -31,7 +29,7 @@ const setup = () => { { const socket = setup(); assert.throws(() => { socket.addMembership(); }, - /multicast address must be specified/); + /^Error: multicast address must be specified$/); socket.close(); } @@ -39,21 +37,23 @@ const setup = () => { { const socket = setup(); assert.throws(() => { socket.dropMembership(); }, - /multicast address must be specified/); + /^Error: multicast address must be specified$/); socket.close(); } // addMembership() with invalid multicast address should throw { const socket = setup(); - assert.throws(() => { socket.addMembership('256.256.256.256'); }, /EINVAL/); + assert.throws(() => { socket.addMembership('256.256.256.256'); }, + /^Error: addMembership EINVAL$/); socket.close(); } // dropMembership() with invalid multicast address should throw { const socket = setup(); - assert.throws(() => { socket.dropMembership('256.256.256.256'); }, /EINVAL/); + assert.throws(() => { socket.dropMembership('256.256.256.256'); }, + /^Error: dropMembership EINVAL$/); socket.close(); } @@ -69,7 +69,7 @@ const setup = () => { const socket = setup(); assert.throws( () => { socket.dropMembership(multicastAddress); }, - /EADDRNOTAVAIL/ + /^Error: dropMembership EADDRNOTAVAIL$/ ); socket.close(); } diff --git a/test/parallel/test-dgram-multicast-loopback.js b/test/parallel/test-dgram-multicast-loopback.js new file mode 100644 index 00000000000000..c1eedcd1c98900 --- /dev/null +++ b/test/parallel/test-dgram-multicast-loopback.js @@ -0,0 +1,23 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +{ + const socket = dgram.createSocket('udp4'); + + assert.throws(() => { + socket.setMulticastLoopback(16); + }, /^Error: setMulticastLoopback EBADF$/); +} + +{ + const socket = dgram.createSocket('udp4'); + + socket.bind(0); + socket.on('listening', common.mustCall(() => { + assert.strictEqual(socket.setMulticastLoopback(16), 16); + assert.strictEqual(socket.setMulticastLoopback(0), 0); + socket.close(); + })); +} diff --git a/test/parallel/test-dgram-multicast-setTTL.js b/test/parallel/test-dgram-multicast-setTTL.js index 83d482f426bcd4..11b5a0a7635857 100644 --- a/test/parallel/test-dgram-multicast-setTTL.js +++ b/test/parallel/test-dgram-multicast-setTTL.js @@ -1,23 +1,23 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const dgram = require('dgram'); const socket = dgram.createSocket('udp4'); -let thrown = false; socket.bind(0); -socket.on('listening', function() { - socket.setMulticastTTL(16); +socket.on('listening', common.mustCall(() => { + const result = socket.setMulticastTTL(16); + assert.strictEqual(result, 16); //Try to set an invalid TTL (valid ttl is > 0 and < 256) - try { + assert.throws(() => { socket.setMulticastTTL(1000); - } catch (e) { - thrown = true; - } + }, /^Error: setMulticastTTL EINVAL$/); - assert(thrown, 'Setting an invalid multicast TTL should throw some error'); + assert.throws(() => { + socket.setMulticastTTL('foo'); + }, /^TypeError: Argument must be a number$/); //close the socket socket.close(); -}); +})); diff --git a/test/parallel/test-dgram-oob-buffer.js b/test/parallel/test-dgram-oob-buffer.js index e52bf7d69b3c6f..ec5c0f943cb7df 100644 --- a/test/parallel/test-dgram-oob-buffer.js +++ b/test/parallel/test-dgram-oob-buffer.js @@ -17,4 +17,4 @@ socket.send(buf, 3, 1, common.PORT, '127.0.0.1', ok); // Since length of zero means nothing, don't error despite OOB. socket.send(buf, 4, 0, common.PORT, '127.0.0.1', ok); -socket.close(); // FIXME should not be necessary +socket.close(); diff --git a/test/parallel/test-dgram-ref.js b/test/parallel/test-dgram-ref.js index 6505ce9b1ec886..7b79340f924b06 100644 --- a/test/parallel/test-dgram-ref.js +++ b/test/parallel/test-dgram-ref.js @@ -1,7 +1,14 @@ 'use strict'; -require('../common'); -var dgram = require('dgram'); +const common = require('../common'); +const dgram = require('dgram'); // should not hang, see #1282 dgram.createSocket('udp4'); dgram.createSocket('udp6'); + +{ + // Test the case of ref()'ing a socket with no handle. + const s = dgram.createSocket('udp4'); + + s.close(common.mustCall(() => s.ref())); +} diff --git a/test/parallel/test-dgram-send-callback-buffer-length.js b/test/parallel/test-dgram-send-callback-buffer-length.js index 76af0e14635be0..8551e97387ea51 100644 --- a/test/parallel/test-dgram-send-callback-buffer-length.js +++ b/test/parallel/test-dgram-send-callback-buffer-length.js @@ -11,6 +11,7 @@ const offset = 20; const len = buf.length - offset; const messageSent = common.mustCall(function messageSent(err, bytes) { + assert.ifError(err); assert.notStrictEqual(bytes, buf.length); assert.strictEqual(bytes, buf.length - offset); client.close(); diff --git a/test/parallel/test-dgram-send-multi-string-array.js b/test/parallel/test-dgram-send-multi-string-array.js new file mode 100644 index 00000000000000..8d73a6d1839fcb --- /dev/null +++ b/test/parallel/test-dgram-send-multi-string-array.js @@ -0,0 +1,13 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const socket = dgram.createSocket('udp4'); +const data = ['foo', 'bar', 'baz']; + +socket.on('message', common.mustCall((msg, rinfo) => { + socket.close(); + assert.deepStrictEqual(msg.toString(), data.join('')); +})); + +socket.bind(() => socket.send(data, socket.address().port, 'localhost')); diff --git a/test/parallel/test-dgram-sendto.js b/test/parallel/test-dgram-sendto.js new file mode 100644 index 00000000000000..350f488f12af0d --- /dev/null +++ b/test/parallel/test-dgram-sendto.js @@ -0,0 +1,24 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const socket = dgram.createSocket('udp4'); + +const errorMessage = + /^Error: Send takes "offset" and "length" as args 2 and 3$/; + +assert.throws(() => { + socket.sendto(); +}, errorMessage); + +assert.throws(() => { + socket.sendto('buffer', 1, 'offset', 'port', 'address', 'cb'); +}, errorMessage); + +assert.throws(() => { + socket.sendto('buffer', 'offset', 1, 'port', 'address', 'cb'); +}, errorMessage); + +assert.throws(() => { + socket.sendto('buffer', 1, 1, 10, false, 'cb'); +}, /^Error: udp4 sockets must send to port, address$/); diff --git a/test/parallel/test-dgram-setBroadcast.js b/test/parallel/test-dgram-setBroadcast.js index 1232faa76c81fe..f4ce7ff06adbe4 100644 --- a/test/parallel/test-dgram-setBroadcast.js +++ b/test/parallel/test-dgram-setBroadcast.js @@ -4,36 +4,22 @@ const common = require('../common'); const assert = require('assert'); const dgram = require('dgram'); -const setup = () => { - return dgram.createSocket({type: 'udp4', reuseAddr: true}); -}; +{ + // Should throw EBADF if the socket is never bound. + const socket = dgram.createSocket('udp4'); -const teardown = (socket) => { - if (socket.close) - socket.close(); -}; - -const runTest = (testCode, expectError) => { - const socket = setup(); - const assertion = expectError ? assert.throws : assert.doesNotThrow; - const wrapped = () => { testCode(socket); }; - assertion(wrapped, expectError); - teardown(socket); -}; + assert.throws(() => { + socket.setBroadcast(true); + }, /^Error: setBroadcast EBADF$/); +} -// Should throw EBADF if socket is never bound. -runTest((socket) => { socket.setBroadcast(true); }, /EBADF/); +{ + // Can call setBroadcast() after binding the socket. + const socket = dgram.createSocket('udp4'); -// Should not throw if broadcast set to false after binding. -runTest((socket) => { - socket.bind(0, common.localhostIPv4, () => { - socket.setBroadcast(false); - }); -}); - -// Should not throw if broadcast set to true after binding. -runTest((socket) => { - socket.bind(0, common.localhostIPv4, () => { + socket.bind(0, common.mustCall(() => { socket.setBroadcast(true); - }); -}); + socket.setBroadcast(false); + socket.close(); + })); +} diff --git a/test/parallel/test-dgram-setTTL.js b/test/parallel/test-dgram-setTTL.js index 9393e53c7f1912..7da3975ad4c3fd 100644 --- a/test/parallel/test-dgram-setTTL.js +++ b/test/parallel/test-dgram-setTTL.js @@ -1,17 +1,22 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const dgram = require('dgram'); const socket = dgram.createSocket('udp4'); socket.bind(0); -socket.on('listening', function() { - var result = socket.setTTL(16); +socket.on('listening', common.mustCall(() => { + const result = socket.setTTL(16); assert.strictEqual(result, 16); - assert.throws(function() { + assert.throws(() => { socket.setTTL('foo'); - }, /Argument must be a number/); + }, /^TypeError: Argument must be a number$/); + + // TTL must be a number from > 0 to < 256 + assert.throws(() => { + socket.setTTL(1000); + }, /^Error: setTTL EINVAL$/); socket.close(); -}); +})); diff --git a/test/parallel/test-dgram-unref.js b/test/parallel/test-dgram-unref.js index e5f26b6f3387b8..1b92428a38e18b 100644 --- a/test/parallel/test-dgram-unref.js +++ b/test/parallel/test-dgram-unref.js @@ -2,8 +2,18 @@ const common = require('../common'); var dgram = require('dgram'); -var s = dgram.createSocket('udp4'); -s.bind(); -s.unref(); +{ + // Test the case of unref()'ing a socket with a handle. + const s = dgram.createSocket('udp4'); + s.bind(); + s.unref(); +} + +{ + // Test the case of unref()'ing a socket with no handle. + const s = dgram.createSocket('udp4'); + + s.close(common.mustCall(() => s.unref())); +} setTimeout(common.fail, 1000).unref(); diff --git a/test/parallel/test-dns-lookup-cb-error.js b/test/parallel/test-dns-lookup-cb-error.js deleted file mode 100644 index 212f037868309e..00000000000000 --- a/test/parallel/test-dns-lookup-cb-error.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const cares = process.binding('cares_wrap'); - -const dns = require('dns'); - -// Stub `getaddrinfo` to *always* error. -cares.getaddrinfo = function() { - return process.binding('uv').UV_ENOENT; -}; - -assert.doesNotThrow(() => { - var tickValue = 0; - - dns.lookup('example.com', common.mustCall((error, result, addressType) => { - assert(error); - assert.strictEqual(tickValue, 1); - assert.strictEqual(error.code, 'ENOENT'); - })); - - // Make sure that the error callback is called - // on next tick. - tickValue = 1; -}); diff --git a/test/parallel/test-dns-lookup.js b/test/parallel/test-dns-lookup.js new file mode 100644 index 00000000000000..a720c46e02a630 --- /dev/null +++ b/test/parallel/test-dns-lookup.js @@ -0,0 +1,89 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cares = process.binding('cares_wrap'); +const dns = require('dns'); + +// Stub `getaddrinfo` to *always* error. +cares.getaddrinfo = () => process.binding('uv').UV_ENOENT; + +assert.throws(() => { + dns.lookup(1, {}); +}, /^TypeError: Invalid arguments: hostname must be a string or falsey$/); + +assert.throws(() => { + dns.lookup(false, 'cb'); +}, /^TypeError: Invalid arguments: callback must be passed$/); + +assert.throws(() => { + dns.lookup(false, 'options', 'cb'); +}, /^TypeError: Invalid arguments: callback must be passed$/); + +assert.throws(() => { + dns.lookup(false, { + hints: 100, + family: 0, + all: false + }, () => {}); +}, /^TypeError: Invalid argument: hints must use valid flags$/); + +assert.throws(() => { + dns.lookup(false, { + hints: 0, + family: 20, + all: false + }, () => {}); +}, /^TypeError: Invalid argument: family must be 4 or 6$/); + +assert.doesNotThrow(() => { + dns.lookup(false, { + hints: 0, + family: 0, + all: true + }, common.mustCall((error, result, addressType) => { + assert.ifError(error); + assert.deepStrictEqual(result, []); + assert.strictEqual(addressType, undefined); + })); +}); + +assert.doesNotThrow(() => { + dns.lookup('127.0.0.1', { + hints: 0, + family: 4, + all: true + }, common.mustCall((error, result, addressType) => { + assert.ifError(error); + assert.deepStrictEqual(result, [{ + address: '127.0.0.1', + family: 4 + }]); + assert.strictEqual(addressType, undefined); + })); +}); + +assert.doesNotThrow(() => { + dns.lookup('127.0.0.1', { + hints: 0, + family: 4, + all: false + }, common.mustCall((error, result, addressType) => { + assert.ifError(error); + assert.deepStrictEqual(result, '127.0.0.1'); + assert.strictEqual(addressType, 4); + })); +}); + +assert.doesNotThrow(() => { + let tickValue = 0; + + dns.lookup('example.com', common.mustCall((error, result, addressType) => { + assert(error); + assert.strictEqual(tickValue, 1); + assert.strictEqual(error.code, 'ENOENT'); + })); + + // Make sure that the error callback is called + // on next tick. + tickValue = 1; +}); diff --git a/test/parallel/test-dns.js b/test/parallel/test-dns.js index 9ee2e9f974f625..27b9b81d7d14a2 100644 --- a/test/parallel/test-dns.js +++ b/test/parallel/test-dns.js @@ -112,7 +112,7 @@ assert.doesNotThrow(() => dns.lookup(NaN, noop)); */ assert.throws(() => { dns.lookup('www.google.com', { hints: (dns.V4MAPPED | dns.ADDRCONFIG) + 1 }, - noop); + noop); }, /^TypeError: Invalid argument: hints must use valid flags$/); assert.throws(() => dns.lookup('www.google.com'), diff --git a/test/parallel/test-domain-multi.js b/test/parallel/test-domain-multi.js index cf85dbca460146..e8c5d4924cb553 100644 --- a/test/parallel/test-domain-multi.js +++ b/test/parallel/test-domain-multi.js @@ -1,26 +1,16 @@ 'use strict'; // Tests of multiple domains happening at once. -require('../common'); -var assert = require('assert'); -var domain = require('domain'); - -var caughtA = false; -var caughtB = false; -var caughtC = false; - +const common = require('../common'); +const domain = require('domain'); +const http = require('http'); var a = domain.create(); a.enter(); // this will be our "root" domain -a.on('error', function(er) { - caughtA = true; - console.log('This should not happen'); - throw er; -}); +a.on('error', common.fail); -var http = require('http'); -var server = http.createServer(function(req, res) { +const server = http.createServer((req, res) => { // child domain of a. var b = domain.create(); a.add(b); @@ -31,47 +21,34 @@ var server = http.createServer(function(req, res) { b.add(req); b.add(res); - b.on('error', function(er) { - caughtB = true; - console.error('Error encountered', er); + b.on('error', common.mustCall((er) => { if (res) { res.writeHead(500); res.end('An error occurred'); } // res.writeHead(500), res.destroy, etc. server.close(); - }); + })); // XXX this bind should not be necessary. // the write cb behavior in http/net should use an // event so that it picks up the domain handling. - res.write('HELLO\n', b.bind(function() { + res.write('HELLO\n', b.bind(() => { throw new Error('this kills domain B, not A'); })); -}).listen(0, function() { - var c = domain.create(); - var req = http.get({ host: 'localhost', port: this.address().port }); +}).listen(0, () => { + const c = domain.create(); + const req = http.get({ host: 'localhost', port: server.address().port }); // add the request to the C domain c.add(req); - req.on('response', function(res) { - console.error('got response'); + req.on('response', (res) => { // add the response object to the C domain c.add(res); res.pipe(process.stdout); }); - c.on('error', function(er) { - caughtC = true; - console.error('Error on c', er.message); - }); -}); - -process.on('exit', function() { - assert.strictEqual(caughtA, false); - assert.strictEqual(caughtB, true); - assert.strictEqual(caughtC, true); - console.log('ok - Errors went where they were supposed to go'); + c.on('error', common.mustCall((er) => { })); }); diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-0.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-0.js new file mode 100644 index 00000000000000..6a3a670b9204c2 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-0.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + + d.run(function() { + throw new Error('boom!'); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-1.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-1.js new file mode 100644 index 00000000000000..e32245176571ef --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-1.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + const d2 = domain.create(); + + d.run(function() { + d2.run(function() { + throw new Error('boom!'); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-2.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-2.js new file mode 100644 index 00000000000000..ff0fd5eec35f6b --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-2.js @@ -0,0 +1,20 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + + d.run(function() { + setTimeout(function() { + throw new Error('boom!'); + }, 1); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-3.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-3.js new file mode 100644 index 00000000000000..cbe5f3ed8dc4a1 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-3.js @@ -0,0 +1,20 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + + d.run(function() { + setImmediate(function() { + throw new Error('boom!'); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-4.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-4.js new file mode 100644 index 00000000000000..4d0dd39454d2b2 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-4.js @@ -0,0 +1,20 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + + d.run(function() { + process.nextTick(function() { + throw new Error('boom!'); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-5.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-5.js new file mode 100644 index 00000000000000..78ef3662a20229 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-5.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + + d.run(function() { + var fs = require('fs'); + fs.exists('/non/existing/file', function onExists() { + throw new Error('boom!'); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-6.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-6.js new file mode 100644 index 00000000000000..c3a91379319db5 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-6.js @@ -0,0 +1,26 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + const d2 = domain.create(); + + d.on('error', function errorHandler() { + }); + + d.run(function() { + d2.run(function() { + setTimeout(function() { + throw new Error('boom!'); + }, 1); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-7.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-7.js new file mode 100644 index 00000000000000..9debc754cea3d1 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-7.js @@ -0,0 +1,26 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + const d2 = domain.create(); + + d.on('error', function errorHandler() { + }); + + d.run(function() { + d2.run(function() { + setImmediate(function() { + throw new Error('boom!'); + }); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-8.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-8.js new file mode 100644 index 00000000000000..f1670cbd300bdf --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-8.js @@ -0,0 +1,26 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + const d2 = domain.create(); + + d.on('error', function errorHandler() { + }); + + d.run(function() { + d2.run(function() { + process.nextTick(function() { + throw new Error('boom!'); + }); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught-9.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-9.js new file mode 100644 index 00000000000000..a4eebd50e96388 --- /dev/null +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught-9.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +function test() { + const d = domain.create(); + const d2 = domain.create(); + + d.on('error', function errorHandler() { + }); + + d.run(function() { + d2.run(function() { + var fs = require('fs'); + fs.exists('/non/existing/file', function onExists() { + throw new Error('boom!'); + }); + }); + }); +} + +if (process.argv[2] === 'child') { + test(); +} else { + common.childShouldThrowAndAbort(); +} diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js deleted file mode 100644 index 833e7374d7f2ab..00000000000000 --- a/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js +++ /dev/null @@ -1,168 +0,0 @@ -'use strict'; - -/* - * This test makes sure that when using --abort-on-uncaught-exception and - * when throwing an error from within a domain that does not have an error - * handler setup, the process aborts. - */ -const common = require('../common'); -const assert = require('assert'); -const domain = require('domain'); -const child_process = require('child_process'); - -const tests = [ - function() { - const d = domain.create(); - - d.run(function() { - throw new Error('boom!'); - }); - }, - - function() { - const d = domain.create(); - const d2 = domain.create(); - - d.run(function() { - d2.run(function() { - throw new Error('boom!'); - }); - }); - }, - - function() { - const d = domain.create(); - - d.run(function() { - setTimeout(function() { - throw new Error('boom!'); - }, 1); - }); - }, - - function() { - const d = domain.create(); - - d.run(function() { - setImmediate(function() { - throw new Error('boom!'); - }); - }); - }, - - function() { - const d = domain.create(); - - d.run(function() { - process.nextTick(function() { - throw new Error('boom!'); - }); - }); - }, - - function() { - const d = domain.create(); - - d.run(function() { - var fs = require('fs'); - fs.exists('/non/existing/file', function onExists() { - throw new Error('boom!'); - }); - }); - }, - - function() { - const d = domain.create(); - const d2 = domain.create(); - - d.on('error', function errorHandler() { - }); - - d.run(function() { - d2.run(function() { - setTimeout(function() { - throw new Error('boom!'); - }, 1); - }); - }); - }, - - function() { - const d = domain.create(); - const d2 = domain.create(); - - d.on('error', function errorHandler() { - }); - - d.run(function() { - d2.run(function() { - setImmediate(function() { - throw new Error('boom!'); - }); - }); - }); - }, - - function() { - const d = domain.create(); - const d2 = domain.create(); - - d.on('error', function errorHandler() { - }); - - d.run(function() { - d2.run(function() { - process.nextTick(function() { - throw new Error('boom!'); - }); - }); - }); - }, - - function() { - const d = domain.create(); - const d2 = domain.create(); - - d.on('error', function errorHandler() { - }); - - d.run(function() { - d2.run(function() { - var fs = require('fs'); - fs.exists('/non/existing/file', function onExists() { - throw new Error('boom!'); - }); - }); - }); - }, -]; - -if (process.argv[2] === 'child') { - const testIndex = +process.argv[3]; - tests[testIndex](); -} else { - - tests.forEach(function(test, testIndex) { - var testCmd = ''; - if (!common.isWindows) { - // Do not create core files, as it can take a lot of disk space on - // continuous testing and developers' machines - testCmd += 'ulimit -c 0 && '; - } - - testCmd += process.argv[0]; - testCmd += ' ' + '--abort-on-uncaught-exception'; - testCmd += ' ' + process.argv[1]; - testCmd += ' ' + 'child'; - testCmd += ' ' + testIndex; - - var child = child_process.exec(testCmd); - - child.on('exit', function onExit(exitCode, signal) { - const errMsg = 'Test at index ' + testIndex + ' should have aborted ' + - 'but instead exited with exit code ' + exitCode + - ' and signal ' + signal; - assert(common.nodeProcessAborted(exitCode, signal), errMsg); - }); - }); -} diff --git a/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js b/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js index fc6a93ccdca8ef..48c77bd2d490cc 100644 --- a/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js +++ b/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js @@ -49,22 +49,24 @@ if (process.argv[2] === 'child') { } function runTestWithoutAbortOnUncaughtException() { - child_process.exec(createTestCmdLine(), - function onTestDone(err, stdout, stderr) { - // When _not_ passing --abort-on-uncaught-exception, the process' - // uncaughtException handler _must_ be called, and thus the error - // message must include only the message of the error thrown from the - // process' uncaughtException handler. - assert(stderr.includes(uncaughtExceptionHandlerErrMsg), - 'stderr output must include proper uncaughtException ' + - 'handler\'s error\'s message'); - assert(!stderr.includes(domainErrMsg), 'stderr output must not ' + - 'include domain\'s error\'s message'); + child_process.exec( + createTestCmdLine(), + function onTestDone(err, stdout, stderr) { + // When _not_ passing --abort-on-uncaught-exception, the process' + // uncaughtException handler _must_ be called, and thus the error + // message must include only the message of the error thrown from the + // process' uncaughtException handler. + assert(stderr.includes(uncaughtExceptionHandlerErrMsg), + 'stderr output must include proper uncaughtException ' + + 'handler\'s error\'s message'); + assert(!stderr.includes(domainErrMsg), + 'stderr output must not include domain\'s error\'s message'); - assert.notEqual(err.code, 0, - 'child process should have exited with a non-zero ' + - 'exit code, but did not'); - }); + assert.notStrictEqual(err.code, 0, + 'child process should have exited with a ' + + 'non-zero exit code, but did not'); + } + ); } function runTestWithAbortOnUncaughtException() { diff --git a/test/parallel/test-domain-timers-uncaught-exception.js b/test/parallel/test-domain-timers-uncaught-exception.js new file mode 100644 index 00000000000000..d564d853ac935f --- /dev/null +++ b/test/parallel/test-domain-timers-uncaught-exception.js @@ -0,0 +1,25 @@ +'use strict'; +const common = require('../common'); + +// This test ensures that the timer callbacks are called in the order in which +// they were created in the event of an unhandled exception in the domain. + +const domain = require('domain').create(); +const assert = require('assert'); + +let first = false; + +domain.run(function() { + setTimeout(() => { throw new Error('FAIL'); }, 1); + setTimeout(() => { first = true; }, 1); + setTimeout(() => { assert.strictEqual(first, true); }, 2); + + // Ensure that 2 ms have really passed + let i = 1e6; + while (i--); +}); + +domain.once('error', common.mustCall((err) => { + assert(err); + assert.strictEqual(err.message, 'FAIL'); +})); diff --git a/test/parallel/test-event-emitter-modify-in-emit.js b/test/parallel/test-event-emitter-modify-in-emit.js index 7864438fff4df6..c13fad4347d617 100644 --- a/test/parallel/test-event-emitter-modify-in-emit.js +++ b/test/parallel/test-event-emitter-modify-in-emit.js @@ -3,7 +3,7 @@ require('../common'); const assert = require('assert'); const events = require('events'); -var callbacks_called = []; +let callbacks_called = []; const e = new events.EventEmitter(); @@ -25,27 +25,27 @@ function callback3() { } e.on('foo', callback1); -assert.equal(1, e.listeners('foo').length); +assert.strictEqual(e.listeners('foo').length, 1); e.emit('foo'); -assert.equal(2, e.listeners('foo').length); +assert.strictEqual(e.listeners('foo').length, 2); assert.deepStrictEqual(['callback1'], callbacks_called); e.emit('foo'); -assert.equal(0, e.listeners('foo').length); +assert.strictEqual(e.listeners('foo').length, 0); assert.deepStrictEqual(['callback1', 'callback2', 'callback3'], callbacks_called); e.emit('foo'); -assert.equal(0, e.listeners('foo').length); +assert.strictEqual(e.listeners('foo').length, 0); assert.deepStrictEqual(['callback1', 'callback2', 'callback3'], callbacks_called); e.on('foo', callback1); e.on('foo', callback2); -assert.equal(2, e.listeners('foo').length); +assert.strictEqual(e.listeners('foo').length, 2); e.removeAllListeners('foo'); -assert.equal(0, e.listeners('foo').length); +assert.strictEqual(e.listeners('foo').length, 0); // Verify that removing callbacks while in emit allows emits to propagate to // all listeners @@ -53,7 +53,7 @@ callbacks_called = []; e.on('foo', callback2); e.on('foo', callback3); -assert.equal(2, e.listeners('foo').length); +assert.strictEqual(2, e.listeners('foo').length); e.emit('foo'); assert.deepStrictEqual(['callback2', 'callback3'], callbacks_called); -assert.equal(0, e.listeners('foo').length); +assert.strictEqual(0, e.listeners('foo').length); diff --git a/test/parallel/test-event-emitter-num-args.js b/test/parallel/test-event-emitter-num-args.js index d858692aad338e..31e57c89c8f23d 100644 --- a/test/parallel/test-event-emitter-num-args.js +++ b/test/parallel/test-event-emitter-num-args.js @@ -4,15 +4,20 @@ var assert = require('assert'); var events = require('events'); const e = new events.EventEmitter(); -const num_args_emited = []; +const num_args_emitted = []; e.on('numArgs', function() { - var numArgs = arguments.length; - console.log('numArgs: ' + numArgs); - num_args_emited.push(numArgs); + const numArgs = arguments.length; + num_args_emitted.push(numArgs); }); -console.log('start'); +e.on('foo', function() { + num_args_emitted.push(arguments.length); +}); + +e.on('foo', function() { + num_args_emitted.push(arguments.length); +}); e.emit('numArgs'); e.emit('numArgs', null); @@ -21,6 +26,8 @@ e.emit('numArgs', null, null, null); e.emit('numArgs', null, null, null, null); e.emit('numArgs', null, null, null, null, null); +e.emit('foo', null, null, null, null); + process.on('exit', function() { - assert.deepStrictEqual([0, 1, 2, 3, 4, 5], num_args_emited); + assert.deepStrictEqual([0, 1, 2, 3, 4, 5, 4, 4], num_args_emitted); }); diff --git a/test/parallel/test-event-emitter-remove-all-listeners.js b/test/parallel/test-event-emitter-remove-all-listeners.js index e32a0e3f94f5b4..1970904df25a75 100644 --- a/test/parallel/test-event-emitter-remove-all-listeners.js +++ b/test/parallel/test-event-emitter-remove-all-listeners.js @@ -77,3 +77,14 @@ function listener() {} ee.removeAllListeners('baz'); assert.strictEqual(ee.listeners('baz').length, 0); } + +{ + const ee = new events.EventEmitter(); + assert.deepStrictEqual(ee, ee.removeAllListeners()); +} + +{ + const ee = new events.EventEmitter(); + ee._events = undefined; + assert.strictEqual(ee, ee.removeAllListeners()); +} diff --git a/test/parallel/test-event-emitter-remove-listeners.js b/test/parallel/test-event-emitter-remove-listeners.js index ff5ee5dc242e0f..2253d20fef0c0b 100644 --- a/test/parallel/test-event-emitter-remove-listeners.js +++ b/test/parallel/test-event-emitter-remove-listeners.js @@ -116,9 +116,23 @@ function listener2() {} ee.emit('hello'); } +{ + const ee = new EventEmitter(); + + assert.deepStrictEqual(ee, ee.removeListener('foo', () => {})); +} + // Verify that the removed listener must be a function assert.throws(() => { const ee = new EventEmitter(); ee.removeListener('foo', null); }, /^TypeError: "listener" argument must be a function$/); + +{ + const ee = new EventEmitter(); + const listener = () => {}; + ee._events = undefined; + const e = ee.removeListener('foo', listener); + assert.strictEqual(e, ee); +} diff --git a/test/parallel/test-event-emitter-special-event-names.js b/test/parallel/test-event-emitter-special-event-names.js index d71d819d3031b2..7ff781f0f90c5a 100644 --- a/test/parallel/test-event-emitter-special-event-names.js +++ b/test/parallel/test-event-emitter-special-event-names.js @@ -7,6 +7,8 @@ const assert = require('assert'); const ee = new EventEmitter(); const handler = () => {}; +assert.deepStrictEqual(ee.eventNames(), []); + assert.strictEqual(ee._events.hasOwnProperty, undefined); assert.strictEqual(ee._events.toString, undefined); diff --git a/test/parallel/test-fs-non-number-arguments-throw.js b/test/parallel/test-fs-non-number-arguments-throw.js index b13041ca3eecb6..3e40a5fd41be38 100644 --- a/test/parallel/test-fs-non-number-arguments-throw.js +++ b/test/parallel/test-fs-non-number-arguments-throw.js @@ -16,17 +16,17 @@ const saneEmitter = fs.createReadStream(tempFile, { start: 4, end: 6 }); assert.throws(function() { fs.createReadStream(tempFile, { start: '4', end: 6 }); }, /^TypeError: "start" option must be a Number$/, - "start as string didn't throw an error for createReadStream"); + "start as string didn't throw an error for createReadStream"); assert.throws(function() { fs.createReadStream(tempFile, { start: 4, end: '6' }); }, /^TypeError: "end" option must be a Number$/, - "end as string didn't throw an error for createReadStream"); + "end as string didn't throw an error for createReadStream"); assert.throws(function() { fs.createWriteStream(tempFile, { start: '4' }); }, /^TypeError: "start" option must be a Number$/, - "start as string didn't throw an error for createWriteStream"); + "start as string didn't throw an error for createWriteStream"); saneEmitter.on('data', common.mustCall(function(data) { assert.strictEqual(sanity, data.toString('utf8'), 'read ' + diff --git a/test/parallel/test-fs-null-bytes.js b/test/parallel/test-fs-null-bytes.js index 3c70d2953ca0f4..e04aa1cb76cb6f 100644 --- a/test/parallel/test-fs-null-bytes.js +++ b/test/parallel/test-fs-null-bytes.js @@ -4,16 +4,15 @@ var assert = require('assert'); var fs = require('fs'); function check(async, sync) { - var expected = /Path must be a string without null bytes/; - var argsSync = Array.prototype.slice.call(arguments, 2); - var argsAsync = argsSync.concat(function(er) { + const expected = /Path must be a string without null bytes/; + const argsSync = Array.prototype.slice.call(arguments, 2); + const argsAsync = argsSync.concat((er) => { assert(er && er.message.match(expected)); - assert.equal(er.code, 'ENOENT'); + assert.strictEqual(er.code, 'ENOENT'); }); if (sync) - assert.throws(function() { - console.error(sync.name, argsSync); + assert.throws(() => { sync.apply(null, argsSync); }, expected); @@ -51,7 +50,7 @@ check(fs.writeFile, fs.writeFileSync, 'foo\u0000bar'); // an 'error' for exists means that it doesn't exist. // one of many reasons why this file is the absolute worst. -fs.exists('foo\u0000bar', function(exists) { +fs.exists('foo\u0000bar', common.mustCall((exists) => { assert(!exists); -}); +})); assert(!fs.existsSync('foo\u0000bar')); diff --git a/test/parallel/test-fs-read-file-assert-encoding.js b/test/parallel/test-fs-read-file-assert-encoding.js new file mode 100644 index 00000000000000..897bcd3bc98795 --- /dev/null +++ b/test/parallel/test-fs-read-file-assert-encoding.js @@ -0,0 +1,13 @@ +'use strict'; +require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +const encoding = 'foo-8'; +const filename = 'bar.txt'; + +assert.throws( + fs.readFile.bind(fs, filename, { encoding }, () => {}), + new RegExp(`Error: Unknown encoding: ${encoding}$`) +); diff --git a/test/parallel/test-fs-read-zero-length.js b/test/parallel/test-fs-read-zero-length.js index 9c4cde52362ccc..71c6385c6024f7 100644 --- a/test/parallel/test-fs-read-zero-length.js +++ b/test/parallel/test-fs-read-zero-length.js @@ -7,7 +7,7 @@ const filepath = path.join(common.fixturesDir, 'x.txt'); const fd = fs.openSync(filepath, 'r'); const expected = ''; -fs.read(fd, 0, 0, 'utf-8', common.mustCall(function(err, str, bytesRead) { +fs.read(fd, 0, 0, 'utf-8', common.mustCall((err, str, bytesRead) => { assert.ok(!err); assert.equal(str, expected); assert.equal(bytesRead, 0); diff --git a/test/parallel/test-fs-readfile-zero-byte-liar.js b/test/parallel/test-fs-readfile-zero-byte-liar.js index 283a986f8a038a..c3887979bb0b4a 100644 --- a/test/parallel/test-fs-readfile-zero-byte-liar.js +++ b/test/parallel/test-fs-readfile-zero-byte-liar.js @@ -3,29 +3,29 @@ const common = require('../common'); var assert = require('assert'); var fs = require('fs'); -var dataExpected = fs.readFileSync(__filename, 'utf8'); +const dataExpected = fs.readFileSync(__filename, 'utf8'); // sometimes stat returns size=0, but it's a lie. fs._fstat = fs.fstat; fs._fstatSync = fs.fstatSync; -fs.fstat = function(fd, cb) { - fs._fstat(fd, function(er, st) { +fs.fstat = (fd, cb) => { + fs._fstat(fd, (er, st) => { if (er) return cb(er); st.size = 0; return cb(er, st); }); }; -fs.fstatSync = function(fd) { - var st = fs._fstatSync(fd); +fs.fstatSync = (fd) => { + const st = fs._fstatSync(fd); st.size = 0; return st; }; -var d = fs.readFileSync(__filename, 'utf8'); -assert.equal(d, dataExpected); +const d = fs.readFileSync(__filename, 'utf8'); +assert.strictEqual(d, dataExpected); -fs.readFile(__filename, 'utf8', common.mustCall(function(er, d) { - assert.equal(d, dataExpected); +fs.readFile(__filename, 'utf8', common.mustCall((er, d) => { + assert.strictEqual(d, dataExpected); })); diff --git a/test/parallel/test-fs-realpath.js b/test/parallel/test-fs-realpath.js index dcaf8177c9499c..adc8459a3eca46 100644 --- a/test/parallel/test-fs-realpath.js +++ b/test/parallel/test-fs-realpath.js @@ -137,13 +137,13 @@ function test_deep_relative_file_symlink(callback) { .relative(path.join(targetsAbsDir, 'nested-index', 'one'), expected); const linkPath1 = path.join(targetsAbsDir, - 'nested-index', 'one', 'symlink1.js'); + 'nested-index', 'one', 'symlink1.js'); try { fs.unlinkSync(linkPath1); } catch (e) {} fs.symlinkSync(linkData1, linkPath1, 'file'); const linkData2 = '../one/symlink1.js'; const entry = path.join(targetsAbsDir, - 'nested-index', 'two', 'symlink1-b.js'); + 'nested-index', 'two', 'symlink1-b.js'); try { fs.unlinkSync(entry); } catch (e) {} fs.symlinkSync(linkData2, entry, 'file'); unlink.push(linkPath1); @@ -170,7 +170,7 @@ function test_deep_relative_dir_symlink(callback) { const linkData2b = '../one/symlink1-dir'; const entry = path.join(targetsAbsDir, - 'nested-index', 'two', 'symlink12-dir'); + 'nested-index', 'two', 'symlink12-dir'); try { fs.unlinkSync(entry); } catch (e) {} fs.symlinkSync(linkData2b, entry, 'dir'); unlink.push(linkPath1b); @@ -237,7 +237,7 @@ function test_relative_input_cwd(callback) { // we need to calculate the relative path to the tmp dir from cwd const entrydir = process.cwd(); const entry = path.relative(entrydir, - path.join(common.tmpDir + '/cycles/realpath-3a')); + path.join(common.tmpDir + '/cycles/realpath-3a')); const expected = common.tmpDir + '/cycles/root.js'; [ [entry, '../cycles/realpath-3b'], @@ -292,14 +292,14 @@ function test_deep_symlink_mix(callback) { [ [entry, common.tmpDir + '/node-test-realpath-d1/foo'], [tmp('node-test-realpath-d1'), - common.tmpDir + '/node-test-realpath-d2'], + common.tmpDir + '/node-test-realpath-d2'], [tmp('node-test-realpath-d2/foo'), '../node-test-realpath-f2'], [tmp('node-test-realpath-f2'), targetsAbsDir + '/nested-index/one/realpath-c'], [targetsAbsDir + '/nested-index/one/realpath-c', targetsAbsDir + '/nested-index/two/realpath-c'], [targetsAbsDir + '/nested-index/two/realpath-c', - common.tmpDir + '/cycles/root.js'] + common.tmpDir + '/cycles/root.js'] ].forEach(function(t) { try { fs.unlinkSync(t[0]); } catch (e) {} fs.symlinkSync(t[1], t[0]); @@ -361,7 +361,7 @@ function test_up_multiple(cb) { } function cleanup() { ['a/b', - 'a' + 'a' ].forEach(function(folder) { try { fs.rmdirSync(tmp(folder)); } catch (ex) {} }); @@ -418,14 +418,14 @@ function test_abs_with_kids(cb) { const root = tmpAbsDir + '/node-test-realpath-abs-kids'; function cleanup() { ['/a/b/c/x.txt', - '/a/link' + '/a/link' ].forEach(function(file) { try { fs.unlinkSync(root + file); } catch (ex) {} }); ['/a/b/c', - '/a/b', - '/a', - '' + '/a/b', + '/a', + '' ].forEach(function(folder) { try { fs.rmdirSync(root + folder); } catch (ex) {} }); @@ -433,9 +433,9 @@ function test_abs_with_kids(cb) { function setup() { cleanup(); ['', - '/a', - '/a/b', - '/a/b/c' + '/a', + '/a/b', + '/a/b/c' ].forEach(function(folder) { console.log('mkdir ' + root + folder); fs.mkdirSync(root + folder, 0o700); diff --git a/test/parallel/test-fs-truncate-sync.js b/test/parallel/test-fs-truncate-sync.js new file mode 100644 index 00000000000000..a7ce2f4d97f3fe --- /dev/null +++ b/test/parallel/test-fs-truncate-sync.js @@ -0,0 +1,20 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const tmp = common.tmpDir; + +common.refreshTmpDir(); + +const filename = path.resolve(tmp, 'truncate-sync-file.txt'); + +fs.writeFileSync(filename, 'hello world', 'utf8'); + +const fd = fs.openSync(filename, 'r+'); + +fs.truncateSync(fd, 5); +assert(fs.readFileSync(fd).equals(Buffer.from('hello'))); + +fs.closeSync(fd); +fs.unlinkSync(filename); diff --git a/test/parallel/test-fs-truncate.js b/test/parallel/test-fs-truncate.js index 1ba0db7f012fe4..de8d6d9fdceadb 100644 --- a/test/parallel/test-fs-truncate.js +++ b/test/parallel/test-fs-truncate.js @@ -146,3 +146,14 @@ function testFtruncate(cb) { assert(fs.readFileSync(file4).equals(Buffer.from('Hi\u0000\u0000'))); })); } + +{ + const file5 = path.resolve(tmp, 'truncate-file-5.txt'); + fs.writeFileSync(file5, 'Hi'); + const fd = fs.openSync(file5, 'r+'); + process.on('exit', () => fs.closeSync(fd)); + fs.ftruncate(fd, undefined, common.mustCall(function(err) { + assert.ifError(err); + assert(fs.readFileSync(file5).equals(Buffer.from(''))); + })); +} diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index f245a7962da0f4..108ca7c7d71c03 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -4,11 +4,11 @@ var assert = require('assert'); var util = require('util'); var fs = require('fs'); -var tests_ok = 0; -var tests_run = 0; +let tests_ok = 0; +let tests_run = 0; function stat_resource(resource) { - if (typeof resource == 'string') { + if (typeof resource === 'string') { return fs.statSync(resource); } else { // ensure mtime has been written to disk @@ -19,8 +19,8 @@ function stat_resource(resource) { function check_mtime(resource, mtime) { mtime = fs._toUnixTimestamp(mtime); - var stats = stat_resource(resource); - var real_mtime = fs._toUnixTimestamp(stats.mtime); + const stats = stat_resource(resource); + const real_mtime = fs._toUnixTimestamp(stats.mtime); // check up to single-second precision // sub-second precision is OS and fs dependant return mtime - real_mtime < 2; @@ -46,9 +46,9 @@ function expect_ok(syscall, resource, err, atime, mtime) { // the tests assume that __filename belongs to the user running the tests // this should be a fairly safe assumption; testing against a temp file // would be even better though (node doesn't have such functionality yet) -function runTest(atime, mtime, callback) { +function testIt(atime, mtime, callback) { - var fd; + let fd; // // test synchronized code paths, these functions throw on failure // @@ -67,8 +67,7 @@ function runTest(atime, mtime, callback) { expect_errno('futimesSync', fd, ex, 'ENOSYS'); } - var err; - err = undefined; + let err = undefined; try { fs.utimesSync('foobarbaz', atime, mtime); } catch (ex) { @@ -90,10 +89,10 @@ function runTest(atime, mtime, callback) { // // test async code paths // - fs.utimes(__filename, atime, mtime, function(err) { + fs.utimes(__filename, atime, mtime, common.mustCall(function(err) { expect_ok('utimes', __filename, err, atime, mtime); - fs.utimes('foobarbaz', atime, mtime, function(err) { + fs.utimes('foobarbaz', atime, mtime, common.mustCall(function(err) { expect_errno('utimes', 'foobarbaz', err, 'ENOENT'); // don't close this fd @@ -103,34 +102,36 @@ function runTest(atime, mtime, callback) { fd = fs.openSync(__filename, 'r'); } - fs.futimes(fd, atime, mtime, function(err) { + fs.futimes(fd, atime, mtime, common.mustCall(function(err) { expect_ok('futimes', fd, err, atime, mtime); - fs.futimes(-1, atime, mtime, function(err) { + fs.futimes(-1, atime, mtime, common.mustCall(function(err) { expect_errno('futimes', -1, err, 'EBADF'); syncTests(); callback(); - }); + })); tests_run++; - }); + })); tests_run++; - }); + })); tests_run++; - }); + })); tests_run++; } -var stats = fs.statSync(__filename); +const stats = fs.statSync(__filename); // run tests +const runTest = common.mustCall(testIt, 6); + runTest(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), function() { runTest(new Date(), new Date(), function() { runTest(123456.789, 123456.789, function() { runTest(stats.mtime, stats.mtime, function() { runTest(NaN, Infinity, function() { - runTest('123456', -1, function() { + runTest('123456', -1, common.mustCall(function() { // done - }); + })); }); }); }); @@ -140,5 +141,5 @@ runTest(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), function() { process.on('exit', function() { console.log('Tests run / ok:', tests_run, '/', tests_ok); - assert.equal(tests_ok, tests_run); + assert.strictEqual(tests_ok, tests_run); }); diff --git a/test/parallel/test-fs-write-file-sync.js b/test/parallel/test-fs-write-file-sync.js index 7ae9e122cae8be..ca6324ac1ff789 100644 --- a/test/parallel/test-fs-write-file-sync.js +++ b/test/parallel/test-fs-write-file-sync.js @@ -1,11 +1,11 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var path = require('path'); -var fs = require('fs'); -var openCount = 0; -var mode; -var content; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +let openCount = 0; +let mode; +let content; // Need to hijack fs.open/close to make sure that things // get closed once they're opened. @@ -28,39 +28,39 @@ if (common.isWindows) { common.refreshTmpDir(); // Test writeFileSync -var file1 = path.join(common.tmpDir, 'testWriteFileSync.txt'); +const file1 = path.join(common.tmpDir, 'testWriteFileSync.txt'); fs.writeFileSync(file1, '123', {mode: mode}); content = fs.readFileSync(file1, {encoding: 'utf8'}); -assert.equal('123', content); +assert.strictEqual(content, '123'); -assert.equal(mode, fs.statSync(file1).mode & 0o777); +assert.strictEqual(fs.statSync(file1).mode & 0o777, mode); // Test appendFileSync -var file2 = path.join(common.tmpDir, 'testAppendFileSync.txt'); +const file2 = path.join(common.tmpDir, 'testAppendFileSync.txt'); fs.appendFileSync(file2, 'abc', {mode: mode}); content = fs.readFileSync(file2, {encoding: 'utf8'}); -assert.equal('abc', content); +assert.strictEqual(content, 'abc'); -assert.equal(mode, fs.statSync(file2).mode & mode); +assert.strictEqual(fs.statSync(file2).mode & mode, mode); // Test writeFileSync with file descriptor -var file3 = path.join(common.tmpDir, 'testWriteFileSyncFd.txt'); +const file3 = path.join(common.tmpDir, 'testWriteFileSyncFd.txt'); -var fd = fs.openSync(file3, 'w+', mode); +const fd = fs.openSync(file3, 'w+', mode); fs.writeFileSync(fd, '123'); fs.closeSync(fd); content = fs.readFileSync(file3, {encoding: 'utf8'}); -assert.equal('123', content); +assert.strictEqual(content, '123'); -assert.equal(mode, fs.statSync(file3).mode & 0o777); +assert.strictEqual(fs.statSync(file3).mode & 0o777, mode); // Verify that all opened files were closed. -assert.equal(0, openCount); +assert.strictEqual(openCount, 0); function openSync() { openCount++; diff --git a/test/parallel/test-handle-wrap-close-abort.js b/test/parallel/test-handle-wrap-close-abort.js index 5355e65df60821..e9f69195ad29cd 100644 --- a/test/parallel/test-handle-wrap-close-abort.js +++ b/test/parallel/test-handle-wrap-close-abort.js @@ -13,4 +13,4 @@ setTimeout(function() { setTimeout(function() { throw new Error('setTimeout'); }, 1); -}); +}, 1); diff --git a/test/parallel/test-http-abort-queued-2.js b/test/parallel/test-http-abort-queued-2.js new file mode 100644 index 00000000000000..77dc2a535b0e4f --- /dev/null +++ b/test/parallel/test-http-abort-queued-2.js @@ -0,0 +1,36 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +let socketsCreated = 0; + +class Agent extends http.Agent { + createConnection(options, oncreate) { + const socket = super.createConnection(options, oncreate); + socketsCreated++; + return socket; + } +} + +const server = http.createServer((req, res) => res.end()); + +server.listen(0, common.mustCall(() => { + const port = server.address().port; + const agent = new Agent({ + keepAlive: true, + maxSockets: 1 + }); + + http.get({agent, port}, (res) => res.resume()); + + const req = http.get({agent, port}, common.fail); + req.abort(); + + http.get({agent, port}, common.mustCall((res) => { + res.resume(); + assert.strictEqual(socketsCreated, 1); + agent.destroy(); + server.close(); + })); +})); diff --git a/test/parallel/test-http-chunked-304.js b/test/parallel/test-http-chunked-304.js index 5ea1912b72dfee..82fe138fd926da 100644 --- a/test/parallel/test-http-chunked-304.js +++ b/test/parallel/test-http-chunked-304.js @@ -12,32 +12,35 @@ var net = require('net'); // Likewise for 304 responses. Verify that no empty chunk is sent when // the user explicitly sets a Transfer-Encoding header. -test(204, function() { - test(304); -}); +test(204); +test(304); -function test(statusCode, next) { - var server = http.createServer(function(req, res) { +function test(statusCode) { + const server = http.createServer(common.mustCall((req, res) => { res.writeHead(statusCode, { 'Transfer-Encoding': 'chunked' }); res.end(); server.close(); - }); + })); - server.listen(0, function() { - var conn = net.createConnection(this.address().port, function() { - conn.write('GET / HTTP/1.1\r\n\r\n'); + server.listen(0, common.mustCall(() => { + const conn = net.createConnection( + server.address().port, + common.mustCall(() => { + conn.write('GET / HTTP/1.1\r\n\r\n'); - var resp = ''; - conn.setEncoding('utf8'); - conn.on('data', function(data) { - resp += data; - }); + let resp = ''; + conn.setEncoding('utf8'); + conn.on('data', common.mustCall((data) => { + resp += data; + })); - conn.on('end', common.mustCall(function() { - assert.equal(/^Connection: close\r\n$/m.test(resp), true); - assert.equal(/^0\r\n$/m.test(resp), false); - if (next) process.nextTick(next); - })); - }); - }); + conn.on('end', common.mustCall(() => { + // Connection: close should be in the response + assert.strictEqual(/^Connection: close\r\n$/m.test(resp), true); + // Make sure this doesn't end with 0\r\n\r\n + assert.strictEqual(/^0\r\n$/m.test(resp), false); + })); + }) + ); + })); } diff --git a/test/parallel/test-http-client-abort-no-agent.js b/test/parallel/test-http-client-abort-no-agent.js new file mode 100644 index 00000000000000..875d2ce6469d46 --- /dev/null +++ b/test/parallel/test-http-client-abort-no-agent.js @@ -0,0 +1,19 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); +const net = require('net'); + +const server = http.createServer(common.fail); + +server.listen(0, common.mustCall(() => { + const req = http.get({ + createConnection(options, oncreate) { + const socket = net.createConnection(options, oncreate); + socket.once('close', () => server.close()); + return socket; + }, + port: server.address().port + }); + + req.abort(); +})); diff --git a/test/parallel/test-http-client-abort-unix-socket.js b/test/parallel/test-http-client-abort-unix-socket.js new file mode 100644 index 00000000000000..0b7c5e5ddea6dd --- /dev/null +++ b/test/parallel/test-http-client-abort-unix-socket.js @@ -0,0 +1,24 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); + +const server = http.createServer(common.fail); + +class Agent extends http.Agent { + createConnection(options, oncreate) { + const socket = super.createConnection(options, oncreate); + socket.once('close', () => server.close()); + return socket; + } +} + +common.refreshTmpDir(); + +server.listen(common.PIPE, common.mustCall(() => { + const req = http.get({ + agent: new Agent(), + socketPath: common.PIPE + }); + + req.abort(); +})); diff --git a/test/parallel/test-http-client-unescaped-path.js b/test/parallel/test-http-client-unescaped-path.js index e01df255a8042c..1a74943e838259 100644 --- a/test/parallel/test-http-client-unescaped-path.js +++ b/test/parallel/test-http-client-unescaped-path.js @@ -1,9 +1,10 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var http = require('http'); +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); -assert.throws(function() { - // Path with spaces in it should throw. - http.get({ path: 'bad path' }, common.fail); -}, /contains unescaped characters/); +for (let i = 0; i <= 32; i += 1) { + const path = 'bad' + String.fromCharCode(i) + 'path'; + assert.throws(() => http.get({ path }, common.fail), + /contains unescaped characters/); +} diff --git a/test/parallel/test-http-common.js b/test/parallel/test-http-common.js new file mode 100644 index 00000000000000..1629856ce57d09 --- /dev/null +++ b/test/parallel/test-http-common.js @@ -0,0 +1,33 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const httpCommon = require('_http_common'); +const checkIsHttpToken = httpCommon._checkIsHttpToken; +const checkInvalidHeaderChar = httpCommon._checkInvalidHeaderChar; + +// checkIsHttpToken +assert(checkIsHttpToken('t')); +assert(checkIsHttpToken('tt')); +assert(checkIsHttpToken('ttt')); +assert(checkIsHttpToken('tttt')); +assert(checkIsHttpToken('ttttt')); + +assert.strictEqual(checkIsHttpToken(''), false); +assert.strictEqual(checkIsHttpToken(' '), false); +assert.strictEqual(checkIsHttpToken('あ'), false); +assert.strictEqual(checkIsHttpToken('あa'), false); +assert.strictEqual(checkIsHttpToken('aaaaあaaaa'), false); + +// checkInvalidHeaderChar +assert(checkInvalidHeaderChar('あ')); +assert(checkInvalidHeaderChar('aaaaあaaaa')); + +assert.strictEqual(checkInvalidHeaderChar(''), false); +assert.strictEqual(checkInvalidHeaderChar(1), false); +assert.strictEqual(checkInvalidHeaderChar(' '), false); +assert.strictEqual(checkInvalidHeaderChar(false), false); +assert.strictEqual(checkInvalidHeaderChar('t'), false); +assert.strictEqual(checkInvalidHeaderChar('tt'), false); +assert.strictEqual(checkInvalidHeaderChar('ttt'), false); +assert.strictEqual(checkInvalidHeaderChar('tttt'), false); +assert.strictEqual(checkInvalidHeaderChar('ttttt'), false); diff --git a/test/parallel/test-http-double-content-length.js b/test/parallel/test-http-double-content-length.js index a73cf49854ed35..f6c13becfd83dd 100644 --- a/test/parallel/test-http-double-content-length.js +++ b/test/parallel/test-http-double-content-length.js @@ -22,9 +22,9 @@ server.listen(0, () => { port: server.address().port, // Send two content-length header values. headers: {'Content-Length': [1, 2]}}, - (res) => { - common.fail('an error should have occurred'); - } + (res) => { + common.fail('an error should have occurred'); + } ); req.on('error', common.mustCall(() => { server.close(); diff --git a/test/parallel/test-http-host-headers.js b/test/parallel/test-http-host-headers.js index a9f12d6819314e..863dbae365d164 100644 --- a/test/parallel/test-http-host-headers.js +++ b/test/parallel/test-http-host-headers.js @@ -1,11 +1,10 @@ 'use strict'; -require('../common'); +const common = require('../common'); const http = require('http'); const assert = require('assert'); const httpServer = http.createServer(reqHandler); function reqHandler(req, res) { - console.log('Got request: ' + req.headers.host + ' ' + req.url); if (req.url === '/setHostFalse5') { assert.equal(req.headers.host, undefined); } else { @@ -14,14 +13,9 @@ function reqHandler(req, res) { req.headers.host); } res.writeHead(200, {}); - //process.nextTick(function() { res.end('ok'); }); res.end('ok'); } -function thrower(er) { - throw er; -} - testHttp(); function testHttp() { @@ -30,61 +24,52 @@ function testHttp() { function cb(res) { counter--; - console.log('back from http request. counter = ' + counter); if (counter === 0) { httpServer.close(); } res.resume(); } - httpServer.listen(0, function(er) { - console.error(`test http server listening on ${this.address().port}`); - - if (er) throw er; - + httpServer.listen(0, (er) => { + assert.ifError(er); http.get({ method: 'GET', path: '/' + (counter++), host: 'localhost', - //agent: false, - port: this.address().port, + port: httpServer.address().port, rejectUnauthorized: false - }, cb).on('error', thrower); + }, cb).on('error', common.fail); http.request({ method: 'GET', path: '/' + (counter++), host: 'localhost', - //agent: false, - port: this.address().port, + port: httpServer.address().port, rejectUnauthorized: false - }, cb).on('error', thrower).end(); + }, cb).on('error', common.fail).end(); http.request({ method: 'POST', path: '/' + (counter++), host: 'localhost', - //agent: false, - port: this.address().port, + port: httpServer.address().port, rejectUnauthorized: false - }, cb).on('error', thrower).end(); + }, cb).on('error', common.fail).end(); http.request({ method: 'PUT', path: '/' + (counter++), host: 'localhost', - //agent: false, - port: this.address().port, + port: httpServer.address().port, rejectUnauthorized: false - }, cb).on('error', thrower).end(); + }, cb).on('error', common.fail).end(); http.request({ method: 'DELETE', path: '/' + (counter++), host: 'localhost', - //agent: false, - port: this.address().port, + port: httpServer.address().port, rejectUnauthorized: false - }, cb).on('error', thrower).end(); + }, cb).on('error', common.fail).end(); }); } diff --git a/test/parallel/test-http-incoming-matchKnownFields.js b/test/parallel/test-http-incoming-matchKnownFields.js new file mode 100644 index 00000000000000..7411be4e847d73 --- /dev/null +++ b/test/parallel/test-http-incoming-matchKnownFields.js @@ -0,0 +1,90 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const IncomingMessage = require('http').IncomingMessage; + +function checkDest(field, result, value) { + const dest = {}; + + if (value) dest[field] = 'test'; + const incomingMessage = new IncomingMessage(field); + // dest is changed by IncomingMessage._addHeaderLine + incomingMessage._addHeaderLine(field, value, dest); + assert.deepStrictEqual(dest, result); +} + +checkDest('', {'': undefined}); +checkDest('Content-Type', {'content-type': undefined}); +checkDest('content-type', {'content-type': 'test'}, 'value'); +checkDest('User-Agent', {'user-agent': undefined}); +checkDest('user-agent', {'user-agent': 'test'}, 'value'); +checkDest('Referer', {referer: undefined}); +checkDest('referer', {referer: 'test'}, 'value'); +checkDest('Host', {host: undefined}); +checkDest('host', {host: 'test'}, 'value'); +checkDest('Authorization', {authorization: undefined}, undefined); +checkDest('authorization', {authorization: 'test'}, 'value'); +checkDest('Proxy-Authorization', {'proxy-authorization': undefined}); +checkDest('proxy-authorization', {'proxy-authorization': 'test'}, 'value'); +checkDest('If-Modified-Since', {'if-modified-since': undefined}); +checkDest('if-modified-since', {'if-modified-since': 'test'}, 'value'); +checkDest('If-Unmodified-Since', {'if-unmodified-since': undefined}); +checkDest('if-unmodified-since', {'if-unmodified-since': 'test'}, 'value'); +checkDest('Form', {form: undefined}); +checkDest('form', {form: 'test, value'}, 'value'); +checkDest('Location', {location: undefined}); +checkDest('location', {location: 'test'}, 'value'); +checkDest('Max-Forwards', {'max-forwards': undefined}); +checkDest('max-forwards', {'max-forwards': 'test'}, 'value'); +checkDest('Retry-After', {'retry-after': undefined}); +checkDest('retry-after', {'retry-after': 'test'}, 'value'); +checkDest('Etag', {etag: undefined}); +checkDest('etag', {etag: 'test'}, 'value'); +checkDest('Last-Modified', {'last-modified': undefined}); +checkDest('last-modified', {'last-modified': 'test'}, 'value'); +checkDest('Server', {server: undefined}); +checkDest('server', {server: 'test'}, 'value'); +checkDest('Age', {age: undefined}); +checkDest('age', {age: 'test'}, 'value'); +checkDest('Expires', {expires: undefined}); +checkDest('expires', {expires: 'test'}, 'value'); +checkDest('Set-Cookie', {'set-cookie': [undefined]}); +checkDest('set-cookie', {'set-cookie': [undefined]}); +checkDest('Transfer-Encoding', {'transfer-encoding': undefined}); +checkDest('transfer-encoding', {'transfer-encoding': 'test, value'}, 'value'); +checkDest('Date', {date: undefined}); +checkDest('date', {date: 'test, value'}, 'value'); +checkDest('Connection', {connection: undefined}); +checkDest('connection', {connection: 'test, value'}, 'value'); +checkDest('Cache-Control', {'cache-control': undefined}); +checkDest('cache-control', {'cache-control': 'test, value'}, 'value'); +checkDest('Transfer-Encoding', {'transfer-encoding': undefined}); +checkDest('transfer-encoding', {'transfer-encoding': 'test, value'}, 'value'); +checkDest('Vary', {vary: undefined}); +checkDest('vary', {vary: 'test, value'}, 'value'); +checkDest('Content-Encoding', {'content-encoding': undefined}, undefined); +checkDest('content-encoding', {'content-encoding': 'test, value'}, 'value'); +checkDest('Cookies', {cookies: undefined}); +checkDest('cookies', {cookies: 'test, value'}, 'value'); +checkDest('Origin', {origin: undefined}); +checkDest('origin', {origin: 'test, value'}, 'value'); +checkDest('Upgrade', {upgrade: undefined}); +checkDest('upgrade', {upgrade: 'test, value'}, 'value'); +checkDest('Expect', {expect: undefined}); +checkDest('expect', {expect: 'test, value'}, 'value'); +checkDest('If-Match', {'if-match': undefined}); +checkDest('if-match', {'if-match': 'test, value'}, 'value'); +checkDest('If-None-Match', {'if-none-match': undefined}); +checkDest('if-none-match', {'if-none-match': 'test, value'}, 'value'); +checkDest('Accept', {accept: undefined}); +checkDest('accept', {accept: 'test, value'}, 'value'); +checkDest('Accept-Encoding', {'accept-encoding': undefined}); +checkDest('accept-encoding', {'accept-encoding': 'test, value'}, 'value'); +checkDest('Accept-Language', {'accept-language': undefined}); +checkDest('accept-language', {'accept-language': 'test, value'}, 'value'); +checkDest('X-Forwarded-For', {'x-forwarded-for': undefined}); +checkDest('x-forwarded-for', {'x-forwarded-for': 'test, value'}, 'value'); +checkDest('X-Forwarded-Host', {'x-forwarded-host': undefined}); +checkDest('x-forwarded-host', {'x-forwarded-host': 'test, value'}, 'value'); +checkDest('X-Forwarded-Proto', {'x-forwarded-proto': undefined}); +checkDest('x-forwarded-proto', {'x-forwarded-proto': 'test, value'}, 'value'); diff --git a/test/parallel/test-http-localaddress.js b/test/parallel/test-http-localaddress.js index fd38f8a901fe81..d507d12ec89e25 100644 --- a/test/parallel/test-http-localaddress.js +++ b/test/parallel/test-http-localaddress.js @@ -21,10 +21,10 @@ var server = http.createServer(function(req, res) { server.listen(0, '127.0.0.1', function() { var options = { host: 'localhost', - port: this.address().port, - path: '/', - method: 'GET', - localAddress: '127.0.0.2' }; + port: this.address().port, + path: '/', + method: 'GET', + localAddress: '127.0.0.2' }; var req = http.request(options, function(res) { res.on('end', function() { diff --git a/test/parallel/test-http-outgoing-proto.js b/test/parallel/test-http-outgoing-proto.js index 738e1d2c8cfe4e..7b3f851f2f5c86 100644 --- a/test/parallel/test-http-outgoing-proto.js +++ b/test/parallel/test-http-outgoing-proto.js @@ -7,7 +7,8 @@ const OutgoingMessage = http.OutgoingMessage; const ClientRequest = http.ClientRequest; const ServerResponse = http.ServerResponse; -assert.throws(OutgoingMessage.prototype._implicitHeader); +assert.throws(OutgoingMessage.prototype._implicitHeader, + /^Error: _implicitHeader\(\) method is not implemented$/); assert.strictEqual( typeof ClientRequest.prototype._implicitHeader, 'function'); assert.strictEqual( diff --git a/test/parallel/test-http-proxy.js b/test/parallel/test-http-proxy.js index 43feb1e3b3838c..48367caaa7d89e 100644 --- a/test/parallel/test-http-proxy.js +++ b/test/parallel/test-http-proxy.js @@ -10,8 +10,8 @@ var cookies = [ ]; var headers = {'content-type': 'text/plain', - 'set-cookie': cookies, - 'hello': 'world' }; + 'set-cookie': cookies, + 'hello': 'world' }; var backend = http.createServer(function(req, res) { console.error('backend request'); diff --git a/test/parallel/test-http-response-splitting.js b/test/parallel/test-http-response-splitting.js index e4021e78317759..f2c7bc5d8d1219 100644 --- a/test/parallel/test-http-response-splitting.js +++ b/test/parallel/test-http-response-splitting.js @@ -19,23 +19,23 @@ const y = 'foo⠊Set-Cookie: foo=bar'; var count = 0; +function test(res, code, header) { + assert.throws(() => { + res.writeHead(code, header); + }, /^TypeError: The header content contains invalid characters$/); +} + const server = http.createServer((req, res) => { switch (count++) { case 0: const loc = url.parse(req.url, true).query.lang; - assert.throws(common.mustCall(() => { - res.writeHead(302, {Location: `/foo?lang=${loc}`}); - })); + test(res, 302, {Location: `/foo?lang=${loc}`}); break; case 1: - assert.throws(common.mustCall(() => { - res.writeHead(200, {'foo': x}); - })); + test(res, 200, {'foo': x}); break; case 2: - assert.throws(common.mustCall(() => { - res.writeHead(200, {'foo': y}); - })); + test(res, 200, {'foo': y}); break; default: common.fail('should not get to here.'); diff --git a/test/parallel/test-http-response-statuscode.js b/test/parallel/test-http-response-statuscode.js index 3314506339b564..ed3676b03e1f0c 100644 --- a/test/parallel/test-http-response-statuscode.js +++ b/test/parallel/test-http-response-statuscode.js @@ -3,70 +3,79 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); -const MAX_REQUESTS = 12; -var reqNum = 0; +const MAX_REQUESTS = 13; +let reqNum = 0; + +const createErrorMessage = (code) => { + return new RegExp(`^RangeError: Invalid status code: ${code}$`); +}; const server = http.Server(common.mustCall(function(req, res) { switch (reqNum) { case 0: assert.throws(common.mustCall(() => { res.writeHead(-1); - }, /invalid status code/i)); + }), createErrorMessage(-1)); break; case 1: assert.throws(common.mustCall(() => { res.writeHead(Infinity); - }, /invalid status code/i)); + }), createErrorMessage(0)); break; case 2: assert.throws(common.mustCall(() => { res.writeHead(NaN); - }, /invalid status code/i)); + }), createErrorMessage(0)); break; case 3: assert.throws(common.mustCall(() => { res.writeHead({}); - }, /invalid status code/i)); + }), createErrorMessage(0)); break; case 4: assert.throws(common.mustCall(() => { res.writeHead(99); - }, /invalid status code/i)); + }), createErrorMessage(99)); break; case 5: assert.throws(common.mustCall(() => { res.writeHead(1000); - }, /invalid status code/i)); + }), createErrorMessage(1000)); break; case 6: assert.throws(common.mustCall(() => { res.writeHead('1000'); - }, /invalid status code/i)); + }), createErrorMessage(1000)); break; case 7: assert.throws(common.mustCall(() => { res.writeHead(null); - }, /invalid status code/i)); + }), createErrorMessage(0)); break; case 8: assert.throws(common.mustCall(() => { res.writeHead(true); - }, /invalid status code/i)); + }), createErrorMessage(1)); break; case 9: assert.throws(common.mustCall(() => { res.writeHead([]); - }, /invalid status code/i)); + }), createErrorMessage(0)); break; case 10: assert.throws(common.mustCall(() => { res.writeHead('this is not valid'); - }, /invalid status code/i)); + }), createErrorMessage(0)); break; case 11: assert.throws(common.mustCall(() => { res.writeHead('404 this is not valid either'); - }, /invalid status code/i)); + }), createErrorMessage(0)); + break; + case 12: + assert.throws(common.mustCall(() => { + res.writeHead(); + }), createErrorMessage(0)); this.close(); break; default: diff --git a/test/parallel/test-http-server-unconsume-consume.js b/test/parallel/test-http-server-unconsume-consume.js new file mode 100644 index 00000000000000..d341093303c76f --- /dev/null +++ b/test/parallel/test-http-server-unconsume-consume.js @@ -0,0 +1,22 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); + +const testServer = http.createServer((req, res) => { + common.fail('Should not be called'); + res.end(); +}); +testServer.on('connect', common.mustCall((req, socket, head) => { + socket.write('HTTP/1.1 200 Connection Established' + '\r\n' + + 'Proxy-agent: Node-Proxy' + '\r\n' + + '\r\n'); + // This shouldn't raise an assertion in StreamBase::Consume. + testServer.emit('connection', socket); + testServer.close(); +})); +testServer.listen(0, common.mustCall(() => { + http.request({ + port: testServer.address().port, + method: 'CONNECT' + }, (res) => {}).end(); +})); diff --git a/test/parallel/test-http-status-reason-invalid-chars.js b/test/parallel/test-http-status-reason-invalid-chars.js index 9950eeeee9cdd2..75ccb2c2430c53 100644 --- a/test/parallel/test-http-status-reason-invalid-chars.js +++ b/test/parallel/test-http-status-reason-invalid-chars.js @@ -3,7 +3,6 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); -const net = require('net'); function explicit(req, res) { assert.throws(() => { @@ -34,8 +33,7 @@ const server = http.createServer((req, res) => { implicit(req, res); } }).listen(0, common.mustCall(() => { - const addr = server.address().address; - const hostname = net.isIPv6(addr) ? `[${addr}1]` : addr; + const hostname = 'localhost'; const url = `http://${hostname}:${server.address().port}`; let left = 2; const check = common.mustCall((res) => { diff --git a/test/parallel/test-http-write-head.js b/test/parallel/test-http-write-head.js index 32fff6042e7178..bdb5d906a0096f 100644 --- a/test/parallel/test-http-write-head.js +++ b/test/parallel/test-http-write-head.js @@ -1,12 +1,12 @@ 'use strict'; -require('../common'); -var assert = require('assert'); -var http = require('http'); +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); // Verify that ServerResponse.writeHead() works as setHeader. // Issue 5036 on github. -var s = http.createServer(function(req, res) { +const s = http.createServer(common.mustCall((req, res) => { res.setHeader('test', '1'); // toLowerCase() is used on the name argument, so it must be a string. @@ -31,18 +31,23 @@ var s = http.createServer(function(req, res) { assert.ok(threw, 'Undefined value should throw'); res.writeHead(200, { Test: '2' }); + + assert.throws(() => { + res.writeHead(100, {}); + }, /^Error: Can't render headers after they are sent to the client$/); + res.end(); -}); +})); -s.listen(0, runTest); +s.listen(0, common.mustCall(runTest)); function runTest() { - http.get({ port: this.address().port }, function(response) { - response.on('end', function() { - assert.equal(response.headers['test'], '2'); + http.get({ port: this.address().port }, common.mustCall((response) => { + response.on('end', common.mustCall(() => { + assert.strictEqual(response.headers['test'], '2'); assert.notStrictEqual(response.rawHeaders.indexOf('Test'), -1); s.close(); - }); + })); response.resume(); - }); + })); } diff --git a/test/parallel/test-https-truncate.js b/test/parallel/test-https-truncate.js index 4101a8c974e736..c96b385fc37fde 100644 --- a/test/parallel/test-https-truncate.js +++ b/test/parallel/test-https-truncate.js @@ -1,11 +1,12 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); if (!common.hasCrypto) { common.skip('missing crypto'); return; } + +const assert = require('assert'); const https = require('https'); const fs = require('fs'); @@ -14,7 +15,7 @@ const key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'); const cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'); // number of bytes discovered empirically to trigger the bug -const data = Buffer.allocUnsafe(1024 * 32 + 1); +const data = Buffer.alloc(1024 * 32 + 1); httpsTest(); @@ -36,12 +37,11 @@ function httpsTest() { } -function test(res) { - res.on('end', function() { +const test = common.mustCall(function(res) { + res.on('end', common.mustCall(function() { assert.strictEqual(res._readableState.length, 0); assert.strictEqual(bytes, data.length); - console.log('ok'); - }); + })); // Pause and then resume on each chunk, to ensure that there will be // a lone byte hanging out at the very end. @@ -49,6 +49,6 @@ function test(res) { res.on('data', function(chunk) { bytes += chunk.length; this.pause(); - setTimeout(this.resume.bind(this)); + setTimeout(this.resume.bind(this), 1); }); -} +}); diff --git a/test/parallel/test-internal-util-toInteger.js b/test/parallel/test-internal-util-toInteger.js new file mode 100644 index 00000000000000..57a411964da90f --- /dev/null +++ b/test/parallel/test-internal-util-toInteger.js @@ -0,0 +1,32 @@ +// Flags: --expose-internals +'use strict'; + +require('../common'); +const assert = require('assert'); +const {toInteger} = require('internal/util'); + +const expectZero = [ + '0', '-0', NaN, {}, [], {'a': 'b'}, [1, 2], '0x', '0o', '0b', false, + '', ' ', undefined, null +]; +expectZero.forEach(function(value) { + assert.strictEqual(toInteger(value), 0); +}); + +assert.strictEqual(toInteger(Infinity), Infinity); +assert.strictEqual(toInteger(-Infinity), -Infinity); + +const expectSame = [ + '0x100', '0o100', '0b100', 0x100, -0x100, 0o100, -0o100, 0b100, -0b100, true +]; +expectSame.forEach(function(value) { + assert.strictEqual(toInteger(value), +value, `${value} is not an Integer`); +}); + +const expectIntegers = new Map([ + [[1], 1], [[-1], -1], [['1'], 1], [['-1'], -1], + [3.14, 3], [-3.14, -3], ['3.14', 3], ['-3.14', -3], +]); +expectIntegers.forEach(function(expected, value) { + assert.strictEqual(toInteger(value), expected); +}); diff --git a/test/parallel/test-internal-util-toLength.js b/test/parallel/test-internal-util-toLength.js new file mode 100644 index 00000000000000..ce594c47c1db19 --- /dev/null +++ b/test/parallel/test-internal-util-toLength.js @@ -0,0 +1,35 @@ +// Flags: --expose-internals +'use strict'; + +require('../common'); +const assert = require('assert'); +const {toLength} = require('internal/util'); +const maxValue = Number.MAX_SAFE_INTEGER; + +const expectZero = [ + '0', '-0', NaN, {}, [], {'a': 'b'}, [1, 2], '0x', '0o', '0b', false, + '', ' ', undefined, null, -1, -1.25, -1.1, -1.9, -Infinity +]; +expectZero.forEach(function(value) { + assert.strictEqual(toLength(value), 0); +}); + +assert.strictEqual(toLength(maxValue - 1), maxValue - 1); +assert.strictEqual(maxValue, maxValue); +assert.strictEqual(toLength(Infinity), maxValue); +assert.strictEqual(toLength(maxValue + 1), maxValue); + + +[ + '0x100', '0o100', '0b100', 0x100, -0x100, 0o100, -0o100, 0b100, -0b100, true +].forEach(function(value) { + assert.strictEqual(toLength(value), +value > 0 ? +value : 0); +}); + +const expectIntegers = new Map([ + [[1], 1], [[-1], 0], [['1'], 1], [['-1'], 0], + [3.14, 3], [-3.14, 0], ['3.14', 3], ['-3.14', 0], +]); +expectIntegers.forEach(function(expected, value) { + assert.strictEqual(toLength(value), expected); +}); diff --git a/test/parallel/test-net-connect-local-error.js b/test/parallel/test-net-connect-local-error.js index 197b283bdf3621..2a0c20f6ea4a5e 100644 --- a/test/parallel/test-net-connect-local-error.js +++ b/test/parallel/test-net-connect-local-error.js @@ -10,6 +10,14 @@ var client = net.connect({ }); client.on('error', common.mustCall(function onError(err) { - assert.equal(err.localPort, common.PORT); - assert.equal(err.localAddress, common.localhostIPv4); + assert.strictEqual( + err.localPort, + common.PORT, + `${err.localPort} !== ${common.PORT} in ${err}` + ); + assert.strictEqual( + err.localAddress, + common.localhostIPv4, + `${err.localAddress} !== ${common.localhostIPv4} in ${err}` + ); })); diff --git a/test/parallel/test-npm-install.js b/test/parallel/test-npm-install.js index e72e731ea72ea0..3952088d02edeb 100644 --- a/test/parallel/test-npm-install.js +++ b/test/parallel/test-npm-install.js @@ -49,8 +49,8 @@ const proc = spawn(process.execPath, args, { }); function handleExit(code, signalCode) { - assert.equal(code, 0, 'npm install should run without an error'); - assert.ok(signalCode === null, 'signalCode should be null'); + assert.strictEqual(code, 0, `npm install got error code ${code}`); + assert.strictEqual(signalCode, null, `unexpected signal: ${signalCode}`); assert.doesNotThrow(function() { fs.accessSync(installDir + '/node_modules/package-name'); }); diff --git a/test/parallel/test-os.js b/test/parallel/test-os.js index 5a0a9f6ad14cbc..ce0d2ee054d1f9 100644 --- a/test/parallel/test-os.js +++ b/test/parallel/test-os.js @@ -107,8 +107,8 @@ switch (platform) { const filter = function(e) { return e.address === '127.0.0.1'; }; const actual = interfaces.lo.filter(filter); const expected = [{ address: '127.0.0.1', netmask: '255.0.0.0', - mac: '00:00:00:00:00:00', family: 'IPv4', - internal: true }]; + mac: '00:00:00:00:00:00', family: 'IPv4', + internal: true }]; assert.deepStrictEqual(actual, expected); break; } @@ -117,8 +117,8 @@ switch (platform) { const filter = function(e) { return e.address === '127.0.0.1'; }; const actual = interfaces['Loopback Pseudo-Interface 1'].filter(filter); const expected = [{ address: '127.0.0.1', netmask: '255.0.0.0', - mac: '00:00:00:00:00:00', family: 'IPv4', - internal: true }]; + mac: '00:00:00:00:00:00', family: 'IPv4', + internal: true }]; assert.deepStrictEqual(actual, expected); break; } diff --git a/test/parallel/test-path-parse-format.js b/test/parallel/test-path-parse-format.js index 2db4c27dce072a..aaa92111074099 100644 --- a/test/parallel/test-path-parse-format.js +++ b/test/parallel/test-path-parse-format.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const path = require('path'); @@ -69,23 +69,27 @@ const unixSpecialCaseFormatTests = [ const errors = [ {method: 'parse', input: [null], - message: /Path must be a string. Received null/}, + message: /^TypeError: Path must be a string. Received null$/}, {method: 'parse', input: [{}], - message: /Path must be a string. Received {}/}, + message: /^TypeError: Path must be a string. Received {}$/}, {method: 'parse', input: [true], - message: /Path must be a string. Received true/}, + message: /^TypeError: Path must be a string. Received true$/}, {method: 'parse', input: [1], - message: /Path must be a string. Received 1/}, + message: /^TypeError: Path must be a string. Received 1$/}, {method: 'parse', input: [], - message: /Path must be a string. Received undefined/}, + message: /^TypeError: Path must be a string. Received undefined$/}, {method: 'format', input: [null], - message: /Parameter "pathObject" must be an object, not/}, + message: + /^TypeError: Parameter "pathObject" must be an object, not object$/}, {method: 'format', input: [''], - message: /Parameter "pathObject" must be an object, not string/}, + message: + /^TypeError: Parameter "pathObject" must be an object, not string$/}, {method: 'format', input: [true], - message: /Parameter "pathObject" must be an object, not boolean/}, + message: + /^TypeError: Parameter "pathObject" must be an object, not boolean$/}, {method: 'format', input: [1], - message: /Parameter "pathObject" must be an object, not number/}, + message: + /^TypeError: Parameter "pathObject" must be an object, not number$/}, ]; checkParseFormat(path.win32, winPaths); @@ -158,18 +162,9 @@ assert.equal(failures.length, 0, failures.join('')); function checkErrors(path) { errors.forEach(function(errorCase) { - try { + assert.throws(() => { path[errorCase.method].apply(path, errorCase.input); - } catch (err) { - assert.ok(err instanceof TypeError); - assert.ok( - errorCase.message.test(err.message), - 'expected ' + errorCase.message + ' to match ' + err.message - ); - return; - } - - common.fail('should have thrown'); + }, errorCase.message); }); } diff --git a/test/parallel/test-path.js b/test/parallel/test-path.js index 0a12b5ce92ca75..49d77bd440aa0d 100644 --- a/test/parallel/test-path.js +++ b/test/parallel/test-path.js @@ -10,6 +10,7 @@ const failures = []; // path.basename tests assert.strictEqual(path.basename(f), 'test-path.js'); assert.strictEqual(path.basename(f, '.js'), 'test-path'); +assert.strictEqual(path.basename('.js', '.js'), ''); assert.strictEqual(path.basename(''), ''); assert.strictEqual(path.basename('/dir/basename.ext'), 'basename.ext'); assert.strictEqual(path.basename('/basename.ext'), 'basename.ext'); @@ -59,8 +60,8 @@ assert.strictEqual(path.posix.basename('foo'), 'foo'); // POSIX filenames may include control characters // c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html -const controlCharFilename = 'Icon' + String.fromCharCode(13); -assert.strictEqual(path.posix.basename('/a/b/' + controlCharFilename), +const controlCharFilename = `Icon${String.fromCharCode(13)}`; +assert.strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`), controlCharFilename); @@ -74,6 +75,7 @@ assert.strictEqual(path.posix.dirname('/a'), '/'); assert.strictEqual(path.posix.dirname(''), '.'); assert.strictEqual(path.posix.dirname('/'), '/'); assert.strictEqual(path.posix.dirname('////'), '/'); +assert.strictEqual(path.posix.dirname('//a'), '//'); assert.strictEqual(path.posix.dirname('foo'), '.'); assert.strictEqual(path.win32.dirname('c:\\'), 'c:\\'); @@ -160,8 +162,8 @@ assert.strictEqual(path.win32.dirname('foo'), '.'); ['file//', ''], ['file./', '.'], ['file.//', '.'], -].forEach(function(test) { - [path.posix.extname, path.win32.extname].forEach(function(extname) { +].forEach((test) => { + [path.posix.extname, path.win32.extname].forEach((extname) => { let input = test[0]; let os; if (extname === path.win32.extname) { @@ -208,6 +210,7 @@ const joinTests = [ [ [path.posix.join, path.win32.join], // arguments result [[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'], + [[], '.'], [['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'], [['/foo', '../../../bar'], '/bar'], [['foo', '../../../bar'], '../../bar'], @@ -310,11 +313,11 @@ joinTests.push([ ] ) ]); -joinTests.forEach(function(test) { +joinTests.forEach((test) => { if (!Array.isArray(test[0])) test[0] = [test[0]]; - test[0].forEach(function(join) { - test[1].forEach(function(test) { + test[0].forEach((join) => { + test[1].forEach((test) => { const actual = join.apply(null, test[0]); const expected = test[1]; // For non-Windows specific tests with the Windows join(), we need to try @@ -333,7 +336,7 @@ joinTests.forEach(function(test) { '\n expect=' + JSON.stringify(expected) + '\n actual=' + JSON.stringify(actual); if (actual !== expected && actualAlt !== expected) - failures.push('\n' + message); + failures.push(`\n${message}`); }); }); }); @@ -344,15 +347,15 @@ assert.strictEqual(failures.length, 0, failures.join('')); const typeErrorTests = [true, false, 7, null, {}, undefined, [], NaN]; function fail(fn) { - const args = Array.prototype.slice.call(arguments, 1); + const args = Array.from(arguments).slice(1); - assert.throws(function() { + assert.throws(() => { fn.apply(null, args); }, TypeError); } -typeErrorTests.forEach(function(test) { - [path.posix, path.win32].forEach(function(namespace) { +typeErrorTests.forEach((test) => { + [path.posix, path.win32].forEach((namespace) => { fail(namespace.join, test); fail(namespace.resolve, test); fail(namespace.normalize, test); @@ -396,7 +399,7 @@ assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar'); // path.resolve tests const resolveTests = [ [ path.win32.resolve, - // arguments result + // arguments result [[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'], [['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'], [['c:/ignore', 'c:/some/file'], 'c:\\some\\file'], @@ -413,7 +416,7 @@ const resolveTests = [ ] ], [ path.posix.resolve, - // arguments result + // arguments result [[['/var/lib', '../', 'file/'], '/var/file'], [['/var/lib', '/../', 'file/'], '/file'], [['a/b/c/', '../../..'], process.cwd()], @@ -423,9 +426,9 @@ const resolveTests = [ ] ] ]; -resolveTests.forEach(function(test) { +resolveTests.forEach((test) => { const resolve = test[0]; - test[1].forEach(function(test) { + test[1].forEach((test) => { const actual = resolve.apply(null, test[0]); let actualAlt; const os = resolve === path.win32.resolve ? 'win32' : 'posix'; @@ -514,7 +517,7 @@ const relativeTests = [ ] ], [ path.posix.relative, - // arguments result + // arguments result [['/var/lib', '/var', '..'], ['/var/lib', '/bin', '../../bin'], ['/var/lib', '/var/lib', ''], @@ -530,9 +533,9 @@ const relativeTests = [ ] ] ]; -relativeTests.forEach(function(test) { +relativeTests.forEach((test) => { const relative = test[0]; - test[1].forEach(function(test) { + test[1].forEach((test) => { const actual = relative(test[0], test[1]); const expected = test[2]; const os = relative === path.win32.relative ? 'win32' : 'posix'; @@ -543,7 +546,7 @@ relativeTests.forEach(function(test) { '\n expect=' + JSON.stringify(expected) + '\n actual=' + JSON.stringify(actual); if (actual !== expected) - failures.push('\n' + message); + failures.push(`\n${message}`); }); }); assert.strictEqual(failures.length, 0, failures.join('')); @@ -575,14 +578,14 @@ if (common.isWindows) { // These tests cause resolve() to insert the cwd, so we cannot test them from // non-Windows platforms (easily) assert.strictEqual(path.win32._makeLong('foo\\bar').toLowerCase(), - '\\\\?\\' + process.cwd().toLowerCase() + '\\foo\\bar'); + `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); assert.strictEqual(path.win32._makeLong('foo/bar').toLowerCase(), - '\\\\?\\' + process.cwd().toLowerCase() + '\\foo\\bar'); + `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); const currentDeviceLetter = path.parse(process.cwd()).root.substring(0, 2); assert.strictEqual(path.win32._makeLong(currentDeviceLetter).toLowerCase(), - '\\\\?\\' + process.cwd().toLowerCase()); + `\\\\?\\${process.cwd().toLowerCase()}`); assert.strictEqual(path.win32._makeLong('C').toLowerCase(), - '\\\\?\\' + process.cwd().toLowerCase() + '\\c'); + `\\\\?\\${process.cwd().toLowerCase()}\\c`); } assert.strictEqual(path.win32._makeLong('C:\\foo'), '\\\\?\\C:\\foo'); assert.strictEqual(path.win32._makeLong('C:/foo'), '\\\\?\\C:\\foo'); diff --git a/test/parallel/test-pipe-writev.js b/test/parallel/test-pipe-writev.js new file mode 100644 index 00000000000000..6440b5f623761d --- /dev/null +++ b/test/parallel/test-pipe-writev.js @@ -0,0 +1,46 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +if (common.isWindows) { + common.skip('Unix-specific test'); + return; +} + +common.refreshTmpDir(); + +const server = net.createServer((connection) => { + connection.on('error', (err) => { + throw err; + }); + + const writev = connection._writev.bind(connection); + connection._writev = common.mustCall(writev); + + connection.cork(); + connection.write('pi'); + connection.write('ng'); + connection.end(); +}); + +server.on('error', (err) => { + throw err; +}); + +server.listen(common.PIPE, () => { + const client = net.connect(common.PIPE); + + client.on('error', (err) => { + throw err; + }); + + client.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), 'ping'); + })); + + client.on('end', () => { + server.close(); + }); +}); diff --git a/test/parallel/test-preload.js b/test/parallel/test-preload.js index 4ee564f0520cc5..8cae173f87ae37 100644 --- a/test/parallel/test-preload.js +++ b/test/parallel/test-preload.js @@ -32,43 +32,41 @@ const fixtureD = fixture('define-global.js'); const fixtureThrows = fixture('throws_error4.js'); // test preloading a single module works -childProcess.exec(nodeBinary + ' ' + - preloadOption([fixtureA]) + ' ' + - fixtureB, - function(err, stdout, stderr) { - if (err) throw err; - assert.strictEqual(stdout, 'A\nB\n'); - }); +childProcess.exec(nodeBinary + ' ' + preloadOption([fixtureA]) + ' ' + fixtureB, + function(err, stdout, stderr) { + if (err) throw err; + assert.strictEqual(stdout, 'A\nB\n'); + }); // test preloading multiple modules works -childProcess.exec(nodeBinary + ' ' + - preloadOption([fixtureA, fixtureB]) + ' ' + - fixtureC, +childProcess.exec( + nodeBinary + ' ' + preloadOption([fixtureA, fixtureB]) + ' ' + fixtureC, function(err, stdout, stderr) { if (err) throw err; assert.strictEqual(stdout, 'A\nB\nC\n'); - }); + } +); // test that preloading a throwing module aborts -childProcess.exec(nodeBinary + ' ' + - preloadOption([fixtureA, fixtureThrows]) + ' ' + - fixtureB, +childProcess.exec( + nodeBinary + ' ' + preloadOption([fixtureA, fixtureThrows]) + ' ' + fixtureB, function(err, stdout, stderr) { if (err) { assert.strictEqual(stdout, 'A\n'); } else { throw new Error('Preload should have failed'); } - }); + } +); // test that preload can be used with --eval -childProcess.exec(nodeBinary + ' ' + - preloadOption([fixtureA]) + - '-e "console.log(\'hello\');"', +childProcess.exec( + nodeBinary + ' ' + preloadOption([fixtureA]) + '-e "console.log(\'hello\');"', function(err, stdout, stderr) { if (err) throw err; assert.strictEqual(stdout, 'A\nhello\n'); - }); + } +); // test that preload can be used with stdin const stdinProc = childProcess.spawn( @@ -108,42 +106,43 @@ replProc.on('close', function(code) { // test that preload placement at other points in the cmdline // also test that duplicated preload only gets loaded once -childProcess.exec(nodeBinary + ' ' + - preloadOption([fixtureA]) + - '-e "console.log(\'hello\');" ' + - preloadOption([fixtureA, fixtureB]), +childProcess.exec( + nodeBinary + ' ' + preloadOption([fixtureA]) + + '-e "console.log(\'hello\');" ' + preloadOption([fixtureA, fixtureB]), function(err, stdout, stderr) { if (err) throw err; assert.strictEqual(stdout, 'A\nB\nhello\n'); - }); + } +); // test that preload works with -i -const interactive = childProcess.exec(nodeBinary + ' ' + - preloadOption([fixtureD]) + - '-i', +const interactive = childProcess.exec( + nodeBinary + ' ' + preloadOption([fixtureD]) + '-i', common.mustCall(function(err, stdout, stderr) { assert.ifError(err); assert.strictEqual(stdout, "> 'test'\n> "); - })); + }) +); interactive.stdin.write('a\n'); interactive.stdin.write('process.exit()\n'); -childProcess.exec(nodeBinary + ' ' + - '--require ' + fixture('cluster-preload.js') + ' ' + - fixture('cluster-preload-test.js'), +childProcess.exec( + nodeBinary + ' ' + '--require ' + fixture('cluster-preload.js') + ' ' + + fixture('cluster-preload-test.js'), function(err, stdout, stderr) { if (err) throw err; assert.ok(/worker terminated with code 43/.test(stdout)); - }); + } +); // https://github.com/nodejs/node/issues/1691 process.chdir(common.fixturesDir); -childProcess.exec(nodeBinary + ' ' + - '--expose_debug_as=v8debug ' + - '--require ' + fixture('cluster-preload.js') + ' ' + - 'cluster-preload-test.js', +childProcess.exec( + nodeBinary + ' ' + '--expose_natives_as=v8natives ' + '--require ' + + fixture('cluster-preload.js') + ' ' + 'cluster-preload-test.js', function(err, stdout, stderr) { if (err) throw err; assert.ok(/worker terminated with code 43/.test(stdout)); - }); + } +); diff --git a/test/parallel/test-process-assert.js b/test/parallel/test-process-assert.js new file mode 100644 index 00000000000000..e386c3d7600c06 --- /dev/null +++ b/test/parallel/test-process-assert.js @@ -0,0 +1,11 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +assert.strictEqual(process.assert(1, 'error'), undefined); +assert.throws(() => { + process.assert(undefined, 'errorMessage'); +}, /^Error: errorMessage$/); +assert.throws(() => { + process.assert(false); +}, /^Error: assertion error$/); diff --git a/test/parallel/test-process-cpuUsage.js b/test/parallel/test-process-cpuUsage.js index 92dc71918585c3..0c553c576a1f25 100644 --- a/test/parallel/test-process-cpuUsage.js +++ b/test/parallel/test-process-cpuUsage.js @@ -33,27 +33,57 @@ for (let i = 0; i < 10; i++) { assert(diffUsage.system >= 0); } +const invalidUserArgument = + /^TypeError: value of user property of argument is invalid$/; +const invalidSystemArgument = + /^TypeError: value of system property of argument is invalid$/; + // Ensure that an invalid shape for the previous value argument throws an error. -assert.throws(function() { process.cpuUsage(1); }); -assert.throws(function() { process.cpuUsage({}); }); -assert.throws(function() { process.cpuUsage({ user: 'a' }); }); -assert.throws(function() { process.cpuUsage({ system: 'b' }); }); -assert.throws(function() { process.cpuUsage({ user: null, system: 'c' }); }); -assert.throws(function() { process.cpuUsage({ user: 'd', system: null }); }); -assert.throws(function() { process.cpuUsage({ user: -1, system: 2 }); }); -assert.throws(function() { process.cpuUsage({ user: 3, system: -2 }); }); -assert.throws(function() { +assert.throws(() => { + process.cpuUsage(1); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({}); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({ user: 'a' }); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({ system: 'b' }); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({ user: null, system: 'c' }); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({ user: 'd', system: null }); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({ user: -1, system: 2 }); +}, invalidUserArgument); + +assert.throws(() => { + process.cpuUsage({ user: 3, system: -2 }); +}, invalidSystemArgument); + +assert.throws(() => { process.cpuUsage({ user: Number.POSITIVE_INFINITY, system: 4 }); -}); -assert.throws(function() { +}, invalidUserArgument); + +assert.throws(() => { process.cpuUsage({ user: 5, system: Number.NEGATIVE_INFINITY }); -}); +}, invalidSystemArgument); // Ensure that the return value is the expected shape. function validateResult(result) { diff --git a/test/parallel/test-process-hrtime.js b/test/parallel/test-process-hrtime.js index db16be0ad9e812..9280b671f316d6 100644 --- a/test/parallel/test-process-hrtime.js +++ b/test/parallel/test-process-hrtime.js @@ -3,7 +3,7 @@ require('../common'); var assert = require('assert'); // the default behavior, return an Array "tuple" of numbers -var tuple = process.hrtime(); +const tuple = process.hrtime(); // validate the default behavior validateTuple(tuple); @@ -12,16 +12,16 @@ validateTuple(tuple); validateTuple(process.hrtime(tuple)); // test that only an Array may be passed to process.hrtime() -assert.throws(function() { +assert.throws(() => { process.hrtime(1); -}); +}, /^TypeError: process.hrtime\(\) only accepts an Array tuple$/); function validateTuple(tuple) { assert(Array.isArray(tuple)); - assert.equal(2, tuple.length); - tuple.forEach(function(v) { - assert.equal('number', typeof v); - assert(isFinite(v)); + assert.strictEqual(tuple.length, 2); + tuple.forEach((v) => { + assert.strictEqual(typeof v, 'number'); + assert.strictEqual(isFinite(v), true); }); } diff --git a/test/parallel/test-punycode.js b/test/parallel/test-punycode.js index e869e6a33bf064..5a41d5433dd443 100644 --- a/test/parallel/test-punycode.js +++ b/test/parallel/test-punycode.js @@ -6,18 +6,33 @@ const assert = require('assert'); assert.strictEqual(punycode.encode('ü'), 'tda'); assert.strictEqual(punycode.encode('Goethe'), 'Goethe-'); assert.strictEqual(punycode.encode('Bücher'), 'Bcher-kva'); -assert.strictEqual(punycode.encode( - 'Willst du die Blüthe des frühen, die Früchte des späteren Jahres'), - 'Willst du die Blthe des frhen, die Frchte des spteren Jahres-x9e96lkal'); +assert.strictEqual( + punycode.encode( + 'Willst du die Blüthe des frühen, die Früchte des späteren Jahres' + ), + 'Willst du die Blthe des frhen, die Frchte des spteren Jahres-x9e96lkal' +); assert.strictEqual(punycode.encode('日本語'), 'wgv71a119e'); assert.strictEqual(punycode.decode('tda'), 'ü'); assert.strictEqual(punycode.decode('Goethe-'), 'Goethe'); assert.strictEqual(punycode.decode('Bcher-kva'), 'Bücher'); -assert.strictEqual(punycode.decode( - 'Willst du die Blthe des frhen, die Frchte des spteren Jahres-x9e96lkal'), - 'Willst du die Blüthe des frühen, die Früchte des späteren Jahres'); +assert.strictEqual( + punycode.decode( + 'Willst du die Blthe des frhen, die Frchte des spteren Jahres-x9e96lkal' + ), + 'Willst du die Blüthe des frühen, die Früchte des späteren Jahres' +); assert.strictEqual(punycode.decode('wgv71a119e'), '日本語'); +assert.throws(() => { + punycode.decode(' '); +}, /^RangeError: Invalid input$/); +assert.throws(() => { + punycode.decode('α-'); +}, /^RangeError: Illegal input >= 0x80 \(not a basic code point\)$/); +assert.throws(() => { + punycode.decode('あ'); +}, /^RangeError: Overflow: input needs wider integers to process$/); // http://tools.ietf.org/html/rfc3492#section-7.1 const tests = [ @@ -222,3 +237,9 @@ assert.strictEqual(punycode.ucs2.encode([0xDC00]), '\uDC00'); assert.strictEqual(punycode.ucs2.encode([0xDC00, 0x61, 0x62]), '\uDC00ab'); assert.strictEqual(errors, 0); + +// test map domain +assert.strictEqual(punycode.toASCII('Bücher@日本語.com'), + 'Bücher@xn--wgv71a119e.com'); +assert.strictEqual(punycode.toUnicode('Bücher@xn--wgv71a119e.com'), + 'Bücher@日本語.com'); diff --git a/test/parallel/test-querystring-escape.js b/test/parallel/test-querystring-escape.js index 94f40980bcf818..17073a66bda35a 100644 --- a/test/parallel/test-querystring-escape.js +++ b/test/parallel/test-querystring-escape.js @@ -8,6 +8,7 @@ assert.deepStrictEqual(qs.escape(5), '5'); assert.deepStrictEqual(qs.escape('test'), 'test'); assert.deepStrictEqual(qs.escape({}), '%5Bobject%20Object%5D'); assert.deepStrictEqual(qs.escape([5, 10]), '5%2C10'); +assert.deepStrictEqual(qs.escape('Ŋōđĕ'), '%C5%8A%C5%8D%C4%91%C4%95'); // using toString for objects assert.strictEqual( diff --git a/test/parallel/test-querystring.js b/test/parallel/test-querystring.js index 37cf66705d56d7..6247235e967ac2 100644 --- a/test/parallel/test-querystring.js +++ b/test/parallel/test-querystring.js @@ -44,11 +44,11 @@ var qsTestCases = [ ['foo=%EF%BF%BD', 'foo=%EF%BF%BD', {'foo': '\ufffd' }], // See: https://github.com/joyent/node/issues/1707 ['hasOwnProperty=x&toString=foo&valueOf=bar&__defineGetter__=baz', - 'hasOwnProperty=x&toString=foo&valueOf=bar&__defineGetter__=baz', - { hasOwnProperty: 'x', - toString: 'foo', - valueOf: 'bar', - __defineGetter__: 'baz' }], + 'hasOwnProperty=x&toString=foo&valueOf=bar&__defineGetter__=baz', + { hasOwnProperty: 'x', + toString: 'foo', + valueOf: 'bar', + __defineGetter__: 'baz' }], // See: https://github.com/joyent/node/issues/3058 ['foo&bar=baz', 'foo=&bar=baz', { foo: '', bar: 'baz' }], [null, '', {}], @@ -95,12 +95,27 @@ var qsNoMungeTestCases = [ ['foo=bar&foo=baz', {'foo': ['bar', 'baz']}], ['foo=bar&foo=baz', foreignObject], ['blah=burp', {'blah': 'burp'}], + ['a=!-._~\'()*', {'a': '!-._~\'()*'}], + ['a=abcdefghijklmnopqrstuvwxyz', {'a': 'abcdefghijklmnopqrstuvwxyz'}], + ['a=ABCDEFGHIJKLMNOPQRSTUVWXYZ', {'a': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}], + ['a=0123456789', {'a': '0123456789'}], ['gragh=1&gragh=3&goo=2', {'gragh': ['1', '3'], 'goo': '2'}], ['frappucino=muffin&goat%5B%5D=scone&pond=moose', {'frappucino': 'muffin', 'goat[]': 'scone', 'pond': 'moose'}], ['trololol=yes&lololo=no', {'trololol': 'yes', 'lololo': 'no'}] ]; +const qsUnescapeTestCases = [ + ['there is nothing to unescape here', + 'there is nothing to unescape here'], + ['there%20are%20several%20spaces%20that%20need%20to%20be%20unescaped', + 'there are several spaces that need to be unescaped'], + ['there%2Qare%0-fake%escaped values in%%%%this%9Hstring', + 'there%2Qare%0-fake%escaped values in%%%%this%9Hstring'], + ['%20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F%30%31%32%33%34%35%36%37', + ' !"#$%&\'()*+,-./01234567'] +]; + assert.strictEqual('918854443121279438895193', qs.parse('id=918854443121279438895193').id); @@ -220,8 +235,20 @@ assert.doesNotThrow(function() { assert.equal(f, 'a:b;q:x%3Ay%3By%3Az'); } +// empty string +assert.strictEqual(qs.stringify(), ''); +assert.strictEqual(qs.stringify(0), ''); +assert.strictEqual(qs.stringify([]), ''); +assert.strictEqual(qs.stringify(null), ''); +assert.strictEqual(qs.stringify(true), ''); + check(qs.parse(), {}); +// empty sep +check(qs.parse('a', []), { a: '' }); + +// empty eq +check(qs.parse('a', null, []), { '': 'a' }); // Test limiting assert.equal( @@ -267,6 +294,13 @@ assert.equal(0xd8, b[17]); assert.equal(0xa2, b[18]); assert.equal(0xe6, b[19]); +assert.strictEqual(qs.unescapeBuffer('a+b', true).toString(), 'a b'); +assert.strictEqual(qs.unescapeBuffer('a%').toString(), 'a%'); +assert.strictEqual(qs.unescapeBuffer('a%2').toString(), 'a%2'); +assert.strictEqual(qs.unescapeBuffer('a%20').toString(), 'a '); +assert.strictEqual(qs.unescapeBuffer('a%2g').toString(), 'a%2g'); +assert.strictEqual(qs.unescapeBuffer('a%%').toString(), 'a%%'); + // Test custom decode function demoDecode(str) { @@ -275,6 +309,12 @@ function demoDecode(str) { check(qs.parse('a=a&b=b&c=c', null, null, { decodeURIComponent: demoDecode }), { aa: 'aa', bb: 'bb', cc: 'cc' }); +// Test QueryString.unescape +function errDecode(str) { + throw new Error('To jump to the catch scope'); +} +check(qs.parse('a=a', null, null, { decodeURIComponent: errDecode }), + { a: 'a' }); // Test custom encode function demoEncode(str) { @@ -285,6 +325,12 @@ assert.equal( qs.stringify(obj, null, null, { encodeURIComponent: demoEncode }), 'a=a&b=b&c=c'); +// Test QueryString.unescapeBuffer +qsUnescapeTestCases.forEach(function(testCase) { + assert.strictEqual(qs.unescape(testCase[0]), testCase[1]); + assert.strictEqual(qs.unescapeBuffer(testCase[0]).toString(), testCase[1]); +}); + // test overriding .unescape var prevUnescape = qs.unescape; qs.unescape = function(str) { diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index df516ccc5c3e39..96f67c320e1789 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -60,7 +60,7 @@ function isWarned(emitter) { // disable history fi = new FakeInput(); rli = new readline.Interface({ input: fi, output: fi, terminal: terminal, - historySize: 0 }); + historySize: 0 }); assert.strictEqual(rli.historySize, 0); fi.emit('data', 'asdf\n'); diff --git a/test/parallel/test-readline-keys.js b/test/parallel/test-readline-keys.js index 6bbbb2e918470d..85e3f4df6ff917 100644 --- a/test/parallel/test-readline-keys.js +++ b/test/parallel/test-readline-keys.js @@ -1,10 +1,10 @@ 'use strict'; -require('../common'); -var PassThrough = require('stream').PassThrough; -var assert = require('assert'); -var inherits = require('util').inherits; -var extend = require('util')._extend; -var Interface = require('readline').Interface; +const common = require('../common'); +const PassThrough = require('stream').PassThrough; +const assert = require('assert'); +const inherits = require('util').inherits; +const extend = require('util')._extend; +const Interface = require('readline').Interface; function FakeInput() { @@ -55,7 +55,7 @@ function addTest(sequences, expectedKeys) { const addKeyIntervalTest = (sequences, expectedKeys, interval = 550, assertDelay = 550) => { - return (next) => () => { + const fn = common.mustCall((next) => () => { if (!Array.isArray(sequences)) { sequences = [ sequences ]; @@ -84,7 +84,8 @@ const addKeyIntervalTest = (sequences, expectedKeys, interval = 550, } }; emitKeys(sequences); - }; + }); + return fn; }; // regular alphanumerics diff --git a/test/parallel/test-regress-GH-11480.js b/test/parallel/test-regress-GH-11480.js new file mode 100644 index 00000000000000..bd536e5e7b25eb --- /dev/null +++ b/test/parallel/test-regress-GH-11480.js @@ -0,0 +1,14 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +// https://github.com/nodejs/node/issues/11480 +// This code should not throw a SyntaxError. + +const a = 1; +const b = 1; +let c; + +((a + 1), {c} = b); + +assert.strictEqual(c, undefined); diff --git a/test/parallel/test-repl-require-context.js b/test/parallel/test-repl-require-context.js index 798d6f2db30f49..51a7339773a31e 100644 --- a/test/parallel/test-repl-require-context.js +++ b/test/parallel/test-repl-require-context.js @@ -14,10 +14,7 @@ child.stdout.on('data', (data) => { }); child.on('exit', common.mustCall(() => { - const results = output.split('\n').map((line) => { - return line.replace(/\w*>\w*/, '').trim(); - }); - + const results = output.replace(/^> /mg, '').split('\n'); assert.deepStrictEqual(results, ['undefined', 'true', 'true', '']); })); diff --git a/test/parallel/test-repl-sigint-nested-eval.js b/test/parallel/test-repl-sigint-nested-eval.js index 1bb09ba3963f3e..030c86be8e8dd4 100644 --- a/test/parallel/test-repl-sigint-nested-eval.js +++ b/test/parallel/test-repl-sigint-nested-eval.js @@ -17,18 +17,10 @@ const child = spawn(process.execPath, [ '-i' ], { let stdout = ''; child.stdout.setEncoding('utf8'); -child.stdout.pipe(process.stdout); child.stdout.on('data', function(c) { stdout += c; }); -child.stdin.write = ((original) => { - return (chunk) => { - process.stderr.write(chunk); - return original.call(child.stdin, chunk); - }; -})(child.stdin.write); - child.stdout.once('data', common.mustCall(() => { process.on('SIGUSR2', common.mustCall(() => { process.kill(child.pid, 'SIGINT'); @@ -45,6 +37,12 @@ child.stdout.once('data', common.mustCall(() => { child.on('close', function(code) { assert.strictEqual(code, 0); - assert.notStrictEqual(stdout.indexOf('Script execution interrupted.'), -1); - assert.notStrictEqual(stdout.indexOf('foobar'), -1); + assert.ok( + stdout.includes('Script execution interrupted.'), + `Expected stdout to contain "Script execution interrupted.", got ${stdout}` + ); + assert.ok( + stdout.includes('foobar'), + `Expected stdout to contain "foobar", got ${stdout}` + ); }); diff --git a/test/parallel/test-repl-sigint.js b/test/parallel/test-repl-sigint.js index 5ee974aaea340e..61bc75cc6ffe67 100644 --- a/test/parallel/test-repl-sigint.js +++ b/test/parallel/test-repl-sigint.js @@ -17,18 +17,10 @@ const child = spawn(process.execPath, [ '-i' ], { let stdout = ''; child.stdout.setEncoding('utf8'); -child.stdout.pipe(process.stdout); child.stdout.on('data', function(c) { stdout += c; }); -child.stdin.write = ((original) => { - return (chunk) => { - process.stderr.write(chunk); - return original.call(child.stdin, chunk); - }; -})(child.stdin.write); - child.stdout.once('data', common.mustCall(() => { process.on('SIGUSR2', common.mustCall(() => { process.kill(child.pid, 'SIGINT'); @@ -45,6 +37,12 @@ child.stdout.once('data', common.mustCall(() => { child.on('close', function(code) { assert.strictEqual(code, 0); - assert.notStrictEqual(stdout.indexOf('Script execution interrupted.\n'), -1); - assert.notStrictEqual(stdout.indexOf('42042\n'), -1); + assert.ok( + stdout.includes('Script execution interrupted.\n'), + `Expected stdout to contain "Script execution interrupted.", got ${stdout}` + ); + assert.ok( + stdout.includes('42042\n'), + `Expected stdout to contain "42042", got ${stdout}` + ); }); diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index dfda790c439d97..58201f7446f365 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -231,6 +231,7 @@ putIn.run([ testMe.complete('proxy.', common.mustCall(function(error, data) { assert.strictEqual(error, null); + assert(Array.isArray(data)); })); // Make sure tab completion does not include integer members of an Array @@ -290,7 +291,7 @@ const testNonGlobal = repl.start({ }); const builtins = [['Infinity', '', 'Int16Array', 'Int32Array', - 'Int8Array'], 'I']; + 'Int8Array'], 'I']; if (typeof Intl === 'object') { builtins[0].push('Intl'); @@ -307,9 +308,7 @@ const testCustomCompleterSyncMode = repl.start({ input: putIn, output: putIn, completer: function completer(line) { - const hits = customCompletions.filter((c) => { - return c.indexOf(line) === 0; - }); + const hits = customCompletions.filter((c) => c.startsWith(line)); // Show all completions if none found. return [hits.length ? hits : customCompletions, line]; } @@ -339,9 +338,7 @@ const testCustomCompleterAsyncMode = repl.start({ input: putIn, output: putIn, completer: function completer(line, callback) { - const hits = customCompletions.filter((c) => { - return c.indexOf(line) === 0; - }); + const hits = customCompletions.filter((c) => c.startsWith(line)); // Show all completions if none found. callback(null, [hits.length ? hits : customCompletions, line]); } diff --git a/test/parallel/test-repl-underscore.js b/test/parallel/test-repl-underscore.js index 97fc508ad9eee4..91f32223e180b9 100644 --- a/test/parallel/test-repl-underscore.js +++ b/test/parallel/test-repl-underscore.js @@ -8,6 +8,7 @@ const stream = require('stream'); testSloppyMode(); testStrictMode(); testResetContext(); +testResetContextGlobal(); testMagicMode(); function testSloppyMode() { @@ -131,7 +132,28 @@ function testResetContext() { ]); } -function initRepl(mode) { +function testResetContextGlobal() { + const r = initRepl(repl.REPL_MODE_STRICT, true); + + r.write(`_ = 10; // explicitly set to 10 + _; // 10 from user input + .clear // No output because useGlobal is true + _; // remains 10 + `); + + assertOutput(r.output, [ + 'Expression assignment to _ now disabled.', + '10', + '10', + '10', + ]); + + // delete globals leaked by REPL when `useGlobal` is `true` + delete global.module; + delete global.require; +} + +function initRepl(mode, useGlobal) { const inputStream = new stream.PassThrough(); const outputStream = new stream.PassThrough(); outputStream.accum = ''; @@ -146,7 +168,8 @@ function initRepl(mode) { useColors: false, terminal: false, prompt: '', - replMode: mode + replMode: mode, + useGlobal: useGlobal }); } diff --git a/test/parallel/test-require-symlink.js b/test/parallel/test-require-symlink.js index 38139ef1cfc57d..faa26bfa41cd90 100644 --- a/test/parallel/test-require-symlink.js +++ b/test/parallel/test-require-symlink.js @@ -10,13 +10,15 @@ const spawn = require('child_process').spawn; common.refreshTmpDir(); const linkTarget = path.join(common.fixturesDir, - '/module-require-symlink/node_modules/dep2/'); + '/module-require-symlink/node_modules/dep2/'); -const linkDir = path.join(common.fixturesDir, - '/module-require-symlink/node_modules/dep1/node_modules/dep2'); +const linkDir = path.join( + common.fixturesDir, + '/module-require-symlink/node_modules/dep1/node_modules/dep2' +); const linkScriptTarget = path.join(common.fixturesDir, - '/module-require-symlink/symlinked.js'); + '/module-require-symlink/symlinked.js'); const linkScript = path.join(common.tmpDir, 'module-require-symlink.js'); diff --git a/test/parallel/test-spawn-cmd-named-pipe.js b/test/parallel/test-spawn-cmd-named-pipe.js index c463bf6140053f..b4264880165d39 100644 --- a/test/parallel/test-spawn-cmd-named-pipe.js +++ b/test/parallel/test-spawn-cmd-named-pipe.js @@ -43,7 +43,7 @@ if (!process.argv[2]) { } const args = ['/c', process.execPath, __filename, 'child', - '<', stdinPipeName, '>', stdoutPipeName]; + '<', stdinPipeName, '>', stdoutPipeName]; const child = spawn(comspec, args); diff --git a/test/parallel/test-stdio-closed.js b/test/parallel/test-stdio-closed.js index a85467f76a6d0f..98e4f980d50dd6 100644 --- a/test/parallel/test-stdio-closed.js +++ b/test/parallel/test-stdio-closed.js @@ -2,6 +2,7 @@ const common = require('../common'); const assert = require('assert'); const spawn = require('child_process').spawn; +const fs = require('fs'); if (common.isWindows) { common.skip('platform not supported.'); @@ -9,21 +10,7 @@ if (common.isWindows) { } if (process.argv[2] === 'child') { - try { - process.stdout.write('stdout', function() { - try { - process.stderr.write('stderr', function() { - process.exit(42); - }); - } catch (e) { - process.exit(84); - } - }); - } catch (e) { - assert.strictEqual(e.code, 'EBADF'); - assert.strictEqual(e.message, 'EBADF: bad file descriptor, write'); - process.exit(126); - } + [0, 1, 2].forEach((i) => assert.doesNotThrow(() => fs.fstatSync(i))); return; } @@ -32,5 +19,5 @@ const cmd = `"${process.execPath}" "${__filename}" child 1>&- 2>&-`; const proc = spawn('/bin/sh', ['-c', cmd], { stdio: 'inherit' }); proc.on('exit', common.mustCall(function(exitCode) { - assert.strictEqual(exitCode, common.isAix ? 126 : 42); + assert.strictEqual(exitCode, 0); })); diff --git a/test/parallel/test-stream-duplex.js b/test/parallel/test-stream-duplex.js index 85438c09fdff88..0b71b3d9a50569 100644 --- a/test/parallel/test-stream-duplex.js +++ b/test/parallel/test-stream-duplex.js @@ -5,27 +5,28 @@ const Duplex = require('stream').Transform; const stream = new Duplex({ objectMode: true }); +assert(Duplex() instanceof Duplex); assert(stream._readableState.objectMode); assert(stream._writableState.objectMode); let written; let read; -stream._write = function(obj, _, cb) { +stream._write = (obj, _, cb) => { written = obj; cb(); }; -stream._read = function() {}; +stream._read = () => {}; -stream.on('data', function(obj) { +stream.on('data', (obj) => { read = obj; }); stream.push({ val: 1 }); stream.end({ val: 2 }); -process.on('exit', function() { +process.on('exit', () => { assert.strictEqual(read.val, 1); assert.strictEqual(written.val, 2); }); diff --git a/test/parallel/test-stream-end-paused.js b/test/parallel/test-stream-end-paused.js index 3c46d49ea65d65..4b585fdb999890 100644 --- a/test/parallel/test-stream-end-paused.js +++ b/test/parallel/test-stream-end-paused.js @@ -21,7 +21,7 @@ stream.pause(); setTimeout(common.mustCall(function() { stream.on('end', common.mustCall(function() {})); stream.resume(); -})); +}), 1); process.on('exit', function() { assert(calledRead); diff --git a/test/parallel/test-stream-pipe-await-drain-manual-resume.js b/test/parallel/test-stream-pipe-await-drain-manual-resume.js index 33540b47b3d5e3..96360429e58856 100644 --- a/test/parallel/test-stream-pipe-await-drain-manual-resume.js +++ b/test/parallel/test-stream-pipe-await-drain-manual-resume.js @@ -1,6 +1,7 @@ 'use strict'; const common = require('../common'); const stream = require('stream'); +const assert = require('assert'); // A consumer stream with a very low highWaterMark, which starts in a state // where it buffers the chunk it receives rather than indicating that they @@ -26,6 +27,11 @@ const readable = new stream.Readable({ readable.pipe(writable); readable.once('pause', common.mustCall(() => { + assert.strictEqual( + readable._readableState.awaitDrain, + 1, + 'awaitDrain doesn\'t increase' + ); // First pause, resume manually. The next write() to writable will still // return false, because chunks are still being buffered, so it will increase // the awaitDrain counter again. @@ -34,6 +40,11 @@ readable.once('pause', common.mustCall(() => { })); readable.once('pause', common.mustCall(() => { + assert.strictEqual( + readable._readableState.awaitDrain, + 1, + '.resume() does not reset counter' + ); // Second pause, handle all chunks from now on. Once all callbacks that // are currently queued up are handled, the awaitDrain drain counter should // fall back to 0 and all chunks that are pending on the readable side @@ -50,5 +61,10 @@ readable.push(Buffer.alloc(100)); // Should get through to the writable. readable.push(null); writable.on('finish', common.mustCall(() => { + assert.strictEqual( + readable._readableState.awaitDrain, + 0, + 'awaitDrain not 0 after all chunks are written' + ); // Everything okay, all chunks were written. })); diff --git a/test/parallel/test-stream-pipe-await-drain-push-while-write.js b/test/parallel/test-stream-pipe-await-drain-push-while-write.js index 1dfdfdb80c8d71..67a8f304c31614 100644 --- a/test/parallel/test-stream-pipe-await-drain-push-while-write.js +++ b/test/parallel/test-stream-pipe-await-drain-push-while-write.js @@ -1,16 +1,34 @@ 'use strict'; const common = require('../common'); const stream = require('stream'); +const assert = require('assert'); + +const awaitDrainStates = [ + 1, // after first chunk before callback + 1, // after second chunk before callback + 0 // resolving chunk pushed after first chunk, awaitDrain is decreased +]; // A writable stream which pushes data onto the stream which pipes into it, // but only the first time it's written to. Since it's not paused at this time, // a second write will occur. If the pipe increases awaitDrain twice, we'll // never get subsequent chunks because 'drain' is only emitted once. const writable = new stream.Writable({ - write: common.mustCall((chunk, encoding, cb) => { + write: common.mustCall(function(chunk, encoding, cb) { if (chunk.length === 32 * 1024) { // first chunk - readable.push(new Buffer(33 * 1024)); // above hwm + const beforePush = readable._readableState.awaitDrain; + readable.push(new Buffer(34 * 1024)); // above hwm + // We should check if awaitDrain counter is increased. + const afterPush = readable._readableState.awaitDrain; + assert.strictEqual(afterPush - beforePush, 1, + 'Counter is not increased for awaitDrain'); } + + assert.strictEqual( + awaitDrainStates.shift(), + readable._readableState.awaitDrain, + 'State variable awaitDrain is not correct.' + ); cb(); }, 3) }); diff --git a/test/parallel/test-stream-pipe-await-drain.js b/test/parallel/test-stream-pipe-await-drain.js index fba99ed4563c14..fc822bb60b7aa8 100644 --- a/test/parallel/test-stream-pipe-await-drain.js +++ b/test/parallel/test-stream-pipe-await-drain.js @@ -1,12 +1,14 @@ 'use strict'; const common = require('../common'); const stream = require('stream'); +const assert = require('assert'); // This is very similar to test-stream-pipe-cleanup-pause.js. const reader = new stream.Readable(); const writer1 = new stream.Writable(); const writer2 = new stream.Writable(); +const writer3 = new stream.Writable(); // 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false @@ -19,7 +21,10 @@ writer1._write = common.mustCall(function(chunk, encoding, cb) { this.emit('chunk-received'); cb(); }, 1); + writer1.once('chunk-received', function() { + assert.strictEqual(reader._readableState.awaitDrain, 0, + 'initial value is not 0'); setImmediate(function() { // This one should *not* get through to writer1 because writer2 is not // "done" processing. @@ -29,12 +34,26 @@ writer1.once('chunk-received', function() { // A "slow" consumer: writer2._write = common.mustCall(function(chunk, encoding, cb) { + assert.strictEqual( + reader._readableState.awaitDrain, 1, + 'awaitDrain isn\'t 1 after first push' + ); // Not calling cb here to "simulate" slow stream. + // This should be called exactly once, since the first .write() call + // will return false. +}, 1); +writer3._write = common.mustCall(function(chunk, encoding, cb) { + assert.strictEqual( + reader._readableState.awaitDrain, 2, + 'awaitDrain isn\'t 2 after second push' + ); + // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call // will return false. }, 1); reader.pipe(writer1); reader.pipe(writer2); +reader.pipe(writer3); reader.push(buffer); diff --git a/test/parallel/test-stream-readable-event.js b/test/parallel/test-stream-readable-event.js index a20fc2ee732d0f..a8536bdcbab861 100644 --- a/test/parallel/test-stream-readable-event.js +++ b/test/parallel/test-stream-readable-event.js @@ -20,7 +20,7 @@ const Readable = require('stream').Readable; // we're testing what we think we are assert(!r._readableState.reading); r.on('readable', common.mustCall(function() {})); - }); + }, 1); } { @@ -40,7 +40,7 @@ const Readable = require('stream').Readable; // assert we're testing what we think we are assert(r._readableState.reading); r.on('readable', common.mustCall(function() {})); - }); + }, 1); } { @@ -60,5 +60,5 @@ const Readable = require('stream').Readable; // assert we're testing what we think we are assert(!r._readableState.reading); r.on('readable', common.mustCall(function() {})); - }); + }, 1); } diff --git a/test/parallel/test-stream-transform-objectmode-falsey-value.js b/test/parallel/test-stream-transform-objectmode-falsey-value.js index 429cc1c960eefb..5291a4b7fe89a0 100644 --- a/test/parallel/test-stream-transform-objectmode-falsey-value.js +++ b/test/parallel/test-stream-transform-objectmode-falsey-value.js @@ -30,4 +30,4 @@ var int = setInterval(function() { } else { src.write(i++); } -}); +}, 1); diff --git a/test/parallel/test-stream2-large-read-stall.js b/test/parallel/test-stream2-large-read-stall.js index 823407d396afb6..91eb716cfa8e2a 100644 --- a/test/parallel/test-stream2-large-read-stall.js +++ b/test/parallel/test-stream2-large-read-stall.js @@ -32,7 +32,9 @@ r.on('readable', function() { rs.length); }); -r.on('end', common.mustCall(function() {})); +r.on('end', common.mustCall(function() { + assert.strictEqual(pushes, PUSHCOUNT + 1); +})); var pushes = 0; function push() { @@ -46,9 +48,5 @@ function push() { console.error(' push #%d', pushes); if (r.push(Buffer.allocUnsafe(PUSHSIZE))) - setTimeout(push); + setTimeout(push, 1); } - -process.on('exit', function() { - assert.equal(pushes, PUSHCOUNT + 1); -}); diff --git a/test/parallel/test-stream2-readable-non-empty-end.js b/test/parallel/test-stream2-readable-non-empty-end.js index c08cc287ce1cbf..dd2cb8d51055c7 100644 --- a/test/parallel/test-stream2-readable-non-empty-end.js +++ b/test/parallel/test-stream2-readable-non-empty-end.js @@ -16,7 +16,7 @@ test._read = function(size) { var chunk = chunks[n++]; setTimeout(function() { test.push(chunk === undefined ? null : chunk); - }); + }, 1); }; test.on('end', thrower); @@ -31,7 +31,7 @@ test.on('readable', function() { if (res) { bytesread += res.length; console.error('br=%d len=%d', bytesread, len); - setTimeout(next); + setTimeout(next, 1); } test.read(0); }); diff --git a/test/parallel/test-stream2-readable-wrap.js b/test/parallel/test-stream2-readable-wrap.js index 0cbd106d5b4b35..3bbd5ef0809dcd 100644 --- a/test/parallel/test-stream2-readable-wrap.js +++ b/test/parallel/test-stream2-readable-wrap.js @@ -58,7 +58,7 @@ function runTest(highWaterMark, objectMode, produce) { w._write = function(chunk, encoding, cb) { console.log('_write', chunk); written.push(chunk); - setTimeout(cb); + setTimeout(cb, 1); }; w.on('finish', function() { diff --git a/test/parallel/test-string-decoder-end.js b/test/parallel/test-string-decoder-end.js index 33b47a034a93bc..4769d880cf8d34 100644 --- a/test/parallel/test-string-decoder-end.js +++ b/test/parallel/test-string-decoder-end.js @@ -8,15 +8,11 @@ var assert = require('assert'); var SD = require('string_decoder').StringDecoder; var encodings = ['base64', 'hex', 'utf8', 'utf16le', 'ucs2']; -var bufs = [ '☃💩', 'asdf' ].map(function(b) { - return Buffer.from(b); -}); +const bufs = [ '☃💩', 'asdf' ].map((b) => Buffer.from(b)); // also test just arbitrary bytes from 0-15. -for (var i = 1; i <= 16; i++) { - var bytes = new Array(i).join('.').split('.').map(function(_, j) { - return j + 0x78; - }); +for (let i = 1; i <= 16; i++) { + const bytes = new Array(i).join('.').split('.').map((_, j) => j + 0x78); bufs.push(Buffer.from(bytes)); } @@ -25,7 +21,7 @@ encodings.forEach(testEncoding); console.log('ok'); function testEncoding(encoding) { - bufs.forEach(function(buf) { + bufs.forEach((buf) => { testBuf(encoding, buf); }); } diff --git a/test/parallel/test-string-decoder.js b/test/parallel/test-string-decoder.js index 151ae8b4e0b11a..4cdd235fbaa191 100644 --- a/test/parallel/test-string-decoder.js +++ b/test/parallel/test-string-decoder.js @@ -87,6 +87,9 @@ assert.strictEqual(decoder.write(Buffer.from('F1', 'hex')), ''); assert.strictEqual(decoder.write(Buffer.from('41F2', 'hex')), '\ufffdA'); assert.strictEqual(decoder.end(), '\ufffd'); +// Additional utf8Text test +decoder = new StringDecoder('utf8'); +assert.strictEqual(decoder.text(Buffer.from([0x41]), 2), ''); // Additional UTF-16LE surrogate pair tests decoder = new StringDecoder('utf16le'); @@ -104,6 +107,14 @@ assert.strictEqual(decoder.write(Buffer.from('3DD8', 'hex')), ''); assert.strictEqual(decoder.write(Buffer.from('4D', 'hex')), ''); assert.strictEqual(decoder.end(), '\ud83d'); +assert.throws(() => { + new StringDecoder(1); +}, /^Error: Unknown encoding: 1$/); + +assert.throws(() => { + new StringDecoder('test'); +}, /^Error: Unknown encoding: test$/); + // test verifies that StringDecoder will correctly decode the given input // buffer with the given encoding to the expected output. It will attempt all // possible ways to write() the input buffer, see writeSequences(). The @@ -116,10 +127,10 @@ function test(encoding, input, expected, singleSequence) { } else { sequences = [singleSequence]; } - sequences.forEach(function(sequence) { - var decoder = new StringDecoder(encoding); - var output = ''; - sequence.forEach(function(write) { + sequences.forEach((sequence) => { + const decoder = new StringDecoder(encoding); + let output = ''; + sequence.forEach((write) => { output += decoder.write(input.slice(write[0], write[1])); }); output += decoder.end(); diff --git a/test/parallel/test-timers.js b/test/parallel/test-timers.js index 0b379e0eb45ad0..87397735eebff2 100644 --- a/test/parallel/test-timers.js +++ b/test/parallel/test-timers.js @@ -1,6 +1,6 @@ 'use strict'; -require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); var inputs = [ undefined, @@ -18,13 +18,14 @@ var inputs = [ -10, -1, -0.5, + -0.1, -0.0, 0, 0.0, + 0.1, 0.5, 1, 1.0, - 10, 2147483648, // browser behaviour: timeouts > 2^31-1 run on next tick 12345678901234 // ditto ]; @@ -43,10 +44,17 @@ inputs.forEach(function(value, index) { }, value); }); -process.on('exit', function() { - // assert that all timers have run +// All values in inputs array coerce to 1 ms. Therefore, they should all run +// before a timer set here for 2 ms. + +setTimeout(common.mustCall(function() { + // assert that all other timers have run inputs.forEach(function(value, index) { - assert.equal(true, timeouts[index]); - assert.equal(true, intervals[index]); + assert(timeouts[index]); + assert(intervals[index]); }); -}); +}), 2); + +// Test 10 ms timeout separately. +setTimeout(common.mustCall(function() {}), 10); +setInterval(common.mustCall(function() { clearInterval(this); }), 10); diff --git a/test/parallel/test-tls-client-verify.js b/test/parallel/test-tls-client-verify.js index 983d88296eb26f..a1fa35acf3c124 100644 --- a/test/parallel/test-tls-client-verify.js +++ b/test/parallel/test-tls-client-verify.js @@ -12,36 +12,36 @@ const fs = require('fs'); const hosterr = /Hostname\/IP doesn't match certificate's altnames/g; const testCases = - [{ ca: ['ca1-cert'], - key: 'agent2-key', - cert: 'agent2-cert', - servers: [ + [{ ca: ['ca1-cert'], + key: 'agent2-key', + cert: 'agent2-cert', + servers: [ { ok: true, key: 'agent1-key', cert: 'agent1-cert' }, { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, { ok: false, key: 'agent3-key', cert: 'agent3-cert' } - ] - }, + ] + }, - { ca: [], - key: 'agent2-key', - cert: 'agent2-cert', - servers: [ + { ca: [], + key: 'agent2-key', + cert: 'agent2-cert', + servers: [ { ok: false, key: 'agent1-key', cert: 'agent1-cert' }, { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, { ok: false, key: 'agent3-key', cert: 'agent3-cert' } - ] - }, + ] + }, - { ca: ['ca1-cert', 'ca2-cert'], - key: 'agent2-key', - cert: 'agent2-cert', - servers: [ + { ca: ['ca1-cert', 'ca2-cert'], + key: 'agent2-key', + cert: 'agent2-cert', + servers: [ { ok: true, key: 'agent1-key', cert: 'agent1-cert' }, { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, { ok: true, key: 'agent3-key', cert: 'agent3-cert' } - ] - } - ]; + ] + } + ]; function filenamePEM(n) { return require('path').join(common.fixturesDir, 'keys', n + '.pem'); diff --git a/test/parallel/test-tls-no-sslv3.js b/test/parallel/test-tls-no-sslv3.js index 16a722ef85b9da..fbc7a629611b0d 100644 --- a/test/parallel/test-tls-no-sslv3.js +++ b/test/parallel/test-tls-no-sslv3.js @@ -25,8 +25,8 @@ let stderr = ''; server.listen(0, '127.0.0.1', function() { const address = this.address().address + ':' + this.address().port; const args = ['s_client', - '-ssl3', - '-connect', address]; + '-ssl3', + '-connect', address]; // for the performance and stability issue in s_client on Windows if (common.isWindows) diff --git a/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js b/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js index bd92dc28904183..1ff7decf3cf9cc 100644 --- a/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js +++ b/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js @@ -23,7 +23,7 @@ const server = tls.createServer({}) 'Instance of Error should be passed to error handler'); assert.ok(e.message.match( /SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol/), - 'Expecting SSL unknown protocol'); + 'Expecting SSL unknown protocol'); server.close(); })); diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index 04c1547384c61e..60678032a3efcf 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -15,88 +15,88 @@ if (!common.opensslCli) { // - accepted and "authorized". const testCases = - [{ title: 'Do not request certs. Everyone is unauthorized.', - requestCert: false, - rejectUnauthorized: false, - renegotiate: false, - CAs: ['ca1-cert'], - clients: - [{ name: 'agent1', shouldReject: false, shouldAuth: false }, + [{ title: 'Do not request certs. Everyone is unauthorized.', + requestCert: false, + rejectUnauthorized: false, + renegotiate: false, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: false }, { name: 'agent2', shouldReject: false, shouldAuth: false }, { name: 'agent3', shouldReject: false, shouldAuth: false }, { name: 'nocert', shouldReject: false, shouldAuth: false } - ] - }, - - { title: 'Allow both authed and unauthed connections with CA1', - requestCert: true, - rejectUnauthorized: false, - renegotiate: false, - CAs: ['ca1-cert'], - clients: - [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + ] + }, + + { title: 'Allow both authed and unauthed connections with CA1', + requestCert: true, + rejectUnauthorized: false, + renegotiate: false, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, { name: 'agent2', shouldReject: false, shouldAuth: false }, { name: 'agent3', shouldReject: false, shouldAuth: false }, { name: 'nocert', shouldReject: false, shouldAuth: false } - ] - }, - - { title: 'Do not request certs at connection. Do that later', - requestCert: false, - rejectUnauthorized: false, - renegotiate: true, - CAs: ['ca1-cert'], - clients: - [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + ] + }, + + { title: 'Do not request certs at connection. Do that later', + requestCert: false, + rejectUnauthorized: false, + renegotiate: true, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, { name: 'agent2', shouldReject: false, shouldAuth: false }, { name: 'agent3', shouldReject: false, shouldAuth: false }, { name: 'nocert', shouldReject: false, shouldAuth: false } - ] - }, - - { title: 'Allow only authed connections with CA1', - requestCert: true, - rejectUnauthorized: true, - renegotiate: false, - CAs: ['ca1-cert'], - clients: - [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + ] + }, + + { title: 'Allow only authed connections with CA1', + requestCert: true, + rejectUnauthorized: true, + renegotiate: false, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, { name: 'agent2', shouldReject: true }, { name: 'agent3', shouldReject: true }, { name: 'nocert', shouldReject: true } - ] - }, - - { title: 'Allow only authed connections with CA1 and CA2', - requestCert: true, - rejectUnauthorized: true, - renegotiate: false, - CAs: ['ca1-cert', 'ca2-cert'], - clients: - [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + ] + }, + + { title: 'Allow only authed connections with CA1 and CA2', + requestCert: true, + rejectUnauthorized: true, + renegotiate: false, + CAs: ['ca1-cert', 'ca2-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, { name: 'agent2', shouldReject: true }, { name: 'agent3', shouldReject: false, shouldAuth: true }, { name: 'nocert', shouldReject: true } - ] - }, + ] + }, - { title: 'Allow only certs signed by CA2 but not in the CRL', - requestCert: true, - rejectUnauthorized: true, - renegotiate: false, - CAs: ['ca2-cert'], - crl: 'ca2-crl', - clients: [ + { title: 'Allow only certs signed by CA2 but not in the CRL', + requestCert: true, + rejectUnauthorized: true, + renegotiate: false, + CAs: ['ca2-cert'], + crl: 'ca2-crl', + clients: [ { name: 'agent1', shouldReject: true, shouldAuth: false }, { name: 'agent2', shouldReject: true, shouldAuth: false }, { name: 'agent3', shouldReject: false, shouldAuth: true }, // Agent4 has a cert in the CRL. { name: 'agent4', shouldReject: true, shouldAuth: false }, { name: 'nocert', shouldReject: true } - ] - } - ]; + ] + } + ]; if (!common.hasCrypto) { common.skip('missing crypto'); diff --git a/test/parallel/test-tls-socket-failed-handshake-emits-error.js b/test/parallel/test-tls-socket-failed-handshake-emits-error.js index f655dc97b5a99b..ffeb42c8ebd8da 100644 --- a/test/parallel/test-tls-socket-failed-handshake-emits-error.js +++ b/test/parallel/test-tls-socket-failed-handshake-emits-error.js @@ -23,7 +23,7 @@ const server = net.createServer(function(c) { 'Instance of Error should be passed to error handler'); assert.ok(e.message.match( /SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol/), - 'Expecting SSL unknown protocol'); + 'Expecting SSL unknown protocol'); })); s.on('close', function() { diff --git a/test/parallel/test-tls-startcom-wosign-whitelist.js b/test/parallel/test-tls-startcom-wosign-whitelist.js new file mode 100644 index 00000000000000..fd20e0d8e9745c --- /dev/null +++ b/test/parallel/test-tls-startcom-wosign-whitelist.js @@ -0,0 +1,91 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const tls = require('tls'); +const fs = require('fs'); +const path = require('path'); +let finished = 0; + +function filenamePEM(n) { + return path.join(common.fixturesDir, 'keys', n + '.pem'); +} + +function loadPEM(n) { + return fs.readFileSync(filenamePEM(n)); +} + +const testCases = [ + { // agent8 is signed by fake-startcom-root with notBefore of + // Oct 20 23:59:59 2016 GMT. It passes StartCom/WoSign check. + serverOpts: { + key: loadPEM('agent8-key'), + cert: loadPEM('agent8-cert') + }, + clientOpts: { + ca: loadPEM('fake-startcom-root-cert'), + port: undefined, + rejectUnauthorized: true + }, + errorCode: 'CERT_OK' + }, + { // agent9 is signed by fake-startcom-root with notBefore of + // Oct 21 00:00:01 2016 GMT. It fails StartCom/WoSign check. + serverOpts: { + key: loadPEM('agent9-key'), + cert: loadPEM('agent9-cert') + }, + clientOpts: { + ca: loadPEM('fake-startcom-root-cert'), + port: undefined, + rejectUnauthorized: true + }, + errorCode: 'CERT_REVOKED' + } +]; + + +function runNextTest(server, tindex) { + server.close(function() { + finished++; + runTest(tindex + 1); + }); +} + + +function runTest(tindex) { + const tcase = testCases[tindex]; + + if (!tcase) return; + + const server = tls.createServer(tcase.serverOpts, function(s) { + s.resume(); + }).listen(0, function() { + tcase.clientOpts.port = this.address().port; + const client = tls.connect(tcase.clientOpts); + client.on('error', function(e) { + assert.strictEqual(e.code, tcase.errorCode); + runNextTest(server, tindex); + }); + + client.on('secureConnect', function() { + // agent8 can pass StartCom/WoSign check so that the secureConnect + // is established. + assert.strictEqual(tcase.errorCode, 'CERT_OK'); + client.end(); + runNextTest(server, tindex); + }); + }); +} + + +runTest(0); + +process.on('exit', function() { + assert.strictEqual(finished, testCases.length); +}); diff --git a/test/parallel/test-tls-starttls-server.js b/test/parallel/test-tls-starttls-server.js new file mode 100644 index 00000000000000..ca6a00b25ddc03 --- /dev/null +++ b/test/parallel/test-tls-starttls-server.js @@ -0,0 +1,53 @@ +'use strict'; + +// Test asynchronous SNI+OCSP on TLSSocket created with `server` set to +// `net.Server` instead of `tls.Server` + +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const assert = require('assert'); +const fs = require('fs'); +const net = require('net'); +const tls = require('tls'); + +const key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'); +const cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'); + +const server = net.createServer(common.mustCall((s) => { + const tlsSocket = new tls.TLSSocket(s, { + isServer: true, + server: server, + + secureContext: tls.createSecureContext({ + key: key, + cert: cert + }), + + SNICallback: common.mustCall((hostname, callback) => { + assert.strictEqual(hostname, 'test.test'); + + callback(null, null); + }) + }); + + tlsSocket.on('secure', common.mustCall(() => { + tlsSocket.end(); + server.close(); + })); +})).listen(0, () => { + const opts = { + servername: 'test.test', + port: server.address().port, + rejectUnauthorized: false, + requestOCSP: true + }; + + tls.connect(opts, function() { + this.end(); + }); +}); diff --git a/test/parallel/test-url.js b/test/parallel/test-url.js index fec2233dc0fac9..5a5fd476ebfb05 100644 --- a/test/parallel/test-url.js +++ b/test/parallel/test-url.js @@ -891,8 +891,19 @@ var parseTests = { pathname: '/*', path: '/*', href: 'https:///*' - } + }, + // surrogate in auth + 'http://%F0%9F%98%80@www.example.com/': { + href: 'http://%F0%9F%98%80@www.example.com/', + slashes: true, + protocol: 'http:', + auth: '\uD83D\uDE00', + host: 'www.example.com', + hostname: 'www.example.com', + pathname: '/', + path: '/' + } }; for (const u in parseTests) { diff --git a/test/parallel/test-util-inspect-simd.js b/test/parallel/test-util-inspect-simd.js index ec4ccc1875a817..5e0a2740840c93 100644 --- a/test/parallel/test-util-inspect-simd.js +++ b/test/parallel/test-util-inspect-simd.js @@ -1,12 +1,11 @@ // Flags: --harmony_simd +/* global SIMD */ 'use strict'; require('../common'); const assert = require('assert'); const inspect = require('util').inspect; -const SIMD = global.SIMD; // Pacify eslint. - assert.strictEqual( inspect(SIMD.Bool16x8()), 'Bool16x8 [ false, false, false, false, false, false, false, false ]'); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 1118065f1a09da..b0f89333d25a9b 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -42,7 +42,7 @@ assert.strictEqual(util.inspect({'a': {'b': { 'c': 2}}}, false, 1), '{ a: { b: [Object] } }'); assert.strictEqual(util.inspect(Object.create({}, {visible: {value: 1, enumerable: true}, hidden: {value: 2}})), - '{ visible: 1 }' + '{ visible: 1 }' ); { @@ -206,8 +206,9 @@ for (const showHidden of [true, false]) { // Objects without prototype { const out = util.inspect(Object.create(null, - { name: {value: 'Tim', enumerable: true}, - hidden: {value: 'secret'}}), true); + { name: {value: 'Tim', + enumerable: true}, + hidden: {value: 'secret'}}), true); if (out !== "{ [hidden]: 'secret', name: 'Tim' }" && out !== "{ name: 'Tim', [hidden]: 'secret' }") { common.fail(`unexpected value for out ${out}`); @@ -216,8 +217,8 @@ for (const showHidden of [true, false]) { assert.strictEqual( util.inspect(Object.create(null, - {name: {value: 'Tim', enumerable: true}, - hidden: {value: 'secret'}})), + {name: {value: 'Tim', enumerable: true}, + hidden: {value: 'secret'}})), '{ name: \'Tim\' }' ); diff --git a/test/parallel/test-util-sigint-watchdog.js b/test/parallel/test-util-sigint-watchdog.js index 42e4048bd74a36..207f44b011c3a2 100644 --- a/test/parallel/test-util-sigint-watchdog.js +++ b/test/parallel/test-util-sigint-watchdog.js @@ -16,41 +16,41 @@ if (common.isWindows) { assert.strictEqual(hadPendingSignals, false); next(); }, -(next) => { + (next) => { // Test with one call to the watchdog, one signal. - binding.startSigintWatchdog(); - process.kill(process.pid, 'SIGINT'); - waitForPendingSignal(common.mustCall(() => { - const hadPendingSignals = binding.stopSigintWatchdog(); - assert.strictEqual(hadPendingSignals, true); - next(); - })); -}, -(next) => { + binding.startSigintWatchdog(); + process.kill(process.pid, 'SIGINT'); + waitForPendingSignal(common.mustCall(() => { + const hadPendingSignals = binding.stopSigintWatchdog(); + assert.strictEqual(hadPendingSignals, true); + next(); + })); + }, + (next) => { // Nested calls are okay. - binding.startSigintWatchdog(); - binding.startSigintWatchdog(); - process.kill(process.pid, 'SIGINT'); - waitForPendingSignal(common.mustCall(() => { - const hadPendingSignals1 = binding.stopSigintWatchdog(); - const hadPendingSignals2 = binding.stopSigintWatchdog(); - assert.strictEqual(hadPendingSignals1, true); - assert.strictEqual(hadPendingSignals2, false); - next(); - })); -}, -() => { + binding.startSigintWatchdog(); + binding.startSigintWatchdog(); + process.kill(process.pid, 'SIGINT'); + waitForPendingSignal(common.mustCall(() => { + const hadPendingSignals1 = binding.stopSigintWatchdog(); + const hadPendingSignals2 = binding.stopSigintWatchdog(); + assert.strictEqual(hadPendingSignals1, true); + assert.strictEqual(hadPendingSignals2, false); + next(); + })); + }, + () => { // Signal comes in after first call to stop. - binding.startSigintWatchdog(); - binding.startSigintWatchdog(); - const hadPendingSignals1 = binding.stopSigintWatchdog(); - process.kill(process.pid, 'SIGINT'); - waitForPendingSignal(common.mustCall(() => { - const hadPendingSignals2 = binding.stopSigintWatchdog(); - assert.strictEqual(hadPendingSignals1, false); - assert.strictEqual(hadPendingSignals2, true); - })); -}].reduceRight((a, b) => common.mustCall(b).bind(null, a))(); + binding.startSigintWatchdog(); + binding.startSigintWatchdog(); + const hadPendingSignals1 = binding.stopSigintWatchdog(); + process.kill(process.pid, 'SIGINT'); + waitForPendingSignal(common.mustCall(() => { + const hadPendingSignals2 = binding.stopSigintWatchdog(); + assert.strictEqual(hadPendingSignals1, false); + assert.strictEqual(hadPendingSignals2, true); + })); + }].reduceRight((a, b) => common.mustCall(b).bind(null, a))(); function waitForPendingSignal(cb) { if (binding.watchdogHasPendingSigint()) diff --git a/test/known_issues/test-vm-deleting-property.js b/test/parallel/test-vm-deleting-property.js similarity index 88% rename from test/known_issues/test-vm-deleting-property.js rename to test/parallel/test-vm-deleting-property.js index cda3371a33bf16..994aa0aff94f2d 100644 --- a/test/known_issues/test-vm-deleting-property.js +++ b/test/parallel/test-vm-deleting-property.js @@ -12,4 +12,4 @@ const res = vm.runInContext(` Object.getOwnPropertyDescriptor(this, 'x'); `, context); -assert.strictEqual(res.value, undefined); +assert.strictEqual(res, undefined); diff --git a/test/parallel/test-vm-property-not-on-sandbox.js b/test/parallel/test-vm-property-not-on-sandbox.js new file mode 100644 index 00000000000000..08ea5890784c37 --- /dev/null +++ b/test/parallel/test-vm-property-not-on-sandbox.js @@ -0,0 +1,37 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const vm = require('vm'); + +// This, admittedly contrived, example tests an edge cases of the vm module. +// +// The GetterCallback explicitly checks the global_proxy() if a property is +// not found on the sandbox. In the following test, the explicit check +// inside the callback yields different results than deferring the +// check until after the callback. The check is deferred if the +// callback does not intercept, i.e., if args.GetReturnValue().Set() is +// not called. + +// Check that the GetterCallback explicitly calls GetRealNamedProperty() +// on the global proxy if the property is not found on the sandbox. +// +// foo is not defined on the sandbox until we call CopyProperties(). +// In the GetterCallback, we do not find the property on the sandbox and +// get the property from the global proxy. Since the return value is +// the sandbox, we replace it by +// the global_proxy to keep the correct identities. +// +// This test case is partially inspired by +// https://github.com/nodejs/node/issues/855 +const sandbox = {console}; +sandbox.document = {defaultView: sandbox}; +vm.createContext(sandbox); +const code = `Object.defineProperty( + this, + 'foo', + { get: function() {return document.defaultView} } + ); + var result = foo === this;`; + +vm.runInContext(code, sandbox); +assert.strictEqual(sandbox.result, true); diff --git a/test/parallel/test-vm-sigint-existing-handler.js b/test/parallel/test-vm-sigint-existing-handler.js index 10df3888d38e41..cbd91bef06c950 100644 --- a/test/parallel/test-vm-sigint-existing-handler.js +++ b/test/parallel/test-vm-sigint-existing-handler.js @@ -5,6 +5,11 @@ const vm = require('vm'); const spawn = require('child_process').spawn; +const methods = [ + 'runInThisContext', + 'runInContext' +]; + if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); @@ -12,8 +17,8 @@ if (common.isWindows) { } if (process.argv[2] === 'child') { - const parent = +process.env.REPL_TEST_PPID; - assert.ok(parent); + const method = process.argv[3]; + assert.ok(method); let firstHandlerCalled = 0; process.on('SIGINT', common.mustCall(() => { @@ -27,12 +32,14 @@ if (process.argv[2] === 'child') { // Handler attached _before_ execution. })); - assert.throws(() => { - vm.runInThisContext(`process.kill(${parent}, 'SIGUSR2'); while(true) {}`, { - breakOnSigint: true - }); - }, /Script execution interrupted/); + const script = `process.send('${method}'); while(true) {}`; + const args = method === 'runInContext' ? + [vm.createContext({ process })] : + []; + const options = { breakOnSigint: true }; + assert.throws(() => { vm[method](script, ...args, options); }, + /^Error: Script execution interrupted\.$/); assert.strictEqual(firstHandlerCalled, 0); assert.strictEqual(onceHandlerCalled, 0); @@ -46,7 +53,9 @@ if (process.argv[2] === 'child') { if (afterHandlerCalled++ === 0) { // The first time it just bounces back to check that the `once()` // handler is not called the second time. - process.kill(parent, 'SIGUSR2'); + assert.strictEqual(firstHandlerCalled, 1); + assert.strictEqual(onceHandlerCalled, 1); + process.send(method); return; } @@ -55,26 +64,24 @@ if (process.argv[2] === 'child') { timeout.unref(); }, 2)); - process.kill(parent, 'SIGUSR2'); + process.send(method); return; } -process.env.REPL_TEST_PPID = process.pid; - -// Set the `SIGUSR2` handler before spawning the child process to make sure -// the signal is always handled. -process.on('SIGUSR2', common.mustCall(() => { - // First kill() breaks the while(true) loop, second one invokes the real - // signal handlers. - process.kill(child.pid, 'SIGINT'); -}, 3)); +for (const method of methods) { + const child = spawn(process.execPath, [__filename, 'child', method], { + stdio: [null, 'inherit', 'inherit', 'ipc'] + }); -const child = spawn(process.execPath, [__filename, 'child'], { - stdio: [null, 'inherit', 'inherit'] -}); + child.on('message', common.mustCall(() => { + // First kill() breaks the while(true) loop, second one invokes the real + // signal handlers. + process.kill(child.pid, 'SIGINT'); + }, 3)); -child.on('close', function(code, signal) { - assert.strictEqual(signal, null); - assert.strictEqual(code, 0); -}); + child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(signal, null); + assert.strictEqual(code, 0); + })); +} diff --git a/test/parallel/test-vm-sigint.js b/test/parallel/test-vm-sigint.js index 8846338b78086c..24ad7ab0472ab6 100644 --- a/test/parallel/test-vm-sigint.js +++ b/test/parallel/test-vm-sigint.js @@ -5,6 +5,11 @@ const vm = require('vm'); const spawn = require('child_process').spawn; +const methods = [ + 'runInThisContext', + 'runInContext' +]; + if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); @@ -12,31 +17,32 @@ if (common.isWindows) { } if (process.argv[2] === 'child') { - const parent = +process.env.REPL_TEST_PPID; - assert.ok(parent); + const method = process.argv[3]; + assert.ok(method); + + const script = `process.send('${method}'); while(true) {}`; + const args = method === 'runInContext' ? + [vm.createContext({ process })] : + []; + const options = { breakOnSigint: true }; - assert.throws(() => { - vm.runInThisContext(`process.kill(${parent}, "SIGUSR2"); while(true) {}`, { - breakOnSigint: true - }); - }, /Script execution interrupted/); + assert.throws(() => { vm[method](script, ...args, options); }, + /^Error: Script execution interrupted\.$/); return; } -process.env.REPL_TEST_PPID = process.pid; +for (const method of methods) { + const child = spawn(process.execPath, [__filename, 'child', method], { + stdio: [null, 'pipe', 'inherit', 'ipc'] + }); -// Set the `SIGUSR2` handler before spawning the child process to make sure -// the signal is always handled. -process.on('SIGUSR2', common.mustCall(() => { - process.kill(child.pid, 'SIGINT'); -})); + child.on('message', common.mustCall(() => { + process.kill(child.pid, 'SIGINT'); + })); -const child = spawn(process.execPath, [__filename, 'child'], { - stdio: [null, 'pipe', 'inherit'] -}); - -child.on('close', common.mustCall((code, signal) => { - assert.strictEqual(signal, null); - assert.strictEqual(code, 0); -})); + child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(signal, null); + assert.strictEqual(code, 0); + })); +} diff --git a/test/parallel/test-writeint.js b/test/parallel/test-writeint.js index 43784fb390a1f9..9fce2bc410e1be 100644 --- a/test/parallel/test-writeint.js +++ b/test/parallel/test-writeint.js @@ -4,6 +4,7 @@ */ require('../common'); const assert = require('assert'); +const errorOutOfBounds = /^TypeError: "value" argument is out of bounds$/; function test8(clazz) { var buffer = new clazz(2); @@ -17,10 +18,10 @@ function test8(clazz) { /* Make sure we handle truncation correctly */ assert.throws(function() { buffer.writeInt8(0xabc, 0); - }); + }, errorOutOfBounds); assert.throws(function() { buffer.writeInt8(0xabc, 0); - }); + }, errorOutOfBounds); /* Make sure we handle min/max correctly */ buffer.writeInt8(0x7f, 0); @@ -30,10 +31,10 @@ function test8(clazz) { assert.equal(0x80, buffer[1]); assert.throws(function() { buffer.writeInt8(0x7f + 1, 0); - }); + }, errorOutOfBounds); assert.throws(function() { buffer.writeInt8(-0x80 - 1, 0); - }); + }, errorOutOfBounds); } @@ -70,10 +71,10 @@ function test16(clazz) { assert.equal(0x00, buffer[3]); assert.throws(function() { buffer.writeInt16BE(0x7fff + 1, 0); - }); + }, errorOutOfBounds); assert.throws(function() { buffer.writeInt16BE(-0x8000 - 1, 0); - }); + }, errorOutOfBounds); buffer.writeInt16LE(0x7fff, 0); buffer.writeInt16LE(-0x8000, 2); @@ -83,10 +84,10 @@ function test16(clazz) { assert.equal(0x80, buffer[3]); assert.throws(function() { buffer.writeInt16LE(0x7fff + 1, 0); - }); + }, errorOutOfBounds); assert.throws(function() { buffer.writeInt16LE(-0x8000 - 1, 0); - }); + }, errorOutOfBounds); } @@ -139,10 +140,10 @@ function test32(clazz) { assert.equal(0x00, buffer[7]); assert.throws(function() { buffer.writeInt32BE(0x7fffffff + 1, 0); - }); + }, errorOutOfBounds); assert.throws(function() { buffer.writeInt32BE(-0x80000000 - 1, 0); - }); + }, errorOutOfBounds); buffer.writeInt32LE(0x7fffffff, 0); buffer.writeInt32LE(-0x80000000, 4); @@ -156,10 +157,10 @@ function test32(clazz) { assert.equal(0x80, buffer[7]); assert.throws(function() { buffer.writeInt32LE(0x7fffffff + 1, 0); - }); + }, errorOutOfBounds); assert.throws(function() { buffer.writeInt32LE(-0x80000000 - 1, 0); - }); + }, errorOutOfBounds); } diff --git a/test/parallel/test-zerolengthbufferbug.js b/test/parallel/test-zerolengthbufferbug.js index 9e2cde6b2fadae..056fc725ff5593 100644 --- a/test/parallel/test-zerolengthbufferbug.js +++ b/test/parallel/test-zerolengthbufferbug.js @@ -8,7 +8,7 @@ var server = http.createServer(function(req, res) { var buffer = Buffer.alloc(0); // FIXME: WTF gjslint want this? res.writeHead(200, {'Content-Type': 'text/html', - 'Content-Length': buffer.length}); + 'Content-Length': buffer.length}); res.end(buffer); }); diff --git a/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js b/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js index 37f89f5b94bf08..872c2581c53b90 100644 --- a/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js +++ b/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js @@ -12,11 +12,15 @@ let data = Buffer.concat([ Buffer(10).fill(0) ]); -assert.equal(zlib.gunzipSync(data).toString(), 'abcdef'); +assert.strictEqual(zlib.gunzipSync(data).toString(), 'abcdef'); zlib.gunzip(data, common.mustCall((err, result) => { assert.ifError(err); - assert.equal(result, 'abcdef', 'result should match original string'); + assert.strictEqual( + result.toString(), + 'abcdef', + 'result should match original string' + ); })); // if the trailing garbage happens to look like a gzip header, it should @@ -28,10 +32,16 @@ data = Buffer.concat([ Buffer(10).fill(0) ]); -assert.throws(() => zlib.gunzipSync(data)); +assert.throws( + () => zlib.gunzipSync(data), + /^Error: unknown compression method$/ +); zlib.gunzip(data, common.mustCall((err, result) => { - assert(err); + assert(err instanceof Error); + assert.strictEqual(err.code, 'Z_DATA_ERROR'); + assert.strictEqual(err.message, 'unknown compression method'); + assert.strictEqual(result, undefined); })); // In this case the trailing junk is too short to be a gzip segment @@ -42,8 +52,14 @@ data = Buffer.concat([ Buffer([0x1f, 0x8b, 0xff, 0xff]) ]); -assert.throws(() => zlib.gunzipSync(data)); +assert.throws( + () => zlib.gunzipSync(data), + /^Error: unknown compression method$/ +); zlib.gunzip(data, common.mustCall((err, result) => { - assert(err); + assert(err instanceof Error); + assert.strictEqual(err.code, 'Z_DATA_ERROR'); + assert.strictEqual(err.message, 'unknown compression method'); + assert.strictEqual(result, undefined); })); diff --git a/test/parallel/test-zlib-invalid-input.js b/test/parallel/test-zlib-invalid-input.js index ee2ee85d73ff09..eb9cd334c11b84 100644 --- a/test/parallel/test-zlib-invalid-input.js +++ b/test/parallel/test-zlib-invalid-input.js @@ -21,9 +21,9 @@ nonStringInputs.forEach(function(input) { console.error('Doing the unzips'); // zlib.Unzip classes need to get valid data, or else they'll throw. const unzips = [ zlib.Unzip(), - zlib.Gunzip(), - zlib.Inflate(), - zlib.InflateRaw() ]; + zlib.Gunzip(), + zlib.Inflate(), + zlib.InflateRaw() ]; var hadError = []; unzips.forEach(function(uz, i) { console.error('Error for ' + uz.constructor.name); diff --git a/test/parallel/test-zlib-write-after-close.js b/test/parallel/test-zlib-write-after-close.js index 0c54270ec29b13..fdad1708c81ff0 100644 --- a/test/parallel/test-zlib-write-after-close.js +++ b/test/parallel/test-zlib-write-after-close.js @@ -6,7 +6,5 @@ const zlib = require('zlib'); zlib.gzip('hello', common.mustCall(function(err, out) { const unzip = zlib.createGunzip(); unzip.close(common.mustCall(function() {})); - assert.throws(function() { - unzip.write(out); - }); + assert.throws(() => unzip.write(out), /^Error: zlib binding closed$/); })); diff --git a/test/parallel/test-zlib.js b/test/parallel/test-zlib.js index ea158ded48b5c1..54a4bc473631a0 100644 --- a/test/parallel/test-zlib.js +++ b/test/parallel/test-zlib.js @@ -150,9 +150,9 @@ Object.keys(tests).forEach(function(file) { var Def = pair[0]; var Inf = pair[1]; var opts = { level: level, - windowBits: windowBits, - memLevel: memLevel, - strategy: strategy }; + windowBits: windowBits, + memLevel: memLevel, + strategy: strategy }; total++; diff --git a/test/pseudo-tty/pseudo-tty.status b/test/pseudo-tty/pseudo-tty.status index e16bb28cd7be61..50f54de029d874 100644 --- a/test/pseudo-tty/pseudo-tty.status +++ b/test/pseudo-tty/pseudo-tty.status @@ -4,3 +4,5 @@ prefix pseudo-tty # test issue only, covered under https://github.com/nodejs/node/issues/7973 no_dropped_stdio : SKIP no_interleaved_stdio : SKIP +# being investigated under https://github.com/nodejs/node/issues/9728 +test-tty-wrap : FAIL, PASS diff --git a/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js b/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js index f1a95559b9dc92..f828e92afbe71c 100644 --- a/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js +++ b/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js @@ -5,7 +5,7 @@ const originalRefreshSizeStderr = process.stderr._refreshSize; const originalRefreshSizeStdout = process.stdout._refreshSize; const wrap = (fn, ioStream, string) => { - return () => { + const wrapped = common.mustCall(() => { // The console.log() call prints a string that is in the .out file. In other // words, the console.log() is part of the test, not extraneous debugging. console.log(string); @@ -16,7 +16,8 @@ const wrap = (fn, ioStream, string) => { if (!common.isSunOS || e.code !== 'EINVAL') throw e; } - }; + }); + return wrapped; }; process.stderr._refreshSize = wrap(originalRefreshSizeStderr, diff --git a/test/pummel/test-child-process-spawn-loop.js b/test/pummel/test-child-process-spawn-loop.js index 7e686cada244b3..7a3cf114b4e8e9 100644 --- a/test/pummel/test-child-process-spawn-loop.js +++ b/test/pummel/test-child-process-spawn-loop.js @@ -4,26 +4,26 @@ var assert = require('assert'); var spawn = require('child_process').spawn; -var SIZE = 1000 * 1024; -var N = 40; -var finished = false; +const SIZE = 1000 * 1024; +const N = 40; +let finished = false; function doSpawn(i) { - var child = spawn('python', ['-c', 'print ' + SIZE + ' * "C"']); - var count = 0; + const child = spawn('python', ['-c', 'print ' + SIZE + ' * "C"']); + let count = 0; child.stdout.setEncoding('ascii'); - child.stdout.on('data', function(chunk) { + child.stdout.on('data', (chunk) => { count += chunk.length; }); - child.stderr.on('data', function(chunk) { + child.stderr.on('data', (chunk) => { console.log('stderr: ' + chunk); }); - child.on('close', function() { + child.on('close', () => { // + 1 for \n or + 2 for \r\n on Windows - assert.equal(SIZE + (common.isWindows ? 2 : 1), count); + assert.strictEqual(SIZE + (common.isWindows ? 2 : 1), count); if (i < N) { doSpawn(i + 1); } else { @@ -34,6 +34,6 @@ function doSpawn(i) { doSpawn(0); -process.on('exit', function() { +process.on('exit', () => { assert.ok(finished); }); diff --git a/test/pummel/test-crypto-dh.js b/test/pummel/test-crypto-dh.js index 7656d0ffa92e84..a19e583c516398 100644 --- a/test/pummel/test-crypto-dh.js +++ b/test/pummel/test-crypto-dh.js @@ -8,15 +8,32 @@ if (!common.hasCrypto) { return; } -assert.throws(function() { - crypto.getDiffieHellman('unknown-group'); -}); -assert.throws(function() { - crypto.getDiffieHellman('modp1').setPrivateKey(''); -}); -assert.throws(function() { - crypto.getDiffieHellman('modp1').setPublicKey(''); -}); +assert.throws( + function() { + crypto.getDiffieHellman('unknown-group'); + }, + /^Error: Unknown group$/, + 'crypto.getDiffieHellman(\'unknown-group\') ' + + 'failed to throw the expected error.' +); +assert.throws( + function() { + crypto.getDiffieHellman('modp1').setPrivateKey(''); + }, + new RegExp('^TypeError: crypto\\.getDiffieHellman\\(\\.\\.\\.\\)\\.' + + 'setPrivateKey is not a function$'), + 'crypto.getDiffieHellman(\'modp1\').setPrivateKey(\'\') ' + + 'failed to throw the expected error.' +); +assert.throws( + function() { + crypto.getDiffieHellman('modp1').setPublicKey(''); + }, + new RegExp('^TypeError: crypto\\.getDiffieHellman\\(\\.\\.\\.\\)\\.' + + 'setPublicKey is not a function$'), + 'crypto.getDiffieHellman(\'modp1\').setPublicKey(\'\') ' + + 'failed to throw the expected error.' +); var hashes = { modp1: '630e9acd2cc63f7e80d8507624ba60ac0757201a', diff --git a/test/pummel/test-exec.js b/test/pummel/test-exec.js index 6f6e1511b14442..18404373318917 100644 --- a/test/pummel/test-exec.js +++ b/test/pummel/test-exec.js @@ -63,6 +63,8 @@ exec(SLEEP3_COMMAND, { timeout: 50 }, function(err, stdout, stderr) { assert.ok(err); assert.ok(err.killed); assert.strictEqual(err.signal, 'SIGTERM'); + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); }); @@ -85,6 +87,8 @@ function killMeTwiceCallback(err, stdout, stderr) { assert.ok(err); assert.ok(err.killed); assert.strictEqual(err.signal, 'SIGTERM'); + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); // the timeout should still be in effect console.log('\'sleep 3\' was already killed. Took %d ms', diff); @@ -96,6 +100,8 @@ exec('python -c "print 200000*\'C\'"', {maxBuffer: 1000}, function(err, stdout, stderr) { assert.ok(err); assert.ok(/maxBuffer/.test(err.message)); + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); }); diff --git a/test/pummel/test-fs-watch-file.js b/test/pummel/test-fs-watch-file.js index 4e08e9e9d1cc9b..fc291cfe64c618 100644 --- a/test/pummel/test-fs-watch-file.js +++ b/test/pummel/test-fs-watch-file.js @@ -41,13 +41,13 @@ assert.throws( fs.watchFile(filepathOne); }, function(e) { - return e.message === 'watchFile requires a listener function'; + return e.message === '"watchFile()" requires a listener function'; } ); assert.doesNotThrow( function() { - fs.watchFile(filepathOne, function(curr, prev) { + fs.watchFile(filepathOne, function() { fs.unwatchFile(filepathOne); ++watchSeenOne; }); @@ -68,17 +68,17 @@ assert.throws( fs.watchFile(filepathTwo); }, function(e) { - return e.message === 'watchFile requires a listener function'; + return e.message === '"watchFile()" requires a listener function'; } ); assert.doesNotThrow( function() { - function a(curr, prev) { + function a() { fs.unwatchFile(filepathTwo, a); ++watchSeenTwo; } - function b(curr, prev) { + function b() { fs.unwatchFile(filepathTwo, b); ++watchSeenTwo; } @@ -93,10 +93,10 @@ setTimeout(function() { assert.doesNotThrow( function() { - function a(curr, prev) { + function a() { assert.ok(0); // should not run } - function b(curr, prev) { + function b() { fs.unwatchFile(filenameThree, b); ++watchSeenThree; } @@ -120,7 +120,7 @@ setTimeout(function() { assert.doesNotThrow( function() { - function a(curr, prev) { + function a() { ++watchSeenFour; assert.equal(1, watchSeenFour); fs.unwatchFile('.' + path.sep + filenameFour, a); diff --git a/test/pummel/test-keep-alive.js b/test/pummel/test-keep-alive.js index 1861b2df970e18..47d529b64082fa 100644 --- a/test/pummel/test-keep-alive.js +++ b/test/pummel/test-keep-alive.js @@ -12,8 +12,8 @@ if (common.isWindows) { return; } -var body = 'hello world\n'; -var server = http.createServer(function(req, res) { +const body = 'hello world\n'; +const server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'text/plain' @@ -22,12 +22,12 @@ var server = http.createServer(function(req, res) { res.end(); }); -var keepAliveReqSec = 0; -var normalReqSec = 0; +let keepAliveReqSec = 0; +let normalReqSec = 0; function runAb(opts, callback) { - var args = [ + const args = [ '-c', opts.concurrent || 100, '-t', opts.threads || 2, '-d', opts.duration || '10s', @@ -41,13 +41,11 @@ function runAb(opts, callback) { args.push(url.format({ hostname: '127.0.0.1', port: common.PORT, protocol: 'http'})); - //console.log(comm, args.join(' ')); - - var child = spawn('wrk', args); + const child = spawn('wrk', args); child.stderr.pipe(process.stderr); child.stdout.setEncoding('utf8'); - var stdout; + let stdout; child.stdout.on('data', function(data) { stdout += data; @@ -60,11 +58,11 @@ function runAb(opts, callback) { return; } - var matches = /Requests\/sec:\s*(\d+)\./mi.exec(stdout); - var reqSec = parseInt(matches[1]); + let matches = /Requests\/sec:\s*(\d+)\./mi.exec(stdout); + const reqSec = parseInt(matches[1]); matches = /Keep-Alive requests:\s*(\d+)/mi.exec(stdout); - var keepAliveRequests; + let keepAliveRequests; if (matches) { keepAliveRequests = parseInt(matches[1]); } else { @@ -75,21 +73,19 @@ function runAb(opts, callback) { }); } -server.listen(common.PORT, function() { - runAb({ keepalive: true }, function(reqSec) { +server.listen(common.PORT, () => { + runAb({ keepalive: true }, (reqSec) => { keepAliveReqSec = reqSec; - console.log('keep-alive:', keepAliveReqSec, 'req/sec'); runAb({ keepalive: false }, function(reqSec) { normalReqSec = reqSec; - console.log('normal:' + normalReqSec + ' req/sec'); server.close(); }); }); }); process.on('exit', function() { - assert.equal(true, normalReqSec > 50); - assert.equal(true, keepAliveReqSec > 50); - assert.equal(true, normalReqSec < keepAliveReqSec); + assert.strictEqual(true, normalReqSec > 50); + assert.strictEqual(true, keepAliveReqSec > 50); + assert.strictEqual(true, normalReqSec < keepAliveReqSec); }); diff --git a/test/pummel/test-watch-file.js b/test/pummel/test-watch-file.js index 8fdf6b32b2d78c..8b79ef8ede4a63 100644 --- a/test/pummel/test-watch-file.js +++ b/test/pummel/test-watch-file.js @@ -5,14 +5,11 @@ var assert = require('assert'); var fs = require('fs'); var path = require('path'); -var f = path.join(common.fixturesDir, 'x.txt'); +const f = path.join(common.fixturesDir, 'x.txt'); -console.log('watching for changes of ' + f); - -var changes = 0; +let changes = 0; function watchFile() { - fs.watchFile(f, function(curr, prev) { - console.log(f + ' change'); + fs.watchFile(f, (curr, prev) => { changes++; assert.notDeepStrictEqual(curr.mtime, prev.mtime); fs.unwatchFile(f); @@ -24,7 +21,7 @@ function watchFile() { watchFile(); -var fd = fs.openSync(f, 'w+'); +const fd = fs.openSync(f, 'w+'); fs.writeSync(fd, 'xyz\n'); fs.closeSync(fd); diff --git a/test/sequential/test-buffer-creation-regression.js b/test/sequential/test-buffer-creation-regression.js new file mode 100644 index 00000000000000..b5c8450e036cc8 --- /dev/null +++ b/test/sequential/test-buffer-creation-regression.js @@ -0,0 +1,36 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +function test(arrayBuffer, offset, length) { + const uint8Array = new Uint8Array(arrayBuffer, offset, length); + for (let i = 0; i < length; i += 1) { + uint8Array[i] = 1; + } + + const buffer = Buffer.from(arrayBuffer, offset, length); + for (let i = 0; i < length; i += 1) { + assert.strictEqual(buffer[i], 1); + } +} + +const acceptableOOMErrors = [ + 'Array buffer allocation failed', + 'Invalid array buffer length' +]; + +const size = 8589934592; /* 1 << 33 */ +const offset = 4294967296; /* 1 << 32 */ +const length = 1000; +let arrayBuffer; + +try { + arrayBuffer = new ArrayBuffer(size); +} catch (e) { + if (e instanceof RangeError && acceptableOOMErrors.includes(e.message)) + return common.skip(`Unable to allocate ${size} bytes for ArrayBuffer`); + throw e; +} + +test(arrayBuffer, offset, length); diff --git a/test/sequential/test-crypto-timing-safe-equal.js b/test/sequential/test-crypto-timing-safe-equal.js index 9c4265a672cc0f..7a1f8d2993669b 100644 --- a/test/sequential/test-crypto-timing-safe-equal.js +++ b/test/sequential/test-crypto-timing-safe-equal.js @@ -24,14 +24,14 @@ assert.strictEqual( assert.throws(function() { crypto.timingSafeEqual(Buffer.from([1, 2, 3]), Buffer.from([1, 2])); }, /^TypeError: Input buffers must have the same length$/, - 'should throw when given buffers with different lengths'); + 'should throw when given buffers with different lengths'); assert.throws(function() { crypto.timingSafeEqual('not a buffer', Buffer.from([1, 2])); }, /^TypeError: First argument must be a buffer$/, - 'should throw if the first argument is not a buffer'); + 'should throw if the first argument is not a buffer'); assert.throws(function() { crypto.timingSafeEqual(Buffer.from([1, 2]), 'not a buffer'); }, /^TypeError: Second argument must be a buffer$/, - 'should throw if the second argument is not a buffer'); + 'should throw if the second argument is not a buffer'); diff --git a/test/parallel/test-fs-readfile-tostring-fail.js b/test/sequential/test-fs-readfile-tostring-fail.js similarity index 100% rename from test/parallel/test-fs-readfile-tostring-fail.js rename to test/sequential/test-fs-readfile-tostring-fail.js diff --git a/test/sequential/test-fs-watch.js b/test/sequential/test-fs-watch.js index 43b23bd5bd0a79..34e53f59aa0961 100644 --- a/test/sequential/test-fs-watch.js +++ b/test/sequential/test-fs-watch.js @@ -1,25 +1,25 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var path = require('path'); -var fs = require('fs'); +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); -var expectFilePath = common.isWindows || - common.isLinux || - common.isOSX; +const expectFilePath = common.isWindows || + common.isLinux || + common.isOSX; -var watchSeenOne = 0; -var watchSeenTwo = 0; -var watchSeenThree = 0; +let watchSeenOne = 0; +let watchSeenTwo = 0; +let watchSeenThree = 0; -var testDir = common.tmpDir; +const testDir = common.tmpDir; -var filenameOne = 'watch.txt'; -var filepathOne = path.join(testDir, filenameOne); +const filenameOne = 'watch.txt'; +const filepathOne = path.join(testDir, filenameOne); -var filenameTwo = 'hasOwnProperty'; -var filepathTwo = filenameTwo; -var filepathTwoAbs = path.join(testDir, filenameTwo); +const filenameTwo = 'hasOwnProperty'; +const filepathTwo = filenameTwo; +const filepathTwoAbs = path.join(testDir, filenameTwo); process.on('exit', function() { assert.ok(watchSeenOne > 0); @@ -33,12 +33,12 @@ fs.writeFileSync(filepathOne, 'hello'); assert.doesNotThrow( function() { - var watcher = fs.watch(filepathOne); + const watcher = fs.watch(filepathOne); watcher.on('change', function(event, filename) { - assert.equal('change', event); + assert.strictEqual('change', event); if (expectFilePath) { - assert.equal('watch.txt', filename); + assert.strictEqual('watch.txt', filename); } watcher.close(); ++watchSeenOne; @@ -57,11 +57,11 @@ fs.writeFileSync(filepathTwoAbs, 'howdy'); assert.doesNotThrow( function() { - var watcher = fs.watch(filepathTwo, function(event, filename) { - assert.equal('change', event); + const watcher = fs.watch(filepathTwo, function(event, filename) { + assert.strictEqual('change', event); if (expectFilePath) { - assert.equal('hasOwnProperty', filename); + assert.strictEqual('hasOwnProperty', filename); } watcher.close(); ++watchSeenTwo; @@ -79,13 +79,13 @@ const filepathThree = path.join(testsubdir, filenameThree); assert.doesNotThrow( function() { - var watcher = fs.watch(testsubdir, function(event, filename) { - var renameEv = common.isSunOS ? 'change' : 'rename'; - assert.equal(renameEv, event); + const watcher = fs.watch(testsubdir, function(event, filename) { + const renameEv = common.isSunOS ? 'change' : 'rename'; + assert.strictEqual(renameEv, event); if (expectFilePath) { - assert.equal('newfile.txt', filename); + assert.strictEqual('newfile.txt', filename); } else { - assert.equal(null, filename); + assert.strictEqual(null, filename); } watcher.close(); ++watchSeenThree; @@ -94,7 +94,7 @@ assert.doesNotThrow( ); setImmediate(function() { - var fd = fs.openSync(filepathThree, 'w'); + const fd = fs.openSync(filepathThree, 'w'); fs.closeSync(fd); }); @@ -106,9 +106,9 @@ fs.watch(__filename, {persistent: false}, function() { // whitebox test to ensure that wrapped FSEvent is safe // https://github.com/joyent/node/issues/6690 -var oldhandle; +let oldhandle; assert.throws(function() { - var w = fs.watch(__filename, function(event, filename) { }); + const w = fs.watch(__filename, function(event, filename) { }); oldhandle = w._handle; w._handle = { close: w._handle.close }; w.close(); @@ -116,7 +116,7 @@ assert.throws(function() { oldhandle.close(); // clean up assert.throws(function() { - var w = fs.watchFile(__filename, {persistent: false}, function() {}); + const w = fs.watchFile(__filename, {persistent: false}, function() {}); oldhandle = w._handle; w._handle = { stop: w._handle.stop }; w.stop(); diff --git a/test/sequential/test-module-loading.js b/test/sequential/test-module-loading.js index 2ddaffdf2030a5..5e9c6e1bd4b787 100644 --- a/test/sequential/test-module-loading.js +++ b/test/sequential/test-module-loading.js @@ -97,7 +97,8 @@ console.error('test name clashes'); var my_path = require('../fixtures/path'); assert.ok(my_path.path_func instanceof Function); // this one does not exist and should throw -assert.throws(function() { require('./utils'); }); +assert.throws(function() { require('./utils'); }, + /^Error: Cannot find module '.\/utils'$/); var errorThrown = false; try { @@ -124,7 +125,7 @@ assert.strictEqual(require('../fixtures/registerExt.hello.world').test, 'passed'); console.error('load custom file types that return non-strings'); -require.extensions['.test'] = function(module, filename) { +require.extensions['.test'] = function(module) { module.exports = { custom: 'passed' }; diff --git a/test/sequential/test-regress-GH-897.js b/test/sequential/test-regress-GH-897.js deleted file mode 100644 index 7b1297efd5a1b7..00000000000000 --- a/test/sequential/test-regress-GH-897.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -// Test for bug where a timer duration greater than 0 ms but less than 1 ms -// resulted in the duration being set for 1000 ms. The expected behavior is -// that the timeout would be set for 1 ms, and thus fire more-or-less -// immediately. -// -// Ref: https://github.com/nodejs/node-v0.x-archive/pull/897 - -const common = require('../common'); -const assert = require('assert'); - -const t = Date.now(); -setTimeout(common.mustCall(function() { - const diff = Date.now() - t; - assert.ok(diff < 100, `timer fired after ${diff} ms`); -}), 0.1); diff --git a/test/sequential/test-vm-timeout-rethrow.js b/test/sequential/test-vm-timeout-rethrow.js index f0f9c0b9c51063..7e148bd4d0b94f 100644 --- a/test/sequential/test-vm-timeout-rethrow.js +++ b/test/sequential/test-vm-timeout-rethrow.js @@ -5,15 +5,9 @@ var vm = require('vm'); var spawn = require('child_process').spawn; if (process.argv[2] === 'child') { - var code = 'var j = 0;\n' + - 'for (var i = 0; i < 1000000; i++) j += add(i, i + 1);\n' + - 'j;'; + const code = 'while(true);'; - var ctx = vm.createContext({ - add: function(x, y) { - return x + y; - } - }); + const ctx = vm.createContext(); vm.runInContext(code, ctx, { timeout: 1 }); } else { diff --git a/tools/doc/README.md b/tools/doc/README.md index 6985bc130d62c5..0535243e92f63b 100644 --- a/tools/doc/README.md +++ b/tools/doc/README.md @@ -99,10 +99,9 @@ This event is emitted on instances of SomeClass, not on the module itself. ``` -* Modules have (description, Properties, Functions, Classes, Examples) -* Properties have (type, description) -* Functions have (list of arguments, description) * Classes have (description, Properties, Methods, Events) * Events have (list of arguments, description) +* Functions have (list of arguments, description) * Methods have (list of arguments, description) +* Modules have (description, Properties, Functions, Classes, Examples) * Properties have (type, description) diff --git a/tools/doc/generate.js b/tools/doc/generate.js index 31b23c52a08ba7..b7fcf0d4f90da5 100644 --- a/tools/doc/generate.js +++ b/tools/doc/generate.js @@ -11,16 +11,19 @@ let format = 'json'; let template = null; let inputFile = null; let nodeVersion = null; +let analytics = null; args.forEach(function(arg) { - if (!arg.match(/^--/)) { + if (!arg.startsWith('--')) { inputFile = arg; - } else if (arg.match(/^--format=/)) { + } else if (arg.startsWith('--format=')) { format = arg.replace(/^--format=/, ''); - } else if (arg.match(/^--template=/)) { + } else if (arg.startsWith('--template=')) { template = arg.replace(/^--template=/, ''); - } else if (arg.match(/^--node-version=/)) { + } else if (arg.startsWith('--node-version=')) { nodeVersion = arg.replace(/^--node-version=/, ''); + } else if (arg.startsWith('--analytics=')) { + analytics = arg.replace(/^--analytics=/, ''); } }); @@ -54,6 +57,7 @@ function next(er, input) { filename: inputFile, template: template, nodeVersion: nodeVersion, + analytics: analytics, }, function(er, html) { diff --git a/tools/doc/html.js b/tools/doc/html.js index b3e5f8d708cc14..3dd6f83da503df 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -67,6 +67,7 @@ function toHTML(opts, cb) { filename: opts.filename, template: template, nodeVersion: nodeVersion, + analytics: opts.analytics, }, cb); }); } @@ -90,7 +91,7 @@ function loadGtoc(cb) { function toID(filename) { return filename .replace('.html', '') - .replace(/[^\w\-]/g, '-') + .replace(/[^\w-]/g, '-') .replace(/-+/g, '-'); } @@ -128,6 +129,13 @@ function render(opts, cb) { gtocData.replace('class="nav-' + id, 'class="nav-' + id + ' active') ); + if (opts.analytics) { + template = template.replace( + '', + analyticsScript(opts.analytics) + ); + } + // content has to be the last thing we do with // the lexed tokens, because it's destructive. const content = marked.parser(lexed); @@ -137,6 +145,23 @@ function render(opts, cb) { }); } +function analyticsScript(analytics) { + return ` + + + `; +} + // handle general body-text replacements // for example, link man page references to the actual page function parseText(lexed) { @@ -284,7 +309,7 @@ function linkJsTypeDocs(text) { // Handle types, for example the source Markdown might say // "This argument should be a {Number} or {String}" for (i = 0; i < parts.length; i += 2) { - typeMatches = parts[i].match(/\{([^\}]+)\}/g); + typeMatches = parts[i].match(/\{([^}]+)\}/g); if (typeMatches) { typeMatches.forEach(function(typeMatch) { parts[i] = parts[i].replace(typeMatch, typeParser.toLink(typeMatch)); diff --git a/tools/doc/json.js b/tools/doc/json.js index a782c54028d756..2a966c83ec9388 100644 --- a/tools/doc/json.js +++ b/tools/doc/json.js @@ -31,7 +31,7 @@ function doJSON(input, filename, cb) { // // This is for cases where the markdown semantic structure is lacking. if (type === 'paragraph' || type === 'html') { - var metaExpr = /\n*/g; + var metaExpr = /\n*/g; text = text.replace(metaExpr, function(_0, k, v) { current[k.trim()] = v.trim(); return ''; @@ -371,7 +371,7 @@ function parseListItem(item) { item.name = 'return'; text = text.replace(retExpr, ''); } else { - var nameExpr = /^['`"]?([^'`": \{]+)['`"]?\s*:?\s*/; + var nameExpr = /^['`"]?([^'`": {]+)['`"]?\s*:?\s*/; var name = text.match(nameExpr); if (name) { item.name = name[1]; @@ -388,7 +388,7 @@ function parseListItem(item) { } text = text.trim(); - var typeExpr = /^\{([^\}]+)\}/; + var typeExpr = /^\{([^}]+)\}/; var type = text.match(typeExpr); if (type) { item.type = type[1]; @@ -546,12 +546,12 @@ function deepCopy_(src) { var eventExpr = /^Event(?::|\s)+['"]?([^"']+).*$/i; var classExpr = /^Class:\s*([^ ]+).*?$/i; var propExpr = /^(?:property:?\s*)?[^.]+\.([^ .()]+)\s*?$/i; -var braceExpr = /^(?:property:?\s*)?[^.\[]+(\[[^\]]+\])\s*?$/i; +var braceExpr = /^(?:property:?\s*)?[^.[]+(\[[^\]]+\])\s*?$/i; var classMethExpr = /^class\s*method\s*:?[^.]+\.([^ .()]+)\([^)]*\)\s*?$/i; var methExpr = /^(?:method:?\s*)?(?:[^.]+\.)?([^ .()]+)\([^)]*\)\s*?$/i; -var newExpr = /^new ([A-Z][a-zA-Z]+)\([^\)]*\)\s*?$/; +var newExpr = /^new ([A-Z][a-zA-Z]+)\([^)]*\)\s*?$/; var paramExpr = /\((.*)\);?$/; function newSection(tok) { diff --git a/tools/eslint-rules/align-function-arguments.js b/tools/eslint-rules/align-function-arguments.js deleted file mode 100644 index 015552489a9d44..00000000000000 --- a/tools/eslint-rules/align-function-arguments.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @fileoverview Align arguments in multiline function calls - * @author Rich Trott - */ -'use strict'; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -function checkArgumentAlignment(context, node) { - - function isNodeFirstInLine(node, byEndLocation) { - const firstToken = byEndLocation === true ? context.getLastToken(node, 1) : - context.getTokenBefore(node); - const startLine = byEndLocation === true ? node.loc.end.line : - node.loc.start.line; - const endLine = firstToken ? firstToken.loc.end.line : -1; - - return startLine !== endLine; - } - - if (node.arguments.length === 0) - return; - - var msg = ''; - const first = node.arguments[0]; - var currentLine = first.loc.start.line; - const firstColumn = first.loc.start.column; - - const ignoreTypes = [ - 'ArrowFunctionExpression', - 'FunctionExpression', - 'ObjectExpression', - ]; - - const args = node.arguments; - - // For now, don't bother trying to validate potentially complicating things - // like closures. Different people will have very different ideas and it's - // probably best to implement configuration options. - if (args.some((node) => { return ignoreTypes.indexOf(node.type) !== -1; })) { - return; - } - - if (!isNodeFirstInLine(node)) { - return; - } - - var misaligned; - - args.slice(1).forEach((argument) => { - if (!misaligned) { - if (argument.loc.start.line === currentLine + 1) { - if (argument.loc.start.column !== firstColumn) { - if (isNodeFirstInLine(argument)) { - msg = 'Function argument in column ' + - `${argument.loc.start.column + 1}, ` + - `expected in ${firstColumn + 1}`; - misaligned = argument; - } - } - } - } - currentLine = argument.loc.start.line; - }); - - if (msg) - context.report(misaligned, msg); -} - -module.exports = function(context) { - return { - 'CallExpression': (node) => checkArgumentAlignment(context, node) - }; -}; diff --git a/tools/eslint-rules/timer-arguments.js b/tools/eslint-rules/timer-arguments.js new file mode 100644 index 00000000000000..4dd7816ff82ff2 --- /dev/null +++ b/tools/eslint-rules/timer-arguments.js @@ -0,0 +1,25 @@ +/** + * @fileoverview Require at least two arguments when calling setTimeout() or + * setInterval(). + * @author Rich Trott + */ +'use strict'; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +function isTimer(name) { + return ['setTimeout', 'setInterval'].includes(name); +} + +module.exports = function(context) { + return { + 'CallExpression': function(node) { + const name = node.callee.name; + if (isTimer(name) && node.arguments.length < 2) { + context.report(node, `${name} must have at least 2 arguments`); + } + } + }; +}; diff --git a/tools/eslint/LICENSE b/tools/eslint/LICENSE index d41bdf7951f077..777939e8fc1a7f 100644 --- a/tools/eslint/LICENSE +++ b/tools/eslint/LICENSE @@ -1,5 +1,5 @@ ESLint -Copyright jQuery Foundation and other contributors, https://jquery.org/ +Copyright JS Foundation and other contributors, https://js.foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/tools/eslint/README.md b/tools/eslint/README.md index 4d84a7e3dfd5cd..dcd42cff46685a 100644 --- a/tools/eslint/README.md +++ b/tools/eslint/README.md @@ -13,7 +13,7 @@ [Rules](http://eslint.org/docs/rules/) | [Contributing](http://eslint.org/docs/developer-guide/contributing) | [Reporting Bugs](http://eslint.org/docs/developer-guide/contributing/reporting-bugs) | -[Code of Conduct](https://jquery.org/conduct/) | +[Code of Conduct](https://js.foundation/conduct/) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint) | [Chat Room](https://gitter.im/eslint/eslint) @@ -210,10 +210,7 @@ ESLint has full support for ECMAScript 6. By default, this support is off. You c ESLint doesn't natively support experimental ECMAScript language features. You can use [babel-eslint](https://github.com/babel/babel-eslint) to use any option available in Babel. -Once a language feature has been adopted into the ECMAScript standard, we will accept -issues and pull requests related to the new feature, subject to our [contributing -guidelines](http://eslint.org/docs/developer-guide/contributing). Until then, please use -the appropriate parser and plugin(s) for your experimental feature. +Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](http://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature. ### Where to ask for help? diff --git a/tools/eslint/bin/eslint.js b/tools/eslint/bin/eslint.js index d85d29d7a5bdae..bf534971f24d9b 100755 --- a/tools/eslint/bin/eslint.js +++ b/tools/eslint/bin/eslint.js @@ -5,7 +5,7 @@ * @author Nicholas C. Zakas */ -/* eslint no-console:off, no-process-exit:off */ +/* eslint no-console:off */ "use strict"; @@ -36,7 +36,7 @@ const concat = require("concat-stream"), // Execution //------------------------------------------------------------------------------ -process.on("uncaughtException", function(err) { +process.once("uncaughtException", err => { // lazy load const lodash = require("lodash"); @@ -51,17 +51,17 @@ process.on("uncaughtException", function(err) { console.log(err.stack); } - process.exit(1); + process.exitCode = 1; }); if (useStdIn) { - process.stdin.pipe(concat({ encoding: "string" }, function(text) { + process.stdin.pipe(concat({ encoding: "string" }, text => { process.exitCode = cli.execute(process.argv, text); })); } else if (init) { const configInit = require("../lib/config/config-initializer"); - configInit.initializeConfig(function(err) { + configInit.initializeConfig(err => { if (err) { process.exitCode = 1; console.error(err.message); diff --git a/tools/eslint/conf/eslint.json b/tools/eslint/conf/eslint.json index 4d54e3ab6dac6a..81f5bb8aa5ee82 100755 --- a/tools/eslint/conf/eslint.json +++ b/tools/eslint/conf/eslint.json @@ -4,6 +4,7 @@ "rules": { "no-alert": "off", "no-array-constructor": "off", + "no-await-in-loop": "off", "no-bitwise": "off", "no-caller": "off", "no-case-declarations": "error", @@ -41,7 +42,7 @@ "no-fallthrough": "error", "no-floating-decimal": "off", "no-func-assign": "error", - "no-global-assign": "off", + "no-global-assign": "error", "no-implicit-coercion": "off", "no-implicit-globals": "off", "no-implied-eval": "off", @@ -63,9 +64,9 @@ "no-multi-spaces": "off", "no-multi-str": "off", "no-multiple-empty-lines": "off", - "no-native-reassign": "error", + "no-native-reassign": "off", "no-negated-condition": "off", - "no-negated-in-lhs": "error", + "no-negated-in-lhs": "off", "no-nested-ternary": "off", "no-new": "off", "no-new-func": "off", @@ -91,6 +92,7 @@ "no-restricted-properties": "off", "no-restricted-syntax": "off", "no-return-assign": "off", + "no-return-await": "off", "no-script-url": "off", "no-self-assign": "error", "no-self-compare": "off", @@ -115,7 +117,7 @@ "no-unneeded-ternary": "off", "no-unreachable": "error", "no-unsafe-finally": "error", - "no-unsafe-negation": "off", + "no-unsafe-negation": "error", "no-unused-expressions": "off", "no-unused-labels": "error", "no-unused-vars": "error", @@ -126,6 +128,7 @@ "no-useless-constructor": "off", "no-useless-escape": "off", "no-useless-rename": "off", + "no-useless-return": "off", "no-void": "off", "no-var": "off", "no-warning-comments": "off", @@ -141,6 +144,7 @@ "brace-style": "off", "callback-return": "off", "camelcase": "off", + "capitalized-comments": "off", "class-methods-use-this": "off", "comma-dangle": "off", "comma-spacing": "off", @@ -200,6 +204,7 @@ "padded-blocks": "off", "prefer-arrow-callback": "off", "prefer-const": "off", + "prefer-destructuring": "off", "prefer-numeric-literals": "off", "prefer-reflect": "off", "prefer-rest-params": "off", @@ -208,6 +213,7 @@ "quote-props": "off", "quotes": "off", "radix": "off", + "require-await": "off", "require-jsdoc": "off", "require-yield": "error", "rest-spread-spacing": "off", diff --git a/tools/eslint/lib/ast-utils.js b/tools/eslint/lib/ast-utils.js index 9e171ea316fc31..46dfebe101caa2 100644 --- a/tools/eslint/lib/ast-utils.js +++ b/tools/eslint/lib/ast-utils.js @@ -10,6 +10,7 @@ //------------------------------------------------------------------------------ const esutils = require("esutils"); +const lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers @@ -21,7 +22,7 @@ const arrayOrTypedArrayPattern = /Array$/; const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/; const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/; const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/; -const thisTagPattern = /^[\s\*]*@this/m; +const thisTagPattern = /^[\s*]*@this/m; /** * Checks reference if is non initializer and writable. @@ -83,6 +84,56 @@ function getUpperFunction(node) { return null; } +/** + * Checks whether a given node is a function node or not. + * The following types are function nodes: + * + * - ArrowFunctionExpression + * - FunctionDeclaration + * - FunctionExpression + * + * @param {ASTNode|null} node - A node to check. + * @returns {boolean} `true` if the node is a function node. + */ +function isFunction(node) { + return Boolean(node && anyFunctionPattern.test(node.type)); +} + +/** + * Checks whether a given node is a loop node or not. + * The following types are loop nodes: + * + * - DoWhileStatement + * - ForInStatement + * - ForOfStatement + * - ForStatement + * - WhileStatement + * + * @param {ASTNode|null} node - A node to check. + * @returns {boolean} `true` if the node is a loop node. + */ +function isLoop(node) { + return Boolean(node && anyLoopPattern.test(node.type)); +} + +/** + * Checks whether the given node is in a loop or not. + * + * @param {ASTNode} node - The node to check. + * @returns {boolean} `true` if the node is in a loop. + */ +function isInLoop(node) { + while (node && !isFunction(node)) { + if (isLoop(node)) { + return true; + } + + node = node.parent; + } + + return false; +} + /** * Checks whether or not a node is `null` or `undefined`. * @param {ASTNode} node - A node to check. @@ -176,9 +227,7 @@ function hasJSDocThisTag(node, sourceCode) { // because callbacks don't have its JSDoc comment. // e.g. // sinon.test(/* @this sinon.Sandbox */function() { this.spy(); }); - return sourceCode.getComments(node).leading.some(function(comment) { - return thisTagPattern.test(comment.value); - }); + return sourceCode.getComments(node).leading.some(comment => thisTagPattern.test(comment.value)); } /** @@ -197,6 +246,59 @@ function isParenthesised(sourceCode, node) { nextToken.value === ")" && nextToken.range[0] >= node.range[1]; } +/** + * Gets the `=>` token of the given arrow function node. + * + * @param {ASTNode} node - The arrow function node to get. + * @param {SourceCode} sourceCode - The source code object to get tokens. + * @returns {Token} `=>` token. + */ +function getArrowToken(node, sourceCode) { + let token = sourceCode.getTokenBefore(node.body); + + while (token.value !== "=>") { + token = sourceCode.getTokenBefore(token); + } + + return token; +} + +/** + * Gets the `(` token of the given function node. + * + * @param {ASTNode} node - The function node to get. + * @param {SourceCode} sourceCode - The source code object to get tokens. + * @returns {Token} `(` token. + */ +function getOpeningParenOfParams(node, sourceCode) { + let token = node.id ? sourceCode.getTokenAfter(node.id) : sourceCode.getFirstToken(node); + + while (token.value !== "(") { + token = sourceCode.getTokenAfter(token); + } + + return token; +} + +const lineIndexCache = new WeakMap(); + +/** + * Gets the range index for the first character in each of the lines of `sourceCode`. + * @param {SourceCode} sourceCode A sourceCode object + * @returns {number[]} The indices of the first characters in the each of the lines of the code + */ +function getLineIndices(sourceCode) { + + if (!lineIndexCache.has(sourceCode)) { + const lineIndices = (sourceCode.text.match(/[^\r\n\u2028\u2029]*(\r\n|\r|\n|\u2028|\u2029)/g) || []) + .reduce((indices, line) => indices.concat(indices[indices.length - 1] + line.length), [0]); + + // Store the sourceCode object in a WeakMap to avoid iterating over all of the lines every time a sourceCode object is passed in. + lineIndexCache.set(sourceCode, lineIndices); + } + return lineIndexCache.get(sourceCode); +} + //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ @@ -218,6 +320,9 @@ module.exports = { isCallee, isES5Constructor, getUpperFunction, + isFunction, + isLoop, + isInLoop, isArrayFromMethod, isParenthesised, @@ -583,35 +688,23 @@ module.exports = { }, /** - * Checks whether a given node is a loop node or not. - * The following types are loop nodes: + * Checks whether the given node is an empty block node or not. * - * - DoWhileStatement - * - ForInStatement - * - ForOfStatement - * - ForStatement - * - WhileStatement - * - * @param {ASTNode|null} node - A node to check. - * @returns {boolean} `true` if the node is a loop node. + * @param {ASTNode|null} node - The node to check. + * @returns {boolean} `true` if the node is an empty block. */ - isLoop(node) { - return Boolean(node && anyLoopPattern.test(node.type)); + isEmptyBlock(node) { + return Boolean(node && node.type === "BlockStatement" && node.body.length === 0); }, /** - * Checks whether a given node is a function node or not. - * The following types are function nodes: + * Checks whether the given node is an empty function node or not. * - * - ArrowFunctionExpression - * - FunctionDeclaration - * - FunctionExpression - * - * @param {ASTNode|null} node - A node to check. - * @returns {boolean} `true` if the node is a function node. + * @param {ASTNode|null} node - The node to check. + * @returns {boolean} `true` if the node is an empty function. */ - isFunction(node) { - return Boolean(node && anyFunctionPattern.test(node.type)); + isEmptyFunction(node) { + return isFunction(node) && module.exports.isEmptyBlock(node.body); }, /** @@ -738,5 +831,271 @@ module.exports = { */ isDecimalInteger(node) { return node.type === "Literal" && typeof node.value === "number" && /^(0|[1-9]\d*)$/.test(node.raw); + }, + + /** + * Gets the name and kind of the given function node. + * + * - `function foo() {}` .................... `function 'foo'` + * - `(function foo() {})` .................. `function 'foo'` + * - `(function() {})` ...................... `function` + * - `function* foo() {}` ................... `generator function 'foo'` + * - `(function* foo() {})` ................. `generator function 'foo'` + * - `(function*() {})` ..................... `generator function` + * - `() => {}` ............................. `arrow function` + * - `async () => {}` ....................... `async arrow function` + * - `({ foo: function foo() {} })` ......... `method 'foo'` + * - `({ foo: function() {} })` ............. `method 'foo'` + * - `({ ['foo']: function() {} })` ......... `method 'foo'` + * - `({ [foo]: function() {} })` ........... `method` + * - `({ foo() {} })` ....................... `method 'foo'` + * - `({ foo: function* foo() {} })` ........ `generator method 'foo'` + * - `({ foo: function*() {} })` ............ `generator method 'foo'` + * - `({ ['foo']: function*() {} })` ........ `generator method 'foo'` + * - `({ [foo]: function*() {} })` .......... `generator method` + * - `({ *foo() {} })` ...................... `generator method 'foo'` + * - `({ foo: async function foo() {} })` ... `async method 'foo'` + * - `({ foo: async function() {} })` ....... `async method 'foo'` + * - `({ ['foo']: async function() {} })` ... `async method 'foo'` + * - `({ [foo]: async function() {} })` ..... `async method` + * - `({ async foo() {} })` ................. `async method 'foo'` + * - `({ get foo() {} })` ................... `getter 'foo'` + * - `({ set foo(a) {} })` .................. `setter 'foo'` + * - `class A { constructor() {} }` ......... `constructor` + * - `class A { foo() {} }` ................. `method 'foo'` + * - `class A { *foo() {} }` ................ `generator method 'foo'` + * - `class A { async foo() {} }` ........... `async method 'foo'` + * - `class A { ['foo']() {} }` ............. `method 'foo'` + * - `class A { *['foo']() {} }` ............ `generator method 'foo'` + * - `class A { async ['foo']() {} }` ....... `async method 'foo'` + * - `class A { [foo]() {} }` ............... `method` + * - `class A { *[foo]() {} }` .............. `generator method` + * - `class A { async [foo]() {} }` ......... `async method` + * - `class A { get foo() {} }` ............. `getter 'foo'` + * - `class A { set foo(a) {} }` ............ `setter 'foo'` + * - `class A { static foo() {} }` .......... `static method 'foo'` + * - `class A { static *foo() {} }` ......... `static generator method 'foo'` + * - `class A { static async foo() {} }` .... `static async method 'foo'` + * - `class A { static get foo() {} }` ...... `static getter 'foo'` + * - `class A { static set foo(a) {} }` ..... `static setter 'foo'` + * + * @param {ASTNode} node - The function node to get. + * @returns {string} The name and kind of the function node. + */ + getFunctionNameWithKind(node) { + const parent = node.parent; + const tokens = []; + + if (parent.type === "MethodDefinition" && parent.static) { + tokens.push("static"); + } + if (node.async) { + tokens.push("async"); + } + if (node.generator) { + tokens.push("generator"); + } + + if (node.type === "ArrowFunctionExpression") { + tokens.push("arrow", "function"); + } else if (parent.type === "Property" || parent.type === "MethodDefinition") { + if (parent.kind === "constructor") { + return "constructor"; + } else if (parent.kind === "get") { + tokens.push("getter"); + } else if (parent.kind === "set") { + tokens.push("setter"); + } else { + tokens.push("method"); + } + } else { + tokens.push("function"); + } + + if (node.id) { + tokens.push(`'${node.id.name}'`); + } else { + const name = module.exports.getStaticPropertyName(parent); + + if (name) { + tokens.push(`'${name}'`); + } + } + + return tokens.join(" "); + }, + + /** + * Gets the location of the given function node for reporting. + * + * - `function foo() {}` + * ^^^^^^^^^^^^ + * - `(function foo() {})` + * ^^^^^^^^^^^^ + * - `(function() {})` + * ^^^^^^^^ + * - `function* foo() {}` + * ^^^^^^^^^^^^^ + * - `(function* foo() {})` + * ^^^^^^^^^^^^^ + * - `(function*() {})` + * ^^^^^^^^^ + * - `() => {}` + * ^^ + * - `async () => {}` + * ^^ + * - `({ foo: function foo() {} })` + * ^^^^^^^^^^^^^^^^^ + * - `({ foo: function() {} })` + * ^^^^^^^^^^^^^ + * - `({ ['foo']: function() {} })` + * ^^^^^^^^^^^^^^^^^ + * - `({ [foo]: function() {} })` + * ^^^^^^^^^^^^^^^ + * - `({ foo() {} })` + * ^^^ + * - `({ foo: function* foo() {} })` + * ^^^^^^^^^^^^^^^^^^ + * - `({ foo: function*() {} })` + * ^^^^^^^^^^^^^^ + * - `({ ['foo']: function*() {} })` + * ^^^^^^^^^^^^^^^^^^ + * - `({ [foo]: function*() {} })` + * ^^^^^^^^^^^^^^^^ + * - `({ *foo() {} })` + * ^^^^ + * - `({ foo: async function foo() {} })` + * ^^^^^^^^^^^^^^^^^^^^^^^ + * - `({ foo: async function() {} })` + * ^^^^^^^^^^^^^^^^^^^ + * - `({ ['foo']: async function() {} })` + * ^^^^^^^^^^^^^^^^^^^^^^^ + * - `({ [foo]: async function() {} })` + * ^^^^^^^^^^^^^^^^^^^^^ + * - `({ async foo() {} })` + * ^^^^^^^^^ + * - `({ get foo() {} })` + * ^^^^^^^ + * - `({ set foo(a) {} })` + * ^^^^^^^ + * - `class A { constructor() {} }` + * ^^^^^^^^^^^ + * - `class A { foo() {} }` + * ^^^ + * - `class A { *foo() {} }` + * ^^^^ + * - `class A { async foo() {} }` + * ^^^^^^^^^ + * - `class A { ['foo']() {} }` + * ^^^^^^^ + * - `class A { *['foo']() {} }` + * ^^^^^^^^ + * - `class A { async ['foo']() {} }` + * ^^^^^^^^^^^^^ + * - `class A { [foo]() {} }` + * ^^^^^ + * - `class A { *[foo]() {} }` + * ^^^^^^ + * - `class A { async [foo]() {} }` + * ^^^^^^^^^^^ + * - `class A { get foo() {} }` + * ^^^^^^^ + * - `class A { set foo(a) {} }` + * ^^^^^^^ + * - `class A { static foo() {} }` + * ^^^^^^^^^^ + * - `class A { static *foo() {} }` + * ^^^^^^^^^^^ + * - `class A { static async foo() {} }` + * ^^^^^^^^^^^^^^^^ + * - `class A { static get foo() {} }` + * ^^^^^^^^^^^^^^ + * - `class A { static set foo(a) {} }` + * ^^^^^^^^^^^^^^ + * + * @param {ASTNode} node - The function node to get. + * @param {SourceCode} sourceCode - The source code object to get tokens. + * @returns {string} The location of the function node for reporting. + */ + getFunctionHeadLoc(node, sourceCode) { + const parent = node.parent; + let start = null; + let end = null; + + if (node.type === "ArrowFunctionExpression") { + const arrowToken = getArrowToken(node, sourceCode); + + start = arrowToken.loc.start; + end = arrowToken.loc.end; + } else if (parent.type === "Property" || parent.type === "MethodDefinition") { + start = parent.loc.start; + end = getOpeningParenOfParams(node, sourceCode).loc.start; + } else { + start = node.loc.start; + end = getOpeningParenOfParams(node, sourceCode).loc.start; + } + + return { + start: Object.assign({}, start), + end: Object.assign({}, end), + }; + }, + + /* + * Converts a range index into a (line, column) pair. + * @param {SourceCode} sourceCode A SourceCode object + * @param {number} rangeIndex The range index of a character in a file + * @returns {Object} A {line, column} location object with a 0-indexed column + */ + getLocationFromRangeIndex(sourceCode, rangeIndex) { + const lineIndices = getLineIndices(sourceCode); + + /* + * lineIndices is a sorted list of indices of the first character of each line. + * To figure out which line rangeIndex is on, determine the last index at which rangeIndex could + * be inserted into lineIndices to keep the list sorted. + */ + const lineNumber = lodash.sortedLastIndex(lineIndices, rangeIndex); + + return { line: lineNumber, column: rangeIndex - lineIndices[lineNumber - 1] }; + + }, + + /** + * Converts a (line, column) pair into a range index. + * @param {SourceCode} sourceCode A SourceCode object + * @param {Object} loc A line/column location + * @param {number} loc.line The line number of the location (1-indexed) + * @param {number} loc.column The column number of the location (0-indexed) + * @returns {number} The range index of the location in the file. + */ + getRangeIndexFromLocation(sourceCode, loc) { + return getLineIndices(sourceCode)[loc.line - 1] + loc.column; + }, + + /** + * Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses + * surrounding the node. + * @param {SourceCode} sourceCode The source code object + * @param {ASTNode} node An expression node + * @returns {string} The text representing the node, with all surrounding parentheses included + */ + getParenthesisedText(sourceCode, node) { + let leftToken = sourceCode.getFirstToken(node); + let rightToken = sourceCode.getLastToken(node); + + while ( + sourceCode.getTokenBefore(leftToken) && + sourceCode.getTokenBefore(leftToken).type === "Punctuator" && + sourceCode.getTokenBefore(leftToken).value === "(" && + sourceCode.getTokenAfter(rightToken) && + sourceCode.getTokenAfter(rightToken).type === "Punctuator" && + sourceCode.getTokenAfter(rightToken).value === ")" + ) { + leftToken = sourceCode.getTokenBefore(leftToken); + rightToken = sourceCode.getTokenAfter(rightToken); + } + + return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]); } }; diff --git a/tools/eslint/lib/cli-engine.js b/tools/eslint/lib/cli-engine.js index b9019932fe9b54..de875a4d352926 100644 --- a/tools/eslint/lib/cli-engine.js +++ b/tools/eslint/lib/cli-engine.js @@ -90,7 +90,7 @@ const debug = require("debug")("eslint:cli-engine"); * @private */ function calculateStatsPerFile(messages) { - return messages.reduce(function(stat, message) { + return messages.reduce((stat, message) => { if (message.fatal || message.severity === 2) { stat.errorCount++; } else { @@ -110,7 +110,7 @@ function calculateStatsPerFile(messages) { * @private */ function calculateStatsPerRun(results) { - return results.reduce(function(stat, result) { + return results.reduce((stat, result) => { stat.errorCount += result.errorCount; stat.warningCount += result.warningCount; return stat; @@ -241,7 +241,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) { const parsedBlocks = processor.preprocess(text, filename); const unprocessedMessages = []; - parsedBlocks.forEach(function(block) { + parsedBlocks.forEach(block => { unprocessedMessages.push(eslint.verify(block, config, { filename, allowInlineConfig @@ -320,11 +320,11 @@ function createIgnoreResult(filePath, baseDir) { const isInBowerComponents = baseDir && /^bower_components/.test(path.relative(baseDir, filePath)); if (isHidden) { - message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern \'!\'\") to override."; + message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override."; } else if (isInNodeModules) { - message = "File ignored by default. Use \"--ignore-pattern \'!node_modules/*\'\" to override."; + message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override."; } else if (isInBowerComponents) { - message = "File ignored by default. Use \"--ignore-pattern \'!bower_components/*\'\" to override."; + message = "File ignored by default. Use \"--ignore-pattern '!bower_components/*'\" to override."; } else { message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."; } @@ -442,7 +442,7 @@ function CLIEngine(options) { options = Object.assign( Object.create(null), defaultOptions, - {cwd: process.cwd()}, + { cwd: process.cwd() }, options ); @@ -466,15 +466,15 @@ function CLIEngine(options) { if (this.options.rulePaths) { const cwd = this.options.cwd; - this.options.rulePaths.forEach(function(rulesdir) { + this.options.rulePaths.forEach(rulesdir => { debug(`Loading rules from ${rulesdir}`); rules.load(rulesdir, cwd); }); } - Object.keys(this.options.rules || {}).forEach(function(name) { + Object.keys(this.options.rules || {}).forEach(name => { validator.validateRuleOptions(name, this.options.rules[name], "CLI"); - }.bind(this)); + }); } /** @@ -526,7 +526,7 @@ CLIEngine.getFormatter = function(format) { CLIEngine.getErrorResults = function(results) { const filtered = []; - results.forEach(function(result) { + results.forEach(result => { const filteredMessages = result.messages.filter(isErrorMessage); if (filteredMessages.length > 0) { @@ -549,9 +549,7 @@ CLIEngine.getErrorResults = function(results) { * @returns {void} */ CLIEngine.outputFixes = function(report) { - report.results.filter(function(result) { - return result.hasOwnProperty("output"); - }).forEach(function(result) { + report.results.filter(result => result.hasOwnProperty("output")).forEach(result => { fs.writeFileSync(result.filePath, result.output); }); }; @@ -708,7 +706,7 @@ CLIEngine.prototype = { patterns = this.resolveFileGlobPatterns(patterns); const fileList = globUtil.listFilesToProcess(patterns, options); - fileList.forEach(function(fileInfo) { + fileList.forEach(fileInfo => { executeOnFile(fileInfo.filename, fileInfo.ignored); }); @@ -794,4 +792,6 @@ CLIEngine.prototype = { }; +CLIEngine.version = pkg.version; + module.exports = CLIEngine; diff --git a/tools/eslint/lib/code-path-analysis/code-path-analyzer.js b/tools/eslint/lib/code-path-analysis/code-path-analyzer.js index 655211430b4e2e..cb8b1e1bf8ce8c 100644 --- a/tools/eslint/lib/code-path-analysis/code-path-analyzer.js +++ b/tools/eslint/lib/code-path-analysis/code-path-analyzer.js @@ -569,21 +569,20 @@ function postprocess(analyzer, node) { /** * The class to analyze code paths. * This class implements the EventGenerator interface. - * - * @constructor - * @param {EventGenerator} eventGenerator - An event generator to wrap. */ -function CodePathAnalyzer(eventGenerator) { - this.original = eventGenerator; - this.emitter = eventGenerator.emitter; - this.codePath = null; - this.idGenerator = new IdGenerator("s"); - this.currentNode = null; - this.onLooped = this.onLooped.bind(this); -} +class CodePathAnalyzer { -CodePathAnalyzer.prototype = { - constructor: CodePathAnalyzer, + /** + * @param {EventGenerator} eventGenerator - An event generator to wrap. + */ + constructor(eventGenerator) { + this.original = eventGenerator; + this.emitter = eventGenerator.emitter; + this.codePath = null; + this.idGenerator = new IdGenerator("s"); + this.currentNode = null; + this.onLooped = this.onLooped.bind(this); + } /** * Does the process to enter a given AST node. @@ -608,7 +607,7 @@ CodePathAnalyzer.prototype = { this.original.enterNode(node); this.currentNode = null; - }, + } /** * Does the process to leave a given AST node. @@ -631,7 +630,7 @@ CodePathAnalyzer.prototype = { postprocess(this, node); this.currentNode = null; - }, + } /** * This is called on a code path looped. @@ -652,6 +651,6 @@ CodePathAnalyzer.prototype = { ); } } -}; +} module.exports = CodePathAnalyzer; diff --git a/tools/eslint/lib/code-path-analysis/code-path-segment.js b/tools/eslint/lib/code-path-analysis/code-path-segment.js index b3966c415b0aac..db1eba4560c251 100644 --- a/tools/eslint/lib/code-path-analysis/code-path-segment.js +++ b/tools/eslint/lib/code-path-analysis/code-path-segment.js @@ -68,174 +68,175 @@ function isReachable(segment) { /** * A code path segment. - * - * @constructor - * @param {string} id - An identifier. - * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. - * This array includes unreachable segments. - * @param {boolean} reachable - A flag which shows this is reachable. */ -function CodePathSegment(id, allPrevSegments, reachable) { +class CodePathSegment { /** - * The identifier of this code path. - * Rules use it to store additional information of each rule. - * @type {string} + * @param {string} id - An identifier. + * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. + * This array includes unreachable segments. + * @param {boolean} reachable - A flag which shows this is reachable. */ - this.id = id; + constructor(id, allPrevSegments, reachable) { + + /** + * The identifier of this code path. + * Rules use it to store additional information of each rule. + * @type {string} + */ + this.id = id; + + /** + * An array of the next segments. + * @type {CodePathSegment[]} + */ + this.nextSegments = []; + + /** + * An array of the previous segments. + * @type {CodePathSegment[]} + */ + this.prevSegments = allPrevSegments.filter(isReachable); + + /** + * An array of the next segments. + * This array includes unreachable segments. + * @type {CodePathSegment[]} + */ + this.allNextSegments = []; + + /** + * An array of the previous segments. + * This array includes unreachable segments. + * @type {CodePathSegment[]} + */ + this.allPrevSegments = allPrevSegments; + + /** + * A flag which shows this is reachable. + * @type {boolean} + */ + this.reachable = reachable; + + // Internal data. + Object.defineProperty(this, "internal", { + value: { + used: false, + loopedPrevSegments: [] + } + }); - /** - * An array of the next segments. - * @type {CodePathSegment[]} - */ - this.nextSegments = []; + /* istanbul ignore if */ + if (debug.enabled) { + this.internal.nodes = []; + this.internal.exitNodes = []; + } + } /** - * An array of the previous segments. - * @type {CodePathSegment[]} + * Checks a given previous segment is coming from the end of a loop. + * + * @param {CodePathSegment} segment - A previous segment to check. + * @returns {boolean} `true` if the segment is coming from the end of a loop. */ - this.prevSegments = allPrevSegments.filter(isReachable); + isLoopedPrevSegment(segment) { + return this.internal.loopedPrevSegments.indexOf(segment) !== -1; + } /** - * An array of the next segments. - * This array includes unreachable segments. - * @type {CodePathSegment[]} + * Creates the root segment. + * + * @param {string} id - An identifier. + * @returns {CodePathSegment} The created segment. */ - this.allNextSegments = []; + static newRoot(id) { + return new CodePathSegment(id, [], true); + } /** - * An array of the previous segments. - * This array includes unreachable segments. - * @type {CodePathSegment[]} + * Creates a segment that follows given segments. + * + * @param {string} id - An identifier. + * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. + * @returns {CodePathSegment} The created segment. */ - this.allPrevSegments = allPrevSegments; + static newNext(id, allPrevSegments) { + return new CodePathSegment( + id, + flattenUnusedSegments(allPrevSegments), + allPrevSegments.some(isReachable)); + } /** - * A flag which shows this is reachable. - * @type {boolean} + * Creates an unreachable segment that follows given segments. + * + * @param {string} id - An identifier. + * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. + * @returns {CodePathSegment} The created segment. */ - this.reachable = reachable; - - // Internal data. - Object.defineProperty(this, "internal", {value: { - used: false, - loopedPrevSegments: [] - }}); - - /* istanbul ignore if */ - if (debug.enabled) { - this.internal.nodes = []; - this.internal.exitNodes = []; - } -} + static newUnreachable(id, allPrevSegments) { + const segment = new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false); -CodePathSegment.prototype = { - constructor: CodePathSegment, + // In `if (a) return a; foo();` case, the unreachable segment preceded by + // the return statement is not used but must not be remove. + CodePathSegment.markUsed(segment); + + return segment; + } /** - * Checks a given previous segment is coming from the end of a loop. + * Creates a segment that follows given segments. + * This factory method does not connect with `allPrevSegments`. + * But this inherits `reachable` flag. * - * @param {CodePathSegment} segment - A previous segment to check. - * @returns {boolean} `true` if the segment is coming from the end of a loop. + * @param {string} id - An identifier. + * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. + * @returns {CodePathSegment} The created segment. */ - isLoopedPrevSegment(segment) { - return this.internal.loopedPrevSegments.indexOf(segment) !== -1; + static newDisconnected(id, allPrevSegments) { + return new CodePathSegment(id, [], allPrevSegments.some(isReachable)); } -}; - -/** - * Creates the root segment. - * - * @param {string} id - An identifier. - * @returns {CodePathSegment} The created segment. - */ -CodePathSegment.newRoot = function(id) { - return new CodePathSegment(id, [], true); -}; -/** - * Creates a segment that follows given segments. - * - * @param {string} id - An identifier. - * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. - * @returns {CodePathSegment} The created segment. - */ -CodePathSegment.newNext = function(id, allPrevSegments) { - return new CodePathSegment( - id, - flattenUnusedSegments(allPrevSegments), - allPrevSegments.some(isReachable)); -}; - -/** - * Creates an unreachable segment that follows given segments. - * - * @param {string} id - An identifier. - * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. - * @returns {CodePathSegment} The created segment. - */ -CodePathSegment.newUnreachable = function(id, allPrevSegments) { - const segment = new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false); - - // In `if (a) return a; foo();` case, the unreachable segment preceded by - // the return statement is not used but must not be remove. - CodePathSegment.markUsed(segment); - - return segment; -}; - -/** - * Creates a segment that follows given segments. - * This factory method does not connect with `allPrevSegments`. - * But this inherits `reachable` flag. - * - * @param {string} id - An identifier. - * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. - * @returns {CodePathSegment} The created segment. - */ -CodePathSegment.newDisconnected = function(id, allPrevSegments) { - return new CodePathSegment(id, [], allPrevSegments.some(isReachable)); -}; - -/** - * Makes a given segment being used. - * - * And this function registers the segment into the previous segments as a next. - * - * @param {CodePathSegment} segment - A segment to mark. - * @returns {void} - */ -CodePathSegment.markUsed = function(segment) { - if (segment.internal.used) { - return; - } - segment.internal.used = true; + /** + * Makes a given segment being used. + * + * And this function registers the segment into the previous segments as a next. + * + * @param {CodePathSegment} segment - A segment to mark. + * @returns {void} + */ + static markUsed(segment) { + if (segment.internal.used) { + return; + } + segment.internal.used = true; - let i; + let i; - if (segment.reachable) { - for (i = 0; i < segment.allPrevSegments.length; ++i) { - const prevSegment = segment.allPrevSegments[i]; + if (segment.reachable) { + for (i = 0; i < segment.allPrevSegments.length; ++i) { + const prevSegment = segment.allPrevSegments[i]; - prevSegment.allNextSegments.push(segment); - prevSegment.nextSegments.push(segment); - } - } else { - for (i = 0; i < segment.allPrevSegments.length; ++i) { - segment.allPrevSegments[i].allNextSegments.push(segment); + prevSegment.allNextSegments.push(segment); + prevSegment.nextSegments.push(segment); + } + } else { + for (i = 0; i < segment.allPrevSegments.length; ++i) { + segment.allPrevSegments[i].allNextSegments.push(segment); + } } } -}; -/** - * Marks a previous segment as looped. - * - * @param {CodePathSegment} segment - A segment. - * @param {CodePathSegment} prevSegment - A previous segment to mark. - * @returns {void} - */ -CodePathSegment.markPrevSegmentAsLooped = function(segment, prevSegment) { - segment.internal.loopedPrevSegments.push(prevSegment); -}; + /** + * Marks a previous segment as looped. + * + * @param {CodePathSegment} segment - A segment. + * @param {CodePathSegment} prevSegment - A previous segment to mark. + * @returns {void} + */ + static markPrevSegmentAsLooped(segment, prevSegment) { + segment.internal.loopedPrevSegments.push(prevSegment); + } +} module.exports = CodePathSegment; diff --git a/tools/eslint/lib/code-path-analysis/code-path-state.js b/tools/eslint/lib/code-path-analysis/code-path-state.js index 3b0b1606e2c993..64779c0d3c8b12 100644 --- a/tools/eslint/lib/code-path-analysis/code-path-state.js +++ b/tools/eslint/lib/code-path-analysis/code-path-state.js @@ -221,36 +221,35 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) { /** * A class which manages state to analyze code paths. - * - * @constructor - * @param {IdGenerator} idGenerator - An id generator to generate id for code - * path segments. - * @param {Function} onLooped - A callback function to notify looping. */ -function CodePathState(idGenerator, onLooped) { - this.idGenerator = idGenerator; - this.notifyLooped = onLooped; - this.forkContext = ForkContext.newRoot(idGenerator); - this.choiceContext = null; - this.switchContext = null; - this.tryContext = null; - this.loopContext = null; - this.breakContext = null; - - this.currentSegments = []; - this.initialSegment = this.forkContext.head[0]; - - // returnedSegments and thrownSegments push elements into finalSegments also. - const final = this.finalSegments = []; - const returned = this.returnedForkContext = []; - const thrown = this.thrownForkContext = []; - - returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final); - thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final); -} +class CodePathState { -CodePathState.prototype = { - constructor: CodePathState, + /** + * @param {IdGenerator} idGenerator - An id generator to generate id for code + * path segments. + * @param {Function} onLooped - A callback function to notify looping. + */ + constructor(idGenerator, onLooped) { + this.idGenerator = idGenerator; + this.notifyLooped = onLooped; + this.forkContext = ForkContext.newRoot(idGenerator); + this.choiceContext = null; + this.switchContext = null; + this.tryContext = null; + this.loopContext = null; + this.breakContext = null; + + this.currentSegments = []; + this.initialSegment = this.forkContext.head[ 0 ]; + + // returnedSegments and thrownSegments push elements into finalSegments also. + const final = this.finalSegments = []; + const returned = this.returnedForkContext = []; + const thrown = this.thrownForkContext = []; + + returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final); + thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final); + } /** * The head segments. @@ -258,7 +257,7 @@ CodePathState.prototype = { */ get headSegments() { return this.forkContext.head; - }, + } /** * The parent forking context. @@ -269,7 +268,7 @@ CodePathState.prototype = { const current = this.forkContext; return current && current.upper; - }, + } /** * Creates and stacks new forking context. @@ -285,7 +284,7 @@ CodePathState.prototype = { ); return this.forkContext; - }, + } /** * Pops and merges the last forking context. @@ -298,7 +297,7 @@ CodePathState.prototype = { this.forkContext.replaceHead(lastContext.makeNext(0, -1)); return lastContext; - }, + } /** * Creates a new path. @@ -306,7 +305,7 @@ CodePathState.prototype = { */ forkPath() { this.forkContext.add(this.parentForkContext.makeNext(-1, -1)); - }, + } /** * Creates a bypass path. @@ -316,7 +315,7 @@ CodePathState.prototype = { */ forkBypassPath() { this.forkContext.add(this.parentForkContext.head); - }, + } //-------------------------------------------------------------------------- // ConditionalExpression, LogicalExpression, IfStatement @@ -362,7 +361,7 @@ CodePathState.prototype = { falseForkContext: ForkContext.newEmpty(this.forkContext), processed: false }; - }, + } /** * Pops the last choice context and finalizes it. @@ -449,7 +448,7 @@ CodePathState.prototype = { forkContext.replaceHead(prevForkContext.makeNext(0, -1)); return context; - }, + } /** * Makes a code path segment of the right-hand operand of a logical @@ -494,7 +493,7 @@ CodePathState.prototype = { forkContext.replaceHead(forkContext.makeNext(-1, -1)); } - }, + } /** * Makes a code path segment of the `if` block. @@ -521,7 +520,7 @@ CodePathState.prototype = { forkContext.replaceHead( context.trueForkContext.makeNext(0, -1) ); - }, + } /** * Makes a code path segment of the `else` block. @@ -544,7 +543,7 @@ CodePathState.prototype = { forkContext.replaceHead( context.falseForkContext.makeNext(0, -1) ); - }, + } //-------------------------------------------------------------------------- // SwitchStatement @@ -570,7 +569,7 @@ CodePathState.prototype = { }; this.pushBreakContext(true, label); - }, + } /** * Pops the last context of SwitchStatement and finalizes it. @@ -649,7 +648,7 @@ CodePathState.prototype = { * This is a path after switch statement. */ this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); - }, + } /** * Makes a code path segment for a `SwitchCase` node. @@ -696,7 +695,7 @@ CodePathState.prototype = { context.lastIsDefault = isDefault; context.countForks += 1; - }, + } //-------------------------------------------------------------------------- // TryStatement @@ -723,7 +722,7 @@ CodePathState.prototype = { lastOfTryIsReachable: false, lastOfCatchIsReachable: false }; - }, + } /** * Pops the last context of TryStatement and finalizes it. @@ -777,7 +776,7 @@ CodePathState.prototype = { if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) { this.forkContext.makeUnreachable(); } - }, + } /** * Makes a code path segment for a `catch` block. @@ -802,7 +801,7 @@ CodePathState.prototype = { this.pushForkContext(); this.forkBypassPath(); this.forkContext.add(thrownSegments); - }, + } /** * Makes a code path segment for a `finally` block. @@ -863,7 +862,7 @@ CodePathState.prototype = { this.pushForkContext(true); this.forkContext.add(segments); - }, + } /** * Makes a code path segment from the first throwable node to the `catch` @@ -889,7 +888,7 @@ CodePathState.prototype = { context.thrownForkContext.add(forkContext.head); forkContext.replaceHead(forkContext.makeNext(-1, -1)); - }, + } //-------------------------------------------------------------------------- // Loop Statements @@ -969,7 +968,7 @@ CodePathState.prototype = { default: throw new Error(`unknown type: "${type}"`); } - }, + } /** * Pops the last context of a loop statement and finalizes it. @@ -1039,7 +1038,7 @@ CodePathState.prototype = { } else { forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); } - }, + } /** * Makes a code path segment for the test part of a WhileStatement. @@ -1056,7 +1055,7 @@ CodePathState.prototype = { context.test = test; context.continueDestSegments = testSegments; forkContext.replaceHead(testSegments); - }, + } /** * Makes a code path segment for the body part of a WhileStatement. @@ -1078,7 +1077,7 @@ CodePathState.prototype = { context.brokenForkContext.addAll(choiceContext.falseForkContext); } forkContext.replaceHead(choiceContext.trueForkContext.makeNext(0, -1)); - }, + } /** * Makes a code path segment for the body part of a DoWhileStatement. @@ -1093,7 +1092,7 @@ CodePathState.prototype = { // Update state. context.entrySegments = bodySegments; forkContext.replaceHead(bodySegments); - }, + } /** * Makes a code path segment for the test part of a DoWhileStatement. @@ -1114,7 +1113,7 @@ CodePathState.prototype = { forkContext.replaceHead(testSegments); } - }, + } /** * Makes a code path segment for the test part of a ForStatement. @@ -1133,7 +1132,7 @@ CodePathState.prototype = { context.endOfInitSegments = endOfInitSegments; context.continueDestSegments = context.testSegments = testSegments; forkContext.replaceHead(testSegments); - }, + } /** * Makes a code path segment for the update part of a ForStatement. @@ -1160,7 +1159,7 @@ CodePathState.prototype = { context.continueDestSegments = context.updateSegments = updateSegments; forkContext.replaceHead(updateSegments); - }, + } /** * Makes a code path segment for the body part of a ForStatement. @@ -1211,7 +1210,7 @@ CodePathState.prototype = { } context.continueDestSegments = context.continueDestSegments || bodySegments; forkContext.replaceHead(bodySegments); - }, + } /** * Makes a code path segment for the left part of a ForInStatement and a @@ -1228,7 +1227,7 @@ CodePathState.prototype = { context.prevSegments = forkContext.head; context.leftSegments = context.continueDestSegments = leftSegments; forkContext.replaceHead(leftSegments); - }, + } /** * Makes a code path segment for the right part of a ForInStatement and a @@ -1247,7 +1246,7 @@ CodePathState.prototype = { // Update state. context.endOfLeftSegments = forkContext.head; forkContext.replaceHead(rightSegments); - }, + } /** * Makes a code path segment for the body part of a ForInStatement and a @@ -1269,7 +1268,7 @@ CodePathState.prototype = { // Update state. context.brokenForkContext.add(forkContext.head); forkContext.replaceHead(bodySegments); - }, + } //-------------------------------------------------------------------------- // Control Statements @@ -1291,7 +1290,7 @@ CodePathState.prototype = { brokenForkContext: ForkContext.newEmpty(this.forkContext) }; return this.breakContext; - }, + } /** * Removes the top item of the break context stack. @@ -1315,7 +1314,7 @@ CodePathState.prototype = { } return context; - }, + } /** * Makes a path for a `break` statement. @@ -1341,7 +1340,7 @@ CodePathState.prototype = { } forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - }, + } /** * Makes a path for a `continue` statement. @@ -1377,7 +1376,7 @@ CodePathState.prototype = { } } forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - }, + } /** * Makes a path for a `return` statement. @@ -1394,7 +1393,7 @@ CodePathState.prototype = { getReturnContext(this).returnedForkContext.add(forkContext.head); forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } - }, + } /** * Makes a path for a `throw` statement. @@ -1411,7 +1410,7 @@ CodePathState.prototype = { getThrowContext(this).thrownForkContext.add(forkContext.head); forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } - }, + } /** * Makes the final path. @@ -1424,6 +1423,6 @@ CodePathState.prototype = { this.returnedForkContext.add(segments); } } -}; +} module.exports = CodePathState; diff --git a/tools/eslint/lib/code-path-analysis/code-path.js b/tools/eslint/lib/code-path-analysis/code-path.js index 96363423c23ed5..6ef07b4a2d93b2 100644 --- a/tools/eslint/lib/code-path-analysis/code-path.js +++ b/tools/eslint/lib/code-path-analysis/code-path.js @@ -18,47 +18,56 @@ const IdGenerator = require("./id-generator"); /** * A code path. - * - * @constructor - * @param {string} id - An identifier. - * @param {CodePath|null} upper - The code path of the upper function scope. - * @param {Function} onLooped - A callback function to notify looping. */ -function CodePath(id, upper, onLooped) { +class CodePath { /** - * The identifier of this code path. - * Rules use it to store additional information of each rule. - * @type {string} + * @param {string} id - An identifier. + * @param {CodePath|null} upper - The code path of the upper function scope. + * @param {Function} onLooped - A callback function to notify looping. */ - this.id = id; + constructor(id, upper, onLooped) { - /** - * The code path of the upper function scope. - * @type {CodePath|null} - */ - this.upper = upper; + /** + * The identifier of this code path. + * Rules use it to store additional information of each rule. + * @type {string} + */ + this.id = id; - /** - * The code paths of nested function scopes. - * @type {CodePath[]} - */ - this.childCodePaths = []; + /** + * The code path of the upper function scope. + * @type {CodePath|null} + */ + this.upper = upper; + + /** + * The code paths of nested function scopes. + * @type {CodePath[]} + */ + this.childCodePaths = []; - // Initializes internal state. - Object.defineProperty( - this, - "internal", - {value: new CodePathState(new IdGenerator(`${id}_`), onLooped)}); + // Initializes internal state. + Object.defineProperty( + this, + "internal", + { value: new CodePathState(new IdGenerator(`${id}_`), onLooped) }); - // Adds this into `childCodePaths` of `upper`. - if (upper) { - upper.childCodePaths.push(this); + // Adds this into `childCodePaths` of `upper`. + if (upper) { + upper.childCodePaths.push(this); + } } -} -CodePath.prototype = { - constructor: CodePath, + /** + * Gets the state of a given code path. + * + * @param {CodePath} codePath - A code path to get. + * @returns {CodePathState} The state of the code path. + */ + static getState(codePath) { + return codePath.internal; + } /** * The initial code path segment. @@ -66,7 +75,7 @@ CodePath.prototype = { */ get initialSegment() { return this.internal.initialSegment; - }, + } /** * Final code path segments. @@ -75,7 +84,7 @@ CodePath.prototype = { */ get finalSegments() { return this.internal.finalSegments; - }, + } /** * Final code path segments which is with `return` statements. @@ -85,7 +94,7 @@ CodePath.prototype = { */ get returnedSegments() { return this.internal.returnedForkContext; - }, + } /** * Final code path segments which is with `throw` statements. @@ -93,7 +102,7 @@ CodePath.prototype = { */ get thrownSegments() { return this.internal.thrownForkContext; - }, + } /** * Current code path segments. @@ -101,7 +110,7 @@ CodePath.prototype = { */ get currentSegments() { return this.internal.currentSegments; - }, + } /** * Traverses all segments in this code path. @@ -219,16 +228,6 @@ CodePath.prototype = { } } } -}; - -/** - * Gets the state of a given code path. - * - * @param {CodePath} codePath - A code path to get. - * @returns {CodePathState} The state of the code path. - */ -CodePath.getState = function getState(codePath) { - return codePath.internal; -}; +} module.exports = CodePath; diff --git a/tools/eslint/lib/code-path-analysis/debug-helpers.js b/tools/eslint/lib/code-path-analysis/debug-helpers.js index 5e311eb352b986..622bd6081fa546 100644 --- a/tools/eslint/lib/code-path-analysis/debug-helpers.js +++ b/tools/eslint/lib/code-path-analysis/debug-helpers.js @@ -108,7 +108,7 @@ module.exports = { } if (segment.internal.nodes.length > 0) { - text += segment.internal.nodes.map(function(node) { + text += segment.internal.nodes.map(node => { switch (node.type) { case "Identifier": return `${node.type} (${node.name})`; case "Literal": return `${node.type} (${node.value})`; @@ -116,7 +116,7 @@ module.exports = { } }).join("\\n"); } else if (segment.internal.exitNodes.length > 0) { - text += segment.internal.exitNodes.map(function(node) { + text += segment.internal.exitNodes.map(node => { switch (node.type) { case "Identifier": return `${node.type}:exit (${node.name})`; case "Literal": return `${node.type}:exit (${node.value})`; @@ -176,7 +176,7 @@ module.exports = { stack.push([nextSegment, 0]); } - codePath.returnedSegments.forEach(function(finalSegment) { + codePath.returnedSegments.forEach(finalSegment => { if (lastId === finalSegment.id) { text += "->final"; } else { @@ -185,7 +185,7 @@ module.exports = { lastId = null; }); - codePath.thrownSegments.forEach(function(finalSegment) { + codePath.thrownSegments.forEach(finalSegment => { if (lastId === finalSegment.id) { text += "->thrown"; } else { diff --git a/tools/eslint/lib/code-path-analysis/fork-context.js b/tools/eslint/lib/code-path-analysis/fork-context.js index 6996af1dcc1f71..7423c13199b3ff 100644 --- a/tools/eslint/lib/code-path-analysis/fork-context.js +++ b/tools/eslint/lib/code-path-analysis/fork-context.js @@ -99,21 +99,20 @@ function mergeExtraSegments(context, segments) { /** * A class to manage forking. - * - * @constructor - * @param {IdGenerator} idGenerator - An identifier generator for segments. - * @param {ForkContext|null} upper - An upper fork context. - * @param {number} count - A number of parallel segments. */ -function ForkContext(idGenerator, upper, count) { - this.idGenerator = idGenerator; - this.upper = upper; - this.count = count; - this.segmentsList = []; -} +class ForkContext { -ForkContext.prototype = { - constructor: ForkContext, + /** + * @param {IdGenerator} idGenerator - An identifier generator for segments. + * @param {ForkContext|null} upper - An upper fork context. + * @param {number} count - A number of parallel segments. + */ + constructor(idGenerator, upper, count) { + this.idGenerator = idGenerator; + this.upper = upper; + this.count = count; + this.segmentsList = []; + } /** * The head segments. @@ -123,7 +122,7 @@ ForkContext.prototype = { const list = this.segmentsList; return list.length === 0 ? [] : list[list.length - 1]; - }, + } /** * A flag which shows empty. @@ -131,7 +130,7 @@ ForkContext.prototype = { */ get empty() { return this.segmentsList.length === 0; - }, + } /** * A flag which shows reachable. @@ -141,7 +140,7 @@ ForkContext.prototype = { const segments = this.head; return segments.length > 0 && segments.some(isReachable); - }, + } /** * Creates new segments from this context. @@ -152,7 +151,7 @@ ForkContext.prototype = { */ makeNext(begin, end) { return makeSegments(this, begin, end, CodePathSegment.newNext); - }, + } /** * Creates new segments from this context. @@ -164,7 +163,7 @@ ForkContext.prototype = { */ makeUnreachable(begin, end) { return makeSegments(this, begin, end, CodePathSegment.newUnreachable); - }, + } /** * Creates new segments from this context. @@ -177,7 +176,7 @@ ForkContext.prototype = { */ makeDisconnected(begin, end) { return makeSegments(this, begin, end, CodePathSegment.newDisconnected); - }, + } /** * Adds segments into this context. @@ -190,7 +189,7 @@ ForkContext.prototype = { assert(segments.length >= this.count, `${segments.length} >= ${this.count}`); this.segmentsList.push(mergeExtraSegments(this, segments)); - }, + } /** * Replaces the head segments with given segments. @@ -203,7 +202,7 @@ ForkContext.prototype = { assert(segments.length >= this.count, `${segments.length} >= ${this.count}`); this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments)); - }, + } /** * Adds all segments of a given fork context into this context. @@ -219,7 +218,7 @@ ForkContext.prototype = { for (let i = 0; i < source.length; ++i) { this.segmentsList.push(source[i]); } - }, + } /** * Clears all secments in this context. @@ -229,34 +228,34 @@ ForkContext.prototype = { clear() { this.segmentsList = []; } -}; -/** - * Creates the root fork context. - * - * @param {IdGenerator} idGenerator - An identifier generator for segments. - * @returns {ForkContext} New fork context. - */ -ForkContext.newRoot = function(idGenerator) { - const context = new ForkContext(idGenerator, null, 1); + /** + * Creates the root fork context. + * + * @param {IdGenerator} idGenerator - An identifier generator for segments. + * @returns {ForkContext} New fork context. + */ + static newRoot(idGenerator) { + const context = new ForkContext(idGenerator, null, 1); - context.add([CodePathSegment.newRoot(idGenerator.next())]); + context.add([CodePathSegment.newRoot(idGenerator.next())]); - return context; -}; + return context; + } -/** - * Creates an empty fork context preceded by a given context. - * - * @param {ForkContext} parentContext - The parent fork context. - * @param {boolean} forkLeavingPath - A flag which shows inside of `finally` block. - * @returns {ForkContext} New fork context. - */ -ForkContext.newEmpty = function(parentContext, forkLeavingPath) { - return new ForkContext( - parentContext.idGenerator, - parentContext, - (forkLeavingPath ? 2 : 1) * parentContext.count); -}; + /** + * Creates an empty fork context preceded by a given context. + * + * @param {ForkContext} parentContext - The parent fork context. + * @param {boolean} forkLeavingPath - A flag which shows inside of `finally` block. + * @returns {ForkContext} New fork context. + */ + static newEmpty(parentContext, forkLeavingPath) { + return new ForkContext( + parentContext.idGenerator, + parentContext, + (forkLeavingPath ? 2 : 1) * parentContext.count); + } +} module.exports = ForkContext; diff --git a/tools/eslint/lib/code-path-analysis/id-generator.js b/tools/eslint/lib/code-path-analysis/id-generator.js index f33858cacd4071..062058ddc12639 100644 --- a/tools/eslint/lib/code-path-analysis/id-generator.js +++ b/tools/eslint/lib/code-path-analysis/id-generator.js @@ -15,29 +15,32 @@ /** * A generator for unique ids. - * - * @constructor - * @param {string} prefix - Optional. A prefix of generated ids. - */ -function IdGenerator(prefix) { - this.prefix = String(prefix); - this.n = 0; -} - -/** - * Generates id. - * - * @returns {string} A generated id. */ -IdGenerator.prototype.next = function() { - this.n = 1 + this.n | 0; +class IdGenerator { - /* istanbul ignore if */ - if (this.n < 0) { - this.n = 1; + /** + * @param {string} prefix - Optional. A prefix of generated ids. + */ + constructor(prefix) { + this.prefix = String(prefix); + this.n = 0; } - return this.prefix + this.n; -}; + /** + * Generates id. + * + * @returns {string} A generated id. + */ + next() { + this.n = 1 + this.n | 0; + + /* istanbul ignore if */ + if (this.n < 0) { + this.n = 1; + } + + return this.prefix + this.n; + } +} module.exports = IdGenerator; diff --git a/tools/eslint/lib/config.js b/tools/eslint/lib/config.js index 9ff203c16d9e45..9c56e7ad988e28 100644 --- a/tools/eslint/lib/config.js +++ b/tools/eslint/lib/config.js @@ -179,155 +179,159 @@ function getLocalConfig(thisConfig, directory) { //------------------------------------------------------------------------------ /** - * Config - * @constructor - * @class Config - * @param {Object} options Options to be passed in + * Configuration class */ -function Config(options) { - options = options || {}; +class Config { - this.ignore = options.ignore; - this.ignorePath = options.ignorePath; - this.cache = {}; - this.parser = options.parser; - this.parserOptions = options.parserOptions || {}; + /** + * Config options + * @param {Object} options Options to be passed in + */ + constructor(options) { + options = options || {}; - this.baseConfig = options.baseConfig ? loadConfig(options.baseConfig) : { rules: {} }; + this.ignore = options.ignore; + this.ignorePath = options.ignorePath; + this.cache = {}; + this.parser = options.parser; + this.parserOptions = options.parserOptions || {}; - this.useEslintrc = (options.useEslintrc !== false); + this.baseConfig = options.baseConfig ? loadConfig(options.baseConfig) : { rules: {} }; - this.env = (options.envs || []).reduce(function(envs, name) { - envs[name] = true; - return envs; - }, {}); + this.useEslintrc = (options.useEslintrc !== false); - /* - * Handle declared globals. - * For global variable foo, handle "foo:false" and "foo:true" to set - * whether global is writable. - * If user declares "foo", convert to "foo:false". - */ - this.globals = (options.globals || []).reduce(function(globals, def) { - const parts = def.split(":"); + this.env = (options.envs || []).reduce((envs, name) => { + envs[ name ] = true; + return envs; + }, {}); - globals[parts[0]] = (parts.length > 1 && parts[1] === "true"); + /* + * Handle declared globals. + * For global variable foo, handle "foo:false" and "foo:true" to set + * whether global is writable. + * If user declares "foo", convert to "foo:false". + */ + this.globals = (options.globals || []).reduce((globals, def) => { + const parts = def.split(":"); - return globals; - }, {}); + globals[parts[0]] = (parts.length > 1 && parts[1] === "true"); - const useConfig = options.configFile; + return globals; + }, {}); - this.options = options; + const useConfig = options.configFile; - if (useConfig) { - debug(`Using command line config ${useConfig}`); - if (isResolvable(useConfig) || isResolvable(`eslint-config-${useConfig}`) || useConfig.charAt(0) === "@") { - this.useSpecificConfig = loadConfig(useConfig); - } else { - this.useSpecificConfig = loadConfig(path.resolve(this.options.cwd, useConfig)); + this.options = options; + + if (useConfig) { + debug(`Using command line config ${useConfig}`); + if (isResolvable(useConfig) || isResolvable(`eslint-config-${useConfig}`) || useConfig.charAt(0) === "@") { + this.useSpecificConfig = loadConfig(useConfig); + } else { + this.useSpecificConfig = loadConfig(path.resolve(this.options.cwd, useConfig)); + } } } -} -/** - * Build a config object merging the base config (conf/eslint.json), the - * environments config (conf/environments.js) and eventually the user config. - * @param {string} filePath a file in whose directory we start looking for a local config - * @returns {Object} config object - */ -Config.prototype.getConfig = function(filePath) { - const directory = filePath ? path.dirname(filePath) : this.options.cwd; - let config, - userConfig; + /** + * Build a config object merging the base config (conf/eslint.json), the + * environments config (conf/environments.js) and eventually the user config. + * @param {string} filePath a file in whose directory we start looking for a local config + * @returns {Object} config object + */ + getConfig(filePath) { + const directory = filePath ? path.dirname(filePath) : this.options.cwd; + let config, + userConfig; - debug(`Constructing config for ${filePath ? filePath : "text"}`); + debug(`Constructing config for ${filePath ? filePath : "text"}`); - config = this.cache[directory]; + config = this.cache[directory]; - if (config) { - debug("Using config from cache"); - return config; - } + if (config) { + debug("Using config from cache"); + return config; + } - // Step 1: Determine user-specified config from .eslintrc.* and package.json files - if (this.useEslintrc) { - debug("Using .eslintrc and package.json files"); - userConfig = getLocalConfig(this, directory); - } else { - debug("Not using .eslintrc or package.json files"); - userConfig = {}; - } + // Step 1: Determine user-specified config from .eslintrc.* and package.json files + if (this.useEslintrc) { + debug("Using .eslintrc and package.json files"); + userConfig = getLocalConfig(this, directory); + } else { + debug("Not using .eslintrc or package.json files"); + userConfig = {}; + } - // Step 2: Create a copy of the baseConfig - config = ConfigOps.merge({}, this.baseConfig); + // Step 2: Create a copy of the baseConfig + config = ConfigOps.merge({}, this.baseConfig); - // Step 3: Merge in the user-specified configuration from .eslintrc and package.json - config = ConfigOps.merge(config, userConfig); + // Step 3: Merge in the user-specified configuration from .eslintrc and package.json + config = ConfigOps.merge(config, userConfig); - // Step 4: Merge in command line config file - if (this.useSpecificConfig) { - debug("Merging command line config file"); + // Step 4: Merge in command line config file + if (this.useSpecificConfig) { + debug("Merging command line config file"); - config = ConfigOps.merge(config, this.useSpecificConfig); - } + config = ConfigOps.merge(config, this.useSpecificConfig); + } - // Step 5: Merge in command line environments - debug("Merging command line environment settings"); - config = ConfigOps.merge(config, { env: this.env }); + // Step 5: Merge in command line environments + debug("Merging command line environment settings"); + config = ConfigOps.merge(config, { env: this.env }); - // Step 6: Merge in command line rules - if (this.options.rules) { - debug("Merging command line rules"); - config = ConfigOps.merge(config, { rules: this.options.rules }); - } + // Step 6: Merge in command line rules + if (this.options.rules) { + debug("Merging command line rules"); + config = ConfigOps.merge(config, { rules: this.options.rules }); + } - // Step 7: Merge in command line globals - config = ConfigOps.merge(config, { globals: this.globals }); + // Step 7: Merge in command line globals + config = ConfigOps.merge(config, { globals: this.globals }); - // Only override parser if it is passed explicitly through the command line or if it's not - // defined yet (because the final object will at least have the parser key) - if (this.parser || !config.parser) { - config = ConfigOps.merge(config, { - parser: this.parser - }); - } + // Only override parser if it is passed explicitly through the command line or if it's not + // defined yet (because the final object will at least have the parser key) + if (this.parser || !config.parser) { + config = ConfigOps.merge(config, { + parser: this.parser + }); + } - if (this.parserOptions) { - config = ConfigOps.merge(config, { - parserOptions: this.parserOptions - }); - } + if (this.parserOptions) { + config = ConfigOps.merge(config, { + parserOptions: this.parserOptions + }); + } - // Step 8: Merge in command line plugins - if (this.options.plugins) { - debug("Merging command line plugins"); - Plugins.loadAll(this.options.plugins); - config = ConfigOps.merge(config, { plugins: this.options.plugins }); - } + // Step 8: Merge in command line plugins + if (this.options.plugins) { + debug("Merging command line plugins"); + Plugins.loadAll(this.options.plugins); + config = ConfigOps.merge(config, { plugins: this.options.plugins }); + } - // Step 9: Apply environments to the config if present - if (config.env) { - config = ConfigOps.applyEnvironments(config); - } + // Step 9: Apply environments to the config if present + if (config.env) { + config = ConfigOps.applyEnvironments(config); + } - this.cache[directory] = config; + this.cache[directory] = config; - return config; -}; + return config; + } -/** - * Find local config files from directory and parent directories. - * @param {string} directory The directory to start searching from. - * @returns {string[]} The paths of local config files found. - */ -Config.prototype.findLocalConfigFiles = function(directory) { + /** + * Find local config files from directory and parent directories. + * @param {string} directory The directory to start searching from. + * @returns {string[]} The paths of local config files found. + */ + findLocalConfigFiles(directory) { - if (!this.localConfigFinder) { - this.localConfigFinder = new FileFinder(ConfigFile.CONFIG_FILES, this.options.cwd); - } + if (!this.localConfigFinder) { + this.localConfigFinder = new FileFinder(ConfigFile.CONFIG_FILES, this.options.cwd); + } - return this.localConfigFinder.findAllInDirectoryAndParents(directory); -}; + return this.localConfigFinder.findAllInDirectoryAndParents(directory); + } +} module.exports = Config; diff --git a/tools/eslint/lib/config/autoconfig.js b/tools/eslint/lib/config/autoconfig.js index dd25bcd49191bc..23fdbe69803afc 100644 --- a/tools/eslint/lib/config/autoconfig.js +++ b/tools/eslint/lib/config/autoconfig.js @@ -49,14 +49,12 @@ const MAX_CONFIG_COMBINATIONS = 17, // 16 combinations + 1 for severity only * @returns {Object} registryItems for each rule in provided rulesConfig */ function makeRegistryItems(rulesConfig) { - return Object.keys(rulesConfig).reduce(function(accumulator, ruleId) { - accumulator[ruleId] = rulesConfig[ruleId].map(function(config) { - return { - config, - specificity: config.length || 1, - errorCount: void 0 - }; - }); + return Object.keys(rulesConfig).reduce((accumulator, ruleId) => { + accumulator[ruleId] = rulesConfig[ruleId].map(config => ({ + config, + specificity: config.length || 1, + errorCount: void 0 + })); return accumulator; }, {}); } @@ -173,10 +171,8 @@ Registry.prototype = { newRegistry = new Registry(); newRegistry.rules = Object.assign({}, this.rules); - ruleIds.forEach(function(ruleId) { - const errorFreeItems = newRegistry.rules[ruleId].filter(function(registryItem) { - return (registryItem.errorCount === 0); - }); + ruleIds.forEach(ruleId => { + const errorFreeItems = newRegistry.rules[ruleId].filter(registryItem => (registryItem.errorCount === 0)); if (errorFreeItems.length > 0) { newRegistry.rules[ruleId] = errorFreeItems; @@ -198,10 +194,8 @@ Registry.prototype = { newRegistry = new Registry(); newRegistry.rules = Object.assign({}, this.rules); - ruleIds.forEach(function(ruleId) { - newRegistry.rules[ruleId] = newRegistry.rules[ruleId].filter(function(registryItem) { - return (typeof registryItem.errorCount !== "undefined"); - }); + ruleIds.forEach(ruleId => { + newRegistry.rules[ruleId] = newRegistry.rules[ruleId].filter(registryItem => (typeof registryItem.errorCount !== "undefined")); }); return newRegistry; @@ -218,15 +212,13 @@ Registry.prototype = { const ruleIds = Object.keys(this.rules), failingRegistry = new Registry(); - ruleIds.forEach(function(ruleId) { - const failingConfigs = this.rules[ruleId].filter(function(registryItem) { - return (registryItem.errorCount > 0); - }); + ruleIds.forEach(ruleId => { + const failingConfigs = this.rules[ruleId].filter(registryItem => (registryItem.errorCount > 0)); if (failingConfigs && failingConfigs.length === this.rules[ruleId].length) { failingRegistry.rules[ruleId] = failingConfigs; } - }.bind(this)); + }); return failingRegistry; }, @@ -239,13 +231,13 @@ Registry.prototype = { */ createConfig() { const ruleIds = Object.keys(this.rules), - config = {rules: {}}; + config = { rules: {} }; - ruleIds.forEach(function(ruleId) { + ruleIds.forEach(ruleId => { if (this.rules[ruleId].length === 1) { config.rules[ruleId] = this.rules[ruleId][0].config; } - }.bind(this)); + }); return config; }, @@ -261,11 +253,9 @@ Registry.prototype = { newRegistry = new Registry(); newRegistry.rules = Object.assign({}, this.rules); - ruleIds.forEach(function(ruleId) { - newRegistry.rules[ruleId] = this.rules[ruleId].filter(function(registryItem) { - return (registryItem.specificity === specificity); - }); - }.bind(this)); + ruleIds.forEach(ruleId => { + newRegistry.rules[ruleId] = this.rules[ruleId].filter(registryItem => (registryItem.specificity === specificity)); + }); return newRegistry; }, @@ -294,16 +284,16 @@ Registry.prototype = { const filenames = Object.keys(sourceCodes); const totalFilesLinting = filenames.length * ruleSets.length; - filenames.forEach(function(filename) { + filenames.forEach(filename => { debug(`Linting file: ${filename}`); ruleSetIdx = 0; - ruleSets.forEach(function(ruleSet) { - const lintConfig = Object.assign({}, config, {rules: ruleSet}); + ruleSets.forEach(ruleSet => { + const lintConfig = Object.assign({}, config, { rules: ruleSet }); const lintResults = eslint.verify(sourceCodes[filename], lintConfig); - lintResults.forEach(function(result) { + lintResults.forEach(result => { // It is possible that the error is from a configuration comment // in a linted file, in which case there may not be a config @@ -342,11 +332,9 @@ function extendFromRecommended(config) { ConfigOps.normalizeToStrings(newConfig); - const recRules = Object.keys(recConfig.rules).filter(function(ruleId) { - return ConfigOps.isErrorSeverity(recConfig.rules[ruleId]); - }); + const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId])); - recRules.forEach(function(ruleId) { + recRules.forEach(ruleId => { if (lodash.isEqual(recConfig.rules[ruleId], newConfig.rules[ruleId])) { delete newConfig.rules[ruleId]; } diff --git a/tools/eslint/lib/config/config-file.js b/tools/eslint/lib/config/config-file.js index c11a55fad8413d..90015097a3db97 100644 --- a/tools/eslint/lib/config/config-file.js +++ b/tools/eslint/lib/config/config-file.js @@ -235,7 +235,7 @@ function loadConfigFile(file) { function writeJSONConfigFile(config, filePath) { debug(`Writing JSON config file: ${filePath}`); - const content = stringify(config, {cmp: sortByKey, space: 4}); + const content = stringify(config, { cmp: sortByKey, space: 4 }); fs.writeFileSync(filePath, content, "utf8"); } @@ -253,7 +253,7 @@ function writeYAMLConfigFile(config, filePath) { // lazy load YAML to improve performance when not used const yaml = require("js-yaml"); - const content = yaml.safeDump(config, {sortKeys: true}); + const content = yaml.safeDump(config, { sortKeys: true }); fs.writeFileSync(filePath, content, "utf8"); } @@ -268,7 +268,7 @@ function writeYAMLConfigFile(config, filePath) { function writeJSConfigFile(config, filePath) { debug(`Writing JS config file: ${filePath}`); - const content = `module.exports = ${stringify(config, {cmp: sortByKey, space: 4})};`; + const content = `module.exports = ${stringify(config, { cmp: sortByKey, space: 4 })};`; fs.writeFileSync(filePath, content, "utf8"); } @@ -359,7 +359,7 @@ function applyExtends(config, filePath, relativeTo) { } // Make the last element in an array take the highest precedence - config = configExtends.reduceRight(function(previousValue, parentPath) { + config = configExtends.reduceRight((previousValue, parentPath) => { if (parentPath === "eslint:recommended") { @@ -430,7 +430,7 @@ function normalizePackageName(name, prefix) { * it's a scoped package * package name is "eslint-config", or just a username */ - const scopedPackageShortcutRegex = new RegExp(`^(@[^\/]+)(?:\/(?:${prefix})?)?$`), + const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`), scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`); if (scopedPackageShortcutRegex.test(name)) { @@ -441,7 +441,7 @@ function normalizePackageName(name, prefix) { * for scoped packages, insert the eslint-config after the first / unless * the path is already @scope/eslint or @scope/eslint-config-xxx */ - name = name.replace(/^@([^\/]+)\/(.*)$/, `@$1/${prefix}-$2`); + name = name.replace(/^@([^/]+)\/(.*)$/, `@$1/${prefix}-$2`); } } else if (name.indexOf(`${prefix}-`) !== 0) { name = `${prefix}-${name}`; diff --git a/tools/eslint/lib/config/config-initializer.js b/tools/eslint/lib/config/config-initializer.js index e3aef07baef388..502a73bd6c3ed1 100644 --- a/tools/eslint/lib/config/config-initializer.js +++ b/tools/eslint/lib/config/config-initializer.js @@ -44,10 +44,14 @@ function writeFile(config, format) { extname = ".json"; } + const installedESLint = config.installedESLint; + + delete config.installedESLint; + ConfigFile.write(config, `./.eslintrc${extname}`); log.info(`Successfully created .eslintrc${extname} file in ${process.cwd()}`); - if (config.installedESLint) { + if (installedESLint) { log.info("ESLint was installed locally. We recommend using this local copy instead of your globally-installed copy."); } } @@ -62,9 +66,7 @@ function installModules(config) { // Create a list of modules which should be installed based on config if (config.plugins) { - modules = modules.concat(config.plugins.map(function(name) { - return `eslint-plugin-${name}`; - })); + modules = modules.concat(config.plugins.map(name => `eslint-plugin-${name}`)); } if (config.extends && config.extends.indexOf("eslint:") === -1) { modules.push(`eslint-config-${config.extends}`); @@ -81,7 +83,7 @@ function installModules(config) { const installStatus = npmUtil.checkDevDeps(modules); // Install packages which aren't already installed - const modulesToInstall = Object.keys(installStatus).filter(function(module) { + const modulesToInstall = Object.keys(installStatus).filter(module => { const notInstalled = installStatus[module] === false; if (module === "eslint" && notInstalled) { @@ -128,7 +130,7 @@ function configureRules(answers, config) { const patterns = answers.patterns.split(/[\s]+/); try { - sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, function(total) { + sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, total => { bar.tick((BAR_SOURCE_CODE_TOTAL / total)); }); } catch (e) { @@ -147,20 +149,18 @@ function configureRules(answers, config) { registry.populateFromCoreRules(); // Lint all files with each rule config in the registry - registry = registry.lintSourceCode(sourceCodes, newConfig, function(total) { + registry = registry.lintSourceCode(sourceCodes, newConfig, total => { bar.tick((BAR_TOTAL - BAR_SOURCE_CODE_TOTAL) / total); // Subtract out ticks used at beginning }); - debug(`\nRegistry: ${util.inspect(registry.rules, {depth: null})}`); + debug(`\nRegistry: ${util.inspect(registry.rules, { depth: null })}`); // Create a list of recommended rules, because we don't want to disable them - const recRules = Object.keys(recConfig.rules).filter(function(ruleId) { - return ConfigOps.isErrorSeverity(recConfig.rules[ruleId]); - }); + const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId])); // Find and disable rules which had no error-free configuration const failingRegistry = registry.getFailingRulesRegistry(); - Object.keys(failingRegistry.rules).forEach(function(ruleId) { + Object.keys(failingRegistry.rules).forEach(ruleId => { // If the rule is recommended, set it to error, otherwise disable it disabledConfigs[ruleId] = (recRules.indexOf(ruleId) !== -1) ? 2 : 0; @@ -194,9 +194,7 @@ function configureRules(answers, config) { // Log out some stats to let the user know what happened const finalRuleIds = Object.keys(newConfig.rules); const totalRules = finalRuleIds.length; - const enabledRules = finalRuleIds.filter(function(ruleId) { - return (newConfig.rules[ruleId] !== 0); - }).length; + const enabledRules = finalRuleIds.filter(ruleId => (newConfig.rules[ruleId] !== 0)).length; const resultMessage = [ `\nEnabled ${enabledRules} out of ${totalRules}`, `rules based on ${fileQty}`, @@ -215,7 +213,7 @@ function configureRules(answers, config) { * @returns {Object} config object */ function processAnswers(answers) { - let config = {rules: {}, env: {}}; + let config = { rules: {}, env: {} }; if (answers.es6) { config.env.es6 = true; @@ -227,7 +225,7 @@ function processAnswers(answers) { if (answers.commonjs) { config.env.commonjs = true; } - answers.env.forEach(function(env) { + answers.env.forEach(env => { config.env[env] = true; }); if (answers.jsx) { @@ -266,9 +264,10 @@ function processAnswers(answers) { */ function getConfigForStyleGuide(guide) { const guides = { - google: {extends: "google"}, - airbnb: {extends: "airbnb", plugins: ["react", "jsx-a11y", "import"]}, - standard: {extends: "standard", plugins: ["standard", "promise"]} + google: { extends: "google" }, + airbnb: { extends: "airbnb", plugins: ["react", "jsx-a11y", "import"] }, + "airbnb-base": { extends: "airbnb-base", plugins: ["import"] }, + standard: { extends: "standard", plugins: ["standard", "promise"] } }; if (!guides[guide]) { @@ -296,21 +295,30 @@ function promptUser(callback) { message: "How would you like to configure ESLint?", default: "prompt", choices: [ - {name: "Answer questions about your style", value: "prompt"}, - {name: "Use a popular style guide", value: "guide"}, - {name: "Inspect your JavaScript file(s)", value: "auto"} + { name: "Answer questions about your style", value: "prompt" }, + { name: "Use a popular style guide", value: "guide" }, + { name: "Inspect your JavaScript file(s)", value: "auto" } ] }, { type: "list", name: "styleguide", message: "Which style guide do you want to follow?", - choices: [{name: "Google", value: "google"}, {name: "Airbnb", value: "airbnb"}, {name: "Standard", value: "standard"}], + choices: [{ name: "Google", value: "google" }, { name: "Airbnb", value: "airbnb" }, { name: "Standard", value: "standard" }], when(answers) { answers.packageJsonExists = npmUtil.checkPackageJson(); return answers.source === "guide" && answers.packageJsonExists; } }, + { + type: "confirm", + name: "airbnbReact", + message: "Do you use React?", + default: false, + when(answers) { + return answers.styleguide === "airbnb"; + }, + }, { type: "input", name: "patterns", @@ -335,7 +343,7 @@ function promptUser(callback) { return ((answers.source === "guide" && answers.packageJsonExists) || answers.source === "auto"); } } - ], function(earlyAnswers) { + ], earlyAnswers => { // early exit if you are using a style guide if (earlyAnswers.source === "guide") { @@ -343,7 +351,9 @@ function promptUser(callback) { log.info("A package.json is necessary to install plugins such as style guides. Run `npm init` to create a package.json file and try again."); return; } - + if (earlyAnswers.styleguide === "airbnb" && !earlyAnswers.airbnbReact) { + earlyAnswers.styleguide = "airbnb-base"; + } try { config = getConfigForStyleGuide(earlyAnswers.styleguide); writeFile(config, earlyAnswers.format); @@ -376,7 +386,7 @@ function promptUser(callback) { name: "env", message: "Where will your code run?", default: ["browser"], - choices: [{name: "Browser", value: "browser"}, {name: "Node", value: "node"}] + choices: [{ name: "Browser", value: "browser" }, { name: "Node", value: "node" }] }, { type: "confirm", @@ -384,9 +394,7 @@ function promptUser(callback) { message: "Do you use CommonJS?", default: false, when(answers) { - return answers.env.some(function(env) { - return env === "browser"; - }); + return answers.env.some(env => env === "browser"); } }, { @@ -398,13 +406,13 @@ function promptUser(callback) { { type: "confirm", name: "react", - message: "Do you use React", + message: "Do you use React?", default: false, when(answers) { return answers.jsx; } } - ], function(secondAnswers) { + ], secondAnswers => { // early exit if you are using automatic style generation if (earlyAnswers.source === "auto") { @@ -428,21 +436,21 @@ function promptUser(callback) { name: "indent", message: "What style of indentation do you use?", default: "tab", - choices: [{name: "Tabs", value: "tab"}, {name: "Spaces", value: 4}] + choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }] }, { type: "list", name: "quotes", message: "What quotes do you use for strings?", default: "double", - choices: [{name: "Double", value: "double"}, {name: "Single", value: "single"}] + choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }] }, { type: "list", name: "linebreak", message: "What line endings do you use?", default: "unix", - choices: [{name: "Unix", value: "unix"}, {name: "Windows", value: "windows"}] + choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }] }, { type: "confirm", @@ -457,7 +465,7 @@ function promptUser(callback) { default: "JavaScript", choices: ["JavaScript", "YAML", "JSON"] } - ], function(answers) { + ], answers => { try { const totalAnswers = Object.assign({}, earlyAnswers, secondAnswers, answers); @@ -465,10 +473,8 @@ function promptUser(callback) { installModules(config); writeFile(config, answers.format); } catch (err) { - callback(err); - return; + callback(err); // eslint-disable-line callback-return } - return; }); }); }); diff --git a/tools/eslint/lib/config/config-ops.js b/tools/eslint/lib/config/config-ops.js index 42b0fe81b90615..52dea1a106df79 100644 --- a/tools/eslint/lib/config/config-ops.js +++ b/tools/eslint/lib/config/config-ops.js @@ -18,7 +18,7 @@ const debug = require("debug")("eslint:config-ops"); //------------------------------------------------------------------------------ const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], - RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce(function(map, value, index) { + RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => { map[value] = index; return map; }, {}), @@ -57,9 +57,7 @@ module.exports = { envConfig.env = env; - Object.keys(env).filter(function(name) { - return env[name]; - }).forEach(function(name) { + Object.keys(env).filter(name => env[name]).forEach(name => { const environment = Environments.get(name); if (environment) { @@ -149,7 +147,7 @@ module.exports = { if (typeof src !== "object" && !Array.isArray(src)) { src = [src]; } - Object.keys(src).forEach(function(e, i) { + Object.keys(src).forEach((e, i) => { e = src[i]; if (typeof dst[i] === "undefined") { dst[i] = e; @@ -171,11 +169,11 @@ module.exports = { }); } else { if (target && typeof target === "object") { - Object.keys(target).forEach(function(key) { + Object.keys(target).forEach(key => { dst[key] = target[key]; }); } - Object.keys(src).forEach(function(key) { + Object.keys(src).forEach(key => { if (Array.isArray(src[key]) || Array.isArray(target[key])) { dst[key] = deepmerge(target[key], src[key], key === "plugins", isRule); } else if (typeof src[key] !== "object" || !src[key] || key === "exported" || key === "astGlobals") { @@ -199,7 +197,7 @@ module.exports = { normalize(config) { if (config.rules) { - Object.keys(config.rules).forEach(function(ruleId) { + Object.keys(config.rules).forEach(ruleId => { const ruleConfig = config.rules[ruleId]; if (typeof ruleConfig === "string") { @@ -221,7 +219,7 @@ module.exports = { normalizeToStrings(config) { if (config.rules) { - Object.keys(config.rules).forEach(function(ruleId) { + Object.keys(config.rules).forEach(ruleId => { const ruleConfig = config.rules[ruleId]; if (typeof ruleConfig === "number") { @@ -269,8 +267,6 @@ module.exports = { * @returns {boolean} `true` if the configuration has valid severity. */ isEverySeverityValid(config) { - return Object.keys(config).every(function(ruleId) { - return this.isValidSeverity(config[ruleId]); - }, this); + return Object.keys(config).every(ruleId => this.isValidSeverity(config[ruleId])); } }; diff --git a/tools/eslint/lib/config/config-rule.js b/tools/eslint/lib/config/config-rule.js index eb5c23fe8c840a..d495198aed454b 100644 --- a/tools/eslint/lib/config/config-rule.js +++ b/tools/eslint/lib/config/config-rule.js @@ -23,7 +23,7 @@ const rules = require("../rules"), * @returns {Array[]} An array of arrays. */ function explodeArray(xs) { - return xs.reduce(function(accumulator, x) { + return xs.reduce((accumulator, x) => { accumulator.push([x]); return accumulator; }, []); @@ -49,8 +49,8 @@ function combineArrays(arr1, arr2) { if (arr2.length === 0) { return explodeArray(arr1); } - arr1.forEach(function(x1) { - arr2.forEach(function(x2) { + arr1.forEach(x1 => { + arr2.forEach(x2 => { res.push([].concat(x1, x2)); }); }); @@ -78,16 +78,14 @@ function combineArrays(arr1, arr2) { * @returns {Array[]} Array of arrays of objects grouped by property */ function groupByProperty(objects) { - const groupedObj = objects.reduce(function(accumulator, obj) { + const groupedObj = objects.reduce((accumulator, obj) => { const prop = Object.keys(obj)[0]; accumulator[prop] = accumulator[prop] ? accumulator[prop].concat(obj) : [obj]; return accumulator; }, {}); - return Object.keys(groupedObj).map(function(prop) { - return groupedObj[prop]; - }); + return Object.keys(groupedObj).map(prop => groupedObj[prop]); } @@ -152,16 +150,16 @@ function combinePropertyObjects(objArr1, objArr2) { if (objArr2.length === 0) { return objArr1; } - objArr1.forEach(function(obj1) { - objArr2.forEach(function(obj2) { + objArr1.forEach(obj1 => { + objArr2.forEach(obj2 => { const combinedObj = {}; const obj1Props = Object.keys(obj1); const obj2Props = Object.keys(obj2); - obj1Props.forEach(function(prop1) { + obj1Props.forEach(prop1 => { combinedObj[prop1] = obj1[prop1]; }); - obj2Props.forEach(function(prop2) { + obj2Props.forEach(prop2 => { combinedObj[prop2] = obj2[prop2]; }); res.push(combinedObj); @@ -205,7 +203,7 @@ RuleConfigSet.prototype = { addErrorSeverity(severity) { severity = severity || 2; - this.ruleConfigs = this.ruleConfigs.map(function(config) { + this.ruleConfigs = this.ruleConfigs.map(config => { config.unshift(severity); return config; }); @@ -241,9 +239,7 @@ RuleConfigSet.prototype = { }, combine() { - this.objectConfigs = groupByProperty(this.objectConfigs).reduce(function(accumulator, objArr) { - return combinePropertyObjects(accumulator, objArr); - }, []); + this.objectConfigs = groupByProperty(this.objectConfigs).reduce((accumulator, objArr) => combinePropertyObjects(accumulator, objArr), []); } }; @@ -251,7 +247,7 @@ RuleConfigSet.prototype = { * The object schema could have multiple independent properties. * If any contain enums or booleans, they can be added and then combined */ - Object.keys(obj.properties).forEach(function(prop) { + Object.keys(obj.properties).forEach(prop => { if (obj.properties[prop].enum) { objectConfigSet.add(prop, obj.properties[prop].enum); } @@ -276,7 +272,7 @@ function generateConfigsFromSchema(schema) { const configSet = new RuleConfigSet(); if (Array.isArray(schema)) { - schema.forEach(function(opt) { + schema.forEach(opt => { if (opt.enum) { configSet.addEnums(opt.enum); } @@ -302,7 +298,7 @@ function generateConfigsFromSchema(schema) { function createCoreRuleConfigs() { const ruleList = loadRules(); - return Object.keys(ruleList).reduce(function(accumulator, id) { + return Object.keys(ruleList).reduce((accumulator, id) => { const rule = rules.get(id); const schema = (typeof rule === "function") ? rule.schema : rule.meta.schema; diff --git a/tools/eslint/lib/config/config-validator.js b/tools/eslint/lib/config/config-validator.js index ef285eae4e6032..c5268169b92356 100644 --- a/tools/eslint/lib/config/config-validator.js +++ b/tools/eslint/lib/config/config-validator.js @@ -54,65 +54,59 @@ function getRuleOptionsSchema(id) { } /** - * Validates a rule's options against its schema. - * @param {string} id The rule's unique name. - * @param {array|number} options The given options for the rule. - * @param {string} source The name of the configuration source. - * @returns {void} - */ -function validateRuleOptions(id, options, source) { - const schema = getRuleOptionsSchema(id); - let validateRule = validators.rules[id], - severity, - localOptions, - validSeverity = true; - - if (!validateRule && schema) { - validateRule = schemaValidator(schema, { verbose: true }); - validators.rules[id] = validateRule; +* Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. +* @param {options} options The given options for the rule. +* @returns {number|string} The rule's severity value +*/ +function validateRuleSeverity(options) { + const severity = Array.isArray(options) ? options[0] : options; + + if (severity !== 0 && severity !== 1 && severity !== 2 && !(typeof severity === "string" && /^(?:off|warn|error)$/i.test(severity))) { + throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`); } - // if it's not an array, it should be just a severity - if (Array.isArray(options)) { - localOptions = options.concat(); // clone - severity = localOptions.shift(); - } else { - severity = options; - localOptions = []; + return severity; +} + +/** +* Validates the non-severity options passed to a rule, based on its schema. +* @param {string} id The rule's unique name +* @param {array} localOptions The options for the rule, excluding severity +* @returns {void} +*/ +function validateRuleSchema(id, localOptions) { + const schema = getRuleOptionsSchema(id); + + if (!validators.rules[id] && schema) { + validators.rules[id] = schemaValidator(schema, { verbose: true }); } - validSeverity = ( - severity === 0 || severity === 1 || severity === 2 || - (typeof severity === "string" && /^(?:off|warn|error)$/i.test(severity)) - ); + const validateRule = validators.rules[id]; if (validateRule) { validateRule(localOptions); + if (validateRule.errors) { + throw new Error(validateRule.errors.map(error => `\tValue "${error.value}" ${error.message}.\n`).join("")); + } } +} - if ((validateRule && validateRule.errors) || !validSeverity) { - const message = [ - source, ":\n", - "\tConfiguration for rule \"", id, "\" is invalid:\n" - ]; - - if (!validSeverity) { - message.push( - "\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '", - util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, ""), - "').\n" - ); - } +/** + * Validates a rule's options against its schema. + * @param {string} id The rule's unique name. + * @param {array|number} options The given options for the rule. + * @param {string} source The name of the configuration source. + * @returns {void} + */ +function validateRuleOptions(id, options, source) { + try { + const severity = validateRuleSeverity(options); - if (validateRule && validateRule.errors) { - validateRule.errors.forEach(function(error) { - message.push( - "\tValue \"", error.value, "\" ", error.message, ".\n" - ); - }); + if (severity !== 0 && !(typeof severity === "string" && severity.toLowerCase() === "off")) { + validateRuleSchema(id, Array.isArray(options) ? options.slice(1) : []); } - - throw new Error(message.join("")); + } catch (err) { + throw new Error(`${source}:\n\tConfiguration for rule "${id}" is invalid:\n${err.message}`); } } @@ -134,7 +128,7 @@ function validateEnvironment(environment, source) { } if (typeof environment === "object") { - Object.keys(environment).forEach(function(env) { + Object.keys(environment).forEach(env => { if (!Environments.get(env)) { const message = [ source, ":\n", @@ -158,7 +152,7 @@ function validateEnvironment(environment, source) { function validate(config, source) { if (typeof config.rules === "object") { - Object.keys(config.rules).forEach(function(id) { + Object.keys(config.rules).forEach(id => { validateRuleOptions(id, config.rules[id], source); }); } diff --git a/tools/eslint/lib/config/environments.js b/tools/eslint/lib/config/environments.js index 36b989068ff6da..5c34da9328a4da 100644 --- a/tools/eslint/lib/config/environments.js +++ b/tools/eslint/lib/config/environments.js @@ -22,7 +22,7 @@ let environments = new Map(); * @private */ function load() { - Object.keys(envs).forEach(function(envName) { + Object.keys(envs).forEach(envName => { environments.set(envName, envs[envName]); }); } @@ -65,9 +65,9 @@ module.exports = { */ importPlugin(plugin, pluginName) { if (plugin.environments) { - Object.keys(plugin.environments).forEach(function(envName) { + Object.keys(plugin.environments).forEach(envName => { this.define(`${pluginName}/${envName}`, plugin.environments[envName]); - }, this); + }); } }, diff --git a/tools/eslint/lib/eslint.js b/tools/eslint/lib/eslint.js index fd7685f49257c6..3ae7cfe9c68103 100755 --- a/tools/eslint/lib/eslint.js +++ b/tools/eslint/lib/eslint.js @@ -26,7 +26,22 @@ const assert = require("assert"), Traverser = require("./util/traverser"), RuleContext = require("./rule-context"), rules = require("./rules"), - timing = require("./timing"); + timing = require("./timing"), + + pkg = require("../package.json"); + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * The result of a parsing operation from parseForESLint() + * @typedef {Object} CustomParseResult + * @property {ASTNode} ast The ESTree AST Program node. + * @property {Object} services An object containing additional services related + * to the parser. + */ //------------------------------------------------------------------------------ // Helpers @@ -45,7 +60,7 @@ function parseBooleanConfig(string, comment) { // Collapse whitespace around `:` and `,` to make parsing easier string = string.replace(/\s*([:,])\s*/g, "$1"); - string.split(/\s|,+/).forEach(function(name) { + string.split(/\s|,+/).forEach(name => { if (!name) { return; } @@ -95,7 +110,7 @@ function parseJsonConfig(string, location, messages) { // Optionator cannot parse commaless notations. // But we are supporting that. So this is a fallback for that. items = {}; - string = string.replace(/([a-zA-Z0-9\-\/]+):/g, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/, "$1,"); + string = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,"); try { items = JSON.parse(`{${string}}`); } catch (ex) { @@ -126,7 +141,7 @@ function parseListConfig(string) { // Collapse whitespace around , string = string.replace(/\s*,\s*/g, ","); - string.split(/,+/).forEach(function(name) { + string.split(/,+/).forEach(name => { name = name.trim(); if (!name) { return; @@ -153,7 +168,7 @@ function addDeclaredGlobals(program, globalScope, config) { Object.assign(declaredGlobals, builtin); - Object.keys(config.env).forEach(function(name) { + Object.keys(config.env).forEach(name => { if (config.env[name]) { const env = Environments.get(name), environmentGlobals = env && env.globals; @@ -168,7 +183,7 @@ function addDeclaredGlobals(program, globalScope, config) { Object.assign(declaredGlobals, config.globals); Object.assign(explicitGlobals, config.astGlobals); - Object.keys(declaredGlobals).forEach(function(name) { + Object.keys(declaredGlobals).forEach(name => { let variable = globalScope.set.get(name); if (!variable) { @@ -180,7 +195,7 @@ function addDeclaredGlobals(program, globalScope, config) { variable.writeable = declaredGlobals[name]; }); - Object.keys(explicitGlobals).forEach(function(name) { + Object.keys(explicitGlobals).forEach(name => { let variable = globalScope.set.get(name); if (!variable) { @@ -194,7 +209,7 @@ function addDeclaredGlobals(program, globalScope, config) { }); // mark all exported variables as such - Object.keys(exportedGlobals).forEach(function(name) { + Object.keys(exportedGlobals).forEach(name => { const variable = globalScope.set.get(name); if (variable) { @@ -207,7 +222,7 @@ function addDeclaredGlobals(program, globalScope, config) { * Since we augment the global scope using configuration, we need to update * references and remove the ones that were added by configuration. */ - globalScope.through = globalScope.through.filter(function(reference) { + globalScope.through = globalScope.through.filter(reference => { const name = reference.identifier.name; const variable = globalScope.set.get(name); @@ -238,7 +253,7 @@ function addDeclaredGlobals(program, globalScope, config) { function disableReporting(reportingConfig, start, rulesToDisable) { if (rulesToDisable.length) { - rulesToDisable.forEach(function(rule) { + rulesToDisable.forEach(rule => { reportingConfig.push({ start, end: null, @@ -266,7 +281,7 @@ function enableReporting(reportingConfig, start, rulesToEnable) { let i; if (rulesToEnable.length) { - rulesToEnable.forEach(function(rule) { + rulesToEnable.forEach(rule => { for (i = reportingConfig.length - 1; i >= 0; i--) { if (!reportingConfig[i].end && reportingConfig[i].rule === rule) { reportingConfig[i].end = start; @@ -313,7 +328,7 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa }; const commentRules = {}; - ast.comments.forEach(function(comment) { + ast.comments.forEach(comment => { let value = comment.value.trim(); const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(value); @@ -347,7 +362,7 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa case "eslint": { const items = parseJsonConfig(value, comment.loc, messages); - Object.keys(items).forEach(function(name) { + Object.keys(items).forEach(name => { const ruleValue = items[name]; validator.validateRuleOptions(name, ruleValue, `${filename} line ${comment.loc.start.line}`); @@ -371,7 +386,7 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa }); // apply environment configs - Object.keys(commentConfig.env).forEach(function(name) { + Object.keys(commentConfig.env).forEach(name => { const env = Environments.get(name); if (env) { @@ -442,11 +457,11 @@ function prepareConfig(config) { let parserOptions = {}; if (typeof config.rules === "object") { - Object.keys(config.rules).forEach(function(k) { + Object.keys(config.rules).forEach(k => { const rule = config.rules[k]; if (rule === null) { - throw new Error(`Invalid config for rule '${k}'\.`); + throw new Error(`Invalid config for rule '${k}'.`); } if (Array.isArray(rule)) { copiedRules[k] = rule.slice(); @@ -458,7 +473,7 @@ function prepareConfig(config) { // merge in environment parserOptions if (typeof config.env === "object") { - Object.keys(config.env).forEach(function(envName) { + Object.keys(config.env).forEach(envName => { const env = Environments.get(envName); if (config.env[envName] && env && env.parserOptions) { @@ -598,7 +613,8 @@ module.exports = (function() { * @param {string} text The text to parse. * @param {Object} config The ESLint configuration object. * @param {string} filePath The path to the file being parsed. - * @returns {ASTNode} The AST if successful or null if not. + * @returns {ASTNode|CustomParseResult} The AST or parse result if successful, + * or null if not. * @private */ function parse(text, config, filePath) { @@ -642,7 +658,11 @@ module.exports = (function() { * problem that ESLint identified just like any other. */ try { - return parser.parse(text, parserOptions); + if (typeof parser.parseForESLint === "function") { + return parser.parseForESLint(text, parserOptions); + } else { + return parser.parse(text, parserOptions); + } } catch (ex) { // If the message includes a leading line number, strip it: @@ -738,6 +758,7 @@ module.exports = (function() { api.verify = function(textOrSourceCode, config, filenameOrOptions, saveState) { const text = (typeof textOrSourceCode === "string") ? textOrSourceCode : null; let ast, + parseResult, shebang, allowInlineConfig; @@ -759,7 +780,7 @@ module.exports = (function() { if (envInFile) { if (!config || !config.env) { - config = Object.assign({}, config || {}, {env: envInFile}); + config = Object.assign({}, config || {}, { env: envInFile }); } else { config = Object.assign({}, config); config.env = Object.assign({}, config.env, envInFile); @@ -778,8 +799,8 @@ module.exports = (function() { return messages; } - ast = parse( - stripUnicodeBOM(text).replace(/^#!([^\r\n]+)/, function(match, captured) { + parseResult = parse( + stripUnicodeBOM(text).replace(/^#!([^\r\n]+)/, (match, captured) => { shebang = captured; return `//${captured}`; }), @@ -787,6 +808,14 @@ module.exports = (function() { currentFilename ); + // if this result is from a parseForESLint() method, normalize + if (parseResult && parseResult.ast) { + ast = parseResult.ast; + } else { + ast = parseResult; + parseResult = null; + } + if (ast) { sourceCode = new SourceCode(text, ast); } @@ -808,9 +837,7 @@ module.exports = (function() { ConfigOps.normalize(config); // enable appropriate rules - Object.keys(config.rules).filter(function(key) { - return getRuleSeverity(config.rules[key]) > 0; - }).forEach(function(key) { + Object.keys(config.rules).filter(key => getRuleSeverity(config.rules[key]) > 0).forEach(key => { let ruleCreator; ruleCreator = rules.get(key); @@ -832,13 +859,16 @@ module.exports = (function() { try { const ruleContext = new RuleContext( key, api, severity, options, - config.settings, config.parserOptions, config.parser, ruleCreator.meta); + config.settings, config.parserOptions, config.parser, + ruleCreator.meta, + (parseResult && parseResult.services ? parseResult.services : {}) + ); const rule = ruleCreator.create ? ruleCreator.create(ruleContext) : ruleCreator(ruleContext); // add all the node types as listeners - Object.keys(rule).forEach(function(nodeType) { + Object.keys(rule).forEach(nodeType => { api.on(nodeType, timing.enabled ? timing.time(key, rule[nodeType]) : rule[nodeType] @@ -904,7 +934,7 @@ module.exports = (function() { } // sort by line and column - messages.sort(function(a, b) { + messages.sort((a, b) => { const lineDiff = a.line - b.line; if (lineDiff === 0) { @@ -957,7 +987,7 @@ module.exports = (function() { } if (opts) { - message = message.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, function(fullMatch, term) { + message = message.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (fullMatch, term) => { if (term in opts) { return opts[term]; } @@ -1027,7 +1057,7 @@ module.exports = (function() { }; // copy over methods - Object.keys(externalMethods).forEach(function(methodName) { + Object.keys(externalMethods).forEach(methodName => { const exMethodName = externalMethods[methodName]; // All functions expected to have less arguments than 5. @@ -1152,7 +1182,7 @@ module.exports = (function() { * @returns {void} */ api.defineRules = function(rulesToDefine) { - Object.getOwnPropertyNames(rulesToDefine).forEach(function(ruleId) { + Object.getOwnPropertyNames(rulesToDefine).forEach(ruleId => { defineRule(ruleId, rulesToDefine[ruleId]); }); }; @@ -1165,6 +1195,16 @@ module.exports = (function() { return require("../conf/eslint.json"); }; + /** + * Gets an object with all loaded rules. + * @returns {Map} All loaded rules + */ + api.getRules = function() { + return rules.getAllLoadedRules(); + }; + + api.version = pkg.version; + /** * Gets variables that are declared by a specified node. * diff --git a/tools/eslint/lib/file-finder.js b/tools/eslint/lib/file-finder.js index 18f3b65133d7a3..acb886c9d1e2c2 100644 --- a/tools/eslint/lib/file-finder.js +++ b/tools/eslint/lib/file-finder.js @@ -31,22 +31,6 @@ function getDirectoryEntries(directory) { } } -//------------------------------------------------------------------------------ -// API -//------------------------------------------------------------------------------ - -/** - * FileFinder - * @constructor - * @param {string[]} files The basename(s) of the file(s) to find. - * @param {stirng} cwd Current working directory - */ -function FileFinder(files, cwd) { - this.fileNames = Array.isArray(files) ? files : [files]; - this.cwd = cwd || process.cwd(); - this.cache = {}; -} - /** * Create a hash of filenames from a directory listing * @param {string[]} entries Array of directory entries. @@ -57,7 +41,7 @@ function FileFinder(files, cwd) { function normalizeDirectoryEntries(entries, directory, supportedConfigs) { const fileHash = {}; - entries.forEach(function(entry) { + entries.forEach(entry => { if (supportedConfigs.indexOf(entry) >= 0) { const resolvedEntry = path.resolve(directory, entry); @@ -69,69 +53,89 @@ function normalizeDirectoryEntries(entries, directory, supportedConfigs) { return fileHash; } +//------------------------------------------------------------------------------ +// API +//------------------------------------------------------------------------------ + /** - * Find all instances of files with the specified file names, in directory and - * parent directories. Cache the results. - * Does not check if a matching directory entry is a file. - * Searches for all the file names in this.fileNames. - * Is currently used by lib/config.js to find .eslintrc and package.json files. - * @param {string} directory The directory to start the search from. - * @returns {string[]} The file paths found. + * FileFinder class */ -FileFinder.prototype.findAllInDirectoryAndParents = function(directory) { - const cache = this.cache; - - if (directory) { - directory = path.resolve(this.cwd, directory); - } else { - directory = this.cwd; +class FileFinder { + + /** + * @param {string[]} files The basename(s) of the file(s) to find. + * @param {stirng} cwd Current working directory + */ + constructor(files, cwd) { + this.fileNames = Array.isArray(files) ? files : [files]; + this.cwd = cwd || process.cwd(); + this.cache = {}; } - if (cache.hasOwnProperty(directory)) { - return cache[directory]; - } + /** + * Find all instances of files with the specified file names, in directory and + * parent directories. Cache the results. + * Does not check if a matching directory entry is a file. + * Searches for all the file names in this.fileNames. + * Is currently used by lib/config.js to find .eslintrc and package.json files. + * @param {string} directory The directory to start the search from. + * @returns {string[]} The file paths found. + */ + findAllInDirectoryAndParents(directory) { + const cache = this.cache; + + if (directory) { + directory = path.resolve(this.cwd, directory); + } else { + directory = this.cwd; + } - const dirs = []; - const fileNames = this.fileNames; - let searched = 0; + if (cache.hasOwnProperty(directory)) { + return cache[directory]; + } - do { - dirs[searched++] = directory; - cache[directory] = []; + const dirs = []; + const fileNames = this.fileNames; + let searched = 0; - const filesMap = normalizeDirectoryEntries(getDirectoryEntries(directory), directory, fileNames); + do { + dirs[searched++] = directory; + cache[directory] = []; - if (Object.keys(filesMap).length) { - for (let k = 0; k < fileNames.length; k++) { + const filesMap = normalizeDirectoryEntries(getDirectoryEntries(directory), directory, fileNames); - if (filesMap[fileNames[k]]) { - const filePath = filesMap[fileNames[k]]; + if (Object.keys(filesMap).length) { + for (let k = 0; k < fileNames.length; k++) { - // Add the file path to the cache of each directory searched. - for (let j = 0; j < searched; j++) { - cache[dirs[j]].push(filePath); - } + if (filesMap[fileNames[k]]) { + const filePath = filesMap[fileNames[k]]; + + // Add the file path to the cache of each directory searched. + for (let j = 0; j < searched; j++) { + cache[dirs[j]].push(filePath); + } - break; + break; + } } } - } - const child = directory; + const child = directory; + + // Assign parent directory to directory. + directory = path.dirname(directory); - // Assign parent directory to directory. - directory = path.dirname(directory); + if (directory === child) { + return cache[dirs[0]]; + } + } while (!cache.hasOwnProperty(directory)); - if (directory === child) { - return cache[dirs[0]]; + // Add what has been cached previously to the cache of each directory searched. + for (let i = 0; i < searched; i++) { + dirs.push.apply(cache[dirs[i]], cache[directory]); } - } while (!cache.hasOwnProperty(directory)); - // Add what has been cached previously to the cache of each directory searched. - for (let i = 0; i < searched; i++) { - dirs.push.apply(cache[dirs[i]], cache[directory]); + return cache[dirs[0]]; } - - return cache[dirs[0]]; -}; +} module.exports = FileFinder; diff --git a/tools/eslint/lib/formatters/checkstyle.js b/tools/eslint/lib/formatters/checkstyle.js index 0beedcf6895217..5985ad0eff5752 100644 --- a/tools/eslint/lib/formatters/checkstyle.js +++ b/tools/eslint/lib/formatters/checkstyle.js @@ -35,12 +35,12 @@ module.exports = function(results) { output += ""; output += ""; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; output += ``; - messages.forEach(function(message) { + messages.forEach(message => { output += [ ` 0 ? "red" : "yellow"; + const summary = []; + + if (errors > 0) { + summary.push(`${errors} ${pluralize("error", errors)}`); + } + + if (warnings > 0) { + summary.push(`${warnings} ${pluralize("warning", warnings)}`); + } + + return chalk[summaryColor].bold(`${summary.join(" and ")} found.`); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + let errors = 0; + let warnings = 0; + const resultsWithMessages = results.filter(result => result.messages.length > 0); + + let output = resultsWithMessages.reduce((resultsOutput, result) => { + const messages = result.messages.map(message => { + if (message.fatal || message.severity === 2) { + errors++; + } else { + warnings++; + } + + return `${formatMessage(message, result)}\n\n`; + }); + + return resultsOutput.concat(messages); + }, []).join("\n"); + + output += "\n"; + output += formatSummary(errors, warnings); + + return (errors + warnings) > 0 ? output : ""; +}; diff --git a/tools/eslint/lib/formatters/compact.js b/tools/eslint/lib/formatters/compact.js index 9c7aeb87d7c064..c641039ff284c6 100644 --- a/tools/eslint/lib/formatters/compact.js +++ b/tools/eslint/lib/formatters/compact.js @@ -32,13 +32,13 @@ module.exports = function(results) { let output = "", total = 0; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; total += messages.length; - messages.forEach(function(message) { + messages.forEach(message => { output += `${result.filePath}: `; output += `line ${message.line || 0}`; diff --git a/tools/eslint/lib/formatters/html.js b/tools/eslint/lib/formatters/html.js index 66e89d372cb8db..e61fdea6a93eec 100644 --- a/tools/eslint/lib/formatters/html.js +++ b/tools/eslint/lib/formatters/html.js @@ -70,7 +70,7 @@ function renderMessages(messages, parentIndex) { * @param {Object} message Message. * @returns {string} HTML (table row) describing a message. */ - return lodash.map(messages, function(message) { + return lodash.map(messages, message => { const lineNumber = message.line || 0; const columnNumber = message.column || 0; @@ -91,15 +91,13 @@ function renderMessages(messages, parentIndex) { * @returns {string} HTML string describing the results. */ function renderResults(results) { - return lodash.map(results, function(result, index) { - return resultTemplate({ - index, - color: renderColor(result.errorCount, result.warningCount), - filePath: result.filePath, - summary: renderSummary(result.errorCount, result.warningCount) - - }) + renderMessages(result.messages, index); - }).join("\n"); + return lodash.map(results, (result, index) => resultTemplate({ + index, + color: renderColor(result.errorCount, result.warningCount), + filePath: result.filePath, + summary: renderSummary(result.errorCount, result.warningCount) + + }) + renderMessages(result.messages, index)).join("\n"); } //------------------------------------------------------------------------------ @@ -114,7 +112,7 @@ module.exports = function(results) { totalWarnings = 0; // Iterate over results to get totals - results.forEach(function(result) { + results.forEach(result => { totalErrors += result.errorCount; totalWarnings += result.warningCount; }); diff --git a/tools/eslint/lib/formatters/jslint-xml.js b/tools/eslint/lib/formatters/jslint-xml.js index 7cfa893d32fad2..14743430d8ff94 100644 --- a/tools/eslint/lib/formatters/jslint-xml.js +++ b/tools/eslint/lib/formatters/jslint-xml.js @@ -17,12 +17,12 @@ module.exports = function(results) { output += ""; output += ""; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; output += ``; - messages.forEach(function(message) { + messages.forEach(message => { output += [ `\n"; output += "\n"; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; @@ -43,7 +43,7 @@ module.exports = function(results) { output += `\n`; } - messages.forEach(function(message) { + messages.forEach(message => { const type = message.fatal ? "error" : "failure"; output += ``; diff --git a/tools/eslint/lib/formatters/stylish.js b/tools/eslint/lib/formatters/stylish.js index 578a146c010f57..a176d03ab83e0b 100644 --- a/tools/eslint/lib/formatters/stylish.js +++ b/tools/eslint/lib/formatters/stylish.js @@ -33,7 +33,7 @@ module.exports = function(results) { warnings = 0, summaryColor = "yellow"; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; if (messages.length === 0) { @@ -44,7 +44,7 @@ module.exports = function(results) { output += `${chalk.underline(result.filePath)}\n`; output += `${table( - messages.map(function(message) { + messages.map(message => { let messageType; if (message.fatal || message.severity === 2) { @@ -71,11 +71,7 @@ module.exports = function(results) { return chalk.stripColor(str).length; } } - ).split("\n").map(function(el) { - return el.replace(/(\d+)\s+(\d+)/, function(m, p1, p2) { - return chalk.dim(`${p1}:${p2}`); - }); - }).join("\n")}\n\n`; + ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`; }); if (total > 0) { diff --git a/tools/eslint/lib/formatters/table.js b/tools/eslint/lib/formatters/table.js index cd09626cc79381..b4859154ba610d 100644 --- a/tools/eslint/lib/formatters/table.js +++ b/tools/eslint/lib/formatters/table.js @@ -36,7 +36,7 @@ function drawTable(messages) { chalk.bold("Rule ID") ]); - messages.forEach(function(message) { + messages.forEach(message => { let messageType; if (message.fatal || message.severity === 2) { @@ -92,7 +92,7 @@ function drawTable(messages) { function drawReport(results) { let files; - files = results.map(function(result) { + files = results.map(result => { if (!result.messages.length) { return ""; } @@ -100,9 +100,7 @@ function drawReport(results) { return `\n${result.filePath}\n\n${drawTable(result.messages)}`; }); - files = files.filter(function(content) { - return content.trim(); - }); + files = files.filter(content => content.trim()); return files.join(""); } @@ -120,7 +118,7 @@ module.exports = function(report) { errorCount = 0; warningCount = 0; - report.forEach(function(fileReport) { + report.forEach(fileReport => { errorCount += fileReport.errorCount; warningCount += fileReport.warningCount; }); diff --git a/tools/eslint/lib/formatters/tap.js b/tools/eslint/lib/formatters/tap.js index 568ac1e8b64548..27825d0ba996e7 100644 --- a/tools/eslint/lib/formatters/tap.js +++ b/tools/eslint/lib/formatters/tap.js @@ -44,7 +44,7 @@ function outputDiagnostics(diagnostic) { module.exports = function(results) { let output = `TAP version 13\n1..${results.length}\n`; - results.forEach(function(result, id) { + results.forEach((result, id) => { const messages = result.messages; let testResult = "ok"; let diagnostics = {}; @@ -52,7 +52,7 @@ module.exports = function(results) { if (messages.length > 0) { testResult = "not ok"; - messages.forEach(function(message) { + messages.forEach(message => { const diagnostic = { message: message.message, severity: getMessageType(message), diff --git a/tools/eslint/lib/formatters/unix.js b/tools/eslint/lib/formatters/unix.js index 867bbd5b49fcd3..a5635278bc3fa9 100644 --- a/tools/eslint/lib/formatters/unix.js +++ b/tools/eslint/lib/formatters/unix.js @@ -31,13 +31,13 @@ module.exports = function(results) { let output = "", total = 0; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; total += messages.length; - messages.forEach(function(message) { + messages.forEach(message => { output += `${result.filePath}:`; output += `${message.line || 0}:`; diff --git a/tools/eslint/lib/formatters/visualstudio.js b/tools/eslint/lib/formatters/visualstudio.js index 134a04a5134ca0..feb7fb4bef382b 100644 --- a/tools/eslint/lib/formatters/visualstudio.js +++ b/tools/eslint/lib/formatters/visualstudio.js @@ -33,13 +33,13 @@ module.exports = function(results) { let output = "", total = 0; - results.forEach(function(result) { + results.forEach(result => { const messages = result.messages; total += messages.length; - messages.forEach(function(message) { + messages.forEach(message => { output += result.filePath; output += `(${message.line || 0}`; diff --git a/tools/eslint/lib/ignored-paths.js b/tools/eslint/lib/ignored-paths.js index bc2db8aaac8dc0..bace73db6a394b 100644 --- a/tools/eslint/lib/ignored-paths.js +++ b/tools/eslint/lib/ignored-paths.js @@ -72,160 +72,161 @@ function mergeDefaultOptions(options) { //------------------------------------------------------------------------------ /** - * IgnoredPaths - * @constructor - * @class IgnoredPaths - * @param {Object} options object containing 'ignore', 'ignorePath' and 'patterns' properties + * IgnoredPaths class */ -function IgnoredPaths(options) { - - options = mergeDefaultOptions(options); - - /** - * add pattern to node-ignore instance - * @param {Object} ig, instance of node-ignore - * @param {string} pattern, pattern do add to ig - * @returns {array} raw ignore rules - */ - function addPattern(ig, pattern) { - return ig.addPattern(pattern); - } +class IgnoredPaths { /** - * add ignore file to node-ignore instance - * @param {Object} ig, instance of node-ignore - * @param {string} filepath, file to add to ig - * @returns {array} raw ignore rules + * @param {Object} options object containing 'ignore', 'ignorePath' and 'patterns' properties */ - function addIgnoreFile(ig, filepath) { - ig.ignoreFiles.push(filepath); - return ig.add(fs.readFileSync(filepath, "utf8")); - } - - this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []); - this.baseDir = options.cwd; - - this.ig = { - custom: ignore(), - default: ignore() - }; + constructor(options) { + options = mergeDefaultOptions(options); + + /** + * add pattern to node-ignore instance + * @param {Object} ig, instance of node-ignore + * @param {string} pattern, pattern do add to ig + * @returns {array} raw ignore rules + */ + function addPattern(ig, pattern) { + return ig.addPattern(pattern); + } - // Add a way to keep track of ignored files. This was present in node-ignore - // 2.x, but dropped for now as of 3.0.10. - this.ig.custom.ignoreFiles = []; - this.ig.default.ignoreFiles = []; + /** + * add ignore file to node-ignore instance + * @param {Object} ig, instance of node-ignore + * @param {string} filepath, file to add to ig + * @returns {array} raw ignore rules + */ + function addIgnoreFile(ig, filepath) { + ig.ignoreFiles.push(filepath); + return ig.add(fs.readFileSync(filepath, "utf8")); + } - if (options.dotfiles !== true) { + this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []); + this.baseDir = options.cwd; - /* - * ignore files beginning with a dot, but not files in a parent or - * ancestor directory (which in relative format will begin with `../`). - */ - addPattern(this.ig.default, [".*", "!../"]); - } + this.ig = { + custom: ignore(), + default: ignore() + }; - addPattern(this.ig.default, this.defaultPatterns); + // Add a way to keep track of ignored files. This was present in node-ignore + // 2.x, but dropped for now as of 3.0.10. + this.ig.custom.ignoreFiles = []; + this.ig.default.ignoreFiles = []; - if (options.ignore !== false) { - let ignorePath; + if (options.dotfiles !== true) { - if (options.ignorePath) { - debug("Using specific ignore file"); + /* + * ignore files beginning with a dot, but not files in a parent or + * ancestor directory (which in relative format will begin with `../`). + */ + addPattern(this.ig.default, [".*", "!../"]); + } - try { - fs.statSync(options.ignorePath); - ignorePath = options.ignorePath; - } catch (e) { - e.message = `Cannot read ignore file: ${options.ignorePath}\nError: ${e.message}`; - throw e; + addPattern(this.ig.default, this.defaultPatterns); + + if (options.ignore !== false) { + let ignorePath; + + if (options.ignorePath) { + debug("Using specific ignore file"); + + try { + fs.statSync(options.ignorePath); + ignorePath = options.ignorePath; + } catch (e) { + e.message = `Cannot read ignore file: ${options.ignorePath}\nError: ${e.message}`; + throw e; + } + } else { + debug(`Looking for ignore file in ${options.cwd}`); + ignorePath = findIgnoreFile(options.cwd); + + try { + fs.statSync(ignorePath); + debug(`Loaded ignore file ${ignorePath}`); + } catch (e) { + debug("Could not find ignore file in cwd"); + this.options = options; + } } - } else { - debug(`Looking for ignore file in ${options.cwd}`); - ignorePath = findIgnoreFile(options.cwd); - - try { - fs.statSync(ignorePath); - debug(`Loaded ignore file ${ignorePath}`); - } catch (e) { - debug("Could not find ignore file in cwd"); - this.options = options; + + if (ignorePath) { + debug(`Adding ${ignorePath}`); + this.baseDir = path.dirname(path.resolve(options.cwd, ignorePath)); + addIgnoreFile(this.ig.custom, ignorePath); + addIgnoreFile(this.ig.default, ignorePath); } - } - if (ignorePath) { - debug(`Adding ${ignorePath}`); - this.baseDir = path.dirname(path.resolve(options.cwd, ignorePath)); - addIgnoreFile(this.ig.custom, ignorePath); - addIgnoreFile(this.ig.default, ignorePath); + if (options.ignorePattern) { + addPattern(this.ig.custom, options.ignorePattern); + addPattern(this.ig.default, options.ignorePattern); + } } - if (options.ignorePattern) { - addPattern(this.ig.custom, options.ignorePattern); - addPattern(this.ig.default, options.ignorePattern); - } + this.options = options; } - this.options = options; + /** + * Determine whether a file path is included in the default or custom ignore patterns + * @param {string} filepath Path to check + * @param {string} [category=null] check 'default', 'custom' or both (null) + * @returns {boolean} true if the file path matches one or more patterns, false otherwise + */ + contains(filepath, category) { -} + let result = false; + const absolutePath = path.resolve(this.options.cwd, filepath); + const relativePath = pathUtil.getRelativePath(absolutePath, this.options.cwd); -/** - * Determine whether a file path is included in the default or custom ignore patterns - * @param {string} filepath Path to check - * @param {string} [category=null] check 'default', 'custom' or both (null) - * @returns {boolean} true if the file path matches one or more patterns, false otherwise - */ -IgnoredPaths.prototype.contains = function(filepath, category) { + if ((typeof category === "undefined") || (category === "default")) { + result = result || (this.ig.default.filter([relativePath]).length === 0); + } - let result = false; - const absolutePath = path.resolve(this.options.cwd, filepath); - const relativePath = pathUtil.getRelativePath(absolutePath, this.options.cwd); + if ((typeof category === "undefined") || (category === "custom")) { + result = result || (this.ig.custom.filter([relativePath]).length === 0); + } - if ((typeof category === "undefined") || (category === "default")) { - result = result || (this.ig.default.filter([relativePath]).length === 0); - } + return result; - if ((typeof category === "undefined") || (category === "custom")) { - result = result || (this.ig.custom.filter([relativePath]).length === 0); } - return result; - -}; - -/** - * Returns a list of dir patterns for glob to ignore - * @returns {function()} method to check whether a folder should be ignored by glob. - */ -IgnoredPaths.prototype.getIgnoredFoldersGlobChecker = function() { + /** + * Returns a list of dir patterns for glob to ignore + * @returns {function()} method to check whether a folder should be ignored by glob. + */ + getIgnoredFoldersGlobChecker() { - const ig = ignore().add(DEFAULT_IGNORE_DIRS); + const ig = ignore().add(DEFAULT_IGNORE_DIRS); - if (this.options.ignore) { - ig.add(this.ig.custom); - } + if (this.options.ignore) { + ig.add(this.ig.custom); + } - const filter = ig.createFilter(); + const filter = ig.createFilter(); - /** - * TODO - * 1. - * Actually, it should be `this.options.baseDir`, which is the base dir of `ignore-path`, - * as well as Line 177. - * But doing this leads to a breaking change and fails tests. - * Related to #6759 - */ - const base = this.options.cwd; + /** + * TODO + * 1. + * Actually, it should be `this.options.baseDir`, which is the base dir of `ignore-path`, + * as well as Line 177. + * But doing this leads to a breaking change and fails tests. + * Related to #6759 + */ + const base = this.options.cwd; - return function(absolutePath) { - const relative = pathUtil.getRelativePath(absolutePath, base); + return function(absolutePath) { + const relative = pathUtil.getRelativePath(absolutePath, base); - if (!relative) { - return false; - } + if (!relative) { + return false; + } - return !filter(relative); - }; -}; + return !filter(relative); + }; + } +} module.exports = IgnoredPaths; diff --git a/tools/eslint/lib/internal-rules/internal-consistent-docs-description.js b/tools/eslint/lib/internal-rules/internal-consistent-docs-description.js index 3e4671aa7b151d..a4a5dca03fbbf2 100644 --- a/tools/eslint/lib/internal-rules/internal-consistent-docs-description.js +++ b/tools/eslint/lib/internal-rules/internal-consistent-docs-description.js @@ -95,7 +95,6 @@ function checkMetaDocsDescription(context, exportsNode) { firstWord } }); - return; } } diff --git a/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js b/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js index 783a1109e76571..d1c78efa61e557 100644 --- a/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js +++ b/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js @@ -147,7 +147,6 @@ function checkMetaValidity(context, exportsNode, ruleIsFixable) { if (ruleIsFixable && !hasMetaFixable(metaProperty)) { context.report(metaProperty, "Rule is fixable, but is missing a meta.fixable property."); - return; } } @@ -216,7 +215,7 @@ module.exports = { "Program:exit"() { if (!isCorrectExportsFormat(exportsNode)) { - context.report(exportsNode, "Rule does not export an Object. Make sure the rule follows the new rule format."); + context.report({ node: exportsNode, message: "Rule does not export an Object. Make sure the rule follows the new rule format." }); return; } diff --git a/tools/eslint/lib/load-rules.js b/tools/eslint/lib/load-rules.js index c698faa5e132d0..92fb7bf20ada0c 100644 --- a/tools/eslint/lib/load-rules.js +++ b/tools/eslint/lib/load-rules.js @@ -31,7 +31,7 @@ module.exports = function(rulesDir, cwd) { const rules = Object.create(null); - fs.readdirSync(rulesDir).forEach(function(file) { + fs.readdirSync(rulesDir).forEach(file => { if (path.extname(file) !== ".js") { return; } diff --git a/tools/eslint/lib/rule-context.js b/tools/eslint/lib/rule-context.js index ded5dab962d70c..9c80d2e1a31cc6 100644 --- a/tools/eslint/lib/rule-context.js +++ b/tools/eslint/lib/rule-context.js @@ -61,36 +61,41 @@ const PASSTHROUGHS = [ //------------------------------------------------------------------------------ /** + * Rule context class * Acts as an abstraction layer between rules and the main eslint object. - * @constructor - * @param {string} ruleId The ID of the rule using this object. - * @param {eslint} eslint The eslint object. - * @param {number} severity The configured severity level of the rule. - * @param {Array} options The configuration information to be added to the rule. - * @param {Object} settings The configuration settings passed from the config file. - * @param {Object} parserOptions The parserOptions settings passed from the config file. - * @param {Object} parserPath The parser setting passed from the config file. - * @param {Object} meta The metadata of the rule */ -function RuleContext(ruleId, eslint, severity, options, settings, parserOptions, parserPath, meta) { +class RuleContext { - // public. - this.id = ruleId; - this.options = options; - this.settings = settings; - this.parserOptions = parserOptions; - this.parserPath = parserPath; - this.meta = meta; + /** + * @param {string} ruleId The ID of the rule using this object. + * @param {eslint} eslint The eslint object. + * @param {number} severity The configured severity level of the rule. + * @param {Array} options The configuration information to be added to the rule. + * @param {Object} settings The configuration settings passed from the config file. + * @param {Object} parserOptions The parserOptions settings passed from the config file. + * @param {Object} parserPath The parser setting passed from the config file. + * @param {Object} meta The metadata of the rule + * @param {Object} parserServices The parser services for the rule. + */ + constructor(ruleId, eslint, severity, options, settings, parserOptions, parserPath, meta, parserServices) { - // private. - this.eslint = eslint; - this.severity = severity; + // public. + this.id = ruleId; + this.options = options; + this.settings = settings; + this.parserOptions = parserOptions; + this.parserPath = parserPath; + this.meta = meta; - Object.freeze(this); -} + // create a separate copy and freeze it (it's not nice to freeze other people's objects) + this.parserServices = Object.freeze(Object.assign({}, parserServices)); -RuleContext.prototype = { - constructor: RuleContext, + // private. + this.eslint = eslint; + this.severity = severity; + + Object.freeze(this); + } /** * Passthrough to eslint.getSourceCode(). @@ -98,7 +103,7 @@ RuleContext.prototype = { */ getSourceCode() { return this.eslint.getSourceCode(); - }, + } /** * Passthrough to eslint.report() that automatically assigns the rule ID and severity. @@ -147,7 +152,7 @@ RuleContext.prototype = { this.meta ); } -}; +} // Copy over passthrough methods. All functions will have 5 or fewer parameters. PASSTHROUGHS.forEach(function(name) { diff --git a/tools/eslint/lib/rules.js b/tools/eslint/lib/rules.js index 128a6bcd15b652..80f83882d331cb 100644 --- a/tools/eslint/lib/rules.js +++ b/tools/eslint/lib/rules.js @@ -40,7 +40,7 @@ function define(ruleId, ruleModule) { function load(rulesDir, cwd) { const newRules = loadRules(rulesDir, cwd); - Object.keys(newRules).forEach(function(ruleId) { + Object.keys(newRules).forEach(ruleId => { define(ruleId, newRules[ruleId]); }); } @@ -53,7 +53,7 @@ function load(rulesDir, cwd) { */ function importPlugin(plugin, pluginName) { if (plugin.rules) { - Object.keys(plugin.rules).forEach(function(ruleId) { + Object.keys(plugin.rules).forEach(ruleId => { const qualifiedRuleId = `${pluginName}/${ruleId}`, rule = plugin.rules[ruleId]; @@ -75,6 +75,21 @@ function getHandler(ruleId) { } } +/** + * Get an object with all currently loaded rules + * @returns {Map} All loaded rules + */ +function getAllLoadedRules() { + const allRules = new Map(); + + Object.keys(rules).forEach(name => { + const rule = getHandler(name); + + allRules.set(name, rule); + }); + return allRules; +} + /** * Reset rules storage. * Should be used only in tests. @@ -89,6 +104,7 @@ module.exports = { load, importPlugin, get: getHandler, + getAllLoadedRules, testClear, /** diff --git a/tools/eslint/lib/rules/accessor-pairs.js b/tools/eslint/lib/rules/accessor-pairs.js index 7e8870edc8c8e1..4afdc7136ca2a6 100644 --- a/tools/eslint/lib/rules/accessor-pairs.js +++ b/tools/eslint/lib/rules/accessor-pairs.js @@ -139,9 +139,9 @@ module.exports = { } if (checkSetWithoutGet && isSetPresent && !isGetPresent) { - context.report(node, "Getter is not present."); + context.report({ node, message: "Getter is not present." }); } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) { - context.report(node, "Setter is not present."); + context.report({ node, message: "Setter is not present." }); } } diff --git a/tools/eslint/lib/rules/array-bracket-spacing.js b/tools/eslint/lib/rules/array-bracket-spacing.js index 9bd7e944951a77..73cfbdc3c1fa8e 100644 --- a/tools/eslint/lib/rules/array-bracket-spacing.js +++ b/tools/eslint/lib/rules/array-bracket-spacing.js @@ -179,8 +179,10 @@ module.exports = { const first = sourceCode.getFirstToken(node), second = sourceCode.getFirstToken(node, 1), - penultimate = sourceCode.getLastToken(node, 1), - last = sourceCode.getLastToken(node), + last = node.typeAnnotation + ? sourceCode.getTokenBefore(node.typeAnnotation) + : sourceCode.getLastToken(node), + penultimate = sourceCode.getTokenBefore(last), firstElement = node.elements[0], lastElement = node.elements[node.elements.length - 1]; diff --git a/tools/eslint/lib/rules/arrow-body-style.js b/tools/eslint/lib/rules/arrow-body-style.js index 038aeeb5af2550..9778a6776f5e1f 100644 --- a/tools/eslint/lib/rules/arrow-body-style.js +++ b/tools/eslint/lib/rules/arrow-body-style.js @@ -37,7 +37,7 @@ module.exports = { { type: "object", properties: { - requireReturnForObjectLiteral: {type: "boolean"} + requireReturnForObjectLiteral: { type: "boolean" } }, additionalProperties: false } @@ -46,7 +46,9 @@ module.exports = { maxItems: 2 } ] - } + }, + + fixable: "code" }, create(context) { @@ -55,6 +57,7 @@ module.exports = { const asNeeded = !options[0] || options[0] === "as-needed"; const never = options[0] === "never"; const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; + const sourceCode = context.getSourceCode(); /** * Determines whether a arrow function body needs braces @@ -65,38 +68,85 @@ module.exports = { const arrowBody = node.body; if (arrowBody.type === "BlockStatement") { - if (never) { + const blockBody = arrowBody.body; + + if (blockBody.length !== 1 && !never) { + return; + } + + if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && + blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") { + return; + } + + if (never || asNeeded && blockBody[0].type === "ReturnStatement") { context.report({ node, loc: arrowBody.loc.start, - message: "Unexpected block statement surrounding arrow body." + message: "Unexpected block statement surrounding arrow body.", + fix(fixer) { + if (blockBody.length !== 1 || blockBody[0].type !== "ReturnStatement" || !blockBody[0].argument) { + return null; + } + + const sourceText = sourceCode.getText(); + const returnKeyword = sourceCode.getFirstToken(blockBody[0]); + const firstValueToken = sourceCode.getTokenAfter(returnKeyword); + let lastValueToken = sourceCode.getLastToken(blockBody[0]); + + if (lastValueToken.type === "Punctuator" && lastValueToken.value === ";") { + + /* The last token of the returned value is the last token of the ReturnExpression (if + * the ReturnExpression has no semicolon), or the second-to-last token (if the ReturnExpression + * has a semicolon). + */ + lastValueToken = sourceCode.getTokenBefore(lastValueToken); + } + + const tokenAfterArrowBody = sourceCode.getTokenAfter(arrowBody); + + if (tokenAfterArrowBody && tokenAfterArrowBody.type === "Punctuator" && /^[([/`+-]/.test(tokenAfterArrowBody.value)) { + + // Don't do a fix if the next token would cause ASI issues when preceded by the returned value. + return null; + } + + const textBeforeReturn = sourceText.slice(arrowBody.range[0] + 1, returnKeyword.range[0]); + const textBetweenReturnAndValue = sourceText.slice(returnKeyword.range[1], firstValueToken.range[0]); + const rawReturnValueText = sourceText.slice(firstValueToken.range[0], lastValueToken.range[1]); + const returnValueText = firstValueToken.value === "{" ? `(${rawReturnValueText})` : rawReturnValueText; + const textAfterValue = sourceText.slice(lastValueToken.range[1], blockBody[0].range[1] - 1); + const textAfterReturnStatement = sourceText.slice(blockBody[0].range[1], arrowBody.range[1] - 1); + + /* + * For fixes that only contain spaces around the return value, remove the extra spaces. + * This avoids ugly fixes that end up with extra spaces after the arrow, e.g. `() => 0 ;` + */ + return fixer.replaceText( + arrowBody, + (textBeforeReturn + textBetweenReturnAndValue).replace(/^\s*$/, "") + returnValueText + (textAfterValue + textAfterReturnStatement).replace(/^\s*$/, "") + ); + } }); - } else { - const blockBody = arrowBody.body; - - if (blockBody.length !== 1) { - return; - } - - if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && - blockBody[0].argument.type === "ObjectExpression") { - return; - } - - if (asNeeded && blockBody[0].type === "ReturnStatement") { - context.report({ - node, - loc: arrowBody.loc.start, - message: "Unexpected block statement surrounding arrow body." - }); - } } } else { if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) { context.report({ node, loc: arrowBody.loc.start, - message: "Expected block statement surrounding arrow body." + message: "Expected block statement surrounding arrow body.", + fix(fixer) { + const lastTokenBeforeBody = sourceCode.getTokensBetween(sourceCode.getFirstToken(node), arrowBody) + .reverse() + .find(token => token.value !== "("); + + const firstBodyToken = sourceCode.getTokenAfter(lastTokenBeforeBody); + + return fixer.replaceTextRange( + [firstBodyToken.range[0], node.range[1]], + `{return ${sourceCode.getText().slice(firstBodyToken.range[0], node.range[1])}}` + ); + } }); } } diff --git a/tools/eslint/lib/rules/arrow-parens.js b/tools/eslint/lib/rules/arrow-parens.js index 67bfdf541c2955..e069e307eb2040 100644 --- a/tools/eslint/lib/rules/arrow-parens.js +++ b/tools/eslint/lib/rules/arrow-parens.js @@ -58,7 +58,9 @@ module.exports = { requireForBlockBody && node.params.length === 1 && node.params[0].type === "Identifier" && - node.body.type !== "BlockStatement" + !node.params[0].typeAnnotation && + node.body.type !== "BlockStatement" && + !node.returnType ) { if (token.type === "Punctuator" && token.value === "(") { context.report({ @@ -95,7 +97,12 @@ module.exports = { } // "as-needed": x => x - if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier") { + if (asNeeded && + node.params.length === 1 && + node.params[0].type === "Identifier" && + !node.params[0].typeAnnotation && + !node.returnType + ) { if (token.type === "Punctuator" && token.value === "(") { context.report({ node, diff --git a/tools/eslint/lib/rules/block-scoped-var.js b/tools/eslint/lib/rules/block-scoped-var.js index 0f4705a1f140d9..bb0931a3ceb63f 100644 --- a/tools/eslint/lib/rules/block-scoped-var.js +++ b/tools/eslint/lib/rules/block-scoped-var.js @@ -47,10 +47,7 @@ module.exports = { function report(reference) { const identifier = reference.identifier; - context.report( - identifier, - "'{{name}}' used outside of binding context.", - {name: identifier.name}); + context.report({ node: identifier, message: "'{{name}}' used outside of binding context.", data: { name: identifier.name } }); } /** diff --git a/tools/eslint/lib/rules/block-spacing.js b/tools/eslint/lib/rules/block-spacing.js index f18b3cceba3132..9c0a7f388ba3bb 100644 --- a/tools/eslint/lib/rules/block-spacing.js +++ b/tools/eslint/lib/rules/block-spacing.js @@ -22,7 +22,7 @@ module.exports = { fixable: "whitespace", schema: [ - {enum: ["always", "never"]} + { enum: ["always", "never"] } ] }, diff --git a/tools/eslint/lib/rules/brace-style.js b/tools/eslint/lib/rules/brace-style.js index 6bd8a8f4c87edb..197767b07c19a5 100644 --- a/tools/eslint/lib/rules/brace-style.js +++ b/tools/eslint/lib/rules/brace-style.js @@ -30,7 +30,9 @@ module.exports = { }, additionalProperties: false } - ] + ], + + fixable: "whitespace" }, create(context) { @@ -69,6 +71,28 @@ module.exports = { return token.value === "{" || token.value === "}"; } + /** + * Reports a place where a newline unexpectedly appears + * @param {ASTNode} node The node to report + * @param {string} message The message to report + * @param {Token} firstToken The token before the unexpected newline + * @returns {void} + */ + function reportExtraNewline(node, message, firstToken) { + context.report({ + node, + message, + fix(fixer) { + const secondToken = sourceCode.getTokenAfter(firstToken); + const textBetween = sourceCode.getText().slice(firstToken.range[1], secondToken.range[0]); + const NEWLINE_REGEX = /\r\n|\r|\n|\u2028|\u2029/g; + + // Don't do a fix if there is a comment between the tokens. + return textBetween.trim() ? null : fixer.replaceTextRange([firstToken.range[1], secondToken.range[0]], textBetween.replace(NEWLINE_REGEX, "")); + } + }); + } + /** * Binds a list of properties to a function that verifies that the opening * curly brace is on the same line as its controlling statement of a given @@ -81,7 +105,7 @@ module.exports = { const blockProperties = arguments; return function(node) { - Array.prototype.forEach.call(blockProperties, function(blockProp) { + Array.prototype.forEach.call(blockProperties, blockProp => { const block = node[blockProp]; if (!isBlock(block)) { @@ -98,9 +122,13 @@ module.exports = { } if (style !== "allman" && previousToken.loc.start.line !== curlyToken.loc.start.line) { - context.report(node, OPEN_MESSAGE); + reportExtraNewline(node, OPEN_MESSAGE, previousToken); } else if (style === "allman" && previousToken.loc.start.line === curlyToken.loc.start.line) { - context.report(node, OPEN_MESSAGE_ALLMAN); + context.report({ + node, + message: OPEN_MESSAGE_ALLMAN, + fix: fixer => fixer.insertTextBefore(curlyToken, "\n") + }); } if (!block.body.length) { @@ -108,11 +136,19 @@ module.exports = { } if (curlyToken.loc.start.line === block.body[0].loc.start.line) { - context.report(block.body[0], BODY_MESSAGE); + context.report({ + node: block.body[0], + message: BODY_MESSAGE, + fix: fixer => fixer.insertTextAfter(curlyToken, "\n") + }); } - if (curlyTokenEnd.loc.start.line === block.body[block.body.length - 1].loc.start.line) { - context.report(block.body[block.body.length - 1], CLOSE_MESSAGE_SINGLE); + if (curlyTokenEnd.loc.start.line === block.body[block.body.length - 1].loc.end.line) { + context.report({ + node: block.body[block.body.length - 1], + message: CLOSE_MESSAGE_SINGLE, + fix: fixer => fixer.insertTextBefore(curlyTokenEnd, "\n") + }); } }); }; @@ -135,10 +171,14 @@ module.exports = { if (tokens[0].loc.start.line !== tokens[1].loc.start.line && node.consequent.type === "BlockStatement" && isCurlyPunctuator(tokens[0])) { - context.report(node.alternate, CLOSE_MESSAGE); + reportExtraNewline(node.alternate, CLOSE_MESSAGE, tokens[0]); } } else if (tokens[0].loc.start.line === tokens[1].loc.start.line) { - context.report(node.alternate, CLOSE_MESSAGE_STROUSTRUP_ALLMAN); + context.report({ + node: node.alternate, + message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN, + fix: fixer => fixer.insertTextAfter(tokens[0], "\n") + }); } } @@ -158,10 +198,14 @@ module.exports = { if (style === "1tbs") { if (tokens[0].loc.start.line !== tokens[1].loc.start.line) { - context.report(node.finalizer, CLOSE_MESSAGE); + reportExtraNewline(node.finalizer, CLOSE_MESSAGE, tokens[0]); } } else if (tokens[0].loc.start.line === tokens[1].loc.start.line) { - context.report(node.finalizer, CLOSE_MESSAGE_STROUSTRUP_ALLMAN); + context.report({ + node: node.finalizer, + message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN, + fix: fixer => fixer.insertTextAfter(tokens[0], "\n") + }); } } } @@ -181,11 +225,15 @@ module.exports = { if (isBlock(node.body)) { if (style === "1tbs") { if (previousToken.loc.start.line !== firstToken.loc.start.line) { - context.report(node, CLOSE_MESSAGE); + reportExtraNewline(node, CLOSE_MESSAGE, previousToken); } } else { if (previousToken.loc.start.line === firstToken.loc.start.line) { - context.report(node, CLOSE_MESSAGE_STROUSTRUP_ALLMAN); + context.report({ + node, + message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN, + fix: fixer => fixer.insertTextAfter(previousToken, "\n") + }); } } } @@ -207,9 +255,13 @@ module.exports = { } if (style !== "allman" && tokens[0].loc.start.line !== tokens[1].loc.start.line) { - context.report(node, OPEN_MESSAGE); + reportExtraNewline(node, OPEN_MESSAGE, tokens[0]); } else if (style === "allman" && tokens[0].loc.start.line === tokens[1].loc.start.line) { - context.report(node, OPEN_MESSAGE_ALLMAN); + context.report({ + node, + message: OPEN_MESSAGE_ALLMAN, + fix: fixer => fixer.insertTextBefore(tokens[1], "\n") + }); } } diff --git a/tools/eslint/lib/rules/callback-return.js b/tools/eslint/lib/rules/callback-return.js index 242ef666d2ac6e..08600c01e58cd1 100644 --- a/tools/eslint/lib/rules/callback-return.js +++ b/tools/eslint/lib/rules/callback-return.js @@ -164,7 +164,7 @@ module.exports = { // as long as you're the child of a function at this point you should be asked to return if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) { - context.report(node, "Expected return with your callback function."); + context.report({ node, message: "Expected return with your callback function." }); } } diff --git a/tools/eslint/lib/rules/camelcase.js b/tools/eslint/lib/rules/camelcase.js index 1b22c25e675ca3..6fb1475b21dbcd 100644 --- a/tools/eslint/lib/rules/camelcase.js +++ b/tools/eslint/lib/rules/camelcase.js @@ -38,6 +38,7 @@ module.exports = { // contains reported nodes to avoid reporting twice on destructuring with shorthand notation const reported = []; + const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); /** * Checks if a string contains an underscore and isn't all upper-case @@ -60,7 +61,7 @@ module.exports = { function report(node) { if (reported.indexOf(node) < 0) { reported.push(node); - context.report(node, "Identifier '{{name}}' is not in camel case.", { name: node.name }); + context.report({ node, message: "Identifier '{{name}}' is not in camel case.", data: { name: node.name } }); } } @@ -118,7 +119,7 @@ module.exports = { return; } - if (isUnderscored(name) && effectiveParent.type !== "CallExpression") { + if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { report(node); } @@ -131,7 +132,7 @@ module.exports = { } // Report anything that is underscored that isn't a CallExpression - } else if (isUnderscored(name) && effectiveParent.type !== "CallExpression") { + } else if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { report(node); } } diff --git a/tools/eslint/lib/rules/capitalized-comments.js b/tools/eslint/lib/rules/capitalized-comments.js new file mode 100644 index 00000000000000..29cff4450b535a --- /dev/null +++ b/tools/eslint/lib/rules/capitalized-comments.js @@ -0,0 +1,301 @@ +/** + * @fileoverview enforce or disallow capitalization of the first letter of a comment + * @author Kevin Partington + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const LETTER_PATTERN = require("../util/patterns/letters"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const ALWAYS_MESSAGE = "Comments should not begin with a lowercase character", + NEVER_MESSAGE = "Comments should not begin with an uppercase character", + DEFAULT_IGNORE_PATTERN = /^\s*(?:eslint|istanbul|jscs|jshint|globals?|exported)\b/, + WHITESPACE = /\s/g, + MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/, // TODO: Combine w/ max-len pattern? + DEFAULTS = { + ignorePattern: null, + ignoreInlineComments: false, + ignoreConsecutiveComments: false + }; + +/* + * Base schema body for defining the basic capitalization rule, ignorePattern, + * and ignoreInlineComments values. + * This can be used in a few different ways in the actual schema. + */ +const SCHEMA_BODY = { + type: "object", + properties: { + ignorePattern: { + type: "string" + }, + ignoreInlineComments: { + type: "boolean" + }, + ignoreConsecutiveComments: { + type: "boolean" + } + }, + additionalProperties: false +}; + +/** + * Get normalized options for either block or line comments from the given + * user-provided options. + * - If the user-provided options is just a string, returns a normalized + * set of options using default values for all other options. + * - If the user-provided options is an object, then a normalized option + * set is returned. Options specified in overrides will take priority + * over options specified in the main options object, which will in + * turn take priority over the rule's defaults. + * + * @param {Object|string} rawOptions The user-provided options. + * @param {string} which Either "line" or "block". + * @returns {Object} The normalized options. + */ +function getNormalizedOptions(rawOptions, which) { + if (!rawOptions) { + return Object.assign({}, DEFAULTS); + } + + return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions); +} + +/** + * Get normalized options for block and line comments. + * + * @param {Object|string} rawOptions The user-provided options. + * @returns {Object} An object with "Line" and "Block" keys and corresponding + * normalized options objects. + */ +function getAllNormalizedOptions(rawOptions) { + return { + Line: getNormalizedOptions(rawOptions, "line"), + Block: getNormalizedOptions(rawOptions, "block") + }; +} + +/** + * Creates a regular expression for each ignorePattern defined in the rule + * options. + * + * This is done in order to avoid invoking the RegExp constructor repeatedly. + * + * @param {Object} normalizedOptions The normalized rule options. + * @returns {void} + */ +function createRegExpForIgnorePatterns(normalizedOptions) { + Object.keys(normalizedOptions).forEach(key => { + const ignorePatternStr = normalizedOptions[key].ignorePattern; + + if (ignorePatternStr) { + const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`); + + normalizedOptions[key].ignorePatternRegExp = regExp; + } + }); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce or disallow capitalization of the first letter of a comment", + category: "Stylistic Issues", + recommended: false + }, + fixable: "code", + schema: [ + { enum: ["always", "never"] }, + { + oneOf: [ + SCHEMA_BODY, + { + type: "object", + properties: { + line: SCHEMA_BODY, + block: SCHEMA_BODY + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const capitalize = context.options[0] || "always", + normalizedOptions = getAllNormalizedOptions(context.options[1]), + sourceCode = context.getSourceCode(); + + createRegExpForIgnorePatterns(normalizedOptions); + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Checks whether a comment is an inline comment. + * + * For the purpose of this rule, a comment is inline if: + * 1. The comment is preceded by a token on the same line; and + * 2. The command is followed by a token on the same line. + * + * Note that the comment itself need not be single-line! + * + * Also, it follows from this definition that only block comments can + * be considered as possibly inline. This is because line comments + * would consume any following tokens on the same line as the comment. + * + * @param {ASTNode} comment The comment node to check. + * @returns {boolean} True if the comment is an inline comment, false + * otherwise. + */ + function isInlineComment(comment) { + const previousToken = sourceCode.getTokenOrCommentBefore(comment), + nextToken = sourceCode.getTokenOrCommentAfter(comment); + + return Boolean( + previousToken && + nextToken && + comment.loc.start.line === previousToken.loc.end.line && + comment.loc.end.line === nextToken.loc.start.line + ); + } + + /** + * Determine if a comment follows another comment. + * + * @param {ASTNode} comment The comment to check. + * @returns {boolean} True if the comment follows a valid comment. + */ + function isConsecutiveComment(comment) { + const previousTokenOrComment = sourceCode.getTokenOrCommentBefore(comment); + + return Boolean( + previousTokenOrComment && + ["Block", "Line"].indexOf(previousTokenOrComment.type) !== -1 + ); + } + + /** + * Check a comment to determine if it is valid for this rule. + * + * @param {ASTNode} comment The comment node to process. + * @param {Object} options The options for checking this comment. + * @returns {boolean} True if the comment is valid, false otherwise. + */ + function isCommentValid(comment, options) { + + // 1. Check for default ignore pattern. + if (DEFAULT_IGNORE_PATTERN.test(comment.value)) { + return true; + } + + // 2. Check for custom ignore pattern. + const commentWithoutAsterisks = comment.value + .replace(/\*/g, ""); + + if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { + return true; + } + + // 3. Check for inline comments. + if (options.ignoreInlineComments && isInlineComment(comment)) { + return true; + } + + // 4. Is this a consecutive comment (and are we tolerating those)? + if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) { + return true; + } + + // 5. Does the comment start with a possible URL? + if (MAYBE_URL.test(commentWithoutAsterisks)) { + return true; + } + + // 6. Is the initial word character a letter? + const commentWordCharsOnly = commentWithoutAsterisks + .replace(WHITESPACE, ""); + + if (commentWordCharsOnly.length === 0) { + return true; + } + + const firstWordChar = commentWordCharsOnly[0]; + + if (!LETTER_PATTERN.test(firstWordChar)) { + return true; + } + + // 7. Check the case of the initial word character. + const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(), + isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase(); + + if (capitalize === "always" && isLowercase) { + return false; + } else if (capitalize === "never" && isUppercase) { + return false; + } + + return true; + } + + /** + * Process a comment to determine if it needs to be reported. + * + * @param {ASTNode} comment The comment node to process. + * @returns {void} + */ + function processComment(comment) { + const options = normalizedOptions[comment.type], + commentValid = isCommentValid(comment, options); + + if (!commentValid) { + const message = capitalize === "always" ? + ALWAYS_MESSAGE : + NEVER_MESSAGE; + + context.report({ + node: null, // Intentionally using loc instead + loc: comment.loc, + message, + fix(fixer) { + const match = comment.value.match(LETTER_PATTERN); + + return fixer.replaceTextRange( + + // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*) + [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3], + capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase() + ); + } + }); + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + Program() { + const comments = sourceCode.getAllComments(); + + comments.forEach(processComment); + } + }; + } +}; diff --git a/tools/eslint/lib/rules/comma-dangle.js b/tools/eslint/lib/rules/comma-dangle.js index 763ee89fd5d55e..af7ab2767f5566 100644 --- a/tools/eslint/lib/rules/comma-dangle.js +++ b/tools/eslint/lib/rules/comma-dangle.js @@ -112,11 +112,11 @@ module.exports = { { type: "object", properties: { - arrays: {$refs: "#/defs/valueWithIgnore"}, - objects: {$refs: "#/defs/valueWithIgnore"}, - imports: {$refs: "#/defs/valueWithIgnore"}, - exports: {$refs: "#/defs/valueWithIgnore"}, - functions: {$refs: "#/defs/valueWithIgnore"} + arrays: { $refs: "#/defs/valueWithIgnore" }, + objects: { $refs: "#/defs/valueWithIgnore" }, + imports: { $refs: "#/defs/valueWithIgnore" }, + exports: { $refs: "#/defs/valueWithIgnore" }, + functions: { $refs: "#/defs/valueWithIgnore" } }, additionalProperties: false } @@ -171,15 +171,10 @@ module.exports = { function getTrailingToken(node, lastItem) { switch (node.type) { case "ObjectExpression": - case "ObjectPattern": case "ArrayExpression": - case "ArrayPattern": case "CallExpression": case "NewExpression": return sourceCode.getLastToken(node, 1); - case "FunctionDeclaration": - case "FunctionExpression": - return sourceCode.getTokenBefore(node.body, 1); default: { const nextToken = sourceCode.getTokenAfter(lastItem); diff --git a/tools/eslint/lib/rules/comma-spacing.js b/tools/eslint/lib/rules/comma-spacing.js index 72b5bad6badabe..f571cfa199675a 100644 --- a/tools/eslint/lib/rules/comma-spacing.js +++ b/tools/eslint/lib/rules/comma-spacing.js @@ -141,7 +141,7 @@ module.exports = { function addNullElementsToIgnoreList(node) { let previousToken = sourceCode.getFirstToken(node); - node.elements.forEach(function(element) { + node.elements.forEach(element => { let token; if (element === null) { @@ -164,7 +164,7 @@ module.exports = { return { "Program:exit"() { - tokensAndComments.forEach(function(token, i) { + tokensAndComments.forEach((token, i) => { if (!isComma(token)) { return; diff --git a/tools/eslint/lib/rules/comma-style.js b/tools/eslint/lib/rules/comma-style.js index f707ce80557e09..bb290f90b980d1 100644 --- a/tools/eslint/lib/rules/comma-style.js +++ b/tools/eslint/lib/rules/comma-style.js @@ -41,10 +41,22 @@ module.exports = { create(context) { const style = context.options[0] || "last", sourceCode = context.getSourceCode(); - let exceptions = {}; + const exceptions = { + ArrayPattern: true, + ArrowFunctionExpression: true, + CallExpression: true, + FunctionDeclaration: true, + FunctionExpression: true, + ImportDeclaration: true, + ObjectPattern: true, + }; if (context.options.length === 2 && context.options[1].hasOwnProperty("exceptions")) { - exceptions = context.options[1].exceptions; + const keys = Object.keys(context.options[1].exceptions); + + for (let i = 0; i < keys.length; i++) { + exceptions[keys[i]] = context.options[1].exceptions[keys[i]]; + } } //-------------------------------------------------------------------------- @@ -119,7 +131,7 @@ module.exports = { if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) && astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { - return; + // do nothing. } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { @@ -166,14 +178,14 @@ module.exports = { */ function validateComma(node, property) { const items = node[property], - arrayLiteral = (node.type === "ArrayExpression"); + arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern"); if (items.length > 1 || arrayLiteral) { // seed as opening [ let previousItemToken = sourceCode.getFirstToken(node); - items.forEach(function(item) { + items.forEach(item => { const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), reportItem = item || currentItemToken, @@ -245,11 +257,46 @@ module.exports = { validateComma(node, "properties"); }; } + if (!exceptions.ObjectPattern) { + nodes.ObjectPattern = function(node) { + validateComma(node, "properties"); + }; + } if (!exceptions.ArrayExpression) { nodes.ArrayExpression = function(node) { validateComma(node, "elements"); }; } + if (!exceptions.ArrayPattern) { + nodes.ArrayPattern = function(node) { + validateComma(node, "elements"); + }; + } + if (!exceptions.FunctionDeclaration) { + nodes.FunctionDeclaration = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.FunctionExpression) { + nodes.FunctionExpression = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.ArrowFunctionExpression) { + nodes.ArrowFunctionExpression = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.CallExpression) { + nodes.CallExpression = function(node) { + validateComma(node, "arguments"); + }; + } + if (!exceptions.ImportDeclaration) { + nodes.ImportDeclaration = function(node) { + validateComma(node, "specifiers"); + }; + } return nodes; } diff --git a/tools/eslint/lib/rules/complexity.js b/tools/eslint/lib/rules/complexity.js index 0d837e74d3b650..2f3e4040799872 100644 --- a/tools/eslint/lib/rules/complexity.js +++ b/tools/eslint/lib/rules/complexity.js @@ -91,7 +91,7 @@ module.exports = { } if (complexity > THRESHOLD) { - context.report(node, "Function '{{name}}' has a complexity of {{complexity}}.", { name, complexity }); + context.report({ node, message: "Function '{{name}}' has a complexity of {{complexity}}.", data: { name, complexity } }); } } diff --git a/tools/eslint/lib/rules/consistent-return.js b/tools/eslint/lib/rules/consistent-return.js index eed69c2cb78ac3..0c1a6a7493f663 100644 --- a/tools/eslint/lib/rules/consistent-return.js +++ b/tools/eslint/lib/rules/consistent-return.js @@ -33,6 +33,18 @@ function isUnreachable(segment) { return !segment.reachable; } +/** +* Checks whether a given node is a `constructor` method in an ES6 class +* @param {ASTNode} node A node to check +* @returns {boolean} `true` if the node is a `constructor` method +*/ +function isClassConstructor(node) { + return node.type === "FunctionExpression" && + node.parent && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor"; +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -77,7 +89,8 @@ module.exports = { */ if (!funcInfo.hasReturnValue || funcInfo.codePath.currentSegments.every(isUnreachable) || - astUtils.isES5Constructor(node) + astUtils.isES5Constructor(node) || + isClassConstructor(node) ) { return; } @@ -86,7 +99,7 @@ module.exports = { if (node.type === "Program") { // The head of program. - loc = {line: 1, column: 0}; + loc = { line: 1, column: 0 }; type = "program"; } else if (node.type === "ArrowFunctionExpression") { @@ -113,7 +126,7 @@ module.exports = { node, loc, message: "Expected to return a value at the end of this {{type}}.", - data: {type} + data: { type } }); } diff --git a/tools/eslint/lib/rules/consistent-this.js b/tools/eslint/lib/rules/consistent-this.js index 2a068ed1fc2add..35c2d56272a638 100644 --- a/tools/eslint/lib/rules/consistent-this.js +++ b/tools/eslint/lib/rules/consistent-this.js @@ -43,9 +43,7 @@ module.exports = { * @returns {void} */ function reportBadAssignment(node, alias) { - context.report(node, - "Designated alias '{{alias}}' is not assigned to 'this'.", - { alias }); + context.report({ node, message: "Designated alias '{{alias}}' is not assigned to 'this'.", data: { alias } }); } /** @@ -64,8 +62,7 @@ module.exports = { reportBadAssignment(node, name); } } else if (isThis) { - context.report(node, - "Unexpected alias '{{name}}' for 'this'.", { name }); + context.report({ node, message: "Unexpected alias '{{name}}' for 'this'.", data: { name } }); } } @@ -84,16 +81,14 @@ module.exports = { return; } - if (variable.defs.some(function(def) { - return def.node.type === "VariableDeclarator" && - def.node.init !== null; - })) { + if (variable.defs.some(def => def.node.type === "VariableDeclarator" && + def.node.init !== null)) { return; } // The alias has been declared and not assigned: check it was // assigned later in the same scope. - if (!variable.references.some(function(reference) { + if (!variable.references.some(reference => { const write = reference.writeExpr; return ( @@ -102,9 +97,7 @@ module.exports = { write.parent.operator === "=" ); })) { - variable.defs.map(function(def) { - return def.node; - }).forEach(function(node) { + variable.defs.map(def => def.node).forEach(node => { reportBadAssignment(node, alias); }); } @@ -117,7 +110,7 @@ module.exports = { function ensureWasAssigned() { const scope = context.getScope(); - aliases.forEach(function(alias) { + aliases.forEach(alias => { checkWasAssigned(alias, scope); }); } diff --git a/tools/eslint/lib/rules/constructor-super.js b/tools/eslint/lib/rules/constructor-super.js index 49271cee5899be..e84df7e81da025 100644 --- a/tools/eslint/lib/rules/constructor-super.js +++ b/tools/eslint/lib/rules/constructor-super.js @@ -261,8 +261,8 @@ module.exports = { const isRealLoop = toSegment.prevSegments.length >= 2; funcInfo.codePath.traverseSegments( - {first: toSegment, last: fromSegment}, - function(segment) { + { first: toSegment, last: fromSegment }, + segment => { const info = segInfoMap[segment.id]; const prevSegments = segment.prevSegments; diff --git a/tools/eslint/lib/rules/curly.js b/tools/eslint/lib/rules/curly.js index 02d74a1e037560..801552d69e151b 100644 --- a/tools/eslint/lib/rules/curly.js +++ b/tools/eslint/lib/rules/curly.js @@ -74,10 +74,11 @@ module.exports = { * @private */ function isCollapsedOneLiner(node) { - const before = sourceCode.getTokenBefore(node), - last = sourceCode.getLastToken(node); + const before = sourceCode.getTokenBefore(node); + const last = sourceCode.getLastToken(node); + const lastExcludingSemicolon = last.type === "Punctuator" && last.value === ";" ? sourceCode.getTokenBefore(last) : last; - return before.loc.start.line === last.loc.end.line; + return before.loc.start.line === lastExcludingSemicolon.loc.end.line; } /** @@ -195,7 +196,7 @@ module.exports = { return true; } - if (/^[(\[\/`+-]/.test(tokenAfter.value)) { + if (/^[([/`+-]/.test(tokenAfter.value)) { // If the next token starts with a character that would disrupt ASI, insert a semicolon. return true; @@ -289,7 +290,9 @@ module.exports = { } } else if (multiOrNest) { if (hasBlock && body.body.length === 1 && isOneLiner(body.body[0])) { - expected = false; + const leadingComments = sourceCode.getComments(body.body[0]).leading; + + expected = leadingComments.length > 0; } else if (!isOneLiner(body)) { expected = true; } @@ -337,14 +340,14 @@ module.exports = { * all have braces. * If all nodes shouldn't have braces, make sure they don't. */ - const expected = preparedChecks.some(function(preparedCheck) { + const expected = preparedChecks.some(preparedCheck => { if (preparedCheck.expected !== null) { return preparedCheck.expected; } return preparedCheck.actual; }); - preparedChecks.forEach(function(preparedCheck) { + preparedChecks.forEach(preparedCheck => { preparedCheck.expected = expected; }); } @@ -359,7 +362,7 @@ module.exports = { return { IfStatement(node) { if (node.parent.type !== "IfStatement") { - prepareIfChecks(node).forEach(function(preparedCheck) { + prepareIfChecks(node).forEach(preparedCheck => { preparedCheck.check(); }); } diff --git a/tools/eslint/lib/rules/default-case.js b/tools/eslint/lib/rules/default-case.js index e062798db235ab..070ff3c7a9666b 100644 --- a/tools/eslint/lib/rules/default-case.js +++ b/tools/eslint/lib/rules/default-case.js @@ -4,7 +4,7 @@ */ "use strict"; -const DEFAULT_COMMENT_PATTERN = /^no default$/; +const DEFAULT_COMMENT_PATTERN = /^no default$/i; //------------------------------------------------------------------------------ // Rule Definition @@ -67,9 +67,7 @@ module.exports = { return; } - const hasDefault = node.cases.some(function(v) { - return v.test === null; - }); + const hasDefault = node.cases.some(v => v.test === null); if (!hasDefault) { @@ -83,7 +81,7 @@ module.exports = { } if (!comment || !commentPattern.test(comment.value.trim())) { - context.report(node, "Expected a default case."); + context.report({ node, message: "Expected a default case." }); } } } diff --git a/tools/eslint/lib/rules/eqeqeq.js b/tools/eslint/lib/rules/eqeqeq.js index 4d61399f207ba7..d77607afb5f2aa 100644 --- a/tools/eslint/lib/rules/eqeqeq.js +++ b/tools/eslint/lib/rules/eqeqeq.js @@ -47,7 +47,9 @@ module.exports = { additionalItems: false } ] - } + }, + + fixable: "code" }, create(context) { @@ -112,22 +114,32 @@ module.exports = { function getOperatorLocation(node) { const opToken = sourceCode.getTokenAfter(node.left); - return {line: opToken.loc.start.line, column: opToken.loc.start.column}; + return { line: opToken.loc.start.line, column: opToken.loc.start.column }; } /** * Reports a message for this rule. * @param {ASTNode} node The binary expression node that was checked - * @param {string} message The message to report + * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==') * @returns {void} * @private */ - function report(node, message) { + function report(node, expectedOperator) { context.report({ node, loc: getOperatorLocation(node), - message, - data: { op: node.operator.charAt(0) } + message: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'.", + data: { expectedOperator, actualOperator: node.operator }, + fix(fixer) { + + // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix. + if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) { + const operatorToken = sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + + return fixer.replaceText(operatorToken, expectedOperator); + } + return null; + } }); } @@ -137,7 +149,7 @@ module.exports = { if (node.operator !== "==" && node.operator !== "!=") { if (enforceInverseRuleForNull && isNull) { - report(node, "Expected '{{op}}=' and instead saw '{{op}}=='."); + report(node, node.operator.slice(0, -1)); } return; } @@ -151,7 +163,7 @@ module.exports = { return; } - report(node, "Expected '{{op}}==' and instead saw '{{op}}='."); + report(node, `${node.operator}=`); } }; diff --git a/tools/eslint/lib/rules/func-call-spacing.js b/tools/eslint/lib/rules/func-call-spacing.js index 417f2bdf313e17..5c416f0373fcac 100644 --- a/tools/eslint/lib/rules/func-call-spacing.js +++ b/tools/eslint/lib/rules/func-call-spacing.js @@ -120,7 +120,14 @@ module.exports = { loc: lastCalleeToken.loc.start, message: "Unexpected space between function name and paren.", fix(fixer) { - return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); + + // Only autofix if there is no newline + // https://github.com/eslint/eslint/issues/7787 + if (!hasNewline) { + return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); + } + + return null; } }); } else if (!never && !hasWhitespace) { diff --git a/tools/eslint/lib/rules/func-name-matching.js b/tools/eslint/lib/rules/func-name-matching.js index d4d760cbe45f1b..4eed7a68ea2b51 100644 --- a/tools/eslint/lib/rules/func-name-matching.js +++ b/tools/eslint/lib/rules/func-name-matching.js @@ -54,6 +54,17 @@ function isIdentifier(name, ecmaVersion) { // Rule Definition //------------------------------------------------------------------------------ +const alwaysOrNever = { enum: ["always", "never"] }; +const optionsObject = { + type: "object", + properties: { + includeCommonJSModuleExports: { + type: "boolean" + } + }, + additionalProperties: false +}; + module.exports = { meta: { docs: { @@ -62,24 +73,35 @@ module.exports = { recommended: false }, - schema: [ - { - type: "object", - properties: { - includeCommonJSModuleExports: { - type: "boolean" - } - }, - additionalProperties: false - } - ] + schema: { + anyOf: [{ + type: "array", + additionalItems: false, + items: [alwaysOrNever, optionsObject] + }, { + type: "array", + additionalItems: false, + items: [optionsObject] + }] + } }, create(context) { - - const includeModuleExports = context.options[0] && context.options[0].includeCommonJSModuleExports; + const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {}; + const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always"; + const includeModuleExports = options.includeCommonJSModuleExports; const ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5; + /** + * Compares identifiers based on the nameMatches option + * @param {string} x the first identifier + * @param {string} y the second identifier + * @returns {boolean} whether the two identifiers should warn. + */ + function shouldWarn(x, y) { + return (nameMatches === "always" && x !== y) || (nameMatches === "never" && x === y); + } + /** * Reports * @param {ASTNode} node The node to report @@ -89,10 +111,20 @@ module.exports = { * @returns {void} */ function report(node, name, funcName, isProp) { + let message; + + if (nameMatches === "always" && isProp) { + message = "Function name `{{funcName}}` should match property name `{{name}}`"; + } else if (nameMatches === "always") { + message = "Function name `{{funcName}}` should match variable name `{{name}}`"; + } else if (isProp) { + message = "Function name `{{funcName}}` should not match property name `{{name}}`"; + } else { + message = "Function name `{{funcName}}` should not match variable name `{{name}}`"; + } context.report({ node, - message: isProp ? "Function name `{{funcName}}` should match property name `{{name}}`" - : "Function name `{{funcName}}` should match variable name `{{name}}`", + message, data: { name, funcName @@ -110,7 +142,7 @@ module.exports = { if (!node.init || node.init.type !== "FunctionExpression") { return; } - if (node.init.id && node.id.name !== node.init.id.name) { + if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) { report(node, node.id.name, node.init.id.name, false); } }, @@ -126,7 +158,7 @@ module.exports = { const isProp = node.left.type === "MemberExpression" ? true : false; const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name; - if (node.right.id && isIdentifier(name) && name !== node.right.id.name) { + if (node.right.id && isIdentifier(name) && shouldWarn(name, node.right.id.name)) { report(node, name, node.right.id.name, isProp); } }, @@ -135,12 +167,13 @@ module.exports = { if (node.value.type !== "FunctionExpression" || !node.value.id || node.computed && node.key.type !== "Literal") { return; } - if (node.key.type === "Identifier" && node.key.name !== node.value.id.name) { + if (node.key.type === "Identifier" && shouldWarn(node.key.name, node.value.id.name)) { report(node, node.key.name, node.value.id.name, true); - } else if (node.key.type === "Literal" && - isIdentifier(node.key.value, ecmaVersion) && - node.key.value !== node.value.id.name - ) { + } else if ( + node.key.type === "Literal" && + isIdentifier(node.key.value, ecmaVersion) && + shouldWarn(node.key.value, node.value.id.name) + ) { report(node, node.key.value, node.value.id.name, true); } } diff --git a/tools/eslint/lib/rules/func-names.js b/tools/eslint/lib/rules/func-names.js index 397ef37e91614d..0d8567149493dc 100644 --- a/tools/eslint/lib/rules/func-names.js +++ b/tools/eslint/lib/rules/func-names.js @@ -28,21 +28,23 @@ module.exports = { schema: [ { - enum: ["always", "never"] + enum: ["always", "as-needed", "never"] } ] }, create(context) { const never = context.options[0] === "never"; + const asNeeded = context.options[0] === "as-needed"; /** * Determines whether the current FunctionExpression node is a get, set, or * shorthand method in an object literal or a class. + * @param {ASTNode} node - A node to check. * @returns {boolean} True if the node is a get, set, or shorthand method. */ - function isObjectOrClassMethod() { - const parent = context.getAncestors().pop(); + function isObjectOrClassMethod(node) { + const parent = node.parent; return (parent.type === "MethodDefinition" || ( parent.type === "Property" && ( @@ -53,6 +55,23 @@ module.exports = { )); } + /** + * Determines whether the current FunctionExpression node has a name that would be + * inferred from context in a conforming ES6 environment. + * @param {ASTNode} node - A node to check. + * @returns {boolean} True if the node would have a name assigned automatically. + */ + function hasInferredName(node) { + const parent = node.parent; + + return isObjectOrClassMethod(node) || + (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) || + (parent.type === "Property" && parent.value === node) || + (parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) || + (parent.type === "ExportDefaultDeclaration" && parent.declaration === node) || + (parent.type === "AssignmentPattern" && parent.right === node); + } + return { "FunctionExpression:exit"(node) { @@ -67,11 +86,11 @@ module.exports = { if (never) { if (name) { - context.report(node, "Unexpected function expression name."); + context.report({ node, message: "Unexpected function expression name." }); } } else { - if (!name && !isObjectOrClassMethod()) { - context.report(node, "Missing function expression name."); + if (!name && (asNeeded ? !hasInferredName(node) : !isObjectOrClassMethod(node))) { + context.report({ node, message: "Missing function expression name." }); } } } diff --git a/tools/eslint/lib/rules/func-style.js b/tools/eslint/lib/rules/func-style.js index e0974209c4bb78..123eae3d8a406f 100644 --- a/tools/eslint/lib/rules/func-style.js +++ b/tools/eslint/lib/rules/func-style.js @@ -44,7 +44,7 @@ module.exports = { stack.push(false); if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { - context.report(node, "Expected a function expression."); + context.report({ node, message: "Expected a function expression." }); } }, "FunctionDeclaration:exit"() { @@ -55,7 +55,7 @@ module.exports = { stack.push(false); if (enforceDeclarations && node.parent.type === "VariableDeclarator") { - context.report(node.parent, "Expected a function declaration."); + context.report({ node: node.parent, message: "Expected a function declaration." }); } }, "FunctionExpression:exit"() { @@ -78,7 +78,7 @@ module.exports = { const hasThisExpr = stack.pop(); if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { - context.report(node.parent, "Expected a function declaration."); + context.report({ node: node.parent, message: "Expected a function declaration." }); } }; } diff --git a/tools/eslint/lib/rules/generator-star-spacing.js b/tools/eslint/lib/rules/generator-star-spacing.js index f9ec3a4af52c25..fc676d0cbbb85f 100644 --- a/tools/eslint/lib/rules/generator-star-spacing.js +++ b/tools/eslint/lib/rules/generator-star-spacing.js @@ -28,8 +28,8 @@ module.exports = { { type: "object", properties: { - before: {type: "boolean"}, - after: {type: "boolean"} + before: { type: "boolean" }, + after: { type: "boolean" } }, additionalProperties: false } diff --git a/tools/eslint/lib/rules/global-require.js b/tools/eslint/lib/rules/global-require.js index 3d6492cfde4671..bfd01433957e3e 100644 --- a/tools/eslint/lib/rules/global-require.js +++ b/tools/eslint/lib/rules/global-require.js @@ -23,10 +23,8 @@ const ACCEPTABLE_PARENTS = [ * @returns {Reference|null} Returns the found reference or null if none were found. */ function findReference(scope, node) { - const references = scope.references.filter(function(reference) { - return reference.identifier.range[0] === node.range[0] && - reference.identifier.range[1] === node.range[1]; - }); + const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && + reference.identifier.range[1] === node.range[1]); /* istanbul ignore else: correctly returns null */ if (references.length === 1) { @@ -65,12 +63,10 @@ module.exports = { const currentScope = context.getScope(); if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) { - const isGoodRequire = context.getAncestors().every(function(parent) { - return ACCEPTABLE_PARENTS.indexOf(parent.type) > -1; - }); + const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1); if (!isGoodRequire) { - context.report(node, "Unexpected require()."); + context.report({ node, message: "Unexpected require()." }); } } } diff --git a/tools/eslint/lib/rules/guard-for-in.js b/tools/eslint/lib/rules/guard-for-in.js index 7ccfec90c1c572..754830f6a64be3 100644 --- a/tools/eslint/lib/rules/guard-for-in.js +++ b/tools/eslint/lib/rules/guard-for-in.js @@ -33,7 +33,7 @@ module.exports = { const body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body; if (body && body.type !== "IfStatement") { - context.report(node, "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype."); + context.report({ node, message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." }); } } }; diff --git a/tools/eslint/lib/rules/handle-callback-err.js b/tools/eslint/lib/rules/handle-callback-err.js index e8c6d1b3b8f647..de36a0c1b002c6 100644 --- a/tools/eslint/lib/rules/handle-callback-err.js +++ b/tools/eslint/lib/rules/handle-callback-err.js @@ -59,9 +59,7 @@ module.exports = { * @returns {array} All parameters of the given scope. */ function getParameters(scope) { - return scope.variables.filter(function(variable) { - return variable.defs[0] && variable.defs[0].type === "Parameter"; - }); + return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter"); } /** @@ -76,7 +74,7 @@ module.exports = { if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) { if (firstParameter.references.length === 0) { - context.report(node, "Expected error to be handled."); + context.report({ node, message: "Expected error to be handled." }); } } } diff --git a/tools/eslint/lib/rules/id-blacklist.js b/tools/eslint/lib/rules/id-blacklist.js index 8795cfc6be6964..f94f6d0a4684d4 100644 --- a/tools/eslint/lib/rules/id-blacklist.js +++ b/tools/eslint/lib/rules/id-blacklist.js @@ -67,9 +67,9 @@ module.exports = { * @private */ function report(node) { - context.report(node, "Identifier '{{name}}' is blacklisted.", { + context.report({ node, message: "Identifier '{{name}}' is blacklisted.", data: { name: node.name - }); + } }); } return { diff --git a/tools/eslint/lib/rules/id-length.js b/tools/eslint/lib/rules/id-length.js index 1747552707901c..6a6c69d1017e8c 100644 --- a/tools/eslint/lib/rules/id-length.js +++ b/tools/eslint/lib/rules/id-length.js @@ -50,7 +50,7 @@ module.exports = { const maxLength = typeof options.max !== "undefined" ? options.max : Infinity; const properties = options.properties !== "never"; const exceptions = (options.exceptions ? options.exceptions : []) - .reduce(function(obj, item) { + .reduce((obj, item) => { obj[item] = true; return obj; @@ -102,13 +102,13 @@ module.exports = { const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) { - context.report( + context.report({ node, - isShort ? + message: isShort ? "Identifier name '{{name}}' is too short (< {{min}})." : "Identifier name '{{name}}' is too long (> {{max}}).", - { name, min: minLength, max: maxLength } - ); + data: { name, min: minLength, max: maxLength } + }); } } }; diff --git a/tools/eslint/lib/rules/id-match.js b/tools/eslint/lib/rules/id-match.js index 961a1859049d24..29d06c36024c57 100644 --- a/tools/eslint/lib/rules/id-match.js +++ b/tools/eslint/lib/rules/id-match.js @@ -75,10 +75,10 @@ module.exports = { * @private */ function report(node) { - context.report(node, "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", { + context.report({ node, message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", data: { name: node.name, pattern - }); + } }); } return { diff --git a/tools/eslint/lib/rules/indent.js b/tools/eslint/lib/rules/indent.js index 2b069011f99d02..6c3c27c8e1941a 100644 --- a/tools/eslint/lib/rules/indent.js +++ b/tools/eslint/lib/rules/indent.js @@ -113,6 +113,44 @@ module.exports = { minimum: 0 } } + }, + CallExpression: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + } + } + }, + ArrayExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + ObjectExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] } }, additionalProperties: false @@ -142,7 +180,12 @@ module.exports = { FunctionExpression: { parameters: DEFAULT_PARAMETER_INDENT, body: DEFAULT_FUNCTION_BODY_INDENT - } + }, + CallExpression: { + arguments: DEFAULT_PARAMETER_INDENT + }, + ArrayExpression: 1, + ObjectExpression: 1 }; const sourceCode = context.getSourceCode(); @@ -187,6 +230,18 @@ module.exports = { if (typeof opts.FunctionExpression === "object") { Object.assign(options.FunctionExpression, opts.FunctionExpression); } + + if (typeof opts.CallExpression === "object") { + Object.assign(options.CallExpression, opts.CallExpression); + } + + if (typeof opts.ArrayExpression === "number" || typeof opts.ArrayExpression === "string") { + options.ArrayExpression = opts.ArrayExpression; + } + + if (typeof opts.ObjectExpression === "number" || typeof opts.ObjectExpression === "string") { + options.ObjectExpression = opts.ObjectExpression; + } } } @@ -229,10 +284,10 @@ module.exports = { * @param {int} gottenTabs Indentation tab count in the actual node/code * @param {Object=} loc Error line and column location * @param {boolean} isLastNodeCheck Is the error for last node check + * @param {int} lastNodeCheckEndOffset Number of charecters to skip from the end * @returns {void} */ function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) { - if (gottenSpaces && gottenTabs) { // To avoid conflicts with `no-mixed-spaces-and-tabs`, don't report lines that have both spaces and tabs. @@ -242,8 +297,8 @@ module.exports = { const desiredIndent = (indentType === "space" ? " " : "\t").repeat(needed); const textRange = isLastNodeCheck - ? [node.range[1] - gottenSpaces - gottenTabs - 1, node.range[1] - 1] - : [node.range[0] - gottenSpaces - gottenTabs, node.range[0]]; + ? [node.range[1] - node.loc.end.column, node.range[1] - node.loc.end.column + gottenSpaces + gottenTabs] + : [node.range[0] - node.loc.start.column, node.range[0] - node.loc.start.column + gottenSpaces + gottenTabs]; context.report({ node, @@ -319,6 +374,24 @@ module.exports = { checkNodeIndent(node.alternate, neededIndent); } } + + if (node.type === "TryStatement" && node.handler) { + const catchToken = sourceCode.getFirstToken(node.handler); + + checkNodeIndent(catchToken, neededIndent); + } + + if (node.type === "TryStatement" && node.finalizer) { + const finallyToken = sourceCode.getTokenBefore(node.finalizer); + + checkNodeIndent(finallyToken, neededIndent); + } + + if (node.type === "DoWhileStatement") { + const whileToken = sourceCode.getTokenAfter(node.body); + + checkNodeIndent(whileToken, neededIndent); + } } /** @@ -354,6 +427,45 @@ module.exports = { } } + /** + * Check last node line indent this detects, that block closed correctly + * This function for more complicated return statement case, where closing parenthesis may be followed by ';' + * @param {ASTNode} node Node to examine + * @param {int} firstLineIndent first line needed indent + * @returns {void} + */ + function checkLastReturnStatementLineIndent(node, firstLineIndent) { + const nodeLastToken = sourceCode.getLastToken(node); + let lastToken = nodeLastToken; + + // in case if return statement ends with ');' we have traverse back to ')' + // otherwise we'll measure indent for ';' and replace ')' + while (lastToken.value !== ")") { + lastToken = sourceCode.getTokenBefore(lastToken); + } + + const textBeforeClosingParenthesis = sourceCode.getText(lastToken, lastToken.loc.start.column).slice(0, -1); + + if (textBeforeClosingParenthesis.trim()) { + + // There are tokens before the closing paren, don't report this case + return; + } + + const endIndent = getNodeIndent(lastToken, true); + + if (endIndent.goodChar !== firstLineIndent) { + report( + node, + firstLineIndent, + endIndent.space, + endIndent.tab, + { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, + true + ); + } + } + /** * Check first node line indent is correct * @param {ASTNode} node Node to examine @@ -379,12 +491,17 @@ module.exports = { * if not present then return null * @param {ASTNode} node node to examine * @param {string} type type that is being looked for + * @param {string} stopAtList end points for the evaluating code * @returns {ASTNode|void} if found then node otherwise null */ - function getParentNodeByType(node, type) { + function getParentNodeByType(node, type, stopAtList) { let parent = node.parent; - while (parent.type !== type && parent.type !== "Program") { + if (!stopAtList) { + stopAtList = ["Program"]; + } + + while (parent.type !== type && stopAtList.indexOf(parent.type) === -1 && parent.type !== "Program") { parent = parent.parent; } @@ -401,16 +518,6 @@ module.exports = { return getParentNodeByType(node, "VariableDeclarator"); } - /** - * Returns the ExpressionStatement based on the current node - * if not present then return null - * @param {ASTNode} node node to examine - * @returns {ASTNode|void} if found then node otherwise null - */ - function getAssignmentExpressionNode(node) { - return getParentNodeByType(node, "AssignmentExpression"); - } - /** * Check to see if the node is part of the multi-line variable declaration. * Also if its on the same line as the varNode @@ -604,14 +711,7 @@ module.exports = { let elements = (node.type === "ArrayExpression") ? node.elements : node.properties; // filter out empty elements example would be [ , 2] so remove first element as espree considers it as null - elements = elements.filter(function(elem) { - return elem !== null; - }); - - // Skip if first element is in same line with this node - if (elements.length > 0 && elements[0].loc.start.line === node.loc.start.line) { - return; - } + elements = elements.filter(elem => elem !== null); let nodeIndent; let elementsIndent; @@ -620,41 +720,59 @@ module.exports = { // TODO - come up with a better strategy in future if (isNodeFirstInLine(node)) { const parent = node.parent; - let effectiveParent = parent; - if (parent.type === "MemberExpression") { - if (isNodeFirstInLine(parent)) { - effectiveParent = parent.parent.parent; - } else { - effectiveParent = parent.parent; - } - } - nodeIndent = getNodeIndent(effectiveParent).goodChar; - if (parentVarNode && parentVarNode.loc.start.line !== node.loc.start.line) { + nodeIndent = getNodeIndent(parent).goodChar; + if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) { if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) { - if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === effectiveParent.loc.start.line) { + if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) { nodeIndent = nodeIndent + (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]); - } else if ( - parent.type === "ObjectExpression" || - parent.type === "ArrayExpression" || - parent.type === "CallExpression" || - parent.type === "ArrowFunctionExpression" || - parent.type === "NewExpression" || - parent.type === "LogicalExpression" - ) { - nodeIndent = nodeIndent + indentSize; + } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") { + const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements; + + if (parentElements[0].loc.start.line === parent.loc.start.line && parentElements[0].loc.end.line !== parent.loc.start.line) { + + /* + * If the first element of the array spans multiple lines, don't increase the expected indentation of the rest. + * e.g. [{ + * foo: 1 + * }, + * { + * bar: 1 + * }] + * the second object is not indented. + */ + } else if (typeof options[parent.type] === "number") { + nodeIndent += options[parent.type] * indentSize; + } else { + nodeIndent = parentElements[0].loc.start.column; + } + } else if (parent.type === "CallExpression" || parent.type === "NewExpression") { + if (typeof options.CallExpression.arguments === "number") { + nodeIndent += options.CallExpression.arguments * indentSize; + } else if (options.CallExpression.arguments === "first") { + if (parent.arguments.indexOf(node) !== -1) { + nodeIndent = parent.arguments[0].loc.start.column; + } + } else { + nodeIndent += indentSize; + } + } else if (parent.type === "LogicalExpression" || parent.type === "ArrowFunctionExpression") { + nodeIndent += indentSize; } } - } else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && effectiveParent.type !== "MemberExpression" && effectiveParent.type !== "ExpressionStatement" && effectiveParent.type !== "AssignmentExpression" && effectiveParent.type !== "Property") { + } else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && parent.type !== "MemberExpression" && parent.type !== "ExpressionStatement" && parent.type !== "AssignmentExpression" && parent.type !== "Property") { nodeIndent = nodeIndent + indentSize; } - elementsIndent = nodeIndent + indentSize; - checkFirstNodeLineIndent(node, nodeIndent); } else { nodeIndent = getNodeIndent(node).goodChar; - elementsIndent = nodeIndent + indentSize; + } + + if (options[node.type] === "first") { + elementsIndent = elements.length ? elements[0].loc.start.column : 0; // If there are no elements, elementsIndent doesn't matter. + } else { + elementsIndent = nodeIndent + indentSize * options[node.type]; } /* @@ -675,7 +793,7 @@ module.exports = { } } - checkLastNodeLineIndent(node, elementsIndent - indentSize); + checkLastNodeLineIndent(node, nodeIndent + (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0)); } /** @@ -717,11 +835,13 @@ module.exports = { * not from the beginning of the block. */ const statementsWithProperties = [ - "IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration" + "IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration", "TryStatement" ]; if (node.parent && statementsWithProperties.indexOf(node.parent.type) !== -1 && isNodeBodyBlock(node)) { indent = getNodeIndent(node.parent).goodChar; + } else if (node.parent && node.parent.type === "CatchClause") { + indent = getNodeIndent(node.parent.parent).goodChar; } else { indent = getNodeIndent(node).goodChar; } @@ -750,7 +870,7 @@ module.exports = { * @returns {ASTNode[]} Filtered elements */ function filterOutSameLineVars(node) { - return node.declarations.reduce(function(finalCollection, elem) { + return node.declarations.reduce((finalCollection, elem) => { const lastElem = finalCollection[finalCollection.length - 1]; if ((elem.loc.start.line !== node.loc.start.line && !lastElem) || @@ -832,6 +952,20 @@ module.exports = { } } + /** + * Checks wether a return statement is wrapped in () + * @param {ASTNode} node node to examine + * @returns {boolean} the result + */ + function isWrappedInParenthesis(node) { + const regex = /^return\s*?\(\s*?\);*?/; + + const statementWithoutArgument = sourceCode.getText(node).replace( + sourceCode.getText(node.argument), ""); + + return regex.test(statementWithoutArgument); + } + return { Program(node) { if (node.body.length > 0) { @@ -876,6 +1010,7 @@ module.exports = { }, MemberExpression(node) { + if (typeof options.MemberExpression === "undefined") { return; } @@ -888,11 +1023,11 @@ module.exports = { // alter the expectation of correct indentation. Skip them. // TODO: Add appropriate configuration options for variable // declarations and assignments. - if (getVariableDeclaratorNode(node)) { + if (getParentNodeByType(node, "VariableDeclarator", ["FunctionExpression", "ArrowFunctionExpression"])) { return; } - if (getAssignmentExpressionNode(node)) { + if (getParentNodeByType(node, "AssignmentExpression", ["FunctionExpression"])) { return; } @@ -952,7 +1087,34 @@ module.exports = { } else if (options.FunctionExpression.parameters !== null) { checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionExpression.parameters); } + }, + + ReturnStatement(node) { + if (isSingleLineNode(node)) { + return; + } + + const firstLineIndent = getNodeIndent(node).goodChar; + + // in case if return statement is wrapped in parenthesis + if (isWrappedInParenthesis(node)) { + checkLastReturnStatementLineIndent(node, firstLineIndent); + } else { + checkNodeIndent(node, firstLineIndent); + } + }, + + CallExpression(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.CallExpression.arguments === "first" && node.arguments.length) { + checkNodesIndent(node.arguments.slice(1), node.arguments[0].loc.start.column); + } else if (options.CallExpression.arguments !== null) { + checkNodesIndent(node.arguments, getNodeIndent(node).goodChar + indentSize * options.CallExpression.arguments); + } } + }; } diff --git a/tools/eslint/lib/rules/jsx-quotes.js b/tools/eslint/lib/rules/jsx-quotes.js index 2b6a57b961d88f..5653922d9495d5 100644 --- a/tools/eslint/lib/rules/jsx-quotes.js +++ b/tools/eslint/lib/rules/jsx-quotes.js @@ -48,7 +48,7 @@ module.exports = { schema: [ { - enum: [ "prefer-single", "prefer-double" ] + enum: ["prefer-single", "prefer-double"] } ] }, diff --git a/tools/eslint/lib/rules/key-spacing.js b/tools/eslint/lib/rules/key-spacing.js index b195d31d32a4ee..8d7564a5bbf246 100644 --- a/tools/eslint/lib/rules/key-spacing.js +++ b/tools/eslint/lib/rules/key-spacing.js @@ -417,8 +417,8 @@ module.exports = { function report(property, side, whitespace, expected, mode) { const diff = whitespace.length - expected, nextColon = getNextColon(property.key), - tokenBeforeColon = sourceCode.getTokenBefore(nextColon), - tokenAfterColon = sourceCode.getTokenAfter(nextColon), + tokenBeforeColon = sourceCode.getTokenOrCommentBefore(nextColon), + tokenAfterColon = sourceCode.getTokenOrCommentAfter(nextColon), isKeySide = side === "key", locStart = isKeySide ? tokenBeforeColon.loc.start : tokenAfterColon.loc.start, isExtra = diff > 0, @@ -514,7 +514,7 @@ module.exports = { return [node.properties]; } - return node.properties.reduce(function(groups, property) { + return node.properties.reduce((groups, property) => { const currentGroup = last(groups), prev = last(currentGroup); @@ -579,7 +579,7 @@ module.exports = { * @returns {void} */ function verifyAlignment(node) { - createGroups(node).forEach(function(group) { + createGroups(node).forEach(group => { verifyGroupAlignment(group.filter(isKeyValueProperty)); }); } diff --git a/tools/eslint/lib/rules/keyword-spacing.js b/tools/eslint/lib/rules/keyword-spacing.js index 4a6a024552111c..1dfc291f6e827b 100644 --- a/tools/eslint/lib/rules/keyword-spacing.js +++ b/tools/eslint/lib/rules/keyword-spacing.js @@ -16,10 +16,10 @@ const astUtils = require("../ast-utils"), // Constants //------------------------------------------------------------------------------ -const PREV_TOKEN = /^[\)\]\}>]$/; -const NEXT_TOKEN = /^(?:[\(\[\{<~!]|\+\+?|--?)$/; -const PREV_TOKEN_M = /^[\)\]\}>*]$/; -const NEXT_TOKEN_M = /^[\{*]$/; +const PREV_TOKEN = /^[)\]}>]$/; +const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/; +const PREV_TOKEN_M = /^[)\]}>*]$/; +const NEXT_TOKEN_M = /^[{*]$/; const TEMPLATE_OPEN_PAREN = /\$\{$/; const TEMPLATE_CLOSE_PAREN = /^\}/; const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/; @@ -77,16 +77,16 @@ module.exports = { { type: "object", properties: { - before: {type: "boolean"}, - after: {type: "boolean"}, + before: { type: "boolean" }, + after: { type: "boolean" }, overrides: { type: "object", - properties: KEYS.reduce(function(retv, key) { + properties: KEYS.reduce((retv, key) => { retv[key] = { type: "object", properties: { - before: {type: "boolean"}, - after: {type: "boolean"} + before: { type: "boolean" }, + after: { type: "boolean" } }, additionalProperties: false }; diff --git a/tools/eslint/lib/rules/lines-around-comment.js b/tools/eslint/lib/rules/lines-around-comment.js index 094fefa74f4646..83751cd6a50ad6 100644 --- a/tools/eslint/lib/rules/lines-around-comment.js +++ b/tools/eslint/lib/rules/lines-around-comment.js @@ -21,16 +21,10 @@ const lodash = require("lodash"), * @returns {Array} An array of line numbers. */ function getEmptyLineNums(lines) { - const emptyLines = lines.map(function(line, i) { - return { - code: line.trim(), - num: i + 1 - }; - }).filter(function(line) { - return !line.code; - }).map(function(line) { - return line.num; - }); + const emptyLines = lines.map((line, i) => ({ + code: line.trim(), + num: i + 1 + })).filter(line => !line.code).map(line => line.num); return emptyLines; } @@ -43,7 +37,7 @@ function getEmptyLineNums(lines) { function getCommentLineNums(comments) { const lines = []; - comments.forEach(function(token) { + comments.forEach(token => { const start = token.loc.start.line; const end = token.loc.end.line; diff --git a/tools/eslint/lib/rules/lines-around-directive.js b/tools/eslint/lib/rules/lines-around-directive.js index f0f0ebd0b9037b..b1e54e940b8f64 100644 --- a/tools/eslint/lib/rules/lines-around-directive.js +++ b/tools/eslint/lib/rules/lines-around-directive.js @@ -63,15 +63,32 @@ module.exports = { return node.loc.start.line - tokenLineBefore >= 2; } + /** + * Gets the last token of a node that is on the same line as the rest of the node. + * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing + * semicolon on a different line. + * @param {ASTNode} node A directive node + * @returns {Token} The last token of the node on the line + */ + function getLastTokenOnLine(node) { + const lastToken = sourceCode.getLastToken(node); + const secondToLastToken = sourceCode.getTokenBefore(lastToken); + + return lastToken.type === "Punctuator" && lastToken.value === ";" && lastToken.loc.start.line > secondToLastToken.loc.end.line + ? secondToLastToken + : lastToken; + } + /** * Check if node is followed by a blank newline. * @param {ASTNode} node Node to check. * @returns {boolean} Whether or not the passed in node is followed by a blank newline. */ function hasNewlineAfter(node) { - const tokenAfter = sourceCode.getTokenOrCommentAfter(node); + const lastToken = getLastTokenOnLine(node); + const tokenAfter = sourceCode.getTokenOrCommentAfter(lastToken); - return tokenAfter.loc.start.line - node.loc.end.line >= 2; + return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2; } /** @@ -91,10 +108,12 @@ module.exports = { location }, fix(fixer) { + const lastToken = getLastTokenOnLine(node); + if (expected) { - return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(node, "\n"); + return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n"); } - return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [node.range[1], node.range[1] + 1]); + return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]); } }); } diff --git a/tools/eslint/lib/rules/max-depth.js b/tools/eslint/lib/rules/max-depth.js index 35b7e9ce8946de..74c13ffa9fad2e 100644 --- a/tools/eslint/lib/rules/max-depth.js +++ b/tools/eslint/lib/rules/max-depth.js @@ -91,8 +91,7 @@ module.exports = { const len = ++functionStack[functionStack.length - 1]; if (len > maxDepth) { - context.report(node, "Blocks are nested too deeply ({{depth}}).", - { depth: len }); + context.report({ node, message: "Blocks are nested too deeply ({{depth}}).", data: { depth: len } }); } } diff --git a/tools/eslint/lib/rules/max-len.js b/tools/eslint/lib/rules/max-len.js index d1f6df2996f9aa..dd5a4e1ef62553 100644 --- a/tools/eslint/lib/rules/max-len.js +++ b/tools/eslint/lib/rules/max-len.js @@ -39,6 +39,9 @@ const OPTIONS_SCHEMA = { ignoreTemplateLiterals: { type: "boolean" }, + ignoreRegExpLiterals: { + type: "boolean" + }, ignoreTrailingComments: { type: "boolean" } @@ -100,7 +103,7 @@ module.exports = { function computeLineLength(line, tabWidth) { let extraCharacterCount = 0; - line.replace(/\t/g, function(match, offset) { + line.replace(/\t/g, (match, offset) => { const totalOffset = offset + extraCharacterCount, previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, spaceCount = tabWidth - previousTabStopOffset; @@ -129,6 +132,7 @@ module.exports = { ignoreComments = options.ignoreComments || false, ignoreStrings = options.ignoreStrings || false, ignoreTemplateLiterals = options.ignoreTemplateLiterals || false, + ignoreRegExpLiterals = options.ignoreRegExpLiterals || false, ignoreTrailingComments = options.ignoreTrailingComments || options.ignoreComments || false, ignoreUrls = options.ignoreUrls || false, maxCommentLength = options.comments; @@ -209,9 +213,7 @@ module.exports = { * @returns {ASTNode[]} An array of string nodes. */ function getAllStrings() { - return sourceCode.ast.tokens.filter(function(token) { - return token.type === "String"; - }); + return sourceCode.ast.tokens.filter(token => token.type === "String"); } /** @@ -220,9 +222,17 @@ module.exports = { * @returns {ASTNode[]} An array of template literal nodes. */ function getAllTemplateLiterals() { - return sourceCode.ast.tokens.filter(function(token) { - return token.type === "Template"; - }); + return sourceCode.ast.tokens.filter(token => token.type === "Template"); + } + + + /** + * Retrieves an array containing all RegExp literals in the source code. + * + * @returns {ASTNode[]} An array of RegExp literal nodes. + */ + function getAllRegExpLiterals() { + return sourceCode.ast.tokens.filter(token => token.type === "RegularExpression"); } @@ -264,7 +274,10 @@ module.exports = { const templateLiterals = getAllTemplateLiterals(sourceCode); const templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {}); - lines.forEach(function(line, i) { + const regExpLiterals = getAllRegExpLiterals(sourceCode); + const regExpLiteralsByLine = regExpLiterals.reduce(groupByLineNumber, {}); + + lines.forEach((line, i) => { // i is zero-indexed, line numbers are one-indexed const lineNumber = i + 1; @@ -299,7 +312,8 @@ module.exports = { if (ignorePattern && ignorePattern.test(line) || ignoreUrls && URL_REGEXP.test(line) || ignoreStrings && stringsByLine[lineNumber] || - ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] + ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] || + ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber] ) { // ignore this line diff --git a/tools/eslint/lib/rules/max-lines.js b/tools/eslint/lib/rules/max-lines.js index a54ad9e3538dbc..08cf9f6084b2a1 100644 --- a/tools/eslint/lib/rules/max-lines.js +++ b/tools/eslint/lib/rules/max-lines.js @@ -114,26 +114,18 @@ module.exports = { return { "Program:exit"() { - let lines = sourceCode.lines.map(function(text, i) { - return { lineNumber: i + 1, text }; - }); + let lines = sourceCode.lines.map((text, i) => ({ lineNumber: i + 1, text })); if (skipBlankLines) { - lines = lines.filter(function(l) { - return l.text.trim() !== ""; - }); + lines = lines.filter(l => l.text.trim() !== ""); } if (skipComments) { const comments = sourceCode.getAllComments(); - const commentLines = lodash.flatten(comments.map(function(comment) { - return getLinesWithoutCode(comment); - })); + const commentLines = lodash.flatten(comments.map(comment => getLinesWithoutCode(comment))); - lines = lines.filter(function(l) { - return !lodash.includes(commentLines, l.lineNumber); - }); + lines = lines.filter(l => !lodash.includes(commentLines, l.lineNumber)); } if (lines.length > max) { diff --git a/tools/eslint/lib/rules/max-nested-callbacks.js b/tools/eslint/lib/rules/max-nested-callbacks.js index 7e0c3d24738862..a89f49ae02094e 100644 --- a/tools/eslint/lib/rules/max-nested-callbacks.js +++ b/tools/eslint/lib/rules/max-nested-callbacks.js @@ -81,9 +81,9 @@ module.exports = { } if (callbackStack.length > THRESHOLD) { - const opts = {num: callbackStack.length, max: THRESHOLD}; + const opts = { num: callbackStack.length, max: THRESHOLD }; - context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts); + context.report({ node, message: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", data: opts }); } } diff --git a/tools/eslint/lib/rules/max-params.js b/tools/eslint/lib/rules/max-params.js index fc84efcd40b285..bbf087092e5057 100644 --- a/tools/eslint/lib/rules/max-params.js +++ b/tools/eslint/lib/rules/max-params.js @@ -66,10 +66,10 @@ module.exports = { */ function checkFunction(node) { if (node.params.length > numParams) { - context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", { + context.report({ node, message: "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", data: { count: node.params.length, max: numParams - }); + } }); } } diff --git a/tools/eslint/lib/rules/max-statements.js b/tools/eslint/lib/rules/max-statements.js index 1232930c6e68f1..63d51fa571b7b0 100644 --- a/tools/eslint/lib/rules/max-statements.js +++ b/tools/eslint/lib/rules/max-statements.js @@ -84,10 +84,20 @@ module.exports = { */ function reportIfTooManyStatements(node, count, max) { if (count > max) { - context.report( + const messageEnd = " has too many statements ({{count}}). Maximum allowed is {{max}}."; + let name = "This function"; + + if (node.id) { + name = `Function '${node.id.name}'`; + } else if (node.parent.type === "MethodDefinition" || node.parent.type === "Property") { + name = `Function '${context.getSource(node.parent.key)}'`; + } + + context.report({ node, - "This function has too many statements ({{count}}). Maximum allowed is {{max}}.", - { count, max }); + message: name + messageEnd, + data: { count, max } + }); } } @@ -110,7 +120,7 @@ module.exports = { const count = functionStack.pop(); if (ignoreTopLevelFunctions && functionStack.length === 0) { - topLevelFunctions.push({ node, count}); + topLevelFunctions.push({ node, count }); } else { reportIfTooManyStatements(node, count, maxStatements); } @@ -146,7 +156,7 @@ module.exports = { return; } - topLevelFunctions.forEach(function(element) { + topLevelFunctions.forEach(element => { const count = element.count; const node = element.node; diff --git a/tools/eslint/lib/rules/new-cap.js b/tools/eslint/lib/rules/new-cap.js index 6fcd582a694d1a..e7f7f1ab893396 100644 --- a/tools/eslint/lib/rules/new-cap.js +++ b/tools/eslint/lib/rules/new-cap.js @@ -227,7 +227,7 @@ module.exports = { callee = callee.property; } - context.report(node, callee.loc.start, message); + context.report({ node, loc: callee.loc.start, message }); } //-------------------------------------------------------------------------- diff --git a/tools/eslint/lib/rules/new-parens.js b/tools/eslint/lib/rules/new-parens.js index 29f4b5c2082152..b0fc5ba97950b7 100644 --- a/tools/eslint/lib/rules/new-parens.js +++ b/tools/eslint/lib/rules/new-parens.js @@ -29,20 +29,6 @@ function isClosingParen(token) { return token.type === "Punctuator" && token.value === ")"; } -/** - * Checks whether the given node is inside of another given node. - * - * @param {ASTNode|Token} inner - The inner node to check. - * @param {ASTNode|Token} outer - The outer node to check. - * @returns {boolean} `true` if the `inner` is in `outer`. - */ -function isInRange(inner, outer) { - const ir = inner.range; - const or = outer.range; - - return or[0] <= ir[0] && ir[1] <= or[1]; -} - //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -65,14 +51,15 @@ module.exports = { return { NewExpression(node) { - let token = sourceCode.getTokenAfter(node.callee); - - // Skip ')' - while (token && isClosingParen(token)) { - token = sourceCode.getTokenAfter(token); + if (node.arguments.length !== 0) { + return; // shortcut: if there are arguments, there have to be parens } - if (!(token && isOpeningParen(token) && isInRange(token, node))) { + const lastToken = sourceCode.getLastToken(node); + const hasLastParen = lastToken && isClosingParen(lastToken); + const hasParens = hasLastParen && isOpeningParen(sourceCode.getTokenBefore(lastToken)); + + if (!hasParens) { context.report({ node, message: "Missing '()' invoking a constructor.", diff --git a/tools/eslint/lib/rules/newline-after-var.js b/tools/eslint/lib/rules/newline-after-var.js index 440652b1c10696..51130e23db9ffe 100644 --- a/tools/eslint/lib/rules/newline-after-var.js +++ b/tools/eslint/lib/rules/newline-after-var.js @@ -21,7 +21,9 @@ module.exports = { { enum: ["never", "always"] } - ] + ], + + fixable: "whitespace" }, create(context) { @@ -35,7 +37,7 @@ module.exports = { const mode = context.options[0] === "never" ? "never" : "always"; // Cache starting and ending line numbers of comments for faster lookup - const commentEndLine = sourceCode.getAllComments().reduce(function(result, token) { + const commentEndLine = sourceCode.getAllComments().reduce((result, token) => { result[token.loc.start.line] = token.loc.end.line; return result; }, {}); @@ -119,6 +121,17 @@ module.exports = { return !token || (token.type === "Punctuator" && token.value === "}"); } + /** + * Gets the last line of a group of consecutive comments + * @param {number} commentStartLine The starting line of the group + * @returns {number} The number of the last comment line of the group + */ + function getLastCommentLineOfBlock(commentStartLine) { + const currentCommentEnd = commentEndLine[commentStartLine]; + + return commentEndLine[currentCommentEnd + 1] ? getLastCommentLineOfBlock(currentCommentEnd + 1) : currentCommentEnd; + } + /** * Determine if a token starts more than one line after a comment ends * @param {token} token The token being checked @@ -126,14 +139,7 @@ module.exports = { * @returns {boolean} True if `token` does not start immediately after a comment */ function hasBlankLineAfterComment(token, commentStartLine) { - const commentEnd = commentEndLine[commentStartLine]; - - // If there's another comment, repeat check for blank line - if (commentEndLine[commentEnd + 1]) { - return hasBlankLineAfterComment(token, commentEnd + 1); - } - - return (token.loc.start.line > commentEndLine[commentStartLine] + 1); + return token.loc.start.line > getLastCommentLineOfBlock(commentStartLine) + 1; } /** @@ -145,8 +151,18 @@ module.exports = { * @returns {void} */ function checkForBlankLine(node) { + + /* + * lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will + * sometimes be second-last if there is a semicolon on a different line. + */ const lastToken = getLastToken(node), - nextToken = sourceCode.getTokenAfter(node), + + /* + * If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken + * is the last token of the node. + */ + nextToken = lastToken === sourceCode.getLastToken(node) ? sourceCode.getTokenAfter(node) : sourceCode.getLastToken(node), nextLineNum = lastToken.loc.end.line + 1; // Ignore if there is no following statement @@ -180,7 +196,17 @@ module.exports = { const hasNextLineComment = (typeof commentEndLine[nextLineNum] !== "undefined"); if (mode === "never" && noNextLineToken && !hasNextLineComment) { - context.report(node, NEVER_MESSAGE, { identifier: node.name }); + context.report({ + node, + message: NEVER_MESSAGE, + data: { identifier: node.name }, + fix(fixer) { + const NEWLINE_REGEX = /\r\n|\r|\n|\u2028|\u2029/; + const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(NEWLINE_REGEX); + + return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween[linesBetween.length - 1]}`); + } + }); } // Token on the next line, or comment without blank line @@ -190,7 +216,18 @@ module.exports = { hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum) ) ) { - context.report(node, ALWAYS_MESSAGE, { identifier: node.name }); + context.report({ + node, + message: ALWAYS_MESSAGE, + data: { identifier: node.name }, + fix(fixer) { + if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) { + return fixer.insertTextBefore(nextToken, "\n\n"); + } + + return fixer.insertTextBeforeRange([nextToken.range[0] - nextToken.loc.start.column, nextToken.range[1]], "\n"); + } + }); } } diff --git a/tools/eslint/lib/rules/newline-before-return.js b/tools/eslint/lib/rules/newline-before-return.js index 7d297fd0035313..e8cd74b2c7b728 100644 --- a/tools/eslint/lib/rules/newline-before-return.js +++ b/tools/eslint/lib/rules/newline-before-return.js @@ -36,9 +36,7 @@ module.exports = { function isPrecededByTokens(node, testTokens) { const tokenBefore = sourceCode.getTokenBefore(node); - return testTokens.some(function(token) { - return tokenBefore.value === token; - }); + return testTokens.some(token => tokenBefore.value === token); } /** @@ -82,7 +80,7 @@ module.exports = { return numLinesComments; } - comments.forEach(function(comment) { + comments.forEach(comment => { numLinesComments++; if (comment.type === "Block") { diff --git a/tools/eslint/lib/rules/no-alert.js b/tools/eslint/lib/rules/no-alert.js index 96b5d64c6c4e6b..f2cfc3a87762d2 100644 --- a/tools/eslint/lib/rules/no-alert.js +++ b/tools/eslint/lib/rules/no-alert.js @@ -41,10 +41,8 @@ function report(context, node, identifierName) { * @returns {Reference|null} Returns the found reference or null if none were found. */ function findReference(scope, node) { - const references = scope.references.filter(function(reference) { - return reference.identifier.range[0] === node.range[0] && - reference.identifier.range[1] === node.range[1]; - }); + const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && + reference.identifier.range[1] === node.range[1]); if (references.length === 1) { return references[0]; diff --git a/tools/eslint/lib/rules/no-array-constructor.js b/tools/eslint/lib/rules/no-array-constructor.js index 2c29217d720fcc..70dc8b4cd5ded8 100644 --- a/tools/eslint/lib/rules/no-array-constructor.js +++ b/tools/eslint/lib/rules/no-array-constructor.js @@ -34,7 +34,7 @@ module.exports = { node.callee.type === "Identifier" && node.callee.name === "Array" ) { - context.report(node, "The array literal notation [] is preferrable."); + context.report({ node, message: "The array literal notation [] is preferrable." }); } } diff --git a/tools/eslint/lib/rules/no-await-in-loop.js b/tools/eslint/lib/rules/no-await-in-loop.js new file mode 100644 index 00000000000000..a75f7f2934bc23 --- /dev/null +++ b/tools/eslint/lib/rules/no-await-in-loop.js @@ -0,0 +1,75 @@ +/** + * @fileoverview Rule to disallow uses of await inside of loops. + * @author Nat Mote (nmote) + */ +"use strict"; + +// Node types which are considered loops. +const loopTypes = new Set([ + "ForStatement", + "ForOfStatement", + "ForInStatement", + "WhileStatement", + "DoWhileStatement", +]); + +// Node types at which we should stop looking for loops. For example, it is fine to declare an async +// function within a loop, and use await inside of that. +const boundaryTypes = new Set([ + "FunctionDeclaration", + "FunctionExpression", + "ArrowFunctionExpression", +]); + +module.exports = { + meta: { + docs: { + description: "disallow `await` inside of loops", + category: "Possible Errors", + recommended: false, + }, + schema: [], + }, + create(context) { + return { + AwaitExpression(node) { + const ancestors = context.getAncestors(); + + // Reverse so that we can traverse from the deepest node upwards. + ancestors.reverse(); + + // Create a set of all the ancestors plus this node so that we can check + // if this use of await appears in the body of the loop as opposed to + // the right-hand side of a for...of, for example. + const ancestorSet = new Set(ancestors).add(node); + + for (let i = 0; i < ancestors.length; i++) { + const ancestor = ancestors[i]; + + if (boundaryTypes.has(ancestor.type)) { + + // Short-circuit out if we encounter a boundary type. Loops above + // this do not matter. + return; + } + if (loopTypes.has(ancestor.type)) { + + // Only report if we are actually in the body or another part that gets executed on + // every iteration. + if ( + ancestorSet.has(ancestor.body) || + ancestorSet.has(ancestor.test) || + ancestorSet.has(ancestor.update) + ) { + context.report({ + node, + message: "Unexpected `await` inside a loop." + }); + return; + } + } + } + }, + }; + } +}; diff --git a/tools/eslint/lib/rules/no-bitwise.js b/tools/eslint/lib/rules/no-bitwise.js index 2c6456912f70f8..28028028cae090 100644 --- a/tools/eslint/lib/rules/no-bitwise.js +++ b/tools/eslint/lib/rules/no-bitwise.js @@ -57,7 +57,7 @@ module.exports = { * @returns {void} */ function report(node) { - context.report(node, "Unexpected use of '{{operator}}'.", { operator: node.operator }); + context.report({ node, message: "Unexpected use of '{{operator}}'.", data: { operator: node.operator } }); } /** diff --git a/tools/eslint/lib/rules/no-caller.js b/tools/eslint/lib/rules/no-caller.js index 16c5fa414b0cb8..55a37b7d86406a 100644 --- a/tools/eslint/lib/rules/no-caller.js +++ b/tools/eslint/lib/rules/no-caller.js @@ -29,7 +29,7 @@ module.exports = { propertyName = node.property.name; if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) { - context.report(node, "Avoid arguments.{{property}}.", { property: propertyName }); + context.report({ node, message: "Avoid arguments.{{property}}.", data: { property: propertyName } }); } } diff --git a/tools/eslint/lib/rules/no-catch-shadow.js b/tools/eslint/lib/rules/no-catch-shadow.js index 7f2523333239a7..7cffae3b99d758 100644 --- a/tools/eslint/lib/rules/no-catch-shadow.js +++ b/tools/eslint/lib/rules/no-catch-shadow.js @@ -58,8 +58,7 @@ module.exports = { } if (paramIsShadowing(scope, node.param.name)) { - context.report(node, "Value of '{{name}}' may be overwritten in IE 8 and earlier.", - { name: node.param.name }); + context.report({ node, message: "Value of '{{name}}' may be overwritten in IE 8 and earlier.", data: { name: node.param.name } }); } } }; diff --git a/tools/eslint/lib/rules/no-class-assign.js b/tools/eslint/lib/rules/no-class-assign.js index cbd4b1da81fe42..4b0443abc72858 100644 --- a/tools/eslint/lib/rules/no-class-assign.js +++ b/tools/eslint/lib/rules/no-class-assign.js @@ -30,11 +30,8 @@ module.exports = { * @returns {void} */ function checkVariable(variable) { - astUtils.getModifyingReferences(variable.references).forEach(function(reference) { - context.report( - reference.identifier, - "'{{name}}' is a class.", - {name: reference.identifier.name}); + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, message: "'{{name}}' is a class.", data: { name: reference.identifier.name } }); }); } diff --git a/tools/eslint/lib/rules/no-cond-assign.js b/tools/eslint/lib/rules/no-cond-assign.js index 2d66f55a5ba77b..3e94d12a539942 100644 --- a/tools/eslint/lib/rules/no-cond-assign.js +++ b/tools/eslint/lib/rules/no-cond-assign.js @@ -125,9 +125,9 @@ module.exports = { const ancestor = findConditionalAncestor(node); if (ancestor) { - context.report(ancestor, "Unexpected assignment within {{type}}.", { + context.report({ node: ancestor, message: "Unexpected assignment within {{type}}.", data: { type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type - }); + } }); } } diff --git a/tools/eslint/lib/rules/no-confusing-arrow.js b/tools/eslint/lib/rules/no-confusing-arrow.js index 5e1b051423d674..d6edbcc810e4fb 100644 --- a/tools/eslint/lib/rules/no-confusing-arrow.js +++ b/tools/eslint/lib/rules/no-confusing-arrow.js @@ -36,7 +36,7 @@ module.exports = { schema: [{ type: "object", properties: { - allowParens: {type: "boolean"} + allowParens: { type: "boolean" } }, additionalProperties: false }] @@ -55,7 +55,7 @@ module.exports = { const body = node.body; if (isConditional(body) && !(config.allowParens && astUtils.isParenthesised(sourceCode, body))) { - context.report(node, "Arrow function used ambiguously with a conditional expression."); + context.report({ node, message: "Arrow function used ambiguously with a conditional expression." }); } } diff --git a/tools/eslint/lib/rules/no-const-assign.js b/tools/eslint/lib/rules/no-const-assign.js index 232e9446fd7955..db1848a9819f00 100644 --- a/tools/eslint/lib/rules/no-const-assign.js +++ b/tools/eslint/lib/rules/no-const-assign.js @@ -30,11 +30,8 @@ module.exports = { * @returns {void} */ function checkVariable(variable) { - astUtils.getModifyingReferences(variable.references).forEach(function(reference) { - context.report( - reference.identifier, - "'{{name}}' is constant.", - {name: reference.identifier.name}); + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, message: "'{{name}}' is constant.", data: { name: reference.identifier.name } }); }); } diff --git a/tools/eslint/lib/rules/no-constant-condition.js b/tools/eslint/lib/rules/no-constant-condition.js index f78ddbc2e972b0..7178d5dbecc10e 100644 --- a/tools/eslint/lib/rules/no-constant-condition.js +++ b/tools/eslint/lib/rules/no-constant-condition.js @@ -122,7 +122,7 @@ module.exports = { */ function checkConstantCondition(node) { if (node.test && isConstant(node.test, true)) { - context.report(node, "Unexpected constant condition."); + context.report({ node, message: "Unexpected constant condition." }); } } diff --git a/tools/eslint/lib/rules/no-continue.js b/tools/eslint/lib/rules/no-continue.js index b8956da4b75025..2615fba13e2401 100644 --- a/tools/eslint/lib/rules/no-continue.js +++ b/tools/eslint/lib/rules/no-continue.js @@ -24,7 +24,7 @@ module.exports = { return { ContinueStatement(node) { - context.report(node, "Unexpected use of continue statement."); + context.report({ node, message: "Unexpected use of continue statement." }); } }; diff --git a/tools/eslint/lib/rules/no-control-regex.js b/tools/eslint/lib/rules/no-control-regex.js index 466f5666ac181f..1ebf9800009371 100644 --- a/tools/eslint/lib/rules/no-control-regex.js +++ b/tools/eslint/lib/rules/no-control-regex.js @@ -85,7 +85,7 @@ module.exports = { stringControlChars = regexStr.slice(subStrIndex, -1) .split(consecutiveSlashes) .filter(Boolean) - .map(function(x) { + .map(x => { const match = x.match(stringControlCharWithoutSlash) || [x]; return `\\${match[0]}`; @@ -93,7 +93,7 @@ module.exports = { } } - return controlChars.map(function(x) { + return controlChars.map(x => { const hexCode = `0${x.charCodeAt(0).toString(16)}`.slice(-2); return `\\x${hexCode}`; diff --git a/tools/eslint/lib/rules/no-debugger.js b/tools/eslint/lib/rules/no-debugger.js index 6356d5269b61f1..897b3dbb6094f9 100644 --- a/tools/eslint/lib/rules/no-debugger.js +++ b/tools/eslint/lib/rules/no-debugger.js @@ -24,7 +24,7 @@ module.exports = { return { DebuggerStatement(node) { - context.report(node, "Unexpected 'debugger' statement."); + context.report({ node, message: "Unexpected 'debugger' statement." }); } }; diff --git a/tools/eslint/lib/rules/no-delete-var.js b/tools/eslint/lib/rules/no-delete-var.js index dce202dc834c7e..adc1b5bb9c2c01 100644 --- a/tools/eslint/lib/rules/no-delete-var.js +++ b/tools/eslint/lib/rules/no-delete-var.js @@ -26,7 +26,7 @@ module.exports = { UnaryExpression(node) { if (node.operator === "delete" && node.argument.type === "Identifier") { - context.report(node, "Variables should not be deleted."); + context.report({ node, message: "Variables should not be deleted." }); } } }; diff --git a/tools/eslint/lib/rules/no-div-regex.js b/tools/eslint/lib/rules/no-div-regex.js index c5ffa7ce7e2e7a..84a9b9a3aaa9a6 100644 --- a/tools/eslint/lib/rules/no-div-regex.js +++ b/tools/eslint/lib/rules/no-div-regex.js @@ -29,7 +29,7 @@ module.exports = { const token = sourceCode.getFirstToken(node); if (token.type === "RegularExpression" && token.value[1] === "=") { - context.report(node, "A regular expression literal can be confused with '/='."); + context.report({ node, message: "A regular expression literal can be confused with '/='." }); } } }; diff --git a/tools/eslint/lib/rules/no-dupe-args.js b/tools/eslint/lib/rules/no-dupe-args.js index 0d420eb92aaaf9..cdb38035c0a01f 100644 --- a/tools/eslint/lib/rules/no-dupe-args.js +++ b/tools/eslint/lib/rules/no-dupe-args.js @@ -54,7 +54,7 @@ module.exports = { context.report({ node, message: "Duplicate param '{{name}}'.", - data: {name: variable.name} + data: { name: variable.name } }); } } diff --git a/tools/eslint/lib/rules/no-dupe-class-members.js b/tools/eslint/lib/rules/no-dupe-class-members.js index 3b857a67fb9e65..07b999fab19bb9 100644 --- a/tools/eslint/lib/rules/no-dupe-class-members.js +++ b/tools/eslint/lib/rules/no-dupe-class-members.js @@ -38,8 +38,8 @@ module.exports = { if (!stateMap[key]) { stateMap[key] = { - nonStatic: {init: false, get: false, set: false}, - static: {init: false, get: false, set: false} + nonStatic: { init: false, get: false, set: false }, + static: { init: false, get: false, set: false } }; } @@ -101,7 +101,7 @@ module.exports = { } if (isDuplicate) { - context.report(node, "Duplicate name '{{name}}'.", {name}); + context.report({ node, message: "Duplicate name '{{name}}'.", data: { name } }); } } }; diff --git a/tools/eslint/lib/rules/no-dupe-keys.js b/tools/eslint/lib/rules/no-dupe-keys.js index f34c323f1ed491..f056b1fcbeb43e 100644 --- a/tools/eslint/lib/rules/no-dupe-keys.js +++ b/tools/eslint/lib/rules/no-dupe-keys.js @@ -42,7 +42,7 @@ class ObjectInfo { const name = astUtils.getStaticPropertyName(node); if (!this.properties.has(name)) { - this.properties.set(name, {get: false, set: false}); + this.properties.set(name, { get: false, set: false }); } return this.properties.get(name); } @@ -123,7 +123,7 @@ module.exports = { node: info.node, loc: node.key.loc, message: "Duplicate key '{{name}}'.", - data: {name}, + data: { name }, }); } diff --git a/tools/eslint/lib/rules/no-duplicate-case.js b/tools/eslint/lib/rules/no-duplicate-case.js index 5b20fc3d582980..07823f284c1c3d 100644 --- a/tools/eslint/lib/rules/no-duplicate-case.js +++ b/tools/eslint/lib/rules/no-duplicate-case.js @@ -28,11 +28,11 @@ module.exports = { SwitchStatement(node) { const mapping = {}; - node.cases.forEach(function(switchCase) { + node.cases.forEach(switchCase => { const key = sourceCode.getText(switchCase.test); if (mapping[key]) { - context.report(switchCase, "Duplicate case label."); + context.report({ node: switchCase, message: "Duplicate case label." }); } else { mapping[key] = switchCase; } diff --git a/tools/eslint/lib/rules/no-else-return.js b/tools/eslint/lib/rules/no-else-return.js index 07b596238caf2b..43564346b043e2 100644 --- a/tools/eslint/lib/rules/no-else-return.js +++ b/tools/eslint/lib/rules/no-else-return.js @@ -33,7 +33,7 @@ module.exports = { * @returns {void} */ function displayReport(node) { - context.report(node, "Unnecessary 'else' after 'return'."); + context.report({ node, message: "Unnecessary 'else' after 'return'." }); } /** diff --git a/tools/eslint/lib/rules/no-empty-character-class.js b/tools/eslint/lib/rules/no-empty-character-class.js index 723cebc9450f00..f36c6c9f0d8b19 100644 --- a/tools/eslint/lib/rules/no-empty-character-class.js +++ b/tools/eslint/lib/rules/no-empty-character-class.js @@ -21,7 +21,7 @@ plain-English description of the following regexp: 4. `[gimuy]*`: optional regexp flags 5. `$`: fix the match at the end of the string */ -const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuy]*$/; +const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+])*\/[gimuy]*$/; //------------------------------------------------------------------------------ // Rule Definition @@ -47,7 +47,7 @@ module.exports = { const token = sourceCode.getFirstToken(node); if (token.type === "RegularExpression" && !regex.test(token.value)) { - context.report(node, "Empty class."); + context.report({ node, message: "Empty class." }); } } diff --git a/tools/eslint/lib/rules/no-empty-function.js b/tools/eslint/lib/rules/no-empty-function.js index 8299f40685ca52..65f9c9e1515342 100644 --- a/tools/eslint/lib/rules/no-empty-function.js +++ b/tools/eslint/lib/rules/no-empty-function.js @@ -108,7 +108,7 @@ module.exports = { properties: { allow: { type: "array", - items: {enum: ALLOW_OPTIONS}, + items: { enum: ALLOW_OPTIONS }, uniqueItems: true } }, diff --git a/tools/eslint/lib/rules/no-empty-pattern.js b/tools/eslint/lib/rules/no-empty-pattern.js index 77302fc8d73f9d..11f50b54142e04 100644 --- a/tools/eslint/lib/rules/no-empty-pattern.js +++ b/tools/eslint/lib/rules/no-empty-pattern.js @@ -23,12 +23,12 @@ module.exports = { return { ObjectPattern(node) { if (node.properties.length === 0) { - context.report(node, "Unexpected empty object pattern."); + context.report({ node, message: "Unexpected empty object pattern." }); } }, ArrayPattern(node) { if (node.elements.length === 0) { - context.report(node, "Unexpected empty array pattern."); + context.report({ node, message: "Unexpected empty array pattern." }); } } }; diff --git a/tools/eslint/lib/rules/no-empty.js b/tools/eslint/lib/rules/no-empty.js index 8514b9cf89d0c8..a9b0776c933b07 100644 --- a/tools/eslint/lib/rules/no-empty.js +++ b/tools/eslint/lib/rules/no-empty.js @@ -63,13 +63,13 @@ module.exports = { return; } - context.report(node, "Empty block statement."); + context.report({ node, message: "Empty block statement." }); }, SwitchStatement(node) { if (typeof node.cases === "undefined" || node.cases.length === 0) { - context.report(node, "Empty switch statement."); + context.report({ node, message: "Empty switch statement." }); } } }; diff --git a/tools/eslint/lib/rules/no-eq-null.js b/tools/eslint/lib/rules/no-eq-null.js index 62215d05f1b0eb..7e915a8c726f9f 100644 --- a/tools/eslint/lib/rules/no-eq-null.js +++ b/tools/eslint/lib/rules/no-eq-null.js @@ -30,7 +30,7 @@ module.exports = { if (node.right.type === "Literal" && node.right.raw === "null" && badOperator || node.left.type === "Literal" && node.left.raw === "null" && badOperator) { - context.report(node, "Use ‘===’ to compare with ‘null’."); + context.report({ node, message: "Use ‘===’ to compare with ‘null’." }); } } }; diff --git a/tools/eslint/lib/rules/no-eval.js b/tools/eslint/lib/rules/no-eval.js index af87e4289fcc31..fe1456cba0a431 100644 --- a/tools/eslint/lib/rules/no-eval.js +++ b/tools/eslint/lib/rules/no-eval.js @@ -86,7 +86,7 @@ module.exports = { { type: "object", properties: { - allowIndirect: {type: "boolean"} + allowIndirect: { type: "boolean" } }, additionalProperties: false } diff --git a/tools/eslint/lib/rules/no-ex-assign.js b/tools/eslint/lib/rules/no-ex-assign.js index 6ffa8408677292..20869d5cd107c9 100644 --- a/tools/eslint/lib/rules/no-ex-assign.js +++ b/tools/eslint/lib/rules/no-ex-assign.js @@ -30,10 +30,8 @@ module.exports = { * @returns {void} */ function checkVariable(variable) { - astUtils.getModifyingReferences(variable.references).forEach(function(reference) { - context.report( - reference.identifier, - "Do not assign to the exception parameter."); + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, message: "Do not assign to the exception parameter." }); }); } diff --git a/tools/eslint/lib/rules/no-extend-native.js b/tools/eslint/lib/rules/no-extend-native.js index 27de9b5bd36deb..c44a2e894699e9 100644 --- a/tools/eslint/lib/rules/no-extend-native.js +++ b/tools/eslint/lib/rules/no-extend-native.js @@ -44,14 +44,10 @@ module.exports = { const config = context.options[0] || {}; const exceptions = config.exceptions || []; - let modifiedBuiltins = Object.keys(globals.builtin).filter(function(builtin) { - return builtin[0].toUpperCase() === builtin[0]; - }); + let modifiedBuiltins = Object.keys(globals.builtin).filter(builtin => builtin[0].toUpperCase() === builtin[0]); if (exceptions.length) { - modifiedBuiltins = modifiedBuiltins.filter(function(builtIn) { - return exceptions.indexOf(builtIn) === -1; - }); + modifiedBuiltins = modifiedBuiltins.filter(builtIn => exceptions.indexOf(builtIn) === -1); } return { @@ -72,7 +68,7 @@ module.exports = { return; } - modifiedBuiltins.forEach(function(builtin) { + modifiedBuiltins.forEach(builtin => { if (lhs.object.object.name === builtin) { context.report({ node, diff --git a/tools/eslint/lib/rules/no-extra-boolean-cast.js b/tools/eslint/lib/rules/no-extra-boolean-cast.js index 89a193b2d12435..123a7cacc5256a 100644 --- a/tools/eslint/lib/rules/no-extra-boolean-cast.js +++ b/tools/eslint/lib/rules/no-extra-boolean-cast.js @@ -17,10 +17,13 @@ module.exports = { recommended: true }, - schema: [] + schema: [], + + fixable: "code" }, create(context) { + const sourceCode = context.getSourceCode(); // Node types which have a test which will coerce values to booleans. const BOOLEAN_NODE_TYPES = [ @@ -70,7 +73,11 @@ module.exports = { grandparent.callee.type === "Identifier" && grandparent.callee.name === "Boolean") ) { - context.report(node, "Redundant double negation."); + context.report({ + node, + message: "Redundant double negation.", + fix: fixer => fixer.replaceText(parent, sourceCode.getText(node.argument)) + }); } }, CallExpression(node) { @@ -81,7 +88,11 @@ module.exports = { } if (isInBooleanContext(node, parent)) { - context.report(node, "Redundant Boolean call."); + context.report({ + node, + message: "Redundant Boolean call.", + fix: fixer => fixer.replaceText(node, sourceCode.getText(node.arguments[0])) + }); } } }; diff --git a/tools/eslint/lib/rules/no-extra-label.js b/tools/eslint/lib/rules/no-extra-label.js index b34e075163472d..22afbf405b7ea9 100644 --- a/tools/eslint/lib/rules/no-extra-label.js +++ b/tools/eslint/lib/rules/no-extra-label.js @@ -23,10 +23,13 @@ module.exports = { recommended: false }, - schema: [] + schema: [], + + fixable: "code" }, create(context) { + const sourceCode = context.getSourceCode(); let scopeInfo = null; /** @@ -37,7 +40,7 @@ module.exports = { */ function enterBreakableStatement(node) { scopeInfo = { - label: astUtils.getLabel(node), + label: node.parent.type === "LabeledStatement" ? node.parent.label : null, breakable: true, upper: scopeInfo }; @@ -64,7 +67,7 @@ module.exports = { function enterLabeledStatement(node) { if (!astUtils.isBreakableStatement(node.body)) { scopeInfo = { - label: node.label.name, + label: node.label, breakable: false, upper: scopeInfo }; @@ -99,22 +102,24 @@ module.exports = { } const labelNode = node.label; - const label = labelNode.name; - let info = scopeInfo; - while (info) { - if (info.breakable || info.label === label) { - if (info.breakable && info.label === label) { + for (let info = scopeInfo; info !== null; info = info.upper) { + if (info.breakable || info.label && info.label.name === labelNode.name) { + if (info.breakable && info.label && info.label.name === labelNode.name) { context.report({ node: labelNode, message: "This label '{{name}}' is unnecessary.", - data: labelNode + data: labelNode, + fix(fixer) { + return fixer.replaceTextRange( + [info.label.range[0], labelNode.range[1]], + sourceCode.text.slice(info.label.parent.body.range[0], sourceCode.getFirstToken(node).range[1]) + ); + } }); } return; } - - info = info.upper; } } diff --git a/tools/eslint/lib/rules/no-extra-parens.js b/tools/eslint/lib/rules/no-extra-parens.js index efa3d53bbd3328..004d431701a574 100644 --- a/tools/eslint/lib/rules/no-extra-parens.js +++ b/tools/eslint/lib/rules/no-extra-parens.js @@ -42,9 +42,9 @@ module.exports = { { type: "object", properties: { - conditionalAssign: {type: "boolean"}, - nestedBinaryExpressions: {type: "boolean"}, - returnAssign: {type: "boolean"} + conditionalAssign: { type: "boolean" }, + nestedBinaryExpressions: { type: "boolean" }, + returnAssign: { type: "boolean" } }, additionalProperties: false } @@ -348,12 +348,12 @@ module.exports = { report(node.callee); } if (node.arguments.length === 1) { - if (hasDoubleExcessParens(node.arguments[0]) && precedence(node.arguments[0]) >= precedence({type: "AssignmentExpression"})) { + if (hasDoubleExcessParens(node.arguments[0]) && precedence(node.arguments[0]) >= precedence({ type: "AssignmentExpression" })) { report(node.arguments[0]); } } else { - [].forEach.call(node.arguments, function(arg) { - if (hasExcessParens(arg) && precedence(arg) >= precedence({type: "AssignmentExpression"})) { + [].forEach.call(node.arguments, arg => { + if (hasExcessParens(arg) && precedence(arg) >= precedence({ type: "AssignmentExpression" })) { report(arg); } }); @@ -381,8 +381,8 @@ module.exports = { return { ArrayExpression(node) { - [].forEach.call(node.elements, function(e) { - if (e && hasExcessParens(e) && precedence(e) >= precedence({type: "AssignmentExpression"})) { + [].forEach.call(node.elements, e => { + if (e && hasExcessParens(e) && precedence(e) >= precedence({ type: "AssignmentExpression" })) { report(e); } }); @@ -394,7 +394,7 @@ module.exports = { } if (node.body.type !== "BlockStatement") { - if (sourceCode.getFirstToken(node.body).value !== "{" && hasExcessParens(node.body) && precedence(node.body) >= precedence({type: "AssignmentExpression"})) { + if (sourceCode.getFirstToken(node.body).value !== "{" && hasExcessParens(node.body) && precedence(node.body) >= precedence({ type: "AssignmentExpression" })) { report(node.body); return; } @@ -402,7 +402,6 @@ module.exports = { // Object literals *must* be parenthesised if (node.body.type === "ObjectExpression" && hasDoubleExcessParens(node.body)) { report(node.body); - return; } } }, @@ -425,15 +424,15 @@ module.exports = { return; } - if (hasExcessParens(node.test) && precedence(node.test) >= precedence({type: "LogicalExpression", operator: "||"})) { + if (hasExcessParens(node.test) && precedence(node.test) >= precedence({ type: "LogicalExpression", operator: "||" })) { report(node.test); } - if (hasExcessParens(node.consequent) && precedence(node.consequent) >= precedence({type: "AssignmentExpression"})) { + if (hasExcessParens(node.consequent) && precedence(node.consequent) >= precedence({ type: "AssignmentExpression" })) { report(node.consequent); } - if (hasExcessParens(node.alternate) && precedence(node.alternate) >= precedence({type: "AssignmentExpression"})) { + if (hasExcessParens(node.alternate) && precedence(node.alternate) >= precedence({ type: "AssignmentExpression" })) { report(node.alternate); } }, @@ -509,7 +508,7 @@ module.exports = { !( (node.object.type === "Literal" && typeof node.object.value === "number" && - /^[0-9]+$/.test(sourceCode.getFirstToken(node.object).value)) + astUtils.isDecimalInteger(node.object)) || // RegExp literal is allowed to have parens (#1589) @@ -532,10 +531,10 @@ module.exports = { NewExpression: dryCallNew, ObjectExpression(node) { - [].forEach.call(node.properties, function(e) { + [].forEach.call(node.properties, e => { const v = e.value; - if (v && hasExcessParens(v) && precedence(v) >= precedence({type: "AssignmentExpression"})) { + if (v && hasExcessParens(v) && precedence(v) >= precedence({ type: "AssignmentExpression" })) { report(v); } }); @@ -558,7 +557,7 @@ module.exports = { }, SequenceExpression(node) { - [].forEach.call(node.expressions, function(e) { + [].forEach.call(node.expressions, e => { if (hasExcessParens(e) && precedence(e) >= precedence(node)) { report(e); } @@ -591,7 +590,7 @@ module.exports = { VariableDeclarator(node) { if (node.init && hasExcessParens(node.init) && - precedence(node.init) >= precedence({type: "AssignmentExpression"}) && + precedence(node.init) >= precedence({ type: "AssignmentExpression" }) && // RegExp literal is allowed to have parens (#1589) !(node.init.type === "Literal" && node.init.regex)) { diff --git a/tools/eslint/lib/rules/no-fallthrough.js b/tools/eslint/lib/rules/no-fallthrough.js index 380a53634be1cb..30d13da06ddc8f 100644 --- a/tools/eslint/lib/rules/no-fallthrough.js +++ b/tools/eslint/lib/rules/no-fallthrough.js @@ -109,7 +109,7 @@ module.exports = { if (fallthroughCase && !hasFallthroughComment(node, context, fallthroughCommentPattern)) { context.report({ message: "Expected a 'break' statement before '{{type}}'.", - data: {type: node.test ? "case" : "default"}, + data: { type: node.test ? "case" : "default" }, node }); } diff --git a/tools/eslint/lib/rules/no-func-assign.js b/tools/eslint/lib/rules/no-func-assign.js index daa6fa52ba7301..ea86365b2914eb 100644 --- a/tools/eslint/lib/rules/no-func-assign.js +++ b/tools/eslint/lib/rules/no-func-assign.js @@ -30,11 +30,8 @@ module.exports = { * @returns {void} */ function checkReference(references) { - astUtils.getModifyingReferences(references).forEach(function(reference) { - context.report( - reference.identifier, - "'{{name}}' is a function.", - {name: reference.identifier.name}); + astUtils.getModifyingReferences(references).forEach(reference => { + context.report({ node: reference.identifier, message: "'{{name}}' is a function.", data: { name: reference.identifier.name } }); }); } diff --git a/tools/eslint/lib/rules/no-global-assign.js b/tools/eslint/lib/rules/no-global-assign.js index 2bc38cb5d70bb6..caf2500231e14a 100644 --- a/tools/eslint/lib/rules/no-global-assign.js +++ b/tools/eslint/lib/rules/no-global-assign.js @@ -23,7 +23,7 @@ module.exports = { properties: { exceptions: { type: "array", - items: {type: "string"}, + items: { type: "string" }, uniqueItems: true } }, diff --git a/tools/eslint/lib/rules/no-implicit-globals.js b/tools/eslint/lib/rules/no-implicit-globals.js index fd49f0c5ac3011..f0962cdc7a864a 100644 --- a/tools/eslint/lib/rules/no-implicit-globals.js +++ b/tools/eslint/lib/rules/no-implicit-globals.js @@ -25,27 +25,27 @@ module.exports = { Program() { const scope = context.getScope(); - scope.variables.forEach(function(variable) { + scope.variables.forEach(variable => { if (variable.writeable) { return; } - variable.defs.forEach(function(def) { + variable.defs.forEach(def => { if (def.type === "FunctionName" || (def.type === "Variable" && def.parent.kind === "var")) { - context.report(def.node, "Implicit global variable, assign as global property instead."); + context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." }); } }); }); - scope.implicit.variables.forEach(function(variable) { + scope.implicit.variables.forEach(variable => { const scopeVariable = scope.set.get(variable.name); if (scopeVariable && scopeVariable.writeable) { return; } - variable.defs.forEach(function(def) { - context.report(def.node, "Implicit global variable, assign as global property instead."); + variable.defs.forEach(def => { + context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." }); }); }); } diff --git a/tools/eslint/lib/rules/no-implied-eval.js b/tools/eslint/lib/rules/no-implied-eval.js index 9b48e896821363..4daadd8fb8733d 100644 --- a/tools/eslint/lib/rules/no-implied-eval.js +++ b/tools/eslint/lib/rules/no-implied-eval.js @@ -21,7 +21,7 @@ module.exports = { }, create(context) { - const CALLEE_RE = /set(?:Timeout|Interval)|execScript/; + const CALLEE_RE = /^(setTimeout|setInterval|execScript)$/; /* * Figures out if we should inspect a given binary expression. Is a stack @@ -105,7 +105,7 @@ module.exports = { // remove the entire substack, to avoid duplicate reports const substack = impliedEvalAncestorsStack.pop(); - context.report(substack[0], "Implied eval. Consider passing a function instead of a string."); + context.report({ node: substack[0], message: "Implied eval. Consider passing a function instead of a string." }); } } diff --git a/tools/eslint/lib/rules/no-inline-comments.js b/tools/eslint/lib/rules/no-inline-comments.js index d51a59a183c199..46815d15418f6a 100644 --- a/tools/eslint/lib/rules/no-inline-comments.js +++ b/tools/eslint/lib/rules/no-inline-comments.js @@ -46,7 +46,7 @@ module.exports = { // Should be empty if there was only whitespace around the comment if (!isDirective && (preamble || postamble)) { - context.report(node, "Unexpected comment inline with code."); + context.report({ node, message: "Unexpected comment inline with code." }); } } diff --git a/tools/eslint/lib/rules/no-inner-declarations.js b/tools/eslint/lib/rules/no-inner-declarations.js index e5a186133cc34e..01cc67863ffff5 100644 --- a/tools/eslint/lib/rules/no-inner-declarations.js +++ b/tools/eslint/lib/rules/no-inner-declarations.js @@ -36,8 +36,8 @@ module.exports = { generation = 1; while (ancestor && ["Program", "FunctionDeclaration", - "FunctionExpression", "ArrowFunctionExpression" - ].indexOf(ancestor.type) < 0) { + "FunctionExpression", "ArrowFunctionExpression" + ].indexOf(ancestor.type) < 0) { generation += 1; ancestor = ancestors.pop(); } @@ -63,14 +63,12 @@ module.exports = { body.distance === 2); if (!valid) { - context.report(node, "Move {{type}} declaration to {{body}} root.", - { - type: (node.type === "FunctionDeclaration" ? + context.report({ node, message: "Move {{type}} declaration to {{body}} root.", data: { + type: (node.type === "FunctionDeclaration" ? "function" : "variable"), - body: (body.type === "Program" ? + body: (body.type === "Program" ? "program" : "function body") - } - ); + } }); } } diff --git a/tools/eslint/lib/rules/no-invalid-this.js b/tools/eslint/lib/rules/no-invalid-this.js index fe2bc3a1baa647..64ef4882e252ec 100644 --- a/tools/eslint/lib/rules/no-invalid-this.js +++ b/tools/eslint/lib/rules/no-invalid-this.js @@ -114,7 +114,7 @@ module.exports = { const current = stack.getCurrent(); if (current && !current.valid) { - context.report(node, "Unexpected 'this'."); + context.report({ node, message: "Unexpected 'this'." }); } } }; diff --git a/tools/eslint/lib/rules/no-irregular-whitespace.js b/tools/eslint/lib/rules/no-irregular-whitespace.js index 74a3c10fed1c9d..b1949fbc735479 100644 --- a/tools/eslint/lib/rules/no-irregular-whitespace.js +++ b/tools/eslint/lib/rules/no-irregular-whitespace.js @@ -76,7 +76,7 @@ module.exports = { const locStart = node.loc.start; const locEnd = node.loc.end; - errors = errors.filter(function(error) { + errors = errors.filter(error => { const errorLoc = error[1]; if (errorLoc.line >= locStart.line && errorLoc.line <= locEnd.line) { @@ -142,7 +142,7 @@ module.exports = { function checkForIrregularWhitespace(node) { const sourceLines = sourceCode.lines; - sourceLines.forEach(function(sourceLine, lineIndex) { + sourceLines.forEach((sourceLine, lineIndex) => { const lineNumber = lineIndex + 1; let match; @@ -233,7 +233,7 @@ module.exports = { } // If we have any errors remaining report on them - errors.forEach(function(error) { + errors.forEach(error => { context.report.apply(context, error); }); }; diff --git a/tools/eslint/lib/rules/no-iterator.js b/tools/eslint/lib/rules/no-iterator.js index faa5153335bd76..3677dd94d9f938 100644 --- a/tools/eslint/lib/rules/no-iterator.js +++ b/tools/eslint/lib/rules/no-iterator.js @@ -29,7 +29,7 @@ module.exports = { if (node.property && (node.property.type === "Identifier" && node.property.name === "__iterator__" && !node.computed) || (node.property.type === "Literal" && node.property.value === "__iterator__")) { - context.report(node, "Reserved name '__iterator__'."); + context.report({ node, message: "Reserved name '__iterator__'." }); } } }; diff --git a/tools/eslint/lib/rules/no-label-var.js b/tools/eslint/lib/rules/no-label-var.js index 450c9a91fca893..00133685613609 100644 --- a/tools/eslint/lib/rules/no-label-var.js +++ b/tools/eslint/lib/rules/no-label-var.js @@ -57,7 +57,7 @@ module.exports = { // Recursively find the identifier walking up the scope, starting // with the innermost scope. if (findIdentifier(scope, node.label.name)) { - context.report(node, "Found identifier with same name as label."); + context.report({ node, message: "Found identifier with same name as label." }); } } diff --git a/tools/eslint/lib/rules/no-lone-blocks.js b/tools/eslint/lib/rules/no-lone-blocks.js index 9945147129cd81..9528421ca5bd39 100644 --- a/tools/eslint/lib/rules/no-lone-blocks.js +++ b/tools/eslint/lib/rules/no-lone-blocks.js @@ -34,10 +34,10 @@ module.exports = { function report(node) { const parent = context.getAncestors().pop(); - context.report(node, parent.type === "Program" ? + context.report({ node, message: parent.type === "Program" ? "Block is redundant." : "Nested block is redundant." - ); + }); } /** diff --git a/tools/eslint/lib/rules/no-lonely-if.js b/tools/eslint/lib/rules/no-lonely-if.js index 19517bc3dc491a..31f47b90e06595 100644 --- a/tools/eslint/lib/rules/no-lonely-if.js +++ b/tools/eslint/lib/rules/no-lonely-if.js @@ -55,7 +55,7 @@ module.exports = { node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock && ( node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line || - /^[(\[\/+`-]/.test(tokenAfterElseBlock.value) || + /^[([/+`-]/.test(tokenAfterElseBlock.value) || lastIfToken.value === "++" || lastIfToken.value === "--" ) diff --git a/tools/eslint/lib/rules/no-loop-func.js b/tools/eslint/lib/rules/no-loop-func.js index 6db7a95f7c7254..b8bed958652e46 100644 --- a/tools/eslint/lib/rules/no-loop-func.js +++ b/tools/eslint/lib/rules/no-loop-func.js @@ -185,7 +185,7 @@ module.exports = { if (references.length > 0 && !references.every(isSafe.bind(null, node, loopNode)) ) { - context.report(node, "Don't make functions within a loop."); + context.report({ node, message: "Don't make functions within a loop." }); } } diff --git a/tools/eslint/lib/rules/no-mixed-operators.js b/tools/eslint/lib/rules/no-mixed-operators.js index 12779f8e738c68..b066d74a0c40e0 100644 --- a/tools/eslint/lib/rules/no-mixed-operators.js +++ b/tools/eslint/lib/rules/no-mixed-operators.js @@ -62,9 +62,7 @@ function normalizeOptions(options) { * @returns {boolean} `true` if such group existed. */ function includesBothInAGroup(groups, left, right) { - return groups.some(function(group) { - return group.indexOf(left) !== -1 && group.indexOf(right) !== -1; - }); + return groups.some(group => group.indexOf(left) !== -1 && group.indexOf(right) !== -1); } //------------------------------------------------------------------------------ @@ -86,7 +84,7 @@ module.exports = { type: "array", items: { type: "array", - items: {enum: ALL_OPERATORS}, + items: { enum: ALL_OPERATORS }, minItems: 2, uniqueItems: true }, diff --git a/tools/eslint/lib/rules/no-mixed-requires.js b/tools/eslint/lib/rules/no-mixed-requires.js index 89ba345c248f61..4d51d3ab3a07a4 100644 --- a/tools/eslint/lib/rules/no-mixed-requires.js +++ b/tools/eslint/lib/rules/no-mixed-requires.js @@ -169,7 +169,7 @@ module.exports = { function isMixed(declarations) { const contains = {}; - declarations.forEach(function(declaration) { + declarations.forEach(declaration => { const type = getDeclarationType(declaration.init); contains[type] = true; @@ -190,7 +190,7 @@ module.exports = { function isGrouped(declarations) { const found = {}; - declarations.forEach(function(declaration) { + declarations.forEach(declaration => { if (getDeclarationType(declaration.init) === DECL_REQUIRE) { found[inferModuleType(declaration.init)] = true; } @@ -205,15 +205,9 @@ module.exports = { VariableDeclaration(node) { if (isMixed(node.declarations)) { - context.report( - node, - "Do not mix 'require' and other declarations." - ); + context.report({ node, message: "Do not mix 'require' and other declarations." }); } else if (grouping && !isGrouped(node.declarations)) { - context.report( - node, - "Do not mix core, module, file and computed requires." - ); + context.report({ node, message: "Do not mix core, module, file and computed requires." }); } } }; diff --git a/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js b/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js index 0e2dcb1b8a8672..2b8e89d3c87123 100644 --- a/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js +++ b/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js @@ -89,11 +89,11 @@ module.exports = { const lines = sourceCode.lines, comments = sourceCode.getAllComments(); - comments.forEach(function(comment) { + comments.forEach(comment => { ignoredLocs.push(comment.loc); }); - ignoredLocs.sort(function(first, second) { + ignoredLocs.sort((first, second) => { if (beforeLoc(first, second.start.line, second.start.column)) { return 1; } @@ -114,7 +114,7 @@ module.exports = { regex = /^(?=[\t ]* \t)/; } - lines.forEach(function(line, i) { + lines.forEach((line, i) => { const match = regex.exec(line); if (match) { @@ -132,7 +132,7 @@ module.exports = { return; } - context.report(node, { line: lineNumber, column }, "Mixed spaces and tabs."); + context.report({ node, loc: { line: lineNumber, column }, message: "Mixed spaces and tabs." }); } }); } diff --git a/tools/eslint/lib/rules/no-multi-spaces.js b/tools/eslint/lib/rules/no-multi-spaces.js index 43e26a4415353e..64eeebec55a383 100644 --- a/tools/eslint/lib/rules/no-multi-spaces.js +++ b/tools/eslint/lib/rules/no-multi-spaces.js @@ -47,7 +47,7 @@ module.exports = { lastCommentIndex = 0; if (options && options.exceptions) { - Object.keys(options.exceptions).forEach(function(key) { + Object.keys(options.exceptions).forEach(key => { if (options.exceptions[key]) { exceptions[key] = true; } else { diff --git a/tools/eslint/lib/rules/no-multi-str.js b/tools/eslint/lib/rules/no-multi-str.js index 092226f7cad355..6cf5840e30264b 100644 --- a/tools/eslint/lib/rules/no-multi-str.js +++ b/tools/eslint/lib/rules/no-multi-str.js @@ -42,7 +42,7 @@ module.exports = { const lineBreak = /\n/; if (lineBreak.test(node.raw) && !isJSXElement(node.parent)) { - context.report(node, "Multiline support is limited to browsers supporting ES5 only."); + context.report({ node, message: "Multiline support is limited to browsers supporting ES5 only." }); } } }; diff --git a/tools/eslint/lib/rules/no-multiple-empty-lines.js b/tools/eslint/lib/rules/no-multiple-empty-lines.js index 9d44064d23f1d3..c45c7aa1678927 100644 --- a/tools/eslint/lib/rules/no-multiple-empty-lines.js +++ b/tools/eslint/lib/rules/no-multiple-empty-lines.js @@ -5,6 +5,8 @@ */ "use strict"; +const astUtils = require("../ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -56,8 +58,6 @@ module.exports = { } const sourceCode = context.getSourceCode(); - const fullLines = sourceCode.text.match(/.*(\r\n|\r|\n|\u2028|\u2029)/g) || []; - const lineStartLocations = fullLines.reduce((startIndices, nextLine) => startIndices.concat(startIndices[startIndices.length - 1] + nextLine.length), [0]); // Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines; @@ -81,7 +81,12 @@ module.exports = { return allLines // Given a list of lines, first get a list of line numbers that are non-empty. - .reduce((nonEmptyLineNumbers, line, index) => nonEmptyLineNumbers.concat(line.trim() || templateLiteralLines.has(index + 1) ? [index + 1] : []), []) + .reduce((nonEmptyLineNumbers, line, index) => { + if (line.trim() || templateLiteralLines.has(index + 1)) { + nonEmptyLineNumbers.push(index + 1); + } + return nonEmptyLineNumbers; + }, []) // Add a value at the end to allow trailing empty lines to be checked. .concat(allLines.length + 1) @@ -104,10 +109,15 @@ module.exports = { if (lineNumber - lastLineNumber - 1 > maxAllowed) { context.report({ node, - loc: {start: {line: lastLineNumber + 1, column: 0}, end: {line: lineNumber, column: 0}}, + loc: { start: { line: lastLineNumber + 1, column: 0 }, end: { line: lineNumber, column: 0 } }, message, - data: {max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines"}, - fix: fixer => fixer.removeRange([lineStartLocations[lastLineNumber], lineStartLocations[lineNumber - maxAllowed - 1]]) + data: { max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines" }, + fix(fixer) { + return fixer.removeRange([ + astUtils.getRangeIndexFromLocation(sourceCode, { line: lastLineNumber + 1, column: 0 }), + astUtils.getRangeIndexFromLocation(sourceCode, { line: lineNumber - maxAllowed, column: 0 }) + ]); + } }); } diff --git a/tools/eslint/lib/rules/no-native-reassign.js b/tools/eslint/lib/rules/no-native-reassign.js index 2b1c41b2d100b0..f721fc278fe3ec 100644 --- a/tools/eslint/lib/rules/no-native-reassign.js +++ b/tools/eslint/lib/rules/no-native-reassign.js @@ -27,7 +27,7 @@ module.exports = { properties: { exceptions: { type: "array", - items: {type: "string"}, + items: { type: "string" }, uniqueItems: true } }, diff --git a/tools/eslint/lib/rules/no-negated-condition.js b/tools/eslint/lib/rules/no-negated-condition.js index ea8b1210774f16..8ea8559ea1c96f 100644 --- a/tools/eslint/lib/rules/no-negated-condition.js +++ b/tools/eslint/lib/rules/no-negated-condition.js @@ -69,12 +69,12 @@ module.exports = { } if (isNegatedIf(node)) { - context.report(node, "Unexpected negated condition."); + context.report({ node, message: "Unexpected negated condition." }); } }, ConditionalExpression(node) { if (isNegatedIf(node)) { - context.report(node, "Unexpected negated condition."); + context.report({ node, message: "Unexpected negated condition." }); } } }; diff --git a/tools/eslint/lib/rules/no-negated-in-lhs.js b/tools/eslint/lib/rules/no-negated-in-lhs.js index 6631336ea74d9f..143518060b33bd 100644 --- a/tools/eslint/lib/rules/no-negated-in-lhs.js +++ b/tools/eslint/lib/rules/no-negated-in-lhs.js @@ -29,7 +29,7 @@ module.exports = { BinaryExpression(node) { if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") { - context.report(node, "The 'in' expression's left operand is negated."); + context.report({ node, message: "The 'in' expression's left operand is negated." }); } } }; diff --git a/tools/eslint/lib/rules/no-nested-ternary.js b/tools/eslint/lib/rules/no-nested-ternary.js index 50265913b02ecf..4fe49fc9c01e58 100644 --- a/tools/eslint/lib/rules/no-nested-ternary.js +++ b/tools/eslint/lib/rules/no-nested-ternary.js @@ -26,7 +26,7 @@ module.exports = { ConditionalExpression(node) { if (node.alternate.type === "ConditionalExpression" || node.consequent.type === "ConditionalExpression") { - context.report(node, "Do not nest ternary expressions."); + context.report({ node, message: "Do not nest ternary expressions." }); } } }; diff --git a/tools/eslint/lib/rules/no-new-func.js b/tools/eslint/lib/rules/no-new-func.js index e78bcc0772a024..17ca7c9f03d6b3 100644 --- a/tools/eslint/lib/rules/no-new-func.js +++ b/tools/eslint/lib/rules/no-new-func.js @@ -34,7 +34,7 @@ module.exports = { */ function validateCallee(node) { if (node.callee.name === "Function") { - context.report(node, "The Function constructor is eval."); + context.report({ node, message: "The Function constructor is eval." }); } } diff --git a/tools/eslint/lib/rules/no-new-object.js b/tools/eslint/lib/rules/no-new-object.js index d11a2ebc615350..d4d77b55147a62 100644 --- a/tools/eslint/lib/rules/no-new-object.js +++ b/tools/eslint/lib/rules/no-new-object.js @@ -26,7 +26,7 @@ module.exports = { NewExpression(node) { if (node.callee.name === "Object") { - context.report(node, "The object literal notation {} is preferrable."); + context.report({ node, message: "The object literal notation {} is preferrable." }); } } }; diff --git a/tools/eslint/lib/rules/no-new-require.js b/tools/eslint/lib/rules/no-new-require.js index eed2028de351fa..f9ea1f84bf3bb3 100644 --- a/tools/eslint/lib/rules/no-new-require.js +++ b/tools/eslint/lib/rules/no-new-require.js @@ -26,7 +26,7 @@ module.exports = { NewExpression(node) { if (node.callee.type === "Identifier" && node.callee.name === "require") { - context.report(node, "Unexpected use of new with require."); + context.report({ node, message: "Unexpected use of new with require." }); } } }; diff --git a/tools/eslint/lib/rules/no-new-symbol.js b/tools/eslint/lib/rules/no-new-symbol.js index c65e7c9df90afb..5743a4748a9275 100644 --- a/tools/eslint/lib/rules/no-new-symbol.js +++ b/tools/eslint/lib/rules/no-new-symbol.js @@ -28,11 +28,11 @@ module.exports = { const variable = globalScope.set.get("Symbol"); if (variable && variable.defs.length === 0) { - variable.references.forEach(function(ref) { + variable.references.forEach(ref => { const node = ref.identifier; if (node.parent && node.parent.type === "NewExpression") { - context.report(node, "`Symbol` cannot be called as a constructor."); + context.report({ node, message: "`Symbol` cannot be called as a constructor." }); } }); } diff --git a/tools/eslint/lib/rules/no-new-wrappers.js b/tools/eslint/lib/rules/no-new-wrappers.js index 67e69ee0fefe0a..65bf79b87c50b3 100644 --- a/tools/eslint/lib/rules/no-new-wrappers.js +++ b/tools/eslint/lib/rules/no-new-wrappers.js @@ -28,7 +28,7 @@ module.exports = { const wrapperObjects = ["String", "Number", "Boolean", "Math", "JSON"]; if (wrapperObjects.indexOf(node.callee.name) > -1) { - context.report(node, "Do not use {{fn}} as a constructor.", { fn: node.callee.name }); + context.report({ node, message: "Do not use {{fn}} as a constructor.", data: { fn: node.callee.name } }); } } }; diff --git a/tools/eslint/lib/rules/no-new.js b/tools/eslint/lib/rules/no-new.js index 639ae22685a96b..e0f45de1bd298b 100644 --- a/tools/eslint/lib/rules/no-new.js +++ b/tools/eslint/lib/rules/no-new.js @@ -28,7 +28,7 @@ module.exports = { ExpressionStatement(node) { if (node.expression.type === "NewExpression") { - context.report(node, "Do not use 'new' for side effects."); + context.report({ node, message: "Do not use 'new' for side effects." }); } } }; diff --git a/tools/eslint/lib/rules/no-obj-calls.js b/tools/eslint/lib/rules/no-obj-calls.js index bd9b6ee4f04f76..0ca8a5effb6e86 100644 --- a/tools/eslint/lib/rules/no-obj-calls.js +++ b/tools/eslint/lib/rules/no-obj-calls.js @@ -28,8 +28,8 @@ module.exports = { if (node.callee.type === "Identifier") { const name = node.callee.name; - if (name === "Math" || name === "JSON") { - context.report(node, "'{{name}}' is not a function.", { name }); + if (name === "Math" || name === "JSON" || name === "Reflect") { + context.report({ node, message: "'{{name}}' is not a function.", data: { name } }); } } } diff --git a/tools/eslint/lib/rules/no-octal-escape.js b/tools/eslint/lib/rules/no-octal-escape.js index 25a5b022e92402..04bfb6aae3357c 100644 --- a/tools/eslint/lib/rules/no-octal-escape.js +++ b/tools/eslint/lib/rules/no-octal-escape.js @@ -36,8 +36,7 @@ module.exports = { // \0 is actually not considered an octal if (match[2] !== "0" || typeof match[3] !== "undefined") { - context.report(node, "Don't use octal: '\\{{octalDigit}}'. Use '\\u....' instead.", - { octalDigit }); + context.report({ node, message: "Don't use octal: '\\{{octalDigit}}'. Use '\\u....' instead.", data: { octalDigit } }); } } } diff --git a/tools/eslint/lib/rules/no-octal.js b/tools/eslint/lib/rules/no-octal.js index ebc5e3252d9771..58082d0d1cfb04 100644 --- a/tools/eslint/lib/rules/no-octal.js +++ b/tools/eslint/lib/rules/no-octal.js @@ -26,7 +26,7 @@ module.exports = { Literal(node) { if (typeof node.value === "number" && /^0[0-7]/.test(node.raw)) { - context.report(node, "Octal literals should not be used."); + context.report({ node, message: "Octal literals should not be used." }); } } }; diff --git a/tools/eslint/lib/rules/no-param-reassign.js b/tools/eslint/lib/rules/no-param-reassign.js index c20f340d7ab43a..31f5be3cb25972 100644 --- a/tools/eslint/lib/rules/no-param-reassign.js +++ b/tools/eslint/lib/rules/no-param-reassign.js @@ -22,7 +22,7 @@ module.exports = { { type: "object", properties: { - props: {type: "boolean"} + props: { type: "boolean" } }, additionalProperties: false } @@ -102,15 +102,9 @@ module.exports = { (index === 0 || references[index - 1].identifier !== identifier) ) { if (reference.isWrite()) { - context.report( - identifier, - "Assignment to function parameter '{{name}}'.", - {name: identifier.name}); + context.report({ node: identifier, message: "Assignment to function parameter '{{name}}'.", data: { name: identifier.name } }); } else if (props && isModifyingProp(reference)) { - context.report( - identifier, - "Assignment to property of function parameter '{{name}}'.", - {name: identifier.name}); + context.report({ node: identifier, message: "Assignment to property of function parameter '{{name}}'.", data: { name: identifier.name } }); } } } diff --git a/tools/eslint/lib/rules/no-path-concat.js b/tools/eslint/lib/rules/no-path-concat.js index 6b27678aedc8f8..1e153a43b6c683 100644 --- a/tools/eslint/lib/rules/no-path-concat.js +++ b/tools/eslint/lib/rules/no-path-concat.js @@ -39,7 +39,7 @@ module.exports = { (right.type === "Identifier" && MATCHER.test(right.name))) ) { - context.report(node, "Use path.join() or path.resolve() instead of + to create paths."); + context.report({ node, message: "Use path.join() or path.resolve() instead of + to create paths." }); } } diff --git a/tools/eslint/lib/rules/no-process-env.js b/tools/eslint/lib/rules/no-process-env.js index a2ae1fd408ac44..ef58b38e3cccd4 100644 --- a/tools/eslint/lib/rules/no-process-env.js +++ b/tools/eslint/lib/rules/no-process-env.js @@ -28,7 +28,7 @@ module.exports = { propertyName = node.property.name; if (objectName === "process" && !node.computed && propertyName && propertyName === "env") { - context.report(node, "Unexpected use of process.env."); + context.report({ node, message: "Unexpected use of process.env." }); } } diff --git a/tools/eslint/lib/rules/no-process-exit.js b/tools/eslint/lib/rules/no-process-exit.js index 69023e58e1b109..c0c2455545afab 100644 --- a/tools/eslint/lib/rules/no-process-exit.js +++ b/tools/eslint/lib/rules/no-process-exit.js @@ -33,7 +33,7 @@ module.exports = { if (callee.type === "MemberExpression" && callee.object.name === "process" && callee.property.name === "exit" ) { - context.report(node, "Don't use process.exit(); throw an error instead."); + context.report({ node, message: "Don't use process.exit(); throw an error instead." }); } } diff --git a/tools/eslint/lib/rules/no-proto.js b/tools/eslint/lib/rules/no-proto.js index 03eb88273c4bc2..933746f559cd4b 100644 --- a/tools/eslint/lib/rules/no-proto.js +++ b/tools/eslint/lib/rules/no-proto.js @@ -29,7 +29,7 @@ module.exports = { if (node.property && (node.property.type === "Identifier" && node.property.name === "__proto__" && !node.computed) || (node.property.type === "Literal" && node.property.value === "__proto__")) { - context.report(node, "The '__proto__' property is deprecated."); + context.report({ node, message: "The '__proto__' property is deprecated." }); } } }; diff --git a/tools/eslint/lib/rules/no-prototype-builtins.js b/tools/eslint/lib/rules/no-prototype-builtins.js index e9f46881597333..b9f040eaf67497 100644 --- a/tools/eslint/lib/rules/no-prototype-builtins.js +++ b/tools/eslint/lib/rules/no-prototype-builtins.js @@ -41,7 +41,7 @@ module.exports = { context.report({ message: "Do not access Object.prototype method '{{prop}}' from target object.", loc: node.callee.property.loc.start, - data: {prop: propName}, + data: { prop: propName }, node }); } diff --git a/tools/eslint/lib/rules/no-redeclare.js b/tools/eslint/lib/rules/no-redeclare.js index fcd4943460b421..deb896289b76f0 100644 --- a/tools/eslint/lib/rules/no-redeclare.js +++ b/tools/eslint/lib/rules/no-redeclare.js @@ -21,7 +21,7 @@ module.exports = { { type: "object", properties: { - builtinGlobals: {type: "boolean"} + builtinGlobals: { type: "boolean" } }, additionalProperties: false } @@ -40,20 +40,15 @@ module.exports = { * @private */ function findVariablesInScope(scope) { - scope.variables.forEach(function(variable) { + scope.variables.forEach(variable => { const hasBuiltin = options.builtinGlobals && "writeable" in variable; const count = (hasBuiltin ? 1 : 0) + variable.identifiers.length; if (count >= 2) { - variable.identifiers.sort(function(a, b) { - return a.range[1] - b.range[1]; - }); + variable.identifiers.sort((a, b) => a.range[1] - b.range[1]); for (let i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) { - context.report( - variable.identifiers[i], - "'{{a}}' is already defined.", - {a: variable.name}); + context.report({ node: variable.identifiers[i], message: "'{{a}}' is already defined.", data: { a: variable.name } }); } } }); diff --git a/tools/eslint/lib/rules/no-regex-spaces.js b/tools/eslint/lib/rules/no-regex-spaces.js index c6e26ac3980020..05ac86e87a9db3 100644 --- a/tools/eslint/lib/rules/no-regex-spaces.js +++ b/tools/eslint/lib/rules/no-regex-spaces.js @@ -46,7 +46,7 @@ module.exports = { context.report({ node, message: "Spaces are hard to count. Use {{{count}}}.", - data: {count}, + data: { count }, fix(fixer) { return fixer.replaceTextRange( [valueStart + regexResults.index, valueStart + regexResults.index + count], diff --git a/tools/eslint/lib/rules/no-restricted-globals.js b/tools/eslint/lib/rules/no-restricted-globals.js index 07ff8b532d2307..603a6b2d3762ae 100644 --- a/tools/eslint/lib/rules/no-restricted-globals.js +++ b/tools/eslint/lib/rules/no-restricted-globals.js @@ -40,9 +40,9 @@ module.exports = { * @private */ function reportReference(reference) { - context.report(reference.identifier, "Unexpected use of '{{name}}'.", { + context.report({ node: reference.identifier, message: "Unexpected use of '{{name}}'.", data: { name: reference.identifier.name - }); + } }); } /** @@ -60,14 +60,14 @@ module.exports = { const scope = context.getScope(); // Report variables declared elsewhere (ex: variables defined as "global" by eslint) - scope.variables.forEach(function(variable) { + scope.variables.forEach(variable => { if (!variable.defs.length && isRestricted(variable.name)) { variable.references.forEach(reportReference); } }); // Report variables not declared at all - scope.through.forEach(function(reference) { + scope.through.forEach(reference => { if (isRestricted(reference.identifier.name)) { reportReference(reference); } diff --git a/tools/eslint/lib/rules/no-restricted-imports.js b/tools/eslint/lib/rules/no-restricted-imports.js index 87f9af2a6477e0..c245f22a0a4494 100644 --- a/tools/eslint/lib/rules/no-restricted-imports.js +++ b/tools/eslint/lib/rules/no-restricted-imports.js @@ -8,6 +8,16 @@ // Rule Definition //------------------------------------------------------------------------------ +const ignore = require("ignore"); + +const arrayOfStrings = { + type: "array", + items: { + type: "string" + }, + uniqueItems: true +}; + module.exports = { meta: { docs: { @@ -17,31 +27,55 @@ module.exports = { }, schema: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true + anyOf: [ + arrayOfStrings, + { + type: "array", + items: [{ + type: "object", + properties: { + paths: arrayOfStrings, + patterns: arrayOfStrings + }, + additionalProperties: false + }], + additionalItems: false + } + ] } }, create(context) { - const restrictedImports = context.options; + const options = Array.isArray(context.options) ? context.options : []; + const isStringArray = typeof options[0] !== "object"; + const restrictedPaths = new Set(isStringArray ? context.options : options[0].paths || []); + const restrictedPatterns = isStringArray ? [] : options[0].patterns || []; // if no imports are restricted we don"t need to check - if (restrictedImports.length === 0) { + if (restrictedPaths.size === 0 && restrictedPatterns.length === 0) { return {}; } + const ig = ignore().add(restrictedPatterns); + return { ImportDeclaration(node) { if (node && node.source && node.source.value) { - const value = node.source.value.trim(); + const importName = node.source.value.trim(); - if (restrictedImports.indexOf(value) !== -1) { - context.report(node, "'{{importName}}' import is restricted from being used.", { - importName: value + if (restrictedPaths.has(importName)) { + context.report({ + node, + message: "'{{importName}}' import is restricted from being used.", + data: { importName } + }); + } + if (restrictedPatterns.length > 0 && ig.ignores(importName)) { + context.report({ + node, + message: "'{{importName}}' import is restricted from being used by a pattern.", + data: { importName } }); } } diff --git a/tools/eslint/lib/rules/no-restricted-modules.js b/tools/eslint/lib/rules/no-restricted-modules.js index 1a46c40a81dbe2..3a9634de9e18d1 100644 --- a/tools/eslint/lib/rules/no-restricted-modules.js +++ b/tools/eslint/lib/rules/no-restricted-modules.js @@ -8,6 +8,16 @@ // Rule Definition //------------------------------------------------------------------------------ +const ignore = require("ignore"); + +const arrayOfStrings = { + type: "array", + items: { + type: "string" + }, + uniqueItems: true +}; + module.exports = { meta: { docs: { @@ -17,24 +27,37 @@ module.exports = { }, schema: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true + anyOf: [ + arrayOfStrings, + { + type: "array", + items: [{ + type: "object", + properties: { + paths: arrayOfStrings, + patterns: arrayOfStrings + }, + additionalProperties: false + }], + additionalItems: false + } + ] } }, create(context) { + const options = Array.isArray(context.options) ? context.options : []; + const isStringArray = typeof options[0] !== "object"; + const restrictedPaths = new Set(isStringArray ? context.options : options[0].paths || []); + const restrictedPatterns = isStringArray ? [] : options[0].patterns || []; - // trim restricted module names - const restrictedModules = context.options; - - // if no modules are restricted we don't need to check the CallExpressions - if (restrictedModules.length === 0) { + // if no imports are restricted we don"t need to check + if (restrictedPaths.size === 0 && restrictedPatterns.length === 0) { return {}; } + const ig = ignore().add(restrictedPatterns); + /** * Function to check if a node is a string literal. * @param {ASTNode} node The node to check. @@ -53,36 +76,30 @@ module.exports = { return node.callee.type === "Identifier" && node.callee.name === "require"; } - /** - * Function to check if a node has an argument that is an restricted module and return its name. - * @param {ASTNode} node The node to check - * @returns {undefined|string} restricted module name or undefined if node argument isn't restricted. - */ - function getRestrictedModuleName(node) { - let moduleName; - - // node has arguments and first argument is string - if (node.arguments.length && isString(node.arguments[0])) { - const argumentValue = node.arguments[0].value.trim(); - - // check if argument value is in restricted modules array - if (restrictedModules.indexOf(argumentValue) !== -1) { - moduleName = argumentValue; - } - } - - return moduleName; - } - return { CallExpression(node) { if (isRequireCall(node)) { - const restrictedModuleName = getRestrictedModuleName(node); - if (restrictedModuleName) { - context.report(node, "'{{moduleName}}' module is restricted from being used.", { - moduleName: restrictedModuleName - }); + // node has arguments and first argument is string + if (node.arguments.length && isString(node.arguments[0])) { + const moduleName = node.arguments[0].value.trim(); + + // check if argument value is in restricted modules array + if (restrictedPaths.has(moduleName)) { + context.report({ + node, + message: "'{{moduleName}}' module is restricted from being used.", + data: { moduleName } + }); + } + + if (restrictedPatterns.length > 0 && ig.ignores(moduleName)) { + context.report({ + node, + message: "'{{moduleName}}' module is restricted from being used by a pattern.", + data: { moduleName } + }); + } } } } diff --git a/tools/eslint/lib/rules/no-restricted-properties.js b/tools/eslint/lib/rules/no-restricted-properties.js index f8bd47ba4b2c18..b6c584c57e32e3 100644 --- a/tools/eslint/lib/rules/no-restricted-properties.js +++ b/tools/eslint/lib/rules/no-restricted-properties.js @@ -77,9 +77,9 @@ module.exports = { const propertyName = option.property; if (typeof objectName === "undefined") { - globallyRestrictedProperties.set(propertyName, {message: option.message}); + globallyRestrictedProperties.set(propertyName, { message: option.message }); } else if (typeof propertyName === "undefined") { - globallyRestrictedObjects.set(objectName, {message: option.message}); + globallyRestrictedObjects.set(objectName, { message: option.message }); } else { if (!restrictedProperties.has(objectName)) { restrictedProperties.set(objectName, new Map()); @@ -109,18 +109,18 @@ module.exports = { if (matchedObjectProperty) { const message = matchedObjectProperty.message ? ` ${matchedObjectProperty.message}` : ""; - context.report(node, "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", { + context.report({ node, message: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", data: { objectName, propertyName, message - }); + } }); } else if (globalMatchedProperty) { const message = globalMatchedProperty.message ? ` ${globalMatchedProperty.message}` : ""; - context.report(node, "'{{propertyName}}' is restricted from being used.{{message}}", { + context.report({ node, message: "'{{propertyName}}' is restricted from being used.{{message}}", data: { propertyName, message - }); + } }); } } diff --git a/tools/eslint/lib/rules/no-restricted-syntax.js b/tools/eslint/lib/rules/no-restricted-syntax.js index ab6c36923a69b0..830452d995dab4 100644 --- a/tools/eslint/lib/rules/no-restricted-syntax.js +++ b/tools/eslint/lib/rules/no-restricted-syntax.js @@ -22,9 +22,7 @@ module.exports = { type: "array", items: [ { - enum: Object.keys(nodeTypes).map(function(k) { - return nodeTypes[k]; - }) + enum: Object.keys(nodeTypes).map(k => nodeTypes[k]) } ], uniqueItems: true, @@ -40,10 +38,10 @@ module.exports = { * @returns {void} */ function warn(node) { - context.report(node, "Using '{{type}}' is not allowed.", node); + context.report({ node, message: "Using '{{type}}' is not allowed.", data: node }); } - return context.options.reduce(function(result, nodeType) { + return context.options.reduce((result, nodeType) => { result[nodeType] = warn; return result; diff --git a/tools/eslint/lib/rules/no-return-await.js b/tools/eslint/lib/rules/no-return-await.js new file mode 100644 index 00000000000000..bc0498cb044d70 --- /dev/null +++ b/tools/eslint/lib/rules/no-return-await.js @@ -0,0 +1,94 @@ +/** + * @fileoverview Disallows unnecessary `return await` + * @author Jordan Harband + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const message = "Redundant use of `await` on a return value."; + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary `return await`", + category: "Best Practices", + recommended: false // TODO: set to true + }, + fixable: false, + schema: [ + ] + }, + + create(context) { + + /** + * Reports a found unnecessary `await` expression. + * @param {ASTNode} node The node representing the `await` expression to report + * @returns {void} + */ + function reportUnnecessaryAwait(node) { + context.report({ + node: context.getSourceCode().getFirstToken(node), + loc: node.loc, + message, + }); + } + + /** + * Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting + * this function. For example, a statement in a `try` block will always have an error handler. A statement in + * a `catch` block will only have an error handler if there is also a `finally` block. + * @param {ASTNode} node A node representing a location where an could be thrown + * @returns {boolean} `true` if a thrown error will be caught/handled in this function + */ + function hasErrorHandler(node) { + let ancestor = node; + + while (!astUtils.isFunction(ancestor) && ancestor.type !== "Program") { + if (ancestor.parent.type === "TryStatement" && (ancestor === ancestor.parent.block || ancestor === ancestor.parent.handler && ancestor.parent.finalizer)) { + return true; + } + ancestor = ancestor.parent; + } + return false; + } + + /** + * Checks if a node is placed in tail call position. Once `return` arguments (or arrow function expressions) can be a complex expression, + * an `await` expression could or could not be unnecessary by the definition of this rule. So we're looking for `await` expressions that are in tail position. + * @param {ASTNode} node A node representing the `await` expression to check + * @returns {boolean} The checking result + */ + function isInTailCallPosition(node) { + if (node.parent.type === "ArrowFunctionExpression") { + return true; + } + if (node.parent.type === "ReturnStatement") { + return !hasErrorHandler(node.parent); + } + if (node.parent.type === "ConditionalExpression" && (node === node.parent.consequent || node === node.parent.alternate)) { + return isInTailCallPosition(node.parent); + } + if (node.parent.type === "LogicalExpression" && node === node.parent.right) { + return isInTailCallPosition(node.parent); + } + if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) { + return isInTailCallPosition(node.parent); + } + return false; + } + + return { + AwaitExpression(node) { + if (isInTailCallPosition(node) && !hasErrorHandler(node)) { + reportUnnecessaryAwait(node); + } + }, + }; + } +}; diff --git a/tools/eslint/lib/rules/no-script-url.js b/tools/eslint/lib/rules/no-script-url.js index fd2f1e8c3e8954..98f988ff1a3b96 100644 --- a/tools/eslint/lib/rules/no-script-url.js +++ b/tools/eslint/lib/rules/no-script-url.js @@ -31,7 +31,7 @@ module.exports = { const value = node.value.toLowerCase(); if (value.indexOf("javascript:") === 0) { - context.report(node, "Script URL is a form of eval."); + context.report({ node, message: "Script URL is a form of eval." }); } } } diff --git a/tools/eslint/lib/rules/no-self-compare.js b/tools/eslint/lib/rules/no-self-compare.js index 17ce77a939d53e..54f907f594be06 100644 --- a/tools/eslint/lib/rules/no-self-compare.js +++ b/tools/eslint/lib/rules/no-self-compare.js @@ -31,7 +31,7 @@ module.exports = { if (operators.indexOf(node.operator) > -1 && (node.left.type === "Identifier" && node.right.type === "Identifier" && node.left.name === node.right.name || node.left.type === "Literal" && node.right.type === "Literal" && node.left.value === node.right.value)) { - context.report(node, "Comparing to itself is potentially pointless."); + context.report({ node, message: "Comparing to itself is potentially pointless." }); } } }; diff --git a/tools/eslint/lib/rules/no-sequences.js b/tools/eslint/lib/rules/no-sequences.js index 49f20ea43ff61a..67f9d8212fd4e5 100644 --- a/tools/eslint/lib/rules/no-sequences.js +++ b/tools/eslint/lib/rules/no-sequences.js @@ -101,7 +101,7 @@ module.exports = { const child = sourceCode.getTokenAfter(node.expressions[0]); - context.report(node, child.loc.start, "Unexpected use of comma operator."); + context.report({ node, loc: child.loc.start, message: "Unexpected use of comma operator." }); } }; diff --git a/tools/eslint/lib/rules/no-shadow.js b/tools/eslint/lib/rules/no-shadow.js index 27ea10ef9217aa..e093d48c810aeb 100644 --- a/tools/eslint/lib/rules/no-shadow.js +++ b/tools/eslint/lib/rules/no-shadow.js @@ -27,8 +27,8 @@ module.exports = { { type: "object", properties: { - builtinGlobals: {type: "boolean"}, - hoist: {enum: ["all", "functions", "never"]}, + builtinGlobals: { type: "boolean" }, + hoist: { enum: ["all", "functions", "never"] }, allow: { type: "array", items: { diff --git a/tools/eslint/lib/rules/no-sparse-arrays.js b/tools/eslint/lib/rules/no-sparse-arrays.js index 31bd6f2bbffb00..3044896c612d17 100644 --- a/tools/eslint/lib/rules/no-sparse-arrays.js +++ b/tools/eslint/lib/rules/no-sparse-arrays.js @@ -33,7 +33,7 @@ module.exports = { const emptySpot = node.elements.indexOf(null) > -1; if (emptySpot) { - context.report(node, "Unexpected comma in middle of array."); + context.report({ node, message: "Unexpected comma in middle of array." }); } } diff --git a/tools/eslint/lib/rules/no-tabs.js b/tools/eslint/lib/rules/no-tabs.js index d57ac324c1d58b..19983c57ba9ed4 100644 --- a/tools/eslint/lib/rules/no-tabs.js +++ b/tools/eslint/lib/rules/no-tabs.js @@ -17,7 +17,7 @@ const regex = /\t/; module.exports = { meta: { docs: { - description: "disallow tabs in file", + description: "disallow all tabs", category: "Stylistic Issues", recommended: false }, @@ -31,14 +31,10 @@ module.exports = { const match = regex.exec(line); if (match) { - context.report( - node, - { - line: index + 1, - column: match.index + 1 - }, - "Unexpected tab character." - ); + context.report({ node, loc: { + line: index + 1, + column: match.index + 1 + }, message: "Unexpected tab character." }); } }); } diff --git a/tools/eslint/lib/rules/no-ternary.js b/tools/eslint/lib/rules/no-ternary.js index 2408cd9c39a0ea..3e254f68126f5a 100644 --- a/tools/eslint/lib/rules/no-ternary.js +++ b/tools/eslint/lib/rules/no-ternary.js @@ -25,7 +25,7 @@ module.exports = { return { ConditionalExpression(node) { - context.report(node, "Ternary operator used."); + context.report({ node, message: "Ternary operator used." }); } }; diff --git a/tools/eslint/lib/rules/no-this-before-super.js b/tools/eslint/lib/rules/no-this-before-super.js index 80a769a481a44a..c8d5dc4698d7b0 100644 --- a/tools/eslint/lib/rules/no-this-before-super.js +++ b/tools/eslint/lib/rules/no-this-before-super.js @@ -179,7 +179,7 @@ module.exports = { return; } - codePath.traverseSegments(function(segment, controller) { + codePath.traverseSegments((segment, controller) => { const info = segInfoMap[segment.id]; for (let i = 0; i < info.invalidNodes.length; ++i) { @@ -236,8 +236,8 @@ module.exports = { // Update information inside of the loop. funcInfo.codePath.traverseSegments( - {first: toSegment, last: fromSegment}, - function(segment, controller) { + { first: toSegment, last: fromSegment }, + (segment, controller) => { const info = segInfoMap[segment.id]; if (info.superCalled) { diff --git a/tools/eslint/lib/rules/no-throw-literal.js b/tools/eslint/lib/rules/no-throw-literal.js index 034361c7a620c9..0d1f42985f89ec 100644 --- a/tools/eslint/lib/rules/no-throw-literal.js +++ b/tools/eslint/lib/rules/no-throw-literal.js @@ -65,10 +65,10 @@ module.exports = { ThrowStatement(node) { if (!couldBeError(node.argument)) { - context.report(node, "Expected an object to be thrown."); + context.report({ node, message: "Expected an object to be thrown." }); } else if (node.argument.type === "Identifier") { if (node.argument.name === "undefined") { - context.report(node, "Do not throw undefined."); + context.report({ node, message: "Do not throw undefined." }); } } diff --git a/tools/eslint/lib/rules/no-undef-init.js b/tools/eslint/lib/rules/no-undef-init.js index ca9f0272ba5bf5..9df40e9cebb186 100644 --- a/tools/eslint/lib/rules/no-undef-init.js +++ b/tools/eslint/lib/rules/no-undef-init.js @@ -41,7 +41,7 @@ module.exports = { context.report({ node, message: "It's not necessary to initialize '{{name}}' to undefined.", - data: {name}, + data: { name }, fix(fixer) { if (node.id.type === "ArrayPattern" || node.id.type === "ObjectPattern") { diff --git a/tools/eslint/lib/rules/no-undef.js b/tools/eslint/lib/rules/no-undef.js index 2cd2980f840581..74a33dd9973234 100644 --- a/tools/eslint/lib/rules/no-undef.js +++ b/tools/eslint/lib/rules/no-undef.js @@ -52,7 +52,7 @@ module.exports = { "Program:exit"(/* node */) { const globalScope = context.getScope(); - globalScope.through.forEach(function(ref) { + globalScope.through.forEach(ref => { const identifier = ref.identifier; if (!considerTypeOf && hasTypeOfOperator(identifier)) { diff --git a/tools/eslint/lib/rules/no-undefined.js b/tools/eslint/lib/rules/no-undefined.js index 2aad3d0d1f4b55..18e1d98641dc86 100644 --- a/tools/eslint/lib/rules/no-undefined.js +++ b/tools/eslint/lib/rules/no-undefined.js @@ -28,7 +28,7 @@ module.exports = { const parent = context.getAncestors().pop(); if (!parent || parent.type !== "MemberExpression" || node !== parent.property || parent.computed) { - context.report(node, "Unexpected use of undefined."); + context.report({ node, message: "Unexpected use of undefined." }); } } } diff --git a/tools/eslint/lib/rules/no-underscore-dangle.js b/tools/eslint/lib/rules/no-underscore-dangle.js index abc5967b5348be..6803cc68fc7e81 100644 --- a/tools/eslint/lib/rules/no-underscore-dangle.js +++ b/tools/eslint/lib/rules/no-underscore-dangle.js @@ -57,9 +57,7 @@ module.exports = { * @private */ function isAllowed(identifier) { - return ALLOWED_VARIABLES.some(function(ident) { - return ident === identifier; - }); + return ALLOWED_VARIABLES.some(ident => ident === identifier); } /** diff --git a/tools/eslint/lib/rules/no-unexpected-multiline.js b/tools/eslint/lib/rules/no-unexpected-multiline.js index 5208813dadada0..bae4833983b14e 100644 --- a/tools/eslint/lib/rules/no-unexpected-multiline.js +++ b/tools/eslint/lib/rules/no-unexpected-multiline.js @@ -45,7 +45,7 @@ module.exports = { } if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) { - context.report(node, openParen.loc.start, msg, { char: openParen.value }); + context.report({ node, loc: openParen.loc.start, message: msg, data: { char: openParen.value } }); } } @@ -66,7 +66,7 @@ module.exports = { if (node.tag.loc.end.line === node.quasi.loc.start.line) { return; } - context.report(node, node.loc.start, TAGGED_TEMPLATE_MESSAGE); + context.report({ node, loc: node.loc.start, message: TAGGED_TEMPLATE_MESSAGE }); }, CallExpression(node) { diff --git a/tools/eslint/lib/rules/no-unneeded-ternary.js b/tools/eslint/lib/rules/no-unneeded-ternary.js index c755f5f4b4fd11..cba83ea48140ec 100644 --- a/tools/eslint/lib/rules/no-unneeded-ternary.js +++ b/tools/eslint/lib/rules/no-unneeded-ternary.js @@ -5,6 +5,19 @@ "use strict"; +const astUtils = require("../ast-utils"); + +// Operators that always result in a boolean value +const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]); +const OPERATOR_INVERSES = { + "==": "!=", + "!=": "==", + "===": "!==", + "!==": "===" + + // Operators like < and >= are not true inverses, since both will return false with NaN. +}; + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -27,12 +40,15 @@ module.exports = { }, additionalProperties: false } - ] + ], + + fixable: "code" }, create(context) { const options = context.options[0] || {}; const defaultAssignment = options.defaultAssignment !== false; + const sourceCode = context.getSourceCode(); /** * Test if the node is a boolean literal @@ -44,6 +60,34 @@ module.exports = { return node.type === "Literal" && typeof node.value === "boolean"; } + /** + * Creates an expression that represents the boolean inverse of the expression represented by the original node + * @param {ASTNode} node A node representing an expression + * @returns {string} A string representing an inverted expression + */ + function invertExpression(node) { + if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) { + const operatorToken = sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + + return sourceCode.getText().slice(node.range[0], operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + sourceCode.getText().slice(operatorToken.range[1], node.range[1]); + } + + if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) { + return `!(${astUtils.getParenthesisedText(sourceCode, node)})`; + } + return `!${astUtils.getParenthesisedText(sourceCode, node)}`; + } + + /** + * Tests if a given node always evaluates to a boolean value + * @param {ASTNode} node - An expression node + * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value + */ + function isBooleanExpression(node) { + return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) || + node.type === "UnaryExpression" && node.operator === "!"; + } + /** * Test if the node matches the pattern id ? id : expression * @param {ASTNode} node - The ConditionalExpression to check. @@ -60,9 +104,34 @@ module.exports = { ConditionalExpression(node) { if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { - context.report(node, node.consequent.loc.start, "Unnecessary use of boolean literals in conditional expression."); + context.report({ + node, + loc: node.consequent.loc.start, + message: "Unnecessary use of boolean literals in conditional expression.", + fix(fixer) { + if (node.consequent.value === node.alternate.value) { + + // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true` + return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null; + } + if (node.alternate.value) { + + // Replace `foo() ? false : true` with `!(foo())` + return fixer.replaceText(node, invertExpression(node.test)); + } + + // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise. + + return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`); + } + }); } else if (!defaultAssignment && matchesDefaultAssignment(node)) { - context.report(node, node.consequent.loc.start, "Unnecessary use of conditional expression for default assignment."); + context.report({ + node, + loc: node.consequent.loc.start, + message: "Unnecessary use of conditional expression for default assignment.", + fix: fixer => fixer.replaceText(node, `${astUtils.getParenthesisedText(sourceCode, node.test)} || ${astUtils.getParenthesisedText(sourceCode, node.alternate)}`) + }); } } }; diff --git a/tools/eslint/lib/rules/no-unused-expressions.js b/tools/eslint/lib/rules/no-unused-expressions.js index cdabca204a64df..548e02f463e71a 100644 --- a/tools/eslint/lib/rules/no-unused-expressions.js +++ b/tools/eslint/lib/rules/no-unused-expressions.js @@ -108,7 +108,7 @@ module.exports = { return { ExpressionStatement(node) { if (!isValidExpression(node.expression) && !isDirective(node, context.getAncestors())) { - context.report(node, "Expected an assignment or function call and instead saw an expression."); + context.report({ node, message: "Expected an assignment or function call and instead saw an expression." }); } } }; diff --git a/tools/eslint/lib/rules/no-unused-vars.js b/tools/eslint/lib/rules/no-unused-vars.js index 683176e944f357..ac8f2ed1c0a20a 100644 --- a/tools/eslint/lib/rules/no-unused-vars.js +++ b/tools/eslint/lib/rules/no-unused-vars.js @@ -156,28 +156,6 @@ module.exports = { return false; } - /** - * Checks whether a given node is inside of a loop or not. - * - * @param {ASTNode} node - A node to check. - * @returns {boolean} `true` if the node is inside of a loop. - * @private - */ - function isInsideOfLoop(node) { - while (node) { - if (astUtils.isLoop(node)) { - return true; - } - if (astUtils.isFunction(node)) { - return false; - } - - node = node.parent; - } - - return false; - } - /** * Checks the position of given nodes. * @@ -215,7 +193,7 @@ module.exports = { const granpa = parent.parent; const refScope = ref.from.variableScope; const varScope = ref.resolved.scope.variableScope; - const canBeUsedLater = refScope !== varScope || isInsideOfLoop(id); + const canBeUsedLater = refScope !== varScope || astUtils.isInLoop(id); /* * Inherits the previous node if this reference is in the node. @@ -390,15 +368,11 @@ module.exports = { * @private */ function isUsedVariable(variable) { - const functionNodes = variable.defs.filter(function(def) { - return def.type === "FunctionName"; - }).map(function(def) { - return def.node; - }), + const functionNodes = variable.defs.filter(def => def.type === "FunctionName").map(def => def.node), isFunctionDefinition = functionNodes.length > 0; let rhsNode = null; - return variable.references.some(function(ref) { + return variable.references.some(ref => { if (isForInRef(ref)) { return true; } diff --git a/tools/eslint/lib/rules/no-use-before-define.js b/tools/eslint/lib/rules/no-use-before-define.js index 01c899ca3920c4..ea1cf301f29af4 100644 --- a/tools/eslint/lib/rules/no-use-before-define.js +++ b/tools/eslint/lib/rules/no-use-before-define.js @@ -29,7 +29,7 @@ function parseOptions(options) { classes = options.classes !== false; } - return {functions, classes}; + return { functions, classes }; } /** @@ -154,8 +154,8 @@ module.exports = { { type: "object", properties: { - functions: {type: "boolean"}, - classes: {type: "boolean"} + functions: { type: "boolean" }, + classes: { type: "boolean" } }, additionalProperties: false } @@ -187,7 +187,7 @@ module.exports = { * @private */ function findVariablesInScope(scope) { - scope.references.forEach(function(reference) { + scope.references.forEach(reference => { const variable = reference.resolved; // Skips when the reference is: diff --git a/tools/eslint/lib/rules/no-useless-call.js b/tools/eslint/lib/rules/no-useless-call.js index 2be665992a08e5..eb67bcb3b25271 100644 --- a/tools/eslint/lib/rules/no-useless-call.js +++ b/tools/eslint/lib/rules/no-useless-call.js @@ -96,10 +96,7 @@ module.exports = { const thisArg = node.arguments[0]; if (isValidThisArg(expectedThis, thisArg, sourceCode)) { - context.report( - node, - "unnecessary '.{{name}}()'.", - {name: node.callee.property.name}); + context.report({ node, message: "unnecessary '.{{name}}()'.", data: { name: node.callee.property.name } }); } } }; diff --git a/tools/eslint/lib/rules/no-useless-concat.js b/tools/eslint/lib/rules/no-useless-concat.js index d9cf6a2c354b8b..ed0ef66a2441e1 100644 --- a/tools/eslint/lib/rules/no-useless-concat.js +++ b/tools/eslint/lib/rules/no-useless-concat.js @@ -93,10 +93,11 @@ module.exports = { operatorToken = sourceCode.getTokenAfter(operatorToken); } - context.report( + context.report({ node, - operatorToken.loc.start, - "Unexpected string concatenation of literals."); + loc: operatorToken.loc.start, + message: "Unexpected string concatenation of literals." + }); } } }; diff --git a/tools/eslint/lib/rules/no-useless-escape.js b/tools/eslint/lib/rules/no-useless-escape.js index 629a52a7ec9b9f..b9266bbbafa69a 100644 --- a/tools/eslint/lib/rules/no-useless-escape.js +++ b/tools/eslint/lib/rules/no-useless-escape.js @@ -5,57 +5,70 @@ "use strict"; +const astUtils = require("../ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const VALID_STRING_ESCAPES = [ - "\\", - "n", - "r", - "v", - "t", - "b", - "f", - "u", - "x", - "\n", - "\r" -]; - -const VALID_REGEX_ESCAPES = [ - "\\", - ".", - "-", - "^", - "$", - "*", - "+", - "?", - "{", - "}", - "[", - "]", - "|", - "(", - ")", - "b", - "B", - "c", - "d", - "D", - "f", - "n", - "r", - "s", - "S", - "t", - "v", - "w", - "W", - "x", - "u" -]; +/** +* Returns the union of two sets. +* @param {Set} setA The first set +* @param {Set} setB The second set +* @returns {Set} The union of the two sets +*/ +function union(setA, setB) { + return new Set(function *() { + yield* setA; + yield* setB; + }()); +} + +const VALID_STRING_ESCAPES = new Set("\\nrvtbfux\n\r\u2028\u2029"); +const REGEX_GENERAL_ESCAPES = new Set("\\bcdDfnrsStvwWxu0123456789]"); +const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+?[{}|()B")); + +/** +* Parses a regular expression into a list of characters with character class info. +* @param {string} regExpText The raw text used to create the regular expression +* @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class. +* @example +* +* parseRegExp('a\\b[cd-]') +* +* returns: +* [ +* {text: 'a', index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false}, +* {text: 'b', index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false}, +* {text: 'c', index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false}, +* {text: 'd', index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false}, +* {text: '-', index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false} +* ] +*/ +function parseRegExp(regExpText) { + const charList = []; + + regExpText.split("").reduce((state, char, index) => { + if (!state.escapeNextChar) { + if (char === "\\") { + return Object.assign(state, { escapeNextChar: true }); + } + if (char === "[" && !state.inCharClass) { + return Object.assign(state, { inCharClass: true, startingCharClass: true }); + } + if (char === "]" && state.inCharClass) { + if (charList.length && charList[charList.length - 1].inCharClass) { + charList[charList.length - 1].endsCharClass = true; + } + return Object.assign(state, { inCharClass: false, startingCharClass: false }); + } + } + charList.push({ text: char, index, escaped: state.escapeNextChar, inCharClass: state.inCharClass, startsCharClass: state.startingCharClass, endsCharClass: false }); + return Object.assign(state, { escapeNextChar: false, startingCharClass: false }); + }, { escapeNextChar: false, inCharClass: false, startingCharClass: false }); + + return charList; +} module.exports = { meta: { @@ -69,20 +82,36 @@ module.exports = { }, create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports a node + * @param {ASTNode} node The node to report + * @param {number} startOffset The backslash's offset from the start of the node + * @param {string} character The uselessly escaped character (not including the backslash) + * @returns {void} + */ + function report(node, startOffset, character) { + context.report({ + node, + loc: astUtils.getLocationFromRangeIndex(sourceCode, astUtils.getRangeIndexFromLocation(sourceCode, node.loc.start) + startOffset), + message: "Unnecessary escape character: \\{{character}}.", + data: { character } + }); + } /** - * Checks if the escape character in given slice is unnecessary. + * Checks if the escape character in given string slice is unnecessary. * * @private - * @param {string[]} escapes - list of valid escapes * @param {ASTNode} node - node to validate. * @param {string} match - string slice to validate. * @returns {void} */ - function validate(escapes, node, match) { + function validateString(node, match) { const isTemplateElement = node.type === "TemplateElement"; const escapedChar = match[0][1]; - let isUnnecessaryEscape = escapes.indexOf(escapedChar) === -1; + let isUnnecessaryEscape = !VALID_STRING_ESCAPES.has(escapedChar); let isQuoteEscape; if (isTemplateElement) { @@ -105,17 +134,7 @@ module.exports = { } if (isUnnecessaryEscape && !isQuoteEscape) { - context.report({ - node, - loc: { - line: node.loc.start.line, - column: node.loc.start.column + match.index - }, - message: "Unnecessary escape character: {{character}}.", - data: { - character: match[0] - } - }); + report(node, match.index + 1, match[0].slice(1)); } } @@ -127,10 +146,12 @@ module.exports = { */ function check(node) { const isTemplateElement = node.type === "TemplateElement"; - const value = isTemplateElement ? node.value.raw : node.raw; - const pattern = /\\[^\d]/g; - let nodeEscapes, - match; + + if (isTemplateElement && node.parent && node.parent.parent && node.parent.parent.type === "TaggedTemplateExpression") { + + // Don't report tagged template literals, because the backslash character is accessible to the tag function. + return; + } if (typeof node.value === "string" || isTemplateElement) { @@ -138,20 +159,46 @@ module.exports = { * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/. * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25. */ - if (node.parent.type === "JSXAttribute") { + if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement") { return; } - nodeEscapes = VALID_STRING_ESCAPES; + const value = isTemplateElement ? node.value.raw : node.raw.slice(1, -1); + const pattern = /\\[^\d]/g; + let match; + + while ((match = pattern.exec(value))) { + validateString(node, match); + } } else if (node.regex) { - nodeEscapes = VALID_REGEX_ESCAPES; - } else { - return; - } + parseRegExp(node.regex.pattern) - while ((match = pattern.exec(value))) { - validate(nodeEscapes, node, match); + /* + * The '-' character is a special case, because it's only valid to escape it if it's in a character + * class, and is not at either edge of the character class. To account for this, don't consider '-' + * characters to be valid in general, and filter out '-' characters that appear in the middle of a + * character class. + */ + .filter(charInfo => !(charInfo.text === "-" && charInfo.inCharClass && !charInfo.startsCharClass && !charInfo.endsCharClass)) + + /* + * The '^' character is also a special case; it must always be escaped outside of character classes, but + * it only needs to be escaped in character classes if it's at the beginning of the character class. To + * account for this, consider it to be a valid escape character outside of character classes, and filter + * out '^' characters that appear at the start of a character class. + */ + .filter(charInfo => !(charInfo.text === "^" && charInfo.startsCharClass)) + + // Filter out characters that aren't escaped. + .filter(charInfo => charInfo.escaped) + + // Filter out characters that are valid to escape, based on their position in the regular expression. + .filter(charInfo => !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text)) + + // Report all the remaining characters. + .forEach(charInfo => report(node, charInfo.index, charInfo.text)); } + } return { diff --git a/tools/eslint/lib/rules/no-useless-return.js b/tools/eslint/lib/rules/no-useless-return.js new file mode 100644 index 00000000000000..e2a6da03183501 --- /dev/null +++ b/tools/eslint/lib/rules/no-useless-return.js @@ -0,0 +1,293 @@ +/** + * @fileoverview Disallow redundant return statements + * @author Teddy Katz + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Adds all elements of 2nd argument into 1st argument. + * + * @param {Array} array - The destination array to add. + * @param {Array} elements - The source array to add. + * @returns {void} + */ +const pushAll = Function.apply.bind(Array.prototype.push); + +/** + * Removes the given element from the array. + * + * @param {Array} array - The source array to remove. + * @param {any} element - The target item to remove. + * @returns {void} + */ +function remove(array, element) { + const index = array.indexOf(element); + + if (index !== -1) { + array.splice(index, 1); + } +} + +/** + * Checks whether it can remove the given return statement or not. + * + * @param {ASTNode} node - The return statement node to check. + * @returns {boolean} `true` if the node is removeable. + */ +function isRemovable(node) { + const parent = node.parent; + + return ( + parent.type === "Program" || + parent.type === "BlockStatement" || + parent.type === "SwitchCase" + ); +} + +/** + * Checks whether the given return statement is in a `finally` block or not. + * + * @param {ASTNode} node - The return statement node to check. + * @returns {boolean} `true` if the node is in a `finally` block. + */ +function isInFinally(node) { + while (node && node.parent && !astUtils.isFunction(node)) { + if (node.parent.type === "TryStatement" && node.parent.finalizer === node) { + return true; + } + + node = node.parent; + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow redundant return statements", + category: "Best Practices", + recommended: false + }, + fixable: "code", + schema: [] + }, + + create(context) { + const segmentInfoMap = new WeakMap(); + const usedUnreachableSegments = new WeakSet(); + let scopeInfo = null; + + /** + * Checks whether the given segment is terminated by a return statement or not. + * + * @param {CodePathSegment} segment - The segment to check. + * @returns {boolean} `true` if the segment is terminated by a return statement, or if it's still a part of unreachable. + */ + function isReturned(segment) { + const info = segmentInfoMap.get(segment); + + return !info || info.returned; + } + + /** + * Collects useless return statements from the given previous segments. + * + * A previous segment may be an unreachable segment. + * In that case, the information object of the unreachable segment is not + * initialized because `onCodePathSegmentStart` event is not notified for + * unreachable segments. + * This goes to the previous segments of the unreachable segment recursively + * if the unreachable segment was generated by a return statement. Otherwise, + * this ignores the unreachable segment. + * + * This behavior would simulate code paths for the case that the return + * statement does not exist. + * + * @param {ASTNode[]} uselessReturns - The collected return statements. + * @param {CodePathSegment[]} prevSegments - The previous segments to traverse. + * @param {WeakSet} [traversedSegments] A set of segments that have already been traversed in this call + * @returns {ASTNode[]} `uselessReturns`. + */ + function getUselessReturns(uselessReturns, prevSegments, traversedSegments) { + if (!traversedSegments) { + traversedSegments = new WeakSet(); + } + for (const segment of prevSegments) { + if (!segment.reachable) { + if (!traversedSegments.has(segment)) { + traversedSegments.add(segment); + getUselessReturns( + uselessReturns, + segment.allPrevSegments.filter(isReturned), + traversedSegments + ); + } + continue; + } + + pushAll(uselessReturns, segmentInfoMap.get(segment).uselessReturns); + } + + return uselessReturns; + } + + /** + * Removes the return statements on the given segment from the useless return + * statement list. + * + * This segment may be an unreachable segment. + * In that case, the information object of the unreachable segment is not + * initialized because `onCodePathSegmentStart` event is not notified for + * unreachable segments. + * This goes to the previous segments of the unreachable segment recursively + * if the unreachable segment was generated by a return statement. Otherwise, + * this ignores the unreachable segment. + * + * This behavior would simulate code paths for the case that the return + * statement does not exist. + * + * @param {CodePathSegment} segment - The segment to get return statements. + * @returns {void} + */ + function markReturnStatementsOnSegmentAsUsed(segment) { + if (!segment.reachable) { + usedUnreachableSegments.add(segment); + segment.allPrevSegments + .filter(isReturned) + .filter(prevSegment => !usedUnreachableSegments.has(prevSegment)) + .forEach(markReturnStatementsOnSegmentAsUsed); + return; + } + + const info = segmentInfoMap.get(segment); + + for (const node of info.uselessReturns) { + remove(scopeInfo.uselessReturns, node); + } + info.uselessReturns = []; + } + + /** + * Removes the return statements on the current segments from the useless + * return statement list. + * + * This function will be called at every statement except FunctionDeclaration, + * BlockStatement, and BreakStatement. + * + * - FunctionDeclarations are always executed whether it's returned or not. + * - BlockStatements do nothing. + * - BreakStatements go the next merely. + * + * @returns {void} + */ + function markReturnStatementsOnCurrentSegmentsAsUsed() { + scopeInfo + .codePath + .currentSegments + .forEach(markReturnStatementsOnSegmentAsUsed); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + // Makes and pushs a new scope information. + onCodePathStart(codePath) { + scopeInfo = { + upper: scopeInfo, + uselessReturns: [], + codePath, + }; + }, + + // Reports useless return statements if exist. + onCodePathEnd() { + for (const node of scopeInfo.uselessReturns) { + context.report({ + node, + loc: node.loc, + message: "Unnecessary return statement.", + fix(fixer) { + return isRemovable(node) ? fixer.remove(node) : null; + }, + }); + } + + scopeInfo = scopeInfo.upper; + }, + + // Initializes segments. + // NOTE: This event is notified for only reachable segments. + onCodePathSegmentStart(segment) { + const info = { + uselessReturns: getUselessReturns([], segment.allPrevSegments), + returned: false, + }; + + // Stores the info. + segmentInfoMap.set(segment, info); + }, + + // Adds ReturnStatement node to check whether it's useless or not. + ReturnStatement(node) { + if (node.argument) { + markReturnStatementsOnCurrentSegmentsAsUsed(); + } + if (node.argument || astUtils.isInLoop(node) || isInFinally(node)) { + return; + } + + for (const segment of scopeInfo.codePath.currentSegments) { + const info = segmentInfoMap.get(segment); + + if (info) { + info.uselessReturns.push(node); + info.returned = true; + } + } + scopeInfo.uselessReturns.push(node); + }, + + // Registers for all statement nodes except FunctionDeclaration, BlockStatement, BreakStatement. + // Removes return statements of the current segments from the useless return statement list. + ClassDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ContinueStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + DebuggerStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + DoWhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + EmptyStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ExpressionStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForInStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForOfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + IfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ImportDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + LabeledStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + SwitchStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ThrowStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + TryStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + VariableDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + WhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + WithStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportNamedDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportDefaultDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportAllDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + }; + } +}; diff --git a/tools/eslint/lib/rules/no-var.js b/tools/eslint/lib/rules/no-var.js index 0e98170e65e7c1..3c22f009c63bb6 100644 --- a/tools/eslint/lib/rules/no-var.js +++ b/tools/eslint/lib/rules/no-var.js @@ -5,10 +5,67 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ +/** + * Finds the nearest function scope or global scope walking up the scope + * hierarchy. + * + * @param {escope.Scope} scope - The scope to traverse. + * @returns {escope.Scope} a function scope or global scope containing the given + * scope. + */ +function getEnclosingFunctionScope(scope) { + while (scope.type !== "function" && scope.type !== "global") { + scope = scope.upper; + } + return scope; +} + +/** + * Checks whether the given variable has any references from a more specific + * function expression (i.e. a closure). + * + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is used from a closure. + */ +function isReferencedInClosure(variable) { + const enclosingFunctionScope = getEnclosingFunctionScope(variable.scope); + + return variable.references.some(reference => + getEnclosingFunctionScope(reference.from) !== enclosingFunctionScope); +} + +/** + * Checks whether the given node is the assignee of a loop. + * + * @param {ASTNode} node - A VariableDeclaration node to check. + * @returns {boolean} `true` if the declaration is assigned as part of loop + * iteration. + */ +function isLoopAssignee(node) { + return (node.parent.type === "ForOfStatement" || node.parent.type === "ForInStatement") && + node === node.parent.left; +} + +/** + * Checks whether the given variable declaration is immediately initialized. + * + * @param {ASTNode} node - A VariableDeclaration node to check. + * @returns {boolean} `true` if the declaration has an initializer. + */ +function isDeclarationInitialized(node) { + return node.declarations.every(declarator => declarator.init !== null); +} + const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/; /** @@ -97,6 +154,8 @@ module.exports = { * - A variable is declared on a SwitchCase node. * - A variable is redeclared. * - A variable is used from outside the scope. + * - A variable is used from a closure within a loop. + * - A variable might be used before it is assigned within a loop. * * ## A variable is declared on a SwitchCase node. * @@ -115,6 +174,25 @@ module.exports = { * The language spec disallows accesses from outside of the scope for * `let` declarations. Those variables would cause reference errors. * + * ## A variable is used from a closure within a loop. + * + * A `var` declaration within a loop shares the same variable instance + * across all loop iterations, while a `let` declaration creates a new + * instance for each iteration. This means if a variable in a loop is + * referenced by any closure, changing it from `var` to `let` would + * change the behavior in a way that is generally unsafe. + * + * ## A variable might be used before it is assigned within a loop. + * + * Within a loop, a `let` declaration without an initializer will be + * initialized to null, while a `var` declaration will retain its value + * from the previous iteration, so it is only safe to change `var` to + * `let` if we can statically determine that the variable is always + * assigned a value before its first access in the loop body. To keep + * the implementation simple, we only convert `var` to `let` within + * loops when the variable is a loop assignee or the declaration has an + * initializer. + * * @param {ASTNode} node - A variable declaration node to check. * @returns {boolean} `true` if it can fix the node. */ @@ -122,11 +200,22 @@ module.exports = { const variables = context.getDeclaredVariables(node); const scopeNode = getScopeNode(node); - return !( - node.parent.type === "SwitchCase" || - variables.some(isRedeclared) || - variables.some(isUsedFromOutsideOf(scopeNode)) - ); + if (node.parent.type === "SwitchCase" || + variables.some(isRedeclared) || + variables.some(isUsedFromOutsideOf(scopeNode))) { + return false; + } + + if (astUtils.isInLoop(node)) { + if (variables.some(isReferencedInClosure)) { + return false; + } + if (!isLoopAssignee(node) && !isDeclarationInitialized(node)) { + return false; + } + } + + return true; } /** diff --git a/tools/eslint/lib/rules/no-void.js b/tools/eslint/lib/rules/no-void.js index 16a36fb3a56df1..5202fa49a8543a 100644 --- a/tools/eslint/lib/rules/no-void.js +++ b/tools/eslint/lib/rules/no-void.js @@ -28,7 +28,7 @@ module.exports = { return { UnaryExpression(node) { if (node.operator === "void") { - context.report(node, "Expected 'undefined' and instead saw 'void'."); + context.report({ node, message: "Expected 'undefined' and instead saw 'void'." }); } } }; diff --git a/tools/eslint/lib/rules/no-warning-comments.js b/tools/eslint/lib/rules/no-warning-comments.js index 511bd9bb48d6ed..bda43086865a1c 100644 --- a/tools/eslint/lib/rules/no-warning-comments.js +++ b/tools/eslint/lib/rules/no-warning-comments.js @@ -54,7 +54,7 @@ module.exports = { * @returns {RegExp} The term converted to a RegExp */ function convertToRegExp(term) { - const escaped = term.replace(/[-\/\\$\^*+?.()|\[\]{}]/g, "\\$&"); + const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/g, "\\$&"); let prefix; /* @@ -95,7 +95,7 @@ module.exports = { function commentContainsWarningTerm(comment) { const matches = []; - warningRegExps.forEach(function(regex, index) { + warningRegExps.forEach((regex, index) => { if (regex.test(comment)) { matches.push(warningTerms[index]); } @@ -116,7 +116,7 @@ module.exports = { const matches = commentContainsWarningTerm(node.value); - matches.forEach(function(matchedTerm) { + matches.forEach(matchedTerm => { context.report({ node, message: "Unexpected '{{matchedTerm}}' comment.", diff --git a/tools/eslint/lib/rules/no-with.js b/tools/eslint/lib/rules/no-with.js index 6d5bfd8e61605e..be9e3463606404 100644 --- a/tools/eslint/lib/rules/no-with.js +++ b/tools/eslint/lib/rules/no-with.js @@ -24,7 +24,7 @@ module.exports = { return { WithStatement(node) { - context.report(node, "Unexpected use of 'with' statement."); + context.report({ node, message: "Unexpected use of 'with' statement." }); } }; diff --git a/tools/eslint/lib/rules/object-curly-newline.js b/tools/eslint/lib/rules/object-curly-newline.js index 3ba786a6f1e2c2..88fc79463cb6ae 100644 --- a/tools/eslint/lib/rules/object-curly-newline.js +++ b/tools/eslint/lib/rules/object-curly-newline.js @@ -61,7 +61,7 @@ function normalizeOptionValue(value) { multiline = true; } - return {multiline, minProperties}; + return { multiline, minProperties }; } /** @@ -80,7 +80,7 @@ function normalizeOptions(options) { const value = normalizeOptionValue(options); - return {ObjectExpression: value, ObjectPattern: value}; + return { ObjectExpression: value, ObjectPattern: value }; } //------------------------------------------------------------------------------ diff --git a/tools/eslint/lib/rules/object-property-newline.js b/tools/eslint/lib/rules/object-property-newline.js index f06cb41843e534..a64420be93a910 100644 --- a/tools/eslint/lib/rules/object-property-newline.js +++ b/tools/eslint/lib/rules/object-property-newline.js @@ -27,7 +27,9 @@ module.exports = { }, additionalProperties: false } - ] + ], + + fixable: "whitespace" }, create(context) { @@ -61,7 +63,18 @@ module.exports = { context.report({ node, loc: firstTokenOfCurrentProperty.loc.start, - message: errorMessage + message: errorMessage, + fix(fixer) { + const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty); + const rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]]; + + // Don't perform a fix if there are any comments between the comma and the next property. + if (sourceCode.text.slice(rangeAfterComma[0], rangeAfterComma[1]).trim()) { + return null; + } + + return fixer.replaceTextRange(rangeAfterComma, "\n"); + } }); } } diff --git a/tools/eslint/lib/rules/object-shorthand.js b/tools/eslint/lib/rules/object-shorthand.js index 3ef782461a4018..43997f90692de5 100644 --- a/tools/eslint/lib/rules/object-shorthand.js +++ b/tools/eslint/lib/rules/object-shorthand.js @@ -77,6 +77,9 @@ module.exports = { }, avoidQuotes: { type: "boolean" + }, + avoidExplicitReturnArrows: { + type: "boolean" } }, additionalProperties: false @@ -100,6 +103,8 @@ module.exports = { const PARAMS = context.options[1] || {}; const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; const AVOID_QUOTES = PARAMS.avoidQuotes; + const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows; + const sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -188,7 +193,7 @@ module.exports = { // We have at least 1 shorthand property if (shorthandProperties.length > 0) { - context.report(node, "Unexpected mix of shorthand and non-shorthand properties."); + context.report({ node, message: "Unexpected mix of shorthand and non-shorthand properties." }); } else if (checkRedundancy) { // If all properties of the object contain a method or value with a name matching it's key, @@ -196,18 +201,143 @@ module.exports = { const canAlwaysUseShorthand = properties.every(isRedundant); if (canAlwaysUseShorthand) { - context.report(node, "Expected shorthand for all properties."); + context.report({ node, message: "Expected shorthand for all properties." }); } } } } } + /** + * Fixes a FunctionExpression node by making it into a shorthand property. + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value + * @returns {Object} A fix for this node + */ + function makeFunctionShorthand(fixer, node) { + const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key); + const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key); + const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); + let keyPrefix = ""; + + if (node.value.generator) { + keyPrefix = "*"; + } else if (node.value.async) { + keyPrefix = "async "; + } + + if (node.value.type === "FunctionExpression") { + const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function"); + const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken; + + return fixer.replaceTextRange([firstKeyToken.range[0], tokenBeforeParams.range[1]], keyPrefix + keyText); + } else { + const arrowToken = sourceCode.getTokens(node.value).find(token => token.value === "=>"); + const tokenBeforeArrow = sourceCode.getTokenBefore(arrowToken); + const hasParensAroundParameters = tokenBeforeArrow.type === "Punctuator" && tokenBeforeArrow.value === ")"; + const oldParamText = sourceCode.text.slice(sourceCode.getFirstToken(node.value, node.value.async ? 1 : 0).range[0], tokenBeforeArrow.range[1]); + const newParamText = hasParensAroundParameters ? oldParamText : `(${oldParamText})`; + + return fixer.replaceTextRange([firstKeyToken.range[0], arrowToken.range[1]], keyPrefix + keyText + newParamText); + } + } + + /** + * Fixes a FunctionExpression node by making it into a longform property. + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value + * @returns {Object} A fix for this node + */ + function makeFunctionLongform(fixer, node) { + const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key); + const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key); + const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); + let functionHeader = "function"; + + if (node.value.generator) { + functionHeader = "function*"; + } else if (node.value.async) { + functionHeader = "async function"; + } + + return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`); + } + + /* + * To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`), + * create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is + * traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical + * scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered, + * keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited. + * When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them + * to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule, + * because converting it into a method would change the value of one of the lexical identifiers. + */ + const lexicalScopeStack = []; + const arrowsWithLexicalIdentifiers = new WeakSet(); + const argumentsIdentifiers = new WeakSet(); + + /** + * Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack. + * Also, this marks all `arguments` identifiers so that they can be detected later. + * @returns {void} + */ + function enterFunction() { + lexicalScopeStack.unshift(new Set()); + context.getScope().variables.filter(variable => variable.name === "arguments").forEach(variable => { + variable.references.map(ref => ref.identifier).forEach(identifier => argumentsIdentifiers.add(identifier)); + }); + } + + /** + * Exits a function. This pops the current set of arrow functions off the lexical scope stack. + * @returns {void} + */ + function exitFunction() { + lexicalScopeStack.shift(); + } + + /** + * Marks the current function as having a lexical keyword. This implies that all arrow functions + * in the current lexical scope contain a reference to this lexical keyword. + * @returns {void} + */ + function reportLexicalIdentifier() { + lexicalScopeStack[0].forEach(arrowFunction => arrowsWithLexicalIdentifiers.add(arrowFunction)); + } + //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { + Program: enterFunction, + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + "Program:exit": exitFunction, + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + + ArrowFunctionExpression(node) { + lexicalScopeStack[0].add(node); + }, + "ArrowFunctionExpression:exit"(node) { + lexicalScopeStack[0].delete(node); + }, + + ThisExpression: reportLexicalIdentifier, + Super: reportLexicalIdentifier, + MetaProperty(node) { + if (node.meta.name === "new" && node.property.name === "target") { + reportLexicalIdentifier(); + } + }, + Identifier(node) { + if (argumentsIdentifiers.has(node)) { + reportLexicalIdentifier(); + } + }, + ObjectExpression(node) { if (APPLY_CONSISTENT) { checkConsistency(node, false); @@ -216,7 +346,7 @@ module.exports = { } }, - Property(node) { + "Property:exit"(node) { const isConciseProperty = node.method || node.shorthand; // Ignore destructuring assignment @@ -230,59 +360,31 @@ module.exports = { } // only computed methods can fail the following checks - if (node.computed && node.value.type !== "FunctionExpression") { + if (node.computed && node.value.type !== "FunctionExpression" && node.value.type !== "ArrowFunctionExpression") { return; } //-------------------------------------------------------------- // Checks for property/method shorthand. if (isConciseProperty) { + if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) { - // if we're "never" and concise we should warn now - if (APPLY_NEVER) { - const type = node.method ? "method" : "property"; - + // { x() {} } should be written as { x: function() {} } context.report({ node, - message: "Expected longform {{type}} syntax.", - data: { - type - }, - fix(fixer) { - if (node.method) { - if (node.value.generator) { - return fixer.replaceTextRange([node.range[0], node.key.range[1]], `${node.key.name}: function*`); - } - - return fixer.insertTextAfter(node.key, ": function"); - } - - return fixer.insertTextAfter(node.key, `: ${node.key.name}`); - } + message: `Expected longform method syntax${APPLY_NEVER ? "" : " for string literal keys"}.`, + fix: fixer => makeFunctionLongform(fixer, node) }); - } + } else if (APPLY_NEVER) { - // {'xyz'() {}} should be written as {'xyz': function() {}} - if (AVOID_QUOTES && isStringLiteral(node.key)) { + // { x } should be written as { x: x } context.report({ node, - message: "Expected longform method syntax for string literal keys.", - fix(fixer) { - if (node.computed) { - return fixer.insertTextAfterRange([node.key.range[0], node.key.range[1] + 1], ": function"); - } - - return fixer.insertTextAfter(node.key, ": function"); - } + message: "Expected longform property syntax.", + fix: fixer => fixer.insertTextAfter(node.key, `: ${node.key.name}`) }); } - - return; - } - - //-------------------------------------------------------------- - // Checks for longform properties. - if (node.value.type === "FunctionExpression" && !node.value.id && APPLY_TO_METHODS) { + } else if (APPLY_TO_METHODS && !node.value.id && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) { if (IGNORE_CONSTRUCTORS && isConstructor(node.key.name)) { return; } @@ -291,39 +393,18 @@ module.exports = { } // {[x]: function(){}} should be written as {[x]() {}} - if (node.computed) { + if (node.value.type === "FunctionExpression" || + node.value.type === "ArrowFunctionExpression" && + node.value.body.type === "BlockStatement" && + AVOID_EXPLICIT_RETURN_ARROWS && + !arrowsWithLexicalIdentifiers.has(node.value) + ) { context.report({ node, message: "Expected method shorthand.", - fix(fixer) { - if (node.value.generator) { - return fixer.replaceTextRange( - [node.key.range[0], node.value.range[0] + "function*".length], - `*[${node.key.name}]` - ); - } - - return fixer.removeRange([node.key.range[1] + 1, node.value.range[0] + "function".length]); - } + fix: fixer => makeFunctionShorthand(fixer, node) }); - return; } - - // {x: function(){}} should be written as {x() {}} - context.report({ - node, - message: "Expected method shorthand.", - fix(fixer) { - if (node.value.generator) { - return fixer.replaceTextRange( - [node.key.range[0], node.value.range[0] + "function*".length], - `*${node.key.name}` - ); - } - - return fixer.removeRange([node.key.range[1], node.value.range[0] + "function".length]); - } - }); } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) { // {x: x} should be written as {x} diff --git a/tools/eslint/lib/rules/one-var-declaration-per-line.js b/tools/eslint/lib/rules/one-var-declaration-per-line.js index eb0d5c3bf1ad74..61b505c82d5d71 100644 --- a/tools/eslint/lib/rules/one-var-declaration-per-line.js +++ b/tools/eslint/lib/rules/one-var-declaration-per-line.js @@ -59,7 +59,7 @@ module.exports = { const declarations = node.declarations; let prev; - declarations.forEach(function(current) { + declarations.forEach(current => { if (prev && prev.loc.end.line === current.loc.start.line) { if (always || prev.init || current.init) { context.report({ diff --git a/tools/eslint/lib/rules/one-var.js b/tools/eslint/lib/rules/one-var.js index 27166559714065..9e40d4ea6f26c1 100644 --- a/tools/eslint/lib/rules/one-var.js +++ b/tools/eslint/lib/rules/one-var.js @@ -66,18 +66,18 @@ module.exports = { }; if (typeof mode === "string") { // simple options configuration with just a string - options.var = { uninitialized: mode, initialized: mode}; - options.let = { uninitialized: mode, initialized: mode}; - options.const = { uninitialized: mode, initialized: mode}; + options.var = { uninitialized: mode, initialized: mode }; + options.let = { uninitialized: mode, initialized: mode }; + options.const = { uninitialized: mode, initialized: mode }; } else if (typeof mode === "object") { // options configuration is an object if (mode.hasOwnProperty("var") && typeof mode.var === "string") { - options.var = { uninitialized: mode.var, initialized: mode.var}; + options.var = { uninitialized: mode.var, initialized: mode.var }; } if (mode.hasOwnProperty("let") && typeof mode.let === "string") { - options.let = { uninitialized: mode.let, initialized: mode.let}; + options.let = { uninitialized: mode.let, initialized: mode.let }; } if (mode.hasOwnProperty("const") && typeof mode.const === "string") { - options.const = { uninitialized: mode.const, initialized: mode.const}; + options.const = { uninitialized: mode.const, initialized: mode.const }; } if (mode.hasOwnProperty("uninitialized")) { if (!options.var) { @@ -123,8 +123,8 @@ module.exports = { */ function startBlock() { blockStack.push({ - let: {initialized: false, uninitialized: false}, - const: {initialized: false, uninitialized: false} + let: { initialized: false, uninitialized: false }, + const: { initialized: false, uninitialized: false } }); } @@ -134,7 +134,7 @@ module.exports = { * @private */ function startFunction() { - functionStack.push({initialized: false, uninitialized: false}); + functionStack.push({ initialized: false, uninitialized: false }); startBlock(); } diff --git a/tools/eslint/lib/rules/operator-assignment.js b/tools/eslint/lib/rules/operator-assignment.js index 5e1dd97b996bc7..e003478c7bc427 100644 --- a/tools/eslint/lib/rules/operator-assignment.js +++ b/tools/eslint/lib/rules/operator-assignment.js @@ -70,6 +70,17 @@ function same(a, b) { } } +/** +* Determines if the left side of a node can be safely fixed (i.e. if it activates the same getters/setters and) +* toString calls regardless of whether assignment shorthand is used) +* @param {ASTNode} node The node on the left side of the expression +* @returns {boolean} `true` if the node can be fixed +*/ +function canBeFixed(node) { + return node.type === "Identifier" || + node.type === "MemberExpression" && node.object.type === "Identifier" && (!node.computed || node.property.type === "Literal"); +} + module.exports = { meta: { docs: { @@ -82,11 +93,24 @@ module.exports = { { enum: ["always", "never"] } - ] + ], + + fixable: "code" }, create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Returns the operator token of an AssignmentExpression or BinaryExpression + * @param {ASTNode} node An AssignmentExpression or BinaryExpression node + * @returns {Token} The operator token in the node + */ + function getOperatorToken(node) { + return sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + } + /** * Ensures that an assignment uses the shorthand form where possible. * @param {ASTNode} node An AssignmentExpression node. @@ -101,13 +125,34 @@ module.exports = { const expr = node.right; const operator = expr.operator; - if (isCommutativeOperatorWithShorthand(operator)) { - if (same(left, expr.left) || same(left, expr.right)) { - context.report(node, "Assignment can be replaced with operator assignment."); - } - } else if (isNonCommutativeOperatorWithShorthand(operator)) { + if (isCommutativeOperatorWithShorthand(operator) || isNonCommutativeOperatorWithShorthand(operator)) { if (same(left, expr.left)) { - context.report(node, "Assignment can be replaced with operator assignment."); + context.report({ + node, + message: "Assignment can be replaced with operator assignment.", + fix(fixer) { + if (canBeFixed(left)) { + const equalsToken = getOperatorToken(node); + const operatorToken = getOperatorToken(expr); + const leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]); + const rightText = sourceCode.getText().slice(operatorToken.range[1], node.range[1]); + + return fixer.replaceText(node, `${leftText}${expr.operator}=${rightText}`); + } + return null; + } + }); + } else if (same(left, expr.right) && isCommutativeOperatorWithShorthand(operator)) { + + /* + * This case can't be fixed safely. + * If `a` and `b` both have custom valueOf() behavior, then fixing `a = b * a` to `a *= b` would + * change the execution order of the valueOf() functions. + */ + context.report({ + node, + message: "Assignment can be replaced with operator assignment." + }); } } } @@ -119,7 +164,20 @@ module.exports = { */ function prohibit(node) { if (node.operator !== "=") { - context.report(node, "Unexpected operator assignment shorthand."); + context.report({ + node, + message: "Unexpected operator assignment shorthand.", + fix(fixer) { + if (canBeFixed(node.left)) { + const operatorToken = getOperatorToken(node); + const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]); + const rightText = sourceCode.getText().slice(operatorToken.range[1], node.range[1]); + + return fixer.replaceText(node, `${leftText}= ${leftText}${node.operator.slice(0, -1)}${rightText}`); + } + return null; + } + }); } } diff --git a/tools/eslint/lib/rules/operator-linebreak.js b/tools/eslint/lib/rules/operator-linebreak.js index ce222526e1d410..c8f2b2818e23b2 100644 --- a/tools/eslint/lib/rules/operator-linebreak.js +++ b/tools/eslint/lib/rules/operator-linebreak.js @@ -11,6 +11,8 @@ const astUtils = require("../ast-utils"); // Rule Definition //------------------------------------------------------------------------------ +const LINEBREAK_REGEX = /\r\n|\r|\n|\u2028|\u2029/g; + module.exports = { meta: { docs: { @@ -38,7 +40,9 @@ module.exports = { }, additionalProperties: false } - ] + ], + + fixable: "code" }, create(context) { @@ -62,6 +66,61 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- + /** + * Gets a fixer function to fix rule issues + * @param {Token} operatorToken The operator token of an expression + * @param {string} desiredStyle The style for the rule. One of 'before', 'after', 'none' + * @returns {Function} A fixer function + */ + function getFixer(operatorToken, desiredStyle) { + return fixer => { + const tokenBefore = sourceCode.getTokenBefore(operatorToken); + const tokenAfter = sourceCode.getTokenAfter(operatorToken); + const textBefore = sourceCode.text.slice(tokenBefore.range[1], operatorToken.range[0]); + const textAfter = sourceCode.text.slice(operatorToken.range[1], tokenAfter.range[0]); + const hasLinebreakBefore = !astUtils.isTokenOnSameLine(tokenBefore, operatorToken); + const hasLinebreakAfter = !astUtils.isTokenOnSameLine(operatorToken, tokenAfter); + let newTextBefore, newTextAfter; + + if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") { + + // If there is a comment before and after the operator, don't do a fix. + if (sourceCode.getTokenOrCommentBefore(operatorToken) !== tokenBefore && sourceCode.getTokenOrCommentAfter(operatorToken) !== tokenAfter) { + return null; + } + + /* + * If there is only one linebreak and it's on the wrong side of the operator, swap the text before and after the operator. + * foo && + * bar + * would get fixed to + * foo + * && bar + */ + newTextBefore = textAfter; + newTextAfter = textBefore; + } else { + + // Otherwise, if no linebreak is desired and no comments interfere, replace the linebreaks with empty strings. + newTextBefore = desiredStyle === "before" || textBefore.trim() ? textBefore : textBefore.replace(LINEBREAK_REGEX, ""); + newTextAfter = desiredStyle === "after" || textAfter.trim() ? textAfter : textAfter.replace(LINEBREAK_REGEX, ""); + + // If there was no change (due to interfering comments), don't output a fix. + if (newTextBefore === textBefore && newTextAfter === textAfter) { + return null; + } + } + + if (newTextAfter === "" && tokenAfter.type === "Punctuator" && "+-".includes(operatorToken.value) && tokenAfter.value === operatorToken.value) { + + // To avoid accidentally creating a ++ or -- operator, insert a space if the operator is a +/- and the following token is a unary +/-. + newTextAfter += " "; + } + + return fixer.replaceTextRange([tokenBefore.range[1], tokenAfter.range[0]], newTextBefore + operatorToken.value + newTextAfter); + }; + } + /** * Checks the operator placement * @param {ASTNode} node The node to check @@ -87,12 +146,13 @@ module.exports = { const operator = operatorToken.value; const operatorStyleOverride = styleOverrides[operator]; const style = operatorStyleOverride || globalStyle; + const fix = getFixer(operatorToken, style); // if single line if (astUtils.isTokenOnSameLine(leftToken, operatorToken) && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { - return; + // do nothing. } else if (operatorStyleOverride !== "ignore" && !astUtils.isTokenOnSameLine(leftToken, operatorToken) && !astUtils.isTokenOnSameLine(operatorToken, rightToken)) { @@ -107,7 +167,8 @@ module.exports = { message: "Bad line breaking before and after '{{operator}}'.", data: { operator - } + }, + fix }); } else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) { @@ -121,7 +182,8 @@ module.exports = { message: "'{{operator}}' should be placed at the beginning of the line.", data: { operator - } + }, + fix }); } else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { @@ -135,7 +197,8 @@ module.exports = { message: "'{{operator}}' should be placed at the end of the line.", data: { operator - } + }, + fix }); } else if (style === "none") { @@ -149,7 +212,8 @@ module.exports = { message: "There should be no line break before or after '{{operator}}'.", data: { operator - } + }, + fix }); } diff --git a/tools/eslint/lib/rules/padded-blocks.js b/tools/eslint/lib/rules/padded-blocks.js index a24d421b0f4f23..2b4da39b360214 100644 --- a/tools/eslint/lib/rules/padded-blocks.js +++ b/tools/eslint/lib/rules/padded-blocks.js @@ -173,7 +173,7 @@ module.exports = { if (!blockHasBottomPadding) { context.report({ node, - loc: {line: closeBrace.loc.end.line, column: closeBrace.loc.end.column - 1 }, + loc: { line: closeBrace.loc.end.line, column: closeBrace.loc.end.column - 1 }, fix(fixer) { return fixer.insertTextBefore(closeBrace, "\n"); }, @@ -199,7 +199,7 @@ module.exports = { context.report({ node, - loc: {line: closeBrace.loc.end.line, column: closeBrace.loc.end.column - 1 }, + loc: { line: closeBrace.loc.end.line, column: closeBrace.loc.end.column - 1 }, message: NEVER_MESSAGE, fix(fixer) { return fixer.replaceTextRange([previousToken.end, closeBrace.start - closeBrace.loc.start.column], "\n"); diff --git a/tools/eslint/lib/rules/prefer-arrow-callback.js b/tools/eslint/lib/rules/prefer-arrow-callback.js index 034112093bd405..ee385042f1309e 100644 --- a/tools/eslint/lib/rules/prefer-arrow-callback.js +++ b/tools/eslint/lib/rules/prefer-arrow-callback.js @@ -63,7 +63,7 @@ function getVariableOfArguments(scope) { * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. */ function getCallbackInfo(node) { - const retv = {isCallback: false, isLexicalThis: false}; + const retv = { isCallback: false, isLexicalThis: false }; let parent = node.parent; while (node) { @@ -176,7 +176,7 @@ module.exports = { * @returns {void} */ function enterScope() { - stack.push({this: false, super: false, meta: false}); + stack.push({ this: false, super: false, meta: false }); } /** diff --git a/tools/eslint/lib/rules/prefer-const.js b/tools/eslint/lib/rules/prefer-const.js index 5255f2745c9384..07d8da82a105c4 100644 --- a/tools/eslint/lib/rules/prefer-const.js +++ b/tools/eslint/lib/rules/prefer-const.js @@ -5,12 +5,6 @@ "use strict"; -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const lodash = require("lodash"); - //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ @@ -91,6 +85,17 @@ function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { return null; } + /* + * Due to a bug in acorn, code such as `let foo = 1; let foo = 2;` will not throw a syntax error. As a sanity + * check, make sure that the variable only has one declaration. After the parsing bug is fixed, this check + * will no longer be necessary, because variables declared with `let` or `const` should always have exactly one + * declaration. + * https://github.com/ternjs/acorn/issues/487 + */ + if (variable.defs.length > 1) { + return null; + } + // Finds the unique WriteReference. let writer = null; let isReadBeforeInit = false; @@ -244,8 +249,8 @@ module.exports = { { type: "object", properties: { - destructuring: {enum: ["any", "all"]}, - ignoreReadBeforeAssign: {type: "boolean"} + destructuring: { enum: ["any", "all"] }, + ignoreReadBeforeAssign: { type: "boolean" } }, additionalProperties: false } @@ -254,80 +259,10 @@ module.exports = { create(context) { const options = context.options[0] || {}; + const sourceCode = context.getSourceCode(); const checkingMixedDestructuring = options.destructuring !== "all"; const ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; - let variables = null; - - /** - * Reports a given Identifier node. - * - * @param {ASTNode} node - An Identifier node to report. - * @returns {void} - */ - function report(node) { - const reportArgs = { - node, - message: "'{{name}}' is never reassigned. Use 'const' instead.", - data: node - }, - varDeclParent = findUp(node, "VariableDeclaration", function(parentNode) { - return lodash.endsWith(parentNode.type, "Statement"); - }), - isNormalVarDecl = (node.parent.parent.parent.type === "ForInStatement" || - node.parent.parent.parent.type === "ForOfStatement" || - node.parent.init), - - isDestructuringVarDecl = - - // {let {a} = obj} should be written as {const {a} = obj} - (node.parent.parent.type === "ObjectPattern" && - - // If options.destucturing is "all", then this warning will not occur unless - // every assignment in the destructuring should be const. In that case, it's safe - // to apply the fix. Otherwise, it's safe to apply the fix if there's only one - // assignment occurring. If there is more than one assignment and options.destructuring - // is not "all", then it's not clear how the developer would want to resolve the issue, - // so we should not attempt to do it programmatically. - (options.destructuring === "all" || node.parent.parent.properties.length === 1)) || - - // {let [a] = [1]} should be written as {const [a] = [1]} - (node.parent.type === "ArrayPattern" && - - // See note above about fixing multiple warnings at once. - (options.destructuring === "all" || node.parent.elements.length === 1)); - - if (varDeclParent && - (isNormalVarDecl || isDestructuringVarDecl) && - - // If there are multiple variable declarations, like {let a = 1, b = 2}, then - // do not attempt to fix if one of the declarations should be `const`. It's - // too hard to know how the developer would want to automatically resolve the issue. - varDeclParent.declarations.length === 1) { - - reportArgs.fix = function(fixer) { - return fixer.replaceTextRange( - [varDeclParent.start, varDeclParent.start + "let".length], - "const" - ); - }; - } - - context.report(reportArgs); - } - - /** - * Reports a given variable if the variable should be declared as const. - * - * @param {escope.Variable} variable - A variable to report. - * @returns {void} - */ - function checkVariable(variable) { - const node = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); - - if (node) { - report(node); - } - } + const variables = []; /** * Reports given identifier nodes if all of the nodes should be declared @@ -344,25 +279,39 @@ module.exports = { * @returns {void} */ function checkGroup(nodes) { - if (nodes.every(Boolean)) { - nodes.forEach(report); + const nodesToReport = nodes.filter(Boolean); + + if (nodes.length && (checkingMixedDestructuring || nodesToReport.length === nodes.length)) { + const varDeclParent = findUp(nodes[0], "VariableDeclaration", parentNode => parentNode.type.endsWith("Statement")); + const shouldFix = varDeclParent && + + // If there are multiple variable declarations, like {let a = 1, b = 2}, then + // do not attempt to fix if one of the declarations should be `const`. It's + // too hard to know how the developer would want to automatically resolve the issue. + varDeclParent.declarations.length === 1 && + + // Don't do a fix unless the variable is initialized (or it's in a for-in or for-of loop) + (varDeclParent.parent.type === "ForInStatement" || varDeclParent.parent.type === "ForOfStatement" || varDeclParent.declarations[0].init) && + + // If options.destucturing is "all", then this warning will not occur unless + // every assignment in the destructuring should be const. In that case, it's safe + // to apply the fix. + nodesToReport.length === nodes.length; + + nodesToReport.forEach(node => { + context.report({ + node, + message: "'{{name}}' is never reassigned. Use 'const' instead.", + data: node, + fix: shouldFix ? fixer => fixer.replaceText(sourceCode.getFirstToken(varDeclParent), "const") : null + }); + }); } } return { - Program() { - variables = []; - }, - "Program:exit"() { - if (checkingMixedDestructuring) { - variables.forEach(checkVariable); - } else { - groupByDestructuring(variables, ignoreReadBeforeAssign) - .forEach(checkGroup); - } - - variables = null; + groupByDestructuring(variables, ignoreReadBeforeAssign).forEach(checkGroup); }, VariableDeclaration(node) { diff --git a/tools/eslint/lib/rules/prefer-destructuring.js b/tools/eslint/lib/rules/prefer-destructuring.js new file mode 100644 index 00000000000000..c3fbcaa6310fc8 --- /dev/null +++ b/tools/eslint/lib/rules/prefer-destructuring.js @@ -0,0 +1,173 @@ +/** + * @fileoverview Prefer destructuring from arrays and objects + * @author Alex LaFroscia + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require destructuring from arrays and/or objects", + category: "ECMAScript 6", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + array: { + type: "boolean" + }, + object: { + type: "boolean" + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + enforceForRenamedProperties: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + create(context) { + + let checkArrays = true; + let checkObjects = true; + let enforceForRenamedProperties = false; + const enabledTypes = context.options[0]; + const additionalOptions = context.options[1]; + + if (enabledTypes) { + if (typeof enabledTypes.array !== "undefined") { + checkArrays = enabledTypes.array; + } + + if (typeof enabledTypes.object !== "undefined") { + checkObjects = enabledTypes.object; + } + } + + if (additionalOptions) { + if (typeof additionalOptions.enforceForRenamedProperties !== "undefined") { + enforceForRenamedProperties = additionalOptions.enforceForRenamedProperties; + } + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if the given node node is accessing an array index + * + * This is used to differentiate array index access from object property + * access. + * + * @param {ASTNode} node the node to evaluate + * @returns {boolean} whether or not the node is an integer + */ + function isArrayIndexAccess(node) { + return Number.isInteger(node.property.value); + } + + /** + * Report that the given node should use destructuring + * + * @param {ASTNode} reportNode the node to report + * @param {string} type the type of destructuring that should have been done + * @returns {void} + */ + function report(reportNode, type) { + context.report({ node: reportNode, message: `Use ${type} destructuring` }); + } + + /** + * Check that the `prefer-destructuring` rules are followed based on the + * given left- and right-hand side of the assignment. + * + * Pulled out into a separate method so that VariableDeclarators and + * AssignmentExpressions can share the same verification logic. + * + * @param {ASTNode} leftNode the left-hand side of the assignment + * @param {ASTNode} rightNode the right-hand side of the assignment + * @param {ASTNode} reportNode the node to report the error on + * @returns {void} + */ + function performCheck(leftNode, rightNode, reportNode) { + if (rightNode.type !== "MemberExpression") { + return; + } + + if (checkArrays && isArrayIndexAccess(rightNode)) { + report(reportNode, "array"); + return; + } + + if (checkObjects && enforceForRenamedProperties) { + report(reportNode, "object"); + return; + } + + if (checkObjects) { + const property = rightNode.property; + + if ((property.type === "Literal" && leftNode.name === property.value) || + (property.type === "Identifier" && leftNode.name === property.name)) { + report(reportNode, "object"); + } + } + } + + /** + * Check if a given variable declarator is coming from an property access + * that should be using destructuring instead + * + * @param {ASTNode} node the variable declarator to check + * @returns {void} + */ + function checkVariableDeclarator(node) { + + // Skip if variable is declared without assignment + if (!node.init) { + return; + } + + // We only care about member expressions past this point + if (node.init.type !== "MemberExpression") { + return; + } + + performCheck(node.id, node.init, node); + } + + /** + * Run the `prefer-destructuring` check on an AssignmentExpression + * + * @param {ASTNode} node the AssignmentExpression node + * @returns {void} + */ + function checkAssigmentExpression(node) { + performCheck(node.left, node.right, node); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclarator: checkVariableDeclarator, + AssignmentExpression: checkAssigmentExpression + }; + } +}; diff --git a/tools/eslint/lib/rules/prefer-reflect.js b/tools/eslint/lib/rules/prefer-reflect.js index 64db836d04dd89..49e20989ecb00d 100644 --- a/tools/eslint/lib/rules/prefer-reflect.js +++ b/tools/eslint/lib/rules/prefer-reflect.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to suggest using "Reflect" api over Function/Object methods * @author Keith Cirkel + * @deprecated in ESLint v3.9.0 */ "use strict"; @@ -13,9 +14,12 @@ module.exports = { docs: { description: "require `Reflect` methods where applicable", category: "ECMAScript 6", - recommended: false + recommended: false, + replacedBy: [] }, + deprecated: true, + schema: [ { type: "object", @@ -79,10 +83,10 @@ module.exports = { * @returns {void} */ function report(node, existing, substitute) { - context.report(node, "Avoid using {{existing}}, instead use {{substitute}}.", { + context.report({ node, message: "Avoid using {{existing}}, instead use {{substitute}}.", data: { existing, substitute - }); + } }); } return { diff --git a/tools/eslint/lib/rules/quote-props.js b/tools/eslint/lib/rules/quote-props.js index 2129ce6aa99b87..1dcdd461b598fc 100644 --- a/tools/eslint/lib/rules/quote-props.js +++ b/tools/eslint/lib/rules/quote-props.js @@ -162,7 +162,7 @@ module.exports = { context.report({ node, message: MESSAGE_UNNECESSARY, - data: {property: key.value}, + data: { property: key.value }, fix: fixer => fixer.replaceText(key, getUnquotedKey(key)) }); } @@ -170,14 +170,14 @@ module.exports = { context.report({ node, message: MESSAGE_RESERVED, - data: {property: key.name}, + data: { property: key.name }, fix: fixer => fixer.replaceText(key, getQuotedKey(key)) }); } else if (NUMBERS && key.type === "Literal" && typeof key.value === "number") { context.report({ node, message: MESSAGE_NUMERIC, - data: {property: key.value}, + data: { property: key.value }, fix: fixer => fixer.replaceText(key, getQuotedKey(key)) }); } @@ -195,7 +195,7 @@ module.exports = { context.report({ node, message: MESSAGE_UNQUOTED, - data: {property: key.name || key.value}, + data: { property: key.name || key.value }, fix: fixer => fixer.replaceText(key, getQuotedKey(key)) }); } @@ -213,7 +213,7 @@ module.exports = { let keywordKeyName = null, necessaryQuotes = false; - node.properties.forEach(function(property) { + node.properties.forEach(property => { const key = property.key; let tokens; @@ -257,7 +257,7 @@ module.exports = { context.report({ node: property, message: "Properties should be quoted as '{{property}}' is a reserved word.", - data: {property: keywordKeyName}, + data: { property: keywordKeyName }, fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) }); }); @@ -266,7 +266,7 @@ module.exports = { context.report({ node: property, message: "Inconsistently quoted property '{{key}}' found.", - data: {key: property.key.name || property.key.value}, + data: { key: property.key.name || property.key.value }, fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) }); }); diff --git a/tools/eslint/lib/rules/quotes.js b/tools/eslint/lib/rules/quotes.js index 90e68289e05662..5c53c76908c3df 100644 --- a/tools/eslint/lib/rules/quotes.js +++ b/tools/eslint/lib/rules/quotes.js @@ -51,7 +51,7 @@ QUOTE_SETTINGS.backtick.convert = function(str) { if (newQuote === oldQuote) { return str; } - return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, function(match, escaped, newline) { + return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, (match, escaped, newline) => { if (escaped === oldQuote || oldQuote === "`" && escaped === "${") { return escaped; // unescape } @@ -258,7 +258,11 @@ module.exports = { return; } - const shouldWarn = node.quasis.length === 1 && (node.quasis[0].value.cooked.indexOf("\n") === -1); + /* + * A warning should be produced if the template literal only has one TemplateElement, and has no unescaped newlines. + * An unescaped newline is a newline preceded by an even number of backslashes. + */ + const shouldWarn = node.quasis.length === 1 && !/(^|[^\\])(\\\\)*[\r\n\u2028\u2029]/.test(node.quasis[0].value.raw); if (shouldWarn) { context.report({ @@ -268,6 +272,15 @@ module.exports = { description: settings.description, }, fix(fixer) { + if (isPartOfDirectivePrologue(node)) { + + /* + * TemplateLiterals in a directive prologue aren't actually directives, but if they're + * in the directive prologue, then fixing them might turn them into directives and change + * the behavior of the code. + */ + return null; + } return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); } }); diff --git a/tools/eslint/lib/rules/radix.js b/tools/eslint/lib/rules/radix.js index f36e27d3634b9e..0dfa081b6a3e35 100644 --- a/tools/eslint/lib/rules/radix.js +++ b/tools/eslint/lib/rules/radix.js @@ -145,7 +145,7 @@ module.exports = { // Check `parseInt()` variable = astUtils.getVariableByName(scope, "parseInt"); if (!isShadowed(variable)) { - variable.references.forEach(function(reference) { + variable.references.forEach(reference => { const node = reference.identifier; if (astUtils.isCallee(node)) { @@ -157,7 +157,7 @@ module.exports = { // Check `Number.parseInt()` variable = astUtils.getVariableByName(scope, "Number"); if (!isShadowed(variable)) { - variable.references.forEach(function(reference) { + variable.references.forEach(reference => { const node = reference.identifier.parent; if (isParseIntMethod(node) && astUtils.isCallee(node)) { diff --git a/tools/eslint/lib/rules/require-await.js b/tools/eslint/lib/rules/require-await.js new file mode 100644 index 00000000000000..89b24f75b0f951 --- /dev/null +++ b/tools/eslint/lib/rules/require-await.js @@ -0,0 +1,95 @@ +/** + * @fileoverview Rule to disallow async functions which have no `await` expression. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Capitalize the 1st letter of the given text. + * + * @param {string} text - The text to capitalize. + * @returns {string} The text that the 1st letter was capitalized. + */ +function capitalizeFirstLetter(text) { + return text[0].toUpperCase() + text.slice(1); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow async functions which have no `await` expression", + category: "Best Practices", + recommended: false + }, + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Push the scope info object to the stack. + * + * @returns {void} + */ + function enterFunction() { + scopeInfo = { + upper: scopeInfo, + hasAwait: false, + }; + } + + /** + * Pop the top scope info object from the stack. + * Also, it reports the function if needed. + * + * @param {ASTNode} node - The node to report. + * @returns {void} + */ + function exitFunction(node) { + if (node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) { + context.report({ + node, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + message: "{{name}} has no 'await' expression.", + data: { + name: capitalizeFirstLetter( + astUtils.getFunctionNameWithKind(node) + ) + } + }); + } + + scopeInfo = scopeInfo.upper; + } + + return { + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression: enterFunction, + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + "ArrowFunctionExpression:exit": exitFunction, + + AwaitExpression() { + scopeInfo.hasAwait = true; + } + }; + } +}; diff --git a/tools/eslint/lib/rules/require-jsdoc.js b/tools/eslint/lib/rules/require-jsdoc.js index 9300fce1baa42b..f1ecde81f959ec 100644 --- a/tools/eslint/lib/rules/require-jsdoc.js +++ b/tools/eslint/lib/rules/require-jsdoc.js @@ -27,6 +27,9 @@ module.exports = { }, FunctionDeclaration: { type: "boolean" + }, + ArrowFunctionExpression: { + type: "boolean" } }, additionalProperties: false @@ -52,7 +55,7 @@ module.exports = { * @returns {void} */ function report(node) { - context.report(node, "Missing JSDoc comment."); + context.report({ node, message: "Missing JSDoc comment." }); } /** @@ -98,6 +101,11 @@ module.exports = { if (options.ClassDeclaration) { checkJsDoc(node); } + }, + ArrowFunctionExpression(node) { + if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") { + checkJsDoc(node); + } } }; } diff --git a/tools/eslint/lib/rules/require-yield.js b/tools/eslint/lib/rules/require-yield.js index 36b4ea11a585aa..5cc2944bc692d6 100644 --- a/tools/eslint/lib/rules/require-yield.js +++ b/tools/eslint/lib/rules/require-yield.js @@ -48,9 +48,7 @@ module.exports = { const countYield = stack.pop(); if (countYield === 0 && node.body.body.length > 0) { - context.report( - node, - "This generator function does not have 'yield'."); + context.report({ node, message: "This generator function does not have 'yield'." }); } } diff --git a/tools/eslint/lib/rules/semi.js b/tools/eslint/lib/rules/semi.js index 2f28f1614d1a42..ee37ab018c82fd 100644 --- a/tools/eslint/lib/rules/semi.js +++ b/tools/eslint/lib/rules/semi.js @@ -39,7 +39,7 @@ module.exports = { { type: "object", properties: { - omitLastInOneLineBlock: {type: "boolean"} + omitLastInOneLineBlock: { type: "boolean" } }, additionalProperties: false } @@ -53,7 +53,7 @@ module.exports = { create(context) { - const OPT_OUT_PATTERN = /^[-[(\/+]$/; // One of [(/+-, but not ++ or -- + const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-` const options = context.options[1]; const never = context.options[0] === "never", exceptOneLine = options && options.omitLastInOneLineBlock === true, @@ -127,7 +127,7 @@ module.exports = { const lastTokenLine = lastToken.loc.end.line; const nextTokenLine = nextToken.loc.start.line; - const isOptOutToken = OPT_OUT_PATTERN.test(nextToken.value); + const isOptOutToken = OPT_OUT_PATTERN.test(nextToken.value) && nextToken.value !== "++" && nextToken.value !== "--"; const isDivider = (nextToken.value === "}" || nextToken.value === ";"); return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider; diff --git a/tools/eslint/lib/rules/sort-imports.js b/tools/eslint/lib/rules/sort-imports.js index ae3333c2ac16d7..83f500990239b2 100644 --- a/tools/eslint/lib/rules/sort-imports.js +++ b/tools/eslint/lib/rules/sort-imports.js @@ -39,7 +39,9 @@ module.exports = { }, additionalProperties: false } - ] + ], + + fixable: "code" }, create(context) { @@ -47,7 +49,8 @@ module.exports = { const configuration = context.options[0] || {}, ignoreCase = configuration.ignoreCase || false, ignoreMemberSort = configuration.ignoreMemberSort || false, - memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"]; + memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"], + sourceCode = context.getSourceCode(); let previousDeclaration = null; /** @@ -135,36 +138,49 @@ module.exports = { } } - // Multiple members of an import declaration should also be sorted alphabetically. - if (!ignoreMemberSort && node.specifiers.length > 1) { - let previousSpecifier = null; - let previousSpecifierName = null; + if (!ignoreMemberSort) { + const importSpecifiers = node.specifiers.filter(specifier => specifier.type === "ImportSpecifier"); + const getSortableName = ignoreCase ? specifier => specifier.local.name.toLowerCase() : specifier => specifier.local.name; + const firstUnsortedIndex = importSpecifiers.map(getSortableName).findIndex((name, index, array) => array[index - 1] > name); + + if (firstUnsortedIndex !== -1) { + context.report({ + node: importSpecifiers[firstUnsortedIndex], + message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.", + data: { memberName: importSpecifiers[firstUnsortedIndex].local.name }, + fix(fixer) { + if (importSpecifiers.some(specifier => sourceCode.getComments(specifier).leading.length || sourceCode.getComments(specifier).trailing.length)) { + + // If there are comments in the ImportSpecifier list, don't rearrange the specifiers. + return null; + } - for (let i = 0; i < node.specifiers.length; ++i) { - const currentSpecifier = node.specifiers[i]; + return fixer.replaceTextRange( + [importSpecifiers[0].range[0], importSpecifiers[importSpecifiers.length - 1].range[1]], + importSpecifiers - if (currentSpecifier.type !== "ImportSpecifier") { - continue; - } + // Clone the importSpecifiers array to avoid mutating it + .slice() - let currentSpecifierName = currentSpecifier.local.name; + // Sort the array into the desired order + .sort((specifierA, specifierB) => { + const aName = getSortableName(specifierA); + const bName = getSortableName(specifierB); - if (ignoreCase) { - currentSpecifierName = currentSpecifierName.toLowerCase(); - } + return aName > bName ? 1 : -1; + }) - if (previousSpecifier && currentSpecifierName < previousSpecifierName) { - context.report({ - node: currentSpecifier, - message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.", - data: { - memberName: currentSpecifier.local.name - } - }); - } + // Build a string out of the sorted list of import specifiers and the text between the originals + .reduce((sourceText, specifier, index) => { + const textAfterSpecifier = index === importSpecifiers.length - 1 + ? "" + : sourceCode.getText().slice(importSpecifiers[index].range[1], importSpecifiers[index + 1].range[0]); - previousSpecifier = currentSpecifier; - previousSpecifierName = currentSpecifierName; + return sourceText + sourceCode.getText(specifier) + textAfterSpecifier; + }, "") + ); + } + }); } } diff --git a/tools/eslint/lib/rules/sort-vars.js b/tools/eslint/lib/rules/sort-vars.js index 1e1cf3c959e663..e18cc320ef0553 100644 --- a/tools/eslint/lib/rules/sort-vars.js +++ b/tools/eslint/lib/rules/sort-vars.js @@ -37,7 +37,7 @@ module.exports = { return { VariableDeclaration(node) { - node.declarations.reduce(function(memo, decl) { + node.declarations.reduce((memo, decl) => { if (decl.id.type === "ObjectPattern" || decl.id.type === "ArrayPattern") { return memo; } @@ -51,7 +51,7 @@ module.exports = { } if (currenVariableName < lastVariableName) { - context.report(decl, "Variables within the same declaration block should be sorted alphabetically."); + context.report({ node: decl, message: "Variables within the same declaration block should be sorted alphabetically." }); return memo; } else { return decl; diff --git a/tools/eslint/lib/rules/space-in-parens.js b/tools/eslint/lib/rules/space-in-parens.js index c01170b2bc13b4..af838dfa9e8376 100644 --- a/tools/eslint/lib/rules/space-in-parens.js +++ b/tools/eslint/lib/rules/space-in-parens.js @@ -220,7 +220,7 @@ module.exports = { exceptions = getExceptions(); const tokens = sourceCode.tokensAndComments; - tokens.forEach(function(token, i) { + tokens.forEach((token, i) => { const prevToken = tokens[i - 1]; const nextToken = tokens[i + 1]; diff --git a/tools/eslint/lib/rules/space-infix-ops.js b/tools/eslint/lib/rules/space-infix-ops.js index 9831e8e2af6085..d919a1225a2bf5 100644 --- a/tools/eslint/lib/rules/space-infix-ops.js +++ b/tools/eslint/lib/rules/space-infix-ops.js @@ -57,7 +57,7 @@ module.exports = { const op = tokens[i]; if ( - op.type === "Punctuator" && + (op.type === "Punctuator" || op.type === "Keyword") && OPERATORS.indexOf(op.value) >= 0 && (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0]) ) { diff --git a/tools/eslint/lib/rules/spaced-comment.js b/tools/eslint/lib/rules/spaced-comment.js index a3dce4fa4e3d30..85abd7360e622a 100644 --- a/tools/eslint/lib/rules/spaced-comment.js +++ b/tools/eslint/lib/rules/spaced-comment.js @@ -240,7 +240,7 @@ module.exports = { const config = context.options[1] || {}; const balanced = config.block && config.block.balanced; - const styleRules = ["block", "line"].reduce(function(rule, type) { + const styleRules = ["block", "line"].reduce((rule, type) => { const markers = parseMarkersOption(config[type] && config[type].markers || config.markers); const exceptions = config[type] && config[type].exceptions || config.exceptions || []; const endNeverPattern = "[ \t]+$"; diff --git a/tools/eslint/lib/rules/strict.js b/tools/eslint/lib/rules/strict.js index 1591bd871465d4..34ed443d92c816 100644 --- a/tools/eslint/lib/rules/strict.js +++ b/tools/eslint/lib/rules/strict.js @@ -135,7 +135,7 @@ module.exports = { */ function reportSlice(nodes, start, end, message, fix) { nodes.slice(start, end).forEach(node => { - context.report({node, message, fix: fix ? getFixFunction(node) : null}); + context.report({ node, message, fix: fix ? getFixFunction(node) : null }); }); } @@ -176,19 +176,19 @@ module.exports = { if (isStrict) { if (!isSimpleParameterList(node.params)) { - context.report(useStrictDirectives[0], messages.nonSimpleParameterList); + context.report({ node: useStrictDirectives[0], message: messages.nonSimpleParameterList }); } else if (isParentStrict) { - context.report({node: useStrictDirectives[0], message: messages.unnecessary, fix: getFixFunction(useStrictDirectives[0])}); + context.report({ node: useStrictDirectives[0], message: messages.unnecessary, fix: getFixFunction(useStrictDirectives[0]) }); } else if (isInClass) { - context.report({node: useStrictDirectives[0], message: messages.unnecessaryInClasses, fix: getFixFunction(useStrictDirectives[0])}); + context.report({ node: useStrictDirectives[0], message: messages.unnecessaryInClasses, fix: getFixFunction(useStrictDirectives[0]) }); } reportAllExceptFirst(useStrictDirectives, messages.multiple, true); } else if (isParentGlobal) { if (isSimpleParameterList(node.params)) { - context.report(node, messages.function); + context.report({ node, message: messages.function }); } else { - context.report(node, messages.wrap); + context.report({ node, message: messages.wrap }); } } @@ -221,7 +221,7 @@ module.exports = { if (isSimpleParameterList(node.params)) { reportAll(useStrictDirectives, messages[mode], shouldFix(mode)); } else { - context.report(useStrictDirectives[0], messages.nonSimpleParameterList); + context.report({ node: useStrictDirectives[0], message: messages.nonSimpleParameterList }); reportAllExceptFirst(useStrictDirectives, messages.multiple, true); } } @@ -237,7 +237,7 @@ module.exports = { if (mode === "global") { if (node.body.length > 0 && useStrictDirectives.length === 0) { - context.report(node, messages.global); + context.report({ node, message: messages.global }); } reportAllExceptFirst(useStrictDirectives, messages.multiple, true); } else { diff --git a/tools/eslint/lib/rules/symbol-description.js b/tools/eslint/lib/rules/symbol-description.js index 37ac8be7276656..3f5ffd7463cd5a 100644 --- a/tools/eslint/lib/rules/symbol-description.js +++ b/tools/eslint/lib/rules/symbol-description.js @@ -51,7 +51,7 @@ module.exports = { const variable = astUtils.getVariableByName(scope, "Symbol"); if (variable && variable.defs.length === 0) { - variable.references.forEach(function(reference) { + variable.references.forEach(reference => { const node = reference.identifier; if (astUtils.isCallee(node)) { diff --git a/tools/eslint/lib/rules/template-curly-spacing.js b/tools/eslint/lib/rules/template-curly-spacing.js index 1ac3262fce2597..1d491a24c9c1e2 100644 --- a/tools/eslint/lib/rules/template-curly-spacing.js +++ b/tools/eslint/lib/rules/template-curly-spacing.js @@ -33,7 +33,7 @@ module.exports = { fixable: "whitespace", schema: [ - {enum: ["always", "never"]} + { enum: ["always", "never"] } ] }, diff --git a/tools/eslint/lib/rules/unicode-bom.js b/tools/eslint/lib/rules/unicode-bom.js index 82692894d4a852..2f16a258509e8b 100644 --- a/tools/eslint/lib/rules/unicode-bom.js +++ b/tools/eslint/lib/rules/unicode-bom.js @@ -36,7 +36,7 @@ module.exports = { Program: function checkUnicodeBOM(node) { const sourceCode = context.getSourceCode(), - location = {column: 0, line: 1}, + location = { column: 0, line: 1 }, requireBOM = context.options[0] || "never"; if (!sourceCode.hasBOM && (requireBOM === "always")) { diff --git a/tools/eslint/lib/rules/use-isnan.js b/tools/eslint/lib/rules/use-isnan.js index b4a978b5efe21b..5ec48a0386e1b5 100644 --- a/tools/eslint/lib/rules/use-isnan.js +++ b/tools/eslint/lib/rules/use-isnan.js @@ -25,7 +25,7 @@ module.exports = { return { BinaryExpression(node) { if (/^(?:[<>]|[!=]=)=?$/.test(node.operator) && (node.left.name === "NaN" || node.right.name === "NaN")) { - context.report(node, "Use the isNaN function to compare with NaN."); + context.report({ node, message: "Use the isNaN function to compare with NaN." }); } } }; diff --git a/tools/eslint/lib/rules/valid-jsdoc.js b/tools/eslint/lib/rules/valid-jsdoc.js index 09fc684719a4af..66ad1f8d45de1f 100644 --- a/tools/eslint/lib/rules/valid-jsdoc.js +++ b/tools/eslint/lib/rules/valid-jsdoc.js @@ -202,7 +202,7 @@ module.exports = { elements.forEach(validateType.bind(null, jsdocNode)); - typesToCheck.forEach(function(typeToCheck) { + typesToCheck.forEach(typeToCheck => { if (typeToCheck.expectedType && typeToCheck.expectedType !== typeToCheck.currentType) { context.report({ @@ -246,15 +246,15 @@ module.exports = { } catch (ex) { if (/braces/i.test(ex.message)) { - context.report(jsdocNode, "JSDoc type missing brace."); + context.report({ node: jsdocNode, message: "JSDoc type missing brace." }); } else { - context.report(jsdocNode, "JSDoc syntax error."); + context.report({ node: jsdocNode, message: "JSDoc syntax error." }); } return; } - jsdoc.tags.forEach(function(tag) { + jsdoc.tags.forEach(tag => { switch (tag.title.toLowerCase()) { @@ -262,15 +262,15 @@ module.exports = { case "arg": case "argument": if (!tag.type) { - context.report(jsdocNode, "Missing JSDoc parameter type for '{{name}}'.", { name: tag.name }); + context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", data: { name: tag.name } }); } if (!tag.description && requireParamDescription) { - context.report(jsdocNode, "Missing JSDoc parameter description for '{{name}}'.", { name: tag.name }); + context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", data: { name: tag.name } }); } if (params[tag.name]) { - context.report(jsdocNode, "Duplicate JSDoc parameter '{{name}}'.", { name: tag.name }); + context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", data: { name: tag.name } }); } else if (tag.name.indexOf(".") === -1) { params[tag.name] = 1; } @@ -290,11 +290,11 @@ module.exports = { }); } else { if (requireReturnType && !tag.type) { - context.report(jsdocNode, "Missing JSDoc return type."); + context.report({ node: jsdocNode, message: "Missing JSDoc return type." }); } if (!isValidReturnType(tag) && !tag.description && requireReturnDescription) { - context.report(jsdocNode, "Missing JSDoc return description."); + context.report({ node: jsdocNode, message: "Missing JSDoc return description." }); } } @@ -324,7 +324,7 @@ module.exports = { // check tag preferences if (prefer.hasOwnProperty(tag.title) && tag.title !== prefer[tag.title]) { - context.report(jsdocNode, "Use @{{name}} instead.", { name: prefer[tag.title] }); + context.report({ node: jsdocNode, message: "Use @{{name}} instead.", data: { name: prefer[tag.title] } }); } // validate the types @@ -352,7 +352,7 @@ module.exports = { const jsdocParams = Object.keys(params); if (node.params) { - node.params.forEach(function(param, i) { + node.params.forEach((param, i) => { if (param.type === "AssignmentPattern") { param = param.left; } @@ -362,14 +362,14 @@ module.exports = { // TODO(nzakas): Figure out logical things to do with destructured, default, rest params if (param.type === "Identifier") { if (jsdocParams[i] && (name !== jsdocParams[i])) { - context.report(jsdocNode, "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", { + context.report({ node: jsdocNode, message: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", data: { name, jsdocName: jsdocParams[i] - }); + } }); } else if (!params[name] && !isOverride) { - context.report(jsdocNode, "Missing JSDoc for parameter '{{name}}'.", { + context.report({ node: jsdocNode, message: "Missing JSDoc for parameter '{{name}}'.", data: { name - }); + } }); } } }); @@ -379,7 +379,7 @@ module.exports = { const regex = new RegExp(options.matchDescription); if (!regex.test(jsdoc.description)) { - context.report(jsdocNode, "JSDoc description does not satisfy the regex pattern."); + context.report({ node: jsdocNode, message: "JSDoc description does not satisfy the regex pattern." }); } } diff --git a/tools/eslint/lib/rules/valid-typeof.js b/tools/eslint/lib/rules/valid-typeof.js index ed0a7c017955f2..94b407b600a43c 100644 --- a/tools/eslint/lib/rules/valid-typeof.js +++ b/tools/eslint/lib/rules/valid-typeof.js @@ -62,10 +62,10 @@ module.exports = { const value = sibling.type === "Literal" ? sibling.value : sibling.quasis[0].value.cooked; if (VALID_TYPES.indexOf(value) === -1) { - context.report(sibling, "Invalid typeof comparison value."); + context.report({ node: sibling, message: "Invalid typeof comparison value." }); } } else if (requireStringLiterals && !isTypeofExpression(sibling)) { - context.report(sibling, "Typeof comparisons should be to string literals."); + context.report({ node: sibling, message: "Typeof comparisons should be to string literals." }); } } } diff --git a/tools/eslint/lib/rules/vars-on-top.js b/tools/eslint/lib/rules/vars-on-top.js index 92ed08e2d4b5de..f74db905b1908d 100644 --- a/tools/eslint/lib/rules/vars-on-top.js +++ b/tools/eslint/lib/rules/vars-on-top.js @@ -100,7 +100,7 @@ module.exports = { */ function globalVarCheck(node, parent) { if (!isVarOnTop(node, parent.body)) { - context.report(node, errorMessage); + context.report({ node, message: errorMessage }); } } @@ -115,7 +115,7 @@ module.exports = { if (!(/Function/.test(grandParent.type) && parent.type === "BlockStatement" && isVarOnTop(node, parent.body))) { - context.report(node, errorMessage); + context.report({ node, message: errorMessage }); } } diff --git a/tools/eslint/lib/rules/yield-star-spacing.js b/tools/eslint/lib/rules/yield-star-spacing.js index ecd33c5b38fafb..eb20fc01b0b9a9 100644 --- a/tools/eslint/lib/rules/yield-star-spacing.js +++ b/tools/eslint/lib/rules/yield-star-spacing.js @@ -28,8 +28,8 @@ module.exports = { { type: "object", properties: { - before: {type: "boolean"}, - after: {type: "boolean"} + before: { type: "boolean" }, + after: { type: "boolean" } }, additionalProperties: false } diff --git a/tools/eslint/lib/rules/yoda.js b/tools/eslint/lib/rules/yoda.js index e463a476ab6be4..ba711c63c2f1ae 100644 --- a/tools/eslint/lib/rules/yoda.js +++ b/tools/eslint/lib/rules/yoda.js @@ -4,6 +4,12 @@ */ "use strict"; +//-------------------------------------------------------------------------- +// Requirements +//-------------------------------------------------------------------------- + +const astUtils = require("../ast-utils"); + //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- @@ -54,13 +60,16 @@ function looksLikeLiteral(node) { /** * Attempts to derive a Literal node from nodes that are treated like literals. * @param {ASTNode} node Node to normalize. - * @returns {ASTNode} The original node if the node is already a Literal, or a - * normalized Literal node with the negative number as the - * value if the node represents a negative number literal, - * otherwise null if the node cannot be converted to a - * normalized literal. + * @param {number} [defaultValue] The default value to be returned if the node + * is not a Literal. + * @returns {ASTNode} One of the following options. + * 1. The original node if the node is already a Literal + * 2. A normalized Literal node with the negative number as the value if the + * node represents a negative number literal. + * 3. The Literal node which has the `defaultValue` argument if it exists. + * 4. Otherwise `null`. */ -function getNormalizedLiteral(node) { +function getNormalizedLiteral(node, defaultValue) { if (node.type === "Literal") { return node; } @@ -73,6 +82,14 @@ function getNormalizedLiteral(node) { }; } + if (defaultValue) { + return { + type: "Literal", + value: defaultValue, + raw: String(defaultValue) + }; + } + return null; } @@ -98,12 +115,26 @@ function same(a, b) { case "Literal": return a.value === b.value; - case "MemberExpression": + case "MemberExpression": { + const nameA = astUtils.getStaticPropertyName(a); + + // x.y = x["y"] + if (nameA) { + return ( + same(a.object, b.object) && + nameA === astUtils.getStaticPropertyName(b) + ); + } // x[0] = x[0] // x[y] = x[y] // x.y = x.y - return same(a.object, b.object) && same(a.property, b.property); + return ( + a.computed === b.computed && + same(a.object, b.object) && + same(a.property, b.property) + ); + } case "ThisExpression": return true; @@ -178,7 +209,7 @@ module.exports = { return (node.operator === "&&" && (leftLiteral = getNormalizedLiteral(left.left)) && - (rightLiteral = getNormalizedLiteral(right.right)) && + (rightLiteral = getNormalizedLiteral(right.right, Number.POSITIVE_INFINITY)) && leftLiteral.value <= rightLiteral.value && same(left.right, right.left)); } @@ -191,7 +222,7 @@ module.exports = { let leftLiteral, rightLiteral; return (node.operator === "||" && - (leftLiteral = getNormalizedLiteral(left.right)) && + (leftLiteral = getNormalizedLiteral(left.right, Number.NEGATIVE_INFINITY)) && (rightLiteral = getNormalizedLiteral(right.left)) && leftLiteral.value <= rightLiteral.value && same(left.left, right.right)); diff --git a/tools/eslint/lib/testers/event-generator-tester.js b/tools/eslint/lib/testers/event-generator-tester.js index d85238e9db0471..89693fe94819df 100644 --- a/tools/eslint/lib/testers/event-generator-tester.js +++ b/tools/eslint/lib/testers/event-generator-tester.js @@ -44,19 +44,19 @@ module.exports = { * @returns {void} */ testEventGeneratorInterface(instance) { - this.describe("should implement EventGenerator interface", function() { - this.it("should have `emitter` property.", function() { + this.describe("should implement EventGenerator interface", () => { + this.it("should have `emitter` property.", () => { assert.equal(typeof instance.emitter, "object"); assert.equal(typeof instance.emitter.emit, "function"); }); - this.it("should have `enterNode` property.", function() { + this.it("should have `enterNode` property.", () => { assert.equal(typeof instance.enterNode, "function"); }); - this.it("should have `leaveNode` property.", function() { + this.it("should have `leaveNode` property.", () => { assert.equal(typeof instance.leaveNode, "function"); }); - }.bind(this)); + }); } }; diff --git a/tools/eslint/lib/testers/rule-tester.js b/tools/eslint/lib/testers/rule-tester.js index 25b86993593c4a..5d327ad28b9360 100644 --- a/tools/eslint/lib/testers/rule-tester.js +++ b/tools/eslint/lib/testers/rule-tester.js @@ -252,8 +252,26 @@ RuleTester.prototype = { run(ruleName, rule, test) { const testerConfig = this.testerConfig, + requiredScenarios = ["valid", "invalid"], + scenarioErrors = [], result = {}; + if (lodash.isNil(test) || typeof test !== "object") { + throw new Error(`Test Scenarios for rule ${ruleName} : Could not find test scenario object`); + } + + requiredScenarios.forEach(scenarioType => { + if (lodash.isNil(test[scenarioType])) { + scenarioErrors.push(`Could not find any ${scenarioType} test scenarios`); + } + }); + + if (scenarioErrors.length > 0) { + throw new Error([ + `Test Scenarios for rule ${ruleName} is invalid:` + ].concat(scenarioErrors).join("\n")); + } + /* eslint-disable no-shadow */ /** @@ -307,9 +325,7 @@ RuleTester.prototype = { if (validateSchema.errors) { throw new Error([ `Schema for rule ${ruleName} is invalid:` - ].concat(validateSchema.errors.map(function(error) { - return `\t${error.field}: ${error.message}`; - })).join("\n")); + ].concat(validateSchema.errors.map(error => `\t${error.field}: ${error.message}`)).join("\n")); } } @@ -321,10 +337,10 @@ RuleTester.prototype = { * running the rule under test. */ eslint.reset(); - eslint.on("Program", function(node) { + eslint.on("Program", node => { beforeAST = cloneDeeplyExcludesParent(node); - eslint.on("Program:exit", function(node) { + eslint.on("Program:exit", node => { afterAST = cloneDeeplyExcludesParent(node); }); }); @@ -448,7 +464,7 @@ RuleTester.prototype = { } if (item.errors[i].type) { - assert.equal(messages[i].nodeType, item.errors[i].type, `Error type should be ${item.errors[i].type}`); + assert.equal(messages[i].nodeType, item.errors[i].type, `Error type should be ${item.errors[i].type}, found ${messages[i].nodeType}`); } if (item.errors[i].hasOwnProperty("line")) { @@ -488,18 +504,18 @@ RuleTester.prototype = { * This creates a mocha test suite and pipes all supplied info through * one of the templates above. */ - RuleTester.describe(ruleName, function() { - RuleTester.describe("valid", function() { - test.valid.forEach(function(valid) { - RuleTester.it(valid.code || valid, function() { + RuleTester.describe(ruleName, () => { + RuleTester.describe("valid", () => { + test.valid.forEach(valid => { + RuleTester.it(valid.code || valid, () => { testValidTemplate(ruleName, valid); }); }); }); - RuleTester.describe("invalid", function() { - test.invalid.forEach(function(invalid) { - RuleTester.it(invalid.code, function() { + RuleTester.describe("invalid", () => { + test.invalid.forEach(invalid => { + RuleTester.it(invalid.code, () => { testInvalidTemplate(ruleName, invalid); }); }); diff --git a/tools/eslint/lib/timing.js b/tools/eslint/lib/timing.js index 627aa5f82f8118..20456628640bf6 100644 --- a/tools/eslint/lib/timing.js +++ b/tools/eslint/lib/timing.js @@ -54,18 +54,16 @@ const ALIGN = [alignLeft, alignRight, alignRight]; function display(data) { let total = 0; const rows = Object.keys(data) - .map(function(key) { + .map(key => { const time = data[key]; total += time; return [key, time]; }) - .sort(function(a, b) { - return b[1] - a[1]; - }) + .sort((a, b) => b[1] - a[1]) .slice(0, 10); - rows.forEach(function(row) { + rows.forEach(row => { row.push(`${(row[1] * 100 / total).toFixed(1)}%`); row[1] = row[1].toFixed(3); }); @@ -74,7 +72,7 @@ function display(data) { const widths = []; - rows.forEach(function(row) { + rows.forEach(row => { const len = row.length; for (let i = 0; i < len; i++) { @@ -86,13 +84,13 @@ function display(data) { } }); - const table = rows.map(function(row) { - return row.map(function(cell, index) { - return ALIGN[index](cell, widths[index]); - }).join(" | "); - }); + const table = rows.map(row => + row + .map((cell, index) => ALIGN[index](cell, widths[index])) + .join(" | ") + ); - table.splice(1, 0, widths.map(function(w, index) { + table.splice(1, 0, widths.map((w, index) => { if (index !== 0 && index !== widths.length - 1) { w++; } @@ -130,7 +128,7 @@ module.exports = (function() { } if (enabled) { - process.on("exit", function() { + process.on("exit", () => { display(data); }); } diff --git a/tools/eslint/lib/util/comment-event-generator.js b/tools/eslint/lib/util/comment-event-generator.js index 47cc68f296f87e..dfa7132ff850ef 100644 --- a/tools/eslint/lib/util/comment-event-generator.js +++ b/tools/eslint/lib/util/comment-event-generator.js @@ -20,7 +20,7 @@ */ function emitComments(comments, emitter, locs, eventName) { if (comments.length > 0) { - comments.forEach(function(node) { + comments.forEach(node => { const index = locs.indexOf(node.loc); if (index >= 0) { diff --git a/tools/eslint/lib/util/glob-util.js b/tools/eslint/lib/util/glob-util.js index cba2e694ad5238..198e069e9f0850 100644 --- a/tools/eslint/lib/util/glob-util.js +++ b/tools/eslint/lib/util/glob-util.js @@ -43,9 +43,7 @@ function processPath(options) { const cwd = (options && options.cwd) || process.cwd(); let extensions = (options && options.extensions) || [".js"]; - extensions = extensions.map(function(ext) { - return ext.charAt(0) === "." ? ext.substr(1) : ext; - }); + extensions = extensions.map(ext => ext.replace(/^\./, "")); let suffix = "/**"; @@ -67,7 +65,7 @@ function processPath(options) { const resolvedPath = path.resolve(cwd, pathname); if (shell.test("-d", resolvedPath)) { - newPath = pathname.replace(/[\/\\]$/, "") + suffix; + newPath = pathname.replace(/[/\\]$/, "") + suffix; } return pathUtil.convertPathToPosix(newPath); @@ -145,12 +143,12 @@ function listFilesToProcess(globPatterns, options) { if (added[filename]) { return; } - files.push({filename, ignored}); + files.push({ filename, ignored }); added[filename] = true; } debug("Creating list of files to process."); - globPatterns.forEach(function(pattern) { + globPatterns.forEach(pattern => { const file = path.resolve(cwd, pattern); if (shell.test("-f", file)) { @@ -160,9 +158,9 @@ function listFilesToProcess(globPatterns, options) { } else { // regex to find .hidden or /.hidden patterns, but not ./relative or ../relative - const globIncludesDotfiles = /(?:(?:^\.)|(?:[\/\\]\.))[^\/\\\.].*/.test(pattern); + const globIncludesDotfiles = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/.test(pattern); - const ignoredPaths = new IgnoredPaths(Object.assign({}, options, {dotfiles: options.dotfiles || globIncludesDotfiles})); + const ignoredPaths = new IgnoredPaths(Object.assign({}, options, { dotfiles: options.dotfiles || globIncludesDotfiles })); const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker(); const globOptions = { nodir: true, @@ -170,7 +168,7 @@ function listFilesToProcess(globPatterns, options) { cwd, }; - new GlobSync(pattern, globOptions, shouldIgnore).found.forEach(function(globMatch) { + new GlobSync(pattern, globOptions, shouldIgnore).found.forEach(globMatch => { addFile(path.resolve(cwd, globMatch), false, ignoredPaths); }); } diff --git a/tools/eslint/lib/util/module-resolver.js b/tools/eslint/lib/util/module-resolver.js index 40c107a70e82bd..505c572822699b 100644 --- a/tools/eslint/lib/util/module-resolver.js +++ b/tools/eslint/lib/util/module-resolver.js @@ -30,18 +30,18 @@ const DEFAULT_OPTIONS = { /** * Resolves modules based on a set of options. - * @param {Object} options The options for resolving modules. - * @param {string[]} options.lookupPaths An array of paths to include in the - * lookup with the highest priority paths coming first. - * @constructor */ -function ModuleResolver(options) { - options = options || {}; +class ModuleResolver { - this.options = Object.assign({}, DEFAULT_OPTIONS, options); -} - -ModuleResolver.prototype = { + /** + * Resolves modules based on a set of options. + * @param {Object} options The options for resolving modules. + * @param {string[]} options.lookupPaths An array of paths to include in the + * lookup with the highest priority paths coming first. + */ + constructor(options) { + this.options = Object.assign({}, DEFAULT_OPTIONS, options || {}); + } /** * Resolves the file location of a given module relative to the configured @@ -75,10 +75,8 @@ ModuleResolver.prototype = { } return result; - } - -}; +} //------------------------------------------------------------------------------ // Public API diff --git a/tools/eslint/lib/util/node-event-generator.js b/tools/eslint/lib/util/node-event-generator.js index 95d9132dd2f3b3..1666ae93f53406 100644 --- a/tools/eslint/lib/util/node-event-generator.js +++ b/tools/eslint/lib/util/node-event-generator.js @@ -20,34 +20,33 @@ * leaveNode(node: ASTNode): void; * } * ``` - * - * @param {EventEmitter} emitter - An event emitter which is the destination of events. - * @returns {NodeEventGenerator} new instance. */ -function NodeEventGenerator(emitter) { - this.emitter = emitter; -} +class NodeEventGenerator { -NodeEventGenerator.prototype = { - constructor: NodeEventGenerator, + /** + * @param {EventEmitter} emitter - An event emitter which is the destination of events. + */ + constructor(emitter) { + this.emitter = emitter; + } /** * Emits an event of entering AST node. * @param {ASTNode} node - A node which was entered. * @returns {void} */ - enterNode: function enterNode(node) { + enterNode(node) { this.emitter.emit(node.type, node); - }, + } /** * Emits an event of leaving AST node. * @param {ASTNode} node - A node which was left. * @returns {void} */ - leaveNode: function leaveNode(node) { + leaveNode(node) { this.emitter.emit(`${node.type}:exit`, node); } -}; +} module.exports = NodeEventGenerator; diff --git a/tools/eslint/lib/util/npm-util.js b/tools/eslint/lib/util/npm-util.js index e9131595e7e822..ef1c0c62936347 100644 --- a/tools/eslint/lib/util/npm-util.js +++ b/tools/eslint/lib/util/npm-util.js @@ -53,7 +53,7 @@ function installSyncSaveDev(packages) { if (Array.isArray(packages)) { packages = packages.join(" "); } - shell.exec(`npm i --save-dev ${packages}`, {stdio: "inherit"}); + shell.exec(`npm i --save-dev ${packages}`, { stdio: "inherit" }); } /** @@ -89,7 +89,7 @@ function check(packages, opt) { if (opt.dependencies && typeof fileJson.dependencies === "object") { deps = deps.concat(Object.keys(fileJson.dependencies)); } - return packages.reduce(function(status, pkg) { + return packages.reduce((status, pkg) => { status[pkg] = deps.indexOf(pkg) !== -1; return status; }, {}); @@ -107,7 +107,7 @@ function check(packages, opt) { * and values are booleans indicating installation. */ function checkDeps(packages, rootDir) { - return check(packages, {dependencies: true, startDir: rootDir}); + return check(packages, { dependencies: true, startDir: rootDir }); } /** @@ -121,7 +121,7 @@ function checkDeps(packages, rootDir) { * and values are booleans indicating installation. */ function checkDevDeps(packages) { - return check(packages, {devDependencies: true}); + return check(packages, { devDependencies: true }); } /** diff --git a/tools/eslint/lib/util/patterns/letters.js b/tools/eslint/lib/util/patterns/letters.js new file mode 100644 index 00000000000000..eb255d8f001b70 --- /dev/null +++ b/tools/eslint/lib/util/patterns/letters.js @@ -0,0 +1,36 @@ +/** + * @fileoverview Pattern for detecting any letter (even letters outside of ASCII). + * NOTE: This file was generated using this script in JSCS based on the Unicode 7.0.0 standard: https://github.com/jscs-dev/node-jscs/blob/f5ed14427deb7e7aac84f3056a5aab2d9f3e563e/publish/helpers/generate-patterns.js + * Do not edit this file by hand-- please use https://github.com/mathiasbynens/regenerate to regenerate the regular expression exported from this file. + * @author Kevin Partington + * @license MIT License (from JSCS). See below. + */ + +/* + * The MIT License (MIT) + * + * Copyright 2013-2016 Dulin Marat and other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +"use strict"; + +module.exports = /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/; diff --git a/tools/eslint/lib/util/source-code-fixer.js b/tools/eslint/lib/util/source-code-fixer.js index 064a0a1f902443..3b702e509e77a4 100644 --- a/tools/eslint/lib/util/source-code-fixer.js +++ b/tools/eslint/lib/util/source-code-fixer.js @@ -72,7 +72,7 @@ SourceCodeFixer.applyFixes = function(sourceCode, messages) { let lastFixPos = text.length + 1, prefix = (sourceCode.hasBOM ? BOM : ""); - messages.forEach(function(problem) { + messages.forEach(problem => { if (problem.hasOwnProperty("fix")) { fixes.push(problem); } else { @@ -84,14 +84,12 @@ SourceCodeFixer.applyFixes = function(sourceCode, messages) { debug("Found fixes to apply"); // sort in reverse order of occurrence - fixes.sort(function(a, b) { - return b.fix.range[1] - a.fix.range[1] || b.fix.range[0] - a.fix.range[0]; - }); + fixes.sort((a, b) => b.fix.range[1] - a.fix.range[1] || b.fix.range[0] - a.fix.range[0]); // split into array of characters for easier manipulation const chars = text.split(""); - fixes.forEach(function(problem) { + fixes.forEach(problem => { const fix = problem.fix; let start = fix.range[0]; const end = fix.range[1]; diff --git a/tools/eslint/lib/util/source-code-util.js b/tools/eslint/lib/util/source-code-util.js index 8e660e0961d330..892c32d22a00e8 100644 --- a/tools/eslint/lib/util/source-code-util.js +++ b/tools/eslint/lib/util/source-code-util.js @@ -29,7 +29,7 @@ const debug = require("debug")("eslint:source-code-util"); */ function getSourceCodeOfFile(filename, options) { debug("getting sourceCode of", filename); - const opts = Object.assign({}, options, { rules: {}}); + const opts = Object.assign({}, options, { rules: {} }); const cli = new CLIEngine(opts); const results = cli.executeOnFiles([filename]); @@ -71,7 +71,7 @@ function getSourceCodeOfFiles(patterns, options, cb) { patterns = [patterns]; } - const defaultOptions = Object.assign({}, baseDefaultOptions, {cwd: process.cwd()}); + const defaultOptions = Object.assign({}, baseDefaultOptions, { cwd: process.cwd() }); if (typeof options === "undefined") { opts = defaultOptions; @@ -84,14 +84,14 @@ function getSourceCodeOfFiles(patterns, options, cb) { debug("constructed options:", opts); patterns = globUtil.resolveFileGlobPatterns(patterns, opts); - const filenames = globUtil.listFilesToProcess(patterns, opts).reduce(function(files, fileInfo) { - return !fileInfo.ignored ? files.concat(fileInfo.filename) : files; - }, []); + const filenames = globUtil.listFilesToProcess(patterns, opts) + .filter(fileInfo => !fileInfo.ignored) + .reduce((files, fileInfo) => files.concat(fileInfo.filename), []); if (filenames.length === 0) { debug(`Did not find any files matching pattern(s): ${patterns}`); } - filenames.forEach(function(filename) { + filenames.forEach(filename => { const sourceCode = getSourceCodeOfFile(filename, opts); if (sourceCode) { diff --git a/tools/eslint/lib/util/source-code.js b/tools/eslint/lib/util/source-code.js index 378bdd328fa50a..5d073039d81cd7 100644 --- a/tools/eslint/lib/util/source-code.js +++ b/tools/eslint/lib/util/source-code.js @@ -117,16 +117,16 @@ function SourceCode(text, ast) { */ this.lines = SourceCode.splitLines(this.text); - this.tokensAndComments = ast.tokens.concat(ast.comments).sort(function(left, right) { - return left.range[0] - right.range[0]; - }); + this.tokensAndComments = ast.tokens + .concat(ast.comments) + .sort((left, right) => left.range[0] - right.range[0]); // create token store methods const tokenStore = createTokenStore(ast.tokens); - Object.keys(tokenStore).forEach(function(methodName) { + Object.keys(tokenStore).forEach(methodName => { this[methodName] = tokenStore[methodName]; - }, this); + }); const tokensAndCommentsStore = createTokenStore(this.tokensAndComments); @@ -280,7 +280,7 @@ SourceCode.prototype = { } }); - return result ? Object.assign({parent: resultParent}, result) : null; + return result ? Object.assign({ parent: resultParent }, result) : null; }, /** diff --git a/tools/eslint/lib/util/traverser.js b/tools/eslint/lib/util/traverser.js index 50d18b045eb6ff..d5710bb8ac7b2d 100644 --- a/tools/eslint/lib/util/traverser.js +++ b/tools/eslint/lib/util/traverser.js @@ -46,9 +46,7 @@ function Traverser() { * @private */ Traverser.getKeys = function(node) { - return Object.keys(node).filter(function(key) { - return KEY_BLACKLIST.indexOf(key) === -1; - }); + return Object.keys(node).filter(key => KEY_BLACKLIST.indexOf(key) === -1); }; module.exports = Traverser; diff --git a/tools/eslint/lib/util/xml-escape.js b/tools/eslint/lib/util/xml-escape.js index 698abaf38eaecf..9f43c99c46a23c 100644 --- a/tools/eslint/lib/util/xml-escape.js +++ b/tools/eslint/lib/util/xml-escape.js @@ -15,7 +15,7 @@ * @private */ module.exports = function(s) { - return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/g, function(c) { // eslint-disable-line no-control-regex + return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/g, c => { // eslint-disable-line no-control-regex switch (c) { case "<": return "<"; diff --git a/tools/eslint/node_modules/.bin/eslint b/tools/eslint/node_modules/.bin/eslint new file mode 120000 index 00000000000000..810e4bcb32af34 --- /dev/null +++ b/tools/eslint/node_modules/.bin/eslint @@ -0,0 +1 @@ +../eslint/bin/eslint.js \ No newline at end of file diff --git a/tools/eslint/node_modules/.bin/strip-json-comments b/tools/eslint/node_modules/.bin/strip-json-comments deleted file mode 120000 index 63d549f96f3b2f..00000000000000 --- a/tools/eslint/node_modules/.bin/strip-json-comments +++ /dev/null @@ -1 +0,0 @@ -../strip-json-comments/cli.js \ No newline at end of file diff --git a/tools/eslint/node_modules/acorn/.tern-project b/tools/eslint/node_modules/acorn/.tern-project deleted file mode 100644 index 6718ce07e1c8a0..00000000000000 --- a/tools/eslint/node_modules/acorn/.tern-project +++ /dev/null @@ -1,6 +0,0 @@ -{ - "plugins": { - "node": true, - "es_modules": true - } -} \ No newline at end of file diff --git a/tools/eslint/node_modules/acorn/AUTHORS b/tools/eslint/node_modules/acorn/AUTHORS index 314d7086cf5bf2..306404542a3b07 100644 --- a/tools/eslint/node_modules/acorn/AUTHORS +++ b/tools/eslint/node_modules/acorn/AUTHORS @@ -25,6 +25,7 @@ Joel Kemp Johannes Herr Jordan Klassen Jürg Lehni +Kai Cataldo keeyipchan Keheliya Gallaba Kevin Irish @@ -32,6 +33,7 @@ Kevin Kwok krator Marijn Haverbeke Martin Carlberg +Mat Garcia Mathias Bynens Mathieu 'p01' Henri Matthew Bastien diff --git a/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js b/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js deleted file mode 100644 index 100e8cf280fc56..00000000000000 --- a/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict'; - -// Which Unicode version should be used? -var version = '9.0.0'; - -var start = require('unicode-' + version + '/Binary_Property/ID_Start/code-points.js') - .filter(function(ch) { return ch > 0x7f; }); -var last = -1; -var cont = [0x200c, 0x200d].concat(require('unicode-' + version + '/Binary_Property/ID_Continue/code-points.js') - .filter(function(ch) { return ch > 0x7f && search(start, ch, last + 1) == -1; })); - -function search(arr, ch, starting) { - for (var i = starting; arr[i] <= ch && i < arr.length; last = i++) - if (arr[i] === ch) - return i; - return -1; -} - -function pad(str, width) { - while (str.length < width) str = "0" + str; - return str; -} - -function esc(code) { - var hex = code.toString(16); - if (hex.length <= 2) return "\\x" + pad(hex, 2); - else return "\\u" + pad(hex, 4); -} - -function generate(chars) { - var astral = [], re = ""; - for (var i = 0, at = 0x10000; i < chars.length; i++) { - var from = chars[i], to = from; - while (i < chars.length - 1 && chars[i + 1] == to + 1) { - i++; - to++; - } - if (to <= 0xffff) { - if (from == to) re += esc(from); - else if (from + 1 == to) re += esc(from) + esc(to); - else re += esc(from) + "-" + esc(to); - } else { - astral.push(from - at, to - from); - at = to; - } - } - return {nonASCII: re, astral: astral}; -} - -var startData = generate(start), contData = generate(cont); - -console.log("let nonASCIIidentifierStartChars = \"" + startData.nonASCII + "\""); -console.log("let nonASCIIidentifierChars = \"" + contData.nonASCII + "\""); -console.log("const astralIdentifierStartCodes = " + JSON.stringify(startData.astral)); -console.log("const astralIdentifierCodes = " + JSON.stringify(contData.astral)); diff --git a/tools/eslint/node_modules/acorn/bin/update_authors.sh b/tools/eslint/node_modules/acorn/bin/update_authors.sh deleted file mode 100755 index e08f57273cdd1e..00000000000000 --- a/tools/eslint/node_modules/acorn/bin/update_authors.sh +++ /dev/null @@ -1,6 +0,0 @@ -# Combine existing list of authors with everyone known in git, sort, add header. -tail --lines=+3 AUTHORS > AUTHORS.tmp -git log --format='%aN' | grep -v abraidwood | grep -v Rich-Harris | grep -v ForbesLindesay >> AUTHORS.tmp -echo -e "List of Acorn contributors. Updated before every release.\n" > AUTHORS -sort -u AUTHORS.tmp >> AUTHORS -rm -f AUTHORS.tmp diff --git a/tools/eslint/node_modules/acorn/dist/acorn.es.js b/tools/eslint/node_modules/acorn/dist/acorn.es.js index adb3dd30f3012a..32dd5954ea0e68 100644 --- a/tools/eslint/node_modules/acorn/dist/acorn.es.js +++ b/tools/eslint/node_modules/acorn/dist/acorn.es.js @@ -1305,7 +1305,12 @@ pp$1.checkVariableExport = function(exports, decls) { } pp$1.shouldParseExportStatement = function() { - return this.type.keyword || this.isLet() || this.isAsyncFunction() + return this.type.keyword === "var" + || this.type.keyword === "const" + || this.type.keyword === "class" + || this.type.keyword === "function" + || this.isLet() + || this.isAsyncFunction() } // Parses a comma-separated list of module exports. @@ -1617,6 +1622,24 @@ pp$2.checkLVal = function(expr, isBinding, checkClashes) { } } +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + var pp$3 = Parser.prototype // Check if property name clashes with already added. @@ -2481,6 +2504,10 @@ pp$5.finishNodeAt = function(node, type, pos, loc) { return finishNodeAt.call(this, node, type, pos, loc) } +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + var TokContext = function TokContext(token, isExpr, preserveSpace, override) { this.token = token this.isExpr = !!isExpr @@ -3290,7 +3317,28 @@ pp$7.readWord = function() { return this.finishToken(type, word) } -var version = "4.0.3" +// Acorn is a tiny, fast JavaScript parser written in JavaScript. +// +// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and +// various contributors and released under an MIT license. +// +// Git repositories for Acorn are available at +// +// http://marijnhaverbeke.nl/git/acorn +// https://github.com/ternjs/acorn.git +// +// Please use the [github bug tracker][ghbt] to report issues. +// +// [ghbt]: https://github.com/ternjs/acorn/issues +// +// This file defines the main parser interface. The library also comes +// with a [error-tolerant parser][dammit] and an +// [abstract syntax tree walker][walk], defined in other files. +// +// [dammit]: acorn_loose.js +// [walk]: util/walk.js + +var version = "4.0.4" // The main exported interface (under `self.acorn` when in the // browser) is a `parse` function that takes a code string and diff --git a/tools/eslint/node_modules/acorn/dist/acorn.js b/tools/eslint/node_modules/acorn/dist/acorn.js index 0fc4086bb72fb6..ea572b3ebd3f4b 100644 --- a/tools/eslint/node_modules/acorn/dist/acorn.js +++ b/tools/eslint/node_modules/acorn/dist/acorn.js @@ -2,3362 +2,3410 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.acorn = global.acorn || {}))); -}(this, function (exports) { 'use strict'; - - // Reserved word lists for various dialects of the language - - var reservedWords = { - 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", - 5: "class enum extends super const export import", - 6: "enum", - strict: "implements interface let package private protected public static yield", - strictBind: "eval arguments" - } - - // And the keywords - - var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" +}(this, (function (exports) { 'use strict'; + +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +} + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" + +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +} + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000 + for (var i = 0; i < set.length; i += 2) { + pos += set[i] + if (pos > code) return false + pos += set[i + 1] + if (pos >= code) return true + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) return code === 36 + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) return code === 36 + if (code < 58) return true + if (code < 65) return false + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label + this.keyword = conf.keyword + this.beforeExpr = !!conf.beforeExpr + this.startsExpr = !!conf.startsExpr + this.isLoop = !!conf.isLoop + this.isAssign = !!conf.isAssign + this.prefix = !!conf.prefix + this.postfix = !!conf.postfix + this.binop = conf.binop || null + this.updateContext = null +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; +// Map keyword names to token types. + +var keywordTypes = {} + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name + return keywordTypes[name] = new TokenType(name, options) +} + +var tt = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=", 6), + relational: binop("", 7), + bitShift: binop("<>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class"), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +} + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/ +var lineBreakG = new RegExp(lineBreak.source, "g") + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g + +function isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]" +} + +// Checks if an object has a property. + +function has(obj, propName) { + return Object.prototype.hasOwnProperty.call(obj, propName) +} + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line + this.column = col +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start + this.end = end + if (p.sourceFile !== null) this.source = p.sourceFile +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur + var match = lineBreakG.exec(input) + if (match && match.index < offset) { + ++line + cur = match.index + match[0].length + } else { + return new Position(line, offset - cur) + } + } +} + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. The default is 7. + ecmaVersion: 7, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +} + +// Interpret and default an options object + +function getOptions(opts) { + var options = {} + + for (var opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] + + if (options.ecmaVersion >= 2015) + options.ecmaVersion -= 2009 + + if (options.allowReserved == null) + options.allowReserved = options.ecmaVersion < 5 + + if (isArray(options.onToken)) { + var tokens = options.onToken + options.onToken = function (token) { return tokens.push(token); } + } + if (isArray(options.onComment)) + options.onComment = pushComment(options, options.onComment) + + return options +} + +function pushComment(options, array) { + return function (block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? 'Block' : 'Line', + value: text, + start: start, + end: end + } + if (options.locations) + comment.loc = new SourceLocation(this, startLoc, endLoc) + if (options.ranges) + comment.range = [start, end] + array.push(comment) + } +} + +// Registered plugins +var plugins = {} + +function keywordRegexp(words) { + return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +} + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options) + this.sourceFile = options.sourceFile + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + var reserved = "" + if (!options.allowReserved) { + for (var v = options.ecmaVersion;; v--) + if (reserved = reservedWords[v]) break + if (options.sourceType == "module") reserved += " await" + } + this.reservedWords = keywordRegexp(reserved) + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict + this.reservedWordsStrict = keywordRegexp(reservedStrict) + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) + this.input = String(input) + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false + + // Load plugins + this.loadPlugins(options.plugins) + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1 + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length + } else { + this.pos = this.lineStart = 0 + this.curLine = 1 + } + + // Properties of the current token: + // Its type + this.type = tt.eof + // For tokens that include more information than their type, the value + this.value = null + // Its start and end offset + this.start = this.end = this.pos + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition() + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null + this.lastTokStart = this.lastTokEnd = this.pos + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext() + this.exprAllowed = true + + // Figure out if it's a module code. + this.strict = this.inModule = options.sourceType === "module" + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1 + + // Flags to track whether we are in a function, a generator, an async function. + this.inFunction = this.inGenerator = this.inAsync = false + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = 0 + // Labels in scope. + this.labels = [] + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') + this.skipLineComment(2) +}; + +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; - var keywords = { - 5: ecma5AndLessKeywords, - 6: ecma5AndLessKeywords + " const class extends export import super" + for (var name in pluginConfigs) { + var plugin = plugins[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) } +}; - // ## Character categories +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode() + this.nextToken() + return this.parseTopLevel(node) +}; - // Big ugly regular expressions that match characters in the - // whitespace, identifier, and identifier-start categories. These - // are only applied when a character is found to actually have a - // code point above 128. - // Generated by `bin/generate-identifier-regex.js`. +var pp = Parser.prototype - var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" - var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" +// ## Parser utilities - var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") - var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") +// Test whether a statement node is the string literal `"use strict"`. - nonASCIIidentifierStartChars = nonASCIIidentifierChars = null +pp.isUseStrict = function(stmt) { + return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && + stmt.expression.type === "Literal" && + stmt.expression.raw.slice(1, -1) === "use strict" +} - // These are a run-length and offset encoded representation of the - // >0xffff code points that are a valid part of identifiers. The - // offset starts at 0x10000, and each pair of numbers represents an - // offset to the next range, and then a size of the range. They were - // generated by bin/generate-identifier-regex.js - var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] - var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. - // This has a complexity linear to the value of the code. The - // assumption is that looking up astral identifier characters is - // rare. - function isInAstralSet(code, set) { - var pos = 0x10000 - for (var i = 0; i < set.length; i += 2) { - pos += set[i] - if (pos > code) return false - pos += set[i + 1] - if (pos >= code) return true - } +pp.eat = function(type) { + if (this.type === type) { + this.next() + return true + } else { + return false } +} - // Test whether a given character code starts an identifier. - - function isIdentifierStart(code, astral) { - if (code < 65) return code === 36 - if (code < 91) return true - if (code < 97) return code === 95 - if (code < 123) return true - if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) - if (astral === false) return false - return isInAstralSet(code, astralIdentifierStartCodes) - } +// Tests whether parsed token is a contextual keyword. - // Test whether a given character is part of an identifier. +pp.isContextual = function(name) { + return this.type === tt.name && this.value === name +} - function isIdentifierChar(code, astral) { - if (code < 48) return code === 36 - if (code < 58) return true - if (code < 65) return false - if (code < 91) return true - if (code < 97) return code === 95 - if (code < 123) return true - if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) - if (astral === false) return false - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) - } +// Consumes contextual keyword if possible. - // ## Token types +pp.eatContextual = function(name) { + return this.value === name && this.eat(tt.name) +} - // The assignment of fine-grained, information-carrying type objects - // allows the tokenizer to store the information it has about a - // token in a way that is very cheap for the parser to look up. +// Asserts that following token is given contextual keyword. - // All token type variables start with an underscore, to make them - // easy to recognize. +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) this.unexpected() +} - // The `beforeExpr` property is used to disambiguate between regular - // expressions and divisions. It is set on all token types that can - // be followed by an expression (thus, a slash after them would be a - // regular expression). - // - // The `startsExpr` property is used to check if the token ends a - // `yield` expression. It is set on all token types that either can - // directly start an expression (like a quotation mark) or can - // continue an expression (like the body of a string). - // - // `isLoop` marks a keyword as starting a loop, which is important - // to know when parsing a label, in order to allow or disallow - // continue jumps to that label. - - var TokenType = function TokenType(label, conf) { - if ( conf === void 0 ) conf = {}; - - this.label = label - this.keyword = conf.keyword - this.beforeExpr = !!conf.beforeExpr - this.startsExpr = !!conf.startsExpr - this.isLoop = !!conf.isLoop - this.isAssign = !!conf.isAssign - this.prefix = !!conf.prefix - this.postfix = !!conf.postfix - this.binop = conf.binop || null - this.updateContext = null - }; - - function binop(name, prec) { - return new TokenType(name, {beforeExpr: true, binop: prec}) - } - var beforeExpr = {beforeExpr: true}; - var startsExpr = {startsExpr: true}; - // Map keyword names to token types. - - var keywordTypes = {} - - // Succinct definitions of keyword token types - function kw(name, options) { - if ( options === void 0 ) options = {}; - - options.keyword = name - return keywordTypes[name] = new TokenType(name, options) - } - - var tt = { - num: new TokenType("num", startsExpr), - regexp: new TokenType("regexp", startsExpr), - string: new TokenType("string", startsExpr), - name: new TokenType("name", startsExpr), - eof: new TokenType("eof"), - - // Punctuation token types. - bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), - bracketR: new TokenType("]"), - braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), - braceR: new TokenType("}"), - parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), - parenR: new TokenType(")"), - comma: new TokenType(",", beforeExpr), - semi: new TokenType(";", beforeExpr), - colon: new TokenType(":", beforeExpr), - dot: new TokenType("."), - question: new TokenType("?", beforeExpr), - arrow: new TokenType("=>", beforeExpr), - template: new TokenType("template"), - ellipsis: new TokenType("...", beforeExpr), - backQuote: new TokenType("`", startsExpr), - dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), - - // Operators. These carry several kinds of properties to help the - // parser use them properly (the presence of these properties is - // what categorizes them as operators). - // - // `binop`, when present, specifies that this operator is a binary - // operator, and will refer to its precedence. - // - // `prefix` and `postfix` mark the operator as a prefix or postfix - // unary operator. - // - // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as - // binary operators with a very low precedence, that should result - // in AssignmentExpression nodes. - - eq: new TokenType("=", {beforeExpr: true, isAssign: true}), - assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), - incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), - prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), - logicalOR: binop("||", 1), - logicalAND: binop("&&", 2), - bitwiseOR: binop("|", 3), - bitwiseXOR: binop("^", 4), - bitwiseAND: binop("&", 5), - equality: binop("==/!=", 6), - relational: binop("", 7), - bitShift: binop("<>", 8), - plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), - modulo: binop("%", 10), - star: binop("*", 10), - slash: binop("/", 10), - starstar: new TokenType("**", {beforeExpr: true}), - - // Keyword token types. - _break: kw("break"), - _case: kw("case", beforeExpr), - _catch: kw("catch"), - _continue: kw("continue"), - _debugger: kw("debugger"), - _default: kw("default", beforeExpr), - _do: kw("do", {isLoop: true, beforeExpr: true}), - _else: kw("else", beforeExpr), - _finally: kw("finally"), - _for: kw("for", {isLoop: true}), - _function: kw("function", startsExpr), - _if: kw("if"), - _return: kw("return", beforeExpr), - _switch: kw("switch"), - _throw: kw("throw", beforeExpr), - _try: kw("try"), - _var: kw("var"), - _const: kw("const"), - _while: kw("while", {isLoop: true}), - _with: kw("with"), - _new: kw("new", {beforeExpr: true, startsExpr: true}), - _this: kw("this", startsExpr), - _super: kw("super", startsExpr), - _class: kw("class"), - _extends: kw("extends", beforeExpr), - _export: kw("export"), - _import: kw("import"), - _null: kw("null", startsExpr), - _true: kw("true", startsExpr), - _false: kw("false", startsExpr), - _in: kw("in", {beforeExpr: true, binop: 7}), - _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), - _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), - _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), - _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) - } - - // Matches a whole line break (where CRLF is considered a single - // line break). Used to count lines. - - var lineBreak = /\r\n?|\n|\u2028|\u2029/ - var lineBreakG = new RegExp(lineBreak.source, "g") - - function isNewLine(code) { - return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 - } - - var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ - - var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g - - function isArray(obj) { - return Object.prototype.toString.call(obj) === "[object Array]" - } - - // Checks if an object has a property. - - function has(obj, propName) { - return Object.prototype.hasOwnProperty.call(obj, propName) - } - - // These are used when `options.locations` is on, for the - // `startLoc` and `endLoc` properties. - - var Position = function Position(line, col) { - this.line = line - this.column = col - }; - - Position.prototype.offset = function offset (n) { - return new Position(this.line, this.column + n) - }; - - var SourceLocation = function SourceLocation(p, start, end) { - this.start = start - this.end = end - if (p.sourceFile !== null) this.source = p.sourceFile - }; - - // The `getLineInfo` function is mostly useful when the - // `locations` option is off (for performance reasons) and you - // want to find the line/column position for a given character - // offset. `input` should be the code string that the offset refers - // into. - - function getLineInfo(input, offset) { - for (var line = 1, cur = 0;;) { - lineBreakG.lastIndex = cur - var match = lineBreakG.exec(input) - if (match && match.index < offset) { - ++line - cur = match.index + match[0].length - } else { - return new Position(line, offset - cur) - } - } - } +// Test whether a semicolon can be inserted at the current position. - // A second optional argument can be given to further configure - // the parser process. These options are recognized: - - var defaultOptions = { - // `ecmaVersion` indicates the ECMAScript version to parse. Must - // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support - // for strict mode, the set of reserved words, and support for - // new syntax features. The default is 7. - ecmaVersion: 7, - // `sourceType` indicates the mode the code should be parsed in. - // Can be either `"script"` or `"module"`. This influences global - // strict mode and parsing of `import` and `export` declarations. - sourceType: "script", - // `onInsertedSemicolon` can be a callback that will be called - // when a semicolon is automatically inserted. It will be passed - // th position of the comma as an offset, and if `locations` is - // enabled, it is given the location as a `{line, column}` object - // as second argument. - onInsertedSemicolon: null, - // `onTrailingComma` is similar to `onInsertedSemicolon`, but for - // trailing commas. - onTrailingComma: null, - // By default, reserved words are only enforced if ecmaVersion >= 5. - // Set `allowReserved` to a boolean value to explicitly turn this on - // an off. When this option has the value "never", reserved words - // and keywords can also not be used as property names. - allowReserved: null, - // When enabled, a return at the top level is not considered an - // error. - allowReturnOutsideFunction: false, - // When enabled, import/export statements are not constrained to - // appearing at the top of the program. - allowImportExportEverywhere: false, - // When enabled, hashbang directive in the beginning of file - // is allowed and treated as a line comment. - allowHashBang: false, - // When `locations` is on, `loc` properties holding objects with - // `start` and `end` properties in `{line, column}` form (with - // line being 1-based and column 0-based) will be attached to the - // nodes. - locations: false, - // A function can be passed as `onToken` option, which will - // cause Acorn to call that function with object in the same - // format as tokens returned from `tokenizer().getToken()`. Note - // that you are not allowed to call the parser from the - // callback—that will corrupt its internal state. - onToken: null, - // A function can be passed as `onComment` option, which will - // cause Acorn to call that function with `(block, text, start, - // end)` parameters whenever a comment is skipped. `block` is a - // boolean indicating whether this is a block (`/* */`) comment, - // `text` is the content of the comment, and `start` and `end` are - // character offsets that denote the start and end of the comment. - // When the `locations` option is on, two more parameters are - // passed, the full `{line, column}` locations of the start and - // end of the comments. Note that you are not allowed to call the - // parser from the callback—that will corrupt its internal state. - onComment: null, - // Nodes have their start and end characters offsets recorded in - // `start` and `end` properties (directly on the node, rather than - // the `loc` object, which holds line/column data. To also add a - // [semi-standardized][range] `range` property holding a `[start, - // end]` array with the same numbers, set the `ranges` option to - // `true`. - // - // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 - ranges: false, - // It is possible to parse multiple files into a single AST by - // passing the tree produced by parsing the first file as - // `program` option in subsequent parses. This will add the - // toplevel forms of the parsed file to the `Program` (top) node - // of an existing parse tree. - program: null, - // When `locations` is on, you can pass this to record the source - // file in every node's `loc` object. - sourceFile: null, - // This value, if given, is stored in every node, whether - // `locations` is on or off. - directSourceFile: null, - // When enabled, parenthesized expressions are represented by - // (non-standard) ParenthesizedExpression nodes - preserveParens: false, - plugins: {} - } - - // Interpret and default an options object - - function getOptions(opts) { - var options = {} - - for (var opt in defaultOptions) - options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] - - if (options.ecmaVersion >= 2015) - options.ecmaVersion -= 2009 - - if (options.allowReserved == null) - options.allowReserved = options.ecmaVersion < 5 - - if (isArray(options.onToken)) { - var tokens = options.onToken - options.onToken = function (token) { return tokens.push(token); } - } - if (isArray(options.onComment)) - options.onComment = pushComment(options, options.onComment) +pp.canInsertSemicolon = function() { + return this.type === tt.eof || + this.type === tt.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +} - return options +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) + return true } +} - function pushComment(options, array) { - return function (block, text, start, end, startLoc, endLoc) { - var comment = { - type: block ? 'Block' : 'Line', - value: text, - start: start, - end: end - } - if (options.locations) - comment.loc = new SourceLocation(this, startLoc, endLoc) - if (options.ranges) - comment.range = [start, end] - array.push(comment) - } - } +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. - // Registered plugins - var plugins = {} +pp.semicolon = function() { + if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() +} - function keywordRegexp(words) { - return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) + if (!notNext) + this.next() + return true } +} - var Parser = function Parser(options, input, startPos) { - this.options = options = getOptions(options) - this.sourceFile = options.sourceFile - this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) - var reserved = "" - if (!options.allowReserved) { - for (var v = options.ecmaVersion;; v--) - if (reserved = reservedWords[v]) break - if (options.sourceType == "module") reserved += " await" - } - this.reservedWords = keywordRegexp(reserved) - var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict - this.reservedWordsStrict = keywordRegexp(reservedStrict) - this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) - this.input = String(input) - - // Used to signal to callers of `readWord1` whether the word - // contained any escape sequences. This is needed because words with - // escape sequences must not be interpreted as keywords. - this.containsEsc = false - - // Load plugins - this.loadPlugins(options.plugins) - - // Set up token state - - // The current position of the tokenizer in the input. - if (startPos) { - this.pos = startPos - this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1 - this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length - } else { - this.pos = this.lineStart = 0 - this.curLine = 1 - } - - // Properties of the current token: - // Its type - this.type = tt.eof - // For tokens that include more information than their type, the value - this.value = null - // Its start and end offset - this.start = this.end = this.pos - // And, if locations are used, the {line, column} object - // corresponding to those offsets - this.startLoc = this.endLoc = this.curPosition() - - // Position information for the previous token - this.lastTokEndLoc = this.lastTokStartLoc = null - this.lastTokStart = this.lastTokEnd = this.pos - - // The context stack is used to superficially track syntactic - // context to predict whether a regular expression is allowed in a - // given position. - this.context = this.initialContext() - this.exprAllowed = true - - // Figure out if it's a module code. - this.strict = this.inModule = options.sourceType === "module" +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. - // Used to signify the start of a potential arrow function - this.potentialArrowAt = -1 +pp.expect = function(type) { + this.eat(type) || this.unexpected() +} - // Flags to track whether we are in a function, a generator, an async function. - this.inFunction = this.inGenerator = this.inAsync = false - // Positions to delayed-check that yield/await does not exist in default parameters. - this.yieldPos = this.awaitPos = 0 - // Labels in scope. - this.labels = [] +// Raise an unexpected token error. - // If enabled, skip leading hashbang line. - if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') - this.skipLineComment(2) - }; +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token") +} - // DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them - Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; - Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; +var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = 0 + this.trailingComma = 0 +}; - Parser.prototype.extend = function extend (name, f) { - this[name] = f(this[name]) - }; +pp.checkPatternErrors = function(refDestructuringErrors, andThrow) { + var trailing = refDestructuringErrors && refDestructuringErrors.trailingComma + if (!andThrow) return !!trailing + if (trailing) this.raise(trailing, "Comma is not permitted after the rest element") +} - Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { - var this$1 = this; +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + var pos = refDestructuringErrors && refDestructuringErrors.shorthandAssign + if (!andThrow) return !!pos + if (pos) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") +} - for (var name in pluginConfigs) { - var plugin = plugins[name] - if (!plugin) throw new Error("Plugin '" + name + "' not found") - plugin(this$1, pluginConfigs[name]) - } - }; +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + this.raise(this.yieldPos, "Yield expression cannot be a default value") + if (this.awaitPos) + this.raise(this.awaitPos, "Await expression cannot be a default value") +} - Parser.prototype.parse = function parse () { - var node = this.options.program || this.startNode() - this.nextToken() - return this.parseTopLevel(node) - }; +var pp$1 = Parser.prototype - var pp = Parser.prototype +// ### Statement parsing - // ## Parser utilities +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. - // Test whether a statement node is the string literal `"use strict"`. +pp$1.parseTopLevel = function(node) { + var this$1 = this; - pp.isUseStrict = function(stmt) { - return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && - stmt.expression.type === "Literal" && - stmt.expression.raw.slice(1, -1) === "use strict" + var first = true, exports = {} + if (!node.body) node.body = [] + while (this.type !== tt.eof) { + var stmt = this$1.parseStatement(true, true, exports) + node.body.push(stmt) + if (first) { + if (this$1.isUseStrict(stmt)) this$1.setStrict(true) + first = false + } } + this.next() + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; +pp$1.isLet = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 91 || nextCh == 123) return true // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} + var ident = this.input.slice(next, pos) + if (!this.isKeyword(ident)) return true + } + return false +} + +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp$1.isAsyncFunction = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 8 || this.value != "async") + return false - // Predicate that tests whether the next token is of the given - // type, and if yes, consumes it as a side effect. - - pp.eat = function(type) { - if (this.type === type) { + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +} + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind + + if (this.isLet()) { + starttype = tt._var + kind = "let" + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case tt._debugger: return this.parseDebuggerStatement(node) + case tt._do: return this.parseDoStatement(node) + case tt._for: return this.parseForStatement(node) + case tt._function: + if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() + return this.parseFunctionStatement(node, false) + case tt._class: + if (!declaration) this.unexpected() + return this.parseClass(node, true) + case tt._if: return this.parseIfStatement(node) + case tt._return: return this.parseReturnStatement(node) + case tt._switch: return this.parseSwitchStatement(node) + case tt._throw: return this.parseThrowStatement(node) + case tt._try: return this.parseTryStatement(node) + case tt._const: case tt._var: + kind = kind || this.value + if (!declaration && kind != "var") this.unexpected() + return this.parseVarStatement(node, kind) + case tt._while: return this.parseWhileStatement(node) + case tt._with: return this.parseWithStatement(node) + case tt.braceL: return this.parseBlock() + case tt.semi: return this.parseEmptyStatement(node) + case tt._export: + case tt._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + this.raise(this.start, "'import' and 'export' may only appear at the top level") + if (!this.inModule) + this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") + } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction() && declaration) { this.next() - return true - } else { - return false + return this.parseFunctionStatement(node, true) } + + var maybeName = this.value, expr = this.parseExpression() + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) + return this.parseLabeledStatement(node, maybeName, expr) + else return this.parseExpressionStatement(node, expr) } +} - // Tests whether parsed token is a contextual keyword. +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; - pp.isContextual = function(name) { - return this.type === tt.name && this.value === name + var isBreak = keyword == "break" + this.next() + if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null + else if (this.type !== tt.name) this.unexpected() + else { + node.label = this.parseIdent() + this.semicolon() } - // Consumes contextual keyword if possible. - - pp.eatContextual = function(name) { - return this.value === name && this.eat(tt.name) + // Verify that there is an actual destination to break or + // continue to. + for (var i = 0; i < this.labels.length; ++i) { + var lab = this$1.labels[i] + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break + if (node.label && isBreak) break + } + } + if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +} + +pp$1.parseDebuggerStatement = function(node) { + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") +} + +pp$1.parseDoStatement = function(node) { + this.next() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + this.expect(tt._while) + node.test = this.parseParenExpression() + if (this.options.ecmaVersion >= 6) + this.eat(tt.semi) + else + this.semicolon() + return this.finishNode(node, "DoWhileStatement") +} + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next() + this.labels.push(loopLabel) + this.expect(tt.parenL) + if (this.type === tt.semi) return this.parseFor(node, null) + var isLet = this.isLet() + if (this.type === tt._var || this.type === tt._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value + this.next() + this.parseVar(init$1, true, kind) + this.finishNode(init$1, "VariableDeclaration") + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) + return this.parseForIn(node, init$1) + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors + var init = this.parseExpression(true, refDestructuringErrors) + if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + this.checkPatternErrors(refDestructuringErrors, true) + this.toAssignable(init) + this.checkLVal(init) + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true) + } + return this.parseFor(node, init) +} + +pp$1.parseFunctionStatement = function(node, isAsync) { + this.next() + return this.parseFunction(node, true, false, isAsync) +} + +pp$1.isFunction = function() { + return this.type === tt._function || this.isAsyncFunction() +} + +pp$1.parseIfStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement(!this.strict && this.isFunction()) + node.alternate = this.eat(tt._else) ? this.parseStatement(!this.strict && this.isFunction()) : null + return this.finishNode(node, "IfStatement") +} + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + this.raise(this.start, "'return' outside of function") + this.next() + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") +} + +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.expect(tt.braceL) + this.labels.push(switchLabel) + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + for (var cur, sawDefault = false; this.type != tt.braceR;) { + if (this$1.type === tt._case || this$1.type === tt._default) { + var isCase = this$1.type === tt._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) { + cur.test = this$1.parseExpression() + } else { + if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses") + sawDefault = true + cur.test = null + } + this$1.expect(tt.colon) + } else { + if (!cur) this$1.unexpected() + cur.consequent.push(this$1.parseStatement(true)) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.next() // Closing brace + this.labels.pop() + return this.finishNode(node, "SwitchStatement") +} + +pp$1.parseThrowStatement = function(node) { + this.next() + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + this.raise(this.lastTokEnd, "Illegal newline after throw") + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") +} + +// Reused empty array added for node fields that are always empty. + +var empty = [] + +pp$1.parseTryStatement = function(node) { + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.type === tt._catch) { + var clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.parseBindingAtom() + this.checkLVal(clause.param, true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) + this.raise(node.start, "Missing catch or finally clause") + return this.finishNode(node, "TryStatement") +} + +pp$1.parseVarStatement = function(node, kind) { + this.next() + this.parseVar(node, false, kind) + this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +pp$1.parseWhileStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "WhileStatement") +} + +pp$1.parseWithStatement = function(node) { + if (this.strict) this.raise(this.start, "'with' in strict mode") + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement(false) + return this.finishNode(node, "WithStatement") +} + +pp$1.parseEmptyStatement = function(node) { + this.next() + return this.finishNode(node, "EmptyStatement") +} + +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + + for (var i = 0; i < this.labels.length; ++i) + if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared") + var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null + for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) { + var label = this$1.labels[i$1] + if (label.statementStart == node.start) { + label.statementStart = this$1.start + label.kind = kind + } else break + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) + node.body = this.parseStatement(true) + this.labels.pop() + node.label = expr + return this.finishNode(node, "LabeledStatement") +} + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") +} + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function(allowStrict) { + var this$1 = this; + + var node = this.startNode(), first = true, oldStrict + node.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + var stmt = this$1.parseStatement(true) + node.body.push(stmt) + if (first && allowStrict && this$1.isUseStrict(stmt)) { + oldStrict = this$1.strict + this$1.setStrict(this$1.strict = true) + } + first = false + } + if (oldStrict === false) this.setStrict(false) + return this.finishNode(node, "BlockStatement") +} + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init + this.expect(tt.semi) + node.test = this.type === tt.semi ? null : this.parseExpression() + this.expect(tt.semi) + node.update = this.type === tt.parenR ? null : this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "ForStatement") +} + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, type) +} + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + + node.declarations = [] + node.kind = kind + for (;;) { + var decl = this$1.startNode() + this$1.parseVarId(decl) + if (this$1.eat(tt.eq)) { + decl.init = this$1.parseMaybeAssign(isFor) + } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected() + } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value") + } else { + decl.init = null + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + if (!this$1.eat(tt.comma)) break + } + return node +} + +pp$1.parseVarId = function(decl) { + decl.id = this.parseBindingAtom() + this.checkLVal(decl.id, true) +} + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node) + if (this.options.ecmaVersion >= 6 && !isAsync) + node.generator = this.eat(tt.star) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + if (isStatement) + node.id = this.parseIdent() + + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + + if (!isStatement && this.type === tt.name) + node.id = this.parseIdent() + this.parseFunctionParams(node) + this.parseFunctionBody(node, allowExpressionBody) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +pp$1.parseFunctionParams = function(node) { + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8, true) + this.checkYieldAwaitInDefaultParams() +} + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + + this.next() + this.parseClassId(node, isStatement) + this.parseClassSuper(node) + var classBody = this.startNode() + var hadConstructor = false + classBody.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (this$1.eat(tt.semi)) continue + var method = this$1.startNode() + var isGenerator = this$1.eat(tt.star) + var isAsync = false + var isMaybeStatic = this$1.type === tt.name && this$1.value === "static" + this$1.parsePropertyName(method) + method.static = isMaybeStatic && this$1.type !== tt.parenL + if (method.static) { + if (isGenerator) this$1.unexpected() + isGenerator = this$1.eat(tt.star) + this$1.parsePropertyName(method) + } + if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== tt.parenL && + !this$1.canInsertSemicolon()) { + isAsync = true + this$1.parsePropertyName(method) + } + method.kind = "method" + var isGetSet = false + if (!method.computed) { + var key = method.key; + if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + isGetSet = true + method.kind = key.name + key = this$1.parsePropertyName(method) + } + if (!method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class") + if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier") + if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator") + if (isAsync) this$1.raise(key.start, "Constructor can't be an async method") + method.kind = "constructor" + hadConstructor = true + } + } + this$1.parseClassMethod(classBody, method, isGenerator, isAsync) + if (isGetSet) { + var paramCount = method.kind === "get" ? 0 : 1 + if (method.value.params.length !== paramCount) { + var start = method.value.start + if (method.kind === "get") + this$1.raiseRecoverable(start, "getter should have no params") + else + this$1.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (method.kind === "set" && method.value.params[0].type === "RestElement") + this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params") + } + } } + node.body = this.finishNode(classBody, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} - // Asserts that following token is given contextual keyword. +pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync) + classBody.body.push(this.finishNode(method, "MethodDefinition")) +} - pp.expectContextual = function(name) { - if (!this.eatContextual(name)) this.unexpected() - } +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null +} - // Test whether a semicolon can be inserted at the current position. +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null +} - pp.canInsertSemicolon = function() { - return this.type === tt.eof || - this.type === tt.braceR || - lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) - } +// Parses module export declaration. - pp.insertSemicolon = function() { - if (this.canInsertSemicolon()) { - if (this.options.onInsertedSemicolon) - this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) - return true +pp$1.parseExport = function(node, exports) { + var this$1 = this; + + this.next() + // export * from '...' + if (this.eat(tt.star)) { + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + this.semicolon() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart) + var parens = this.type == tt.parenL + var expr = this.parseMaybeAssign() + var needsSemi = true + if (!parens && (expr.type == "FunctionExpression" || + expr.type == "ClassExpression")) { + needsSemi = false + if (expr.id) { + expr.type = expr.type == "FunctionExpression" + ? "FunctionDeclaration" + : "ClassDeclaration" + } } + node.declaration = expr + if (needsSemi) this.semicolon() + return this.finishNode(node, "ExportDefaultDeclaration") } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true) + if (node.declaration.type === "VariableDeclaration") + this.checkVariableExport(exports, node.declaration.declarations) + else + this.checkExport(exports, node.declaration.id.name, node.declaration.id.start) + node.specifiers = [] + node.source = null + } else { // export { x, y as z } [from '...'] + node.declaration = null + node.specifiers = this.parseExportSpecifiers(exports) + if (this.eatContextual("from")) { + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } else { + // check for keywords used as local names + for (var i = 0; i < node.specifiers.length; i++) { + if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) { + this$1.unexpected(node.specifiers[i].local.start) + } + } - // Consume a semicolon, or, failing that, see if we are allowed to - // pretend that there is a semicolon at this position. - - pp.semicolon = function() { - if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() + node.source = null + } + this.semicolon() } - - pp.afterTrailingComma = function(tokType, notNext) { - if (this.type == tokType) { - if (this.options.onTrailingComma) - this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) - if (!notNext) - this.next() - return true + return this.finishNode(node, "ExportNamedDeclaration") +} + +pp$1.checkExport = function(exports, name, pos) { + if (!exports) return + if (Object.prototype.hasOwnProperty.call(exports, name)) + this.raiseRecoverable(pos, "Duplicate export '" + name + "'") + exports[name] = true +} + +pp$1.checkPatternExport = function(exports, pat) { + var this$1 = this; + + var type = pat.type + if (type == "Identifier") + this.checkExport(exports, pat.name, pat.start) + else if (type == "ObjectPattern") + for (var i = 0; i < pat.properties.length; ++i) + this$1.checkPatternExport(exports, pat.properties[i].value) + else if (type == "ArrayPattern") + for (var i$1 = 0; i$1 < pat.elements.length; ++i$1) { + var elt = pat.elements[i$1] + if (elt) this$1.checkPatternExport(exports, elt) + } + else if (type == "AssignmentPattern") + this.checkPatternExport(exports, pat.left) + else if (type == "ParenthesizedExpression") + this.checkPatternExport(exports, pat.expression) +} + +pp$1.checkVariableExport = function(exports, decls) { + var this$1 = this; + + if (!exports) return + for (var i = 0; i < decls.length; i++) + this$1.checkPatternExport(exports, decls[i].id) +} + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" + || this.type.keyword === "const" + || this.type.keyword === "class" + || this.type.keyword === "function" + || this.isLet() + || this.isAsyncFunction() +} + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function(exports) { + var this$1 = this; + + var nodes = [], first = true + // export { x, y as z } [from '...'] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node = this$1.startNode() + node.local = this$1.parseIdent(this$1.type === tt._default) + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local + this$1.checkExport(exports, node.exported.name, node.exported.start) + nodes.push(this$1.finishNode(node, "ExportSpecifier")) + } + return nodes +} + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next() + // import '...' + if (this.type === tt.string) { + node.specifiers = empty + node.source = this.parseExprAtom() + } else { + node.specifiers = this.parseImportSpecifiers() + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + if (this.type === tt.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode() + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) + if (!this.eat(tt.comma)) return nodes + } + if (this.type === tt.star) { + var node$1 = this.startNode() + this.next() + this.expectContextual("as") + node$1.local = this.parseIdent() + this.checkLVal(node$1.local, true) + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")) + return nodes + } + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node$2 = this$1.startNode() + node$2.imported = this$1.parseIdent(true) + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent() + } else { + node$2.local = node$2.imported + if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start) + if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raiseRecoverable(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved") } + this$1.checkLVal(node$2.local, true) + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")) } + return nodes +} - // Expect a token of a given type. If found, consume it, otherwise, - // raise an unexpected token error. - - pp.expect = function(type) { - this.eat(type) || this.unexpected() - } +var pp$2 = Parser.prototype - // Raise an unexpected token error. +// Convert existing expression atom to assignable pattern +// if possible. - pp.unexpected = function(pos) { - this.raise(pos != null ? pos : this.start, "Unexpected token") - } +pp$2.toAssignable = function(node, isBinding) { + var this$1 = this; - var DestructuringErrors = function DestructuringErrors() { - this.shorthandAssign = 0 - this.trailingComma = 0 - }; + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + this.raise(node.start, "Can not use 'await' as identifier inside an async function") + break - pp.checkPatternErrors = function(refDestructuringErrors, andThrow) { - var trailing = refDestructuringErrors && refDestructuringErrors.trailingComma - if (!andThrow) return !!trailing - if (trailing) this.raise(trailing, "Comma is not permitted after the rest element") - } + case "ObjectPattern": + case "ArrayPattern": + break - pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { - var pos = refDestructuringErrors && refDestructuringErrors.shorthandAssign - if (!andThrow) return !!pos - if (pos) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") - } + case "ObjectExpression": + node.type = "ObjectPattern" + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i] + if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter") + this$1.toAssignable(prop.value, isBinding) + } + break - pp.checkYieldAwaitInDefaultParams = function() { - if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) - this.raise(this.yieldPos, "Yield expression cannot be a default value") - if (this.awaitPos) - this.raise(this.awaitPos, "Await expression cannot be a default value") - } + case "ArrayExpression": + node.type = "ArrayPattern" + this.toAssignableList(node.elements, isBinding) + break - var pp$1 = Parser.prototype + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern" + delete node.operator + this.toAssignable(node.left, isBinding) + // falls through to AssignmentPattern + } else { + this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") + break + } - // ### Statement parsing + case "AssignmentPattern": + break - // Parse a program. Initializes the parser, reads any number of - // statements, and wraps them in a Program node. Optionally takes a - // `program` argument. If present, the statements will be appended - // to its body instead of creating a new node. + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isBinding) + break - pp$1.parseTopLevel = function(node) { - var this$1 = this; + case "MemberExpression": + if (!isBinding) break - var first = true, exports = {} - if (!node.body) node.body = [] - while (this.type !== tt.eof) { - var stmt = this$1.parseStatement(true, true, exports) - node.body.push(stmt) - if (first) { - if (this$1.isUseStrict(stmt)) this$1.setStrict(true) - first = false - } - } - this.next() - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType - } - return this.finishNode(node, "Program") - } - - var loopLabel = {kind: "loop"}; - var switchLabel = {kind: "switch"}; - pp$1.isLet = function() { - if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false - skipWhiteSpace.lastIndex = this.pos - var skip = skipWhiteSpace.exec(this.input) - var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) - if (nextCh === 91 || nextCh == 123) return true // '{' and '[' - if (isIdentifierStart(nextCh, true)) { - for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} - var ident = this.input.slice(next, pos) - if (!this.isKeyword(ident)) return true + default: + this.raise(node.start, "Assigning to rvalue") } - return false } + return node +} - // check 'async [no LineTerminator here] function' - // - 'async /*foo*/ function' is OK. - // - 'async /*\n*/ function' is invalid. - pp$1.isAsyncFunction = function() { - if (this.type !== tt.name || this.options.ecmaVersion < 8 || this.value != "async") - return false +// Convert list of expression atoms to binding list. - skipWhiteSpace.lastIndex = this.pos - var skip = skipWhiteSpace.exec(this.input) - var next = this.pos + skip[0].length - return !lineBreak.test(this.input.slice(this.pos, next)) && - this.input.slice(next, next + 8) === "function" && - (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + + var end = exprList.length + if (end) { + var last = exprList[end - 1] + if (last && last.type == "RestElement") { + --end + } else if (last && last.type == "SpreadElement") { + last.type = "RestElement" + var arg = last.argument + this.toAssignable(arg, isBinding) + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") + this.unexpected(arg.start) + --end + } + + if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + this.unexpected(last.argument.start) + } + for (var i = 0; i < end; i++) { + var elt = exprList[i] + if (elt) this$1.toAssignable(elt, isBinding) } + return exprList +} - // Parse a single statement. - // - // If expecting a statement and finding a slash operator, parse a - // regular expression literal. This is to handle cases like - // `if (foo) /blah/.exec(foo)`, where looking at the previous token - // does not help. +// Parses spread element. - pp$1.parseStatement = function(declaration, topLevel, exports) { - var starttype = this.type, node = this.startNode(), kind +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeAssign(false, refDestructuringErrors) + return this.finishNode(node, "SpreadElement") +} - if (this.isLet()) { - starttype = tt._var - kind = "let" - } +pp$2.parseRest = function(allowNonIdent) { + var node = this.startNode() + this.next() - // Most types of statements are recognized by the keyword they - // start with. Many are trivial to parse, some require a bit of - // complexity. - - switch (starttype) { - case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) - case tt._debugger: return this.parseDebuggerStatement(node) - case tt._do: return this.parseDoStatement(node) - case tt._for: return this.parseForStatement(node) - case tt._function: - if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() - return this.parseFunctionStatement(node, false) - case tt._class: - if (!declaration) this.unexpected() - return this.parseClass(node, true) - case tt._if: return this.parseIfStatement(node) - case tt._return: return this.parseReturnStatement(node) - case tt._switch: return this.parseSwitchStatement(node) - case tt._throw: return this.parseThrowStatement(node) - case tt._try: return this.parseTryStatement(node) - case tt._const: case tt._var: - kind = kind || this.value - if (!declaration && kind != "var") this.unexpected() - return this.parseVarStatement(node, kind) - case tt._while: return this.parseWhileStatement(node) - case tt._with: return this.parseWithStatement(node) - case tt.braceL: return this.parseBlock() - case tt.semi: return this.parseEmptyStatement(node) - case tt._export: - case tt._import: - if (!this.options.allowImportExportEverywhere) { - if (!topLevel) - this.raise(this.start, "'import' and 'export' may only appear at the top level") - if (!this.inModule) - this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") - } - return starttype === tt._import ? this.parseImport(node) : this.parseExport(node, exports) + // RestElement inside of a function parameter must be an identifier + if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() + else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() - // If the statement does not start with a statement keyword or a - // brace, it's an ExpressionStatement or LabeledStatement. We - // simply start parsing an expression, and afterwards, if the - // next token is a colon and the expression was a simple - // Identifier node, we switch to interpreting it as a label. - default: - if (this.isAsyncFunction() && declaration) { - this.next() - return this.parseFunctionStatement(node, true) - } + return this.finishNode(node, "RestElement") +} - var maybeName = this.value, expr = this.parseExpression() - if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) - return this.parseLabeledStatement(node, maybeName, expr) - else return this.parseExpressionStatement(node, expr) - } - } +// Parses lvalue (assignable) atom. - pp$1.parseBreakContinueStatement = function(node, keyword) { - var this$1 = this; +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion < 6) return this.parseIdent() + switch (this.type) { + case tt.name: + return this.parseIdent() - var isBreak = keyword == "break" + case tt.bracketL: + var node = this.startNode() this.next() - if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null - else if (this.type !== tt.name) this.unexpected() - else { - node.label = this.parseIdent() - this.semicolon() - } + node.elements = this.parseBindingList(tt.bracketR, true, true) + return this.finishNode(node, "ArrayPattern") - // Verify that there is an actual destination to break or - // continue to. - for (var i = 0; i < this.labels.length; ++i) { - var lab = this$1.labels[i] - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) break - if (node.label && isBreak) break - } - } - if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) - return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") - } + case tt.braceL: + return this.parseObj(true) - pp$1.parseDebuggerStatement = function(node) { - this.next() - this.semicolon() - return this.finishNode(node, "DebuggerStatement") + default: + this.unexpected() } +} + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { + var this$1 = this; - pp$1.parseDoStatement = function(node) { + var elts = [], first = true + while (!this.eat(close)) { + if (first) first = false + else this$1.expect(tt.comma) + if (allowEmpty && this$1.type === tt.comma) { + elts.push(null) + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === tt.ellipsis) { + var rest = this$1.parseRest(allowNonIdent) + this$1.parseBindingListItem(rest) + elts.push(rest) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + this$1.expect(close) + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc) + this$1.parseBindingListItem(elem) + elts.push(elem) + } + } + return elts +} + +pp$2.parseBindingListItem = function(param) { + return param +} + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom() + if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.right = this.parseMaybeAssign() + return this.finishNode(node, "AssignmentPattern") +} + +// Verify that a node is an lval — something that can be assigned +// to. + +pp$2.checkLVal = function(expr, isBinding, checkClashes) { + var this$1 = this; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") + if (checkClashes) { + if (has(checkClashes, expr.name)) + this.raiseRecoverable(expr.start, "Argument name clash") + checkClashes[expr.name] = true + } + break + + case "MemberExpression": + if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") + break + + case "ObjectPattern": + for (var i = 0; i < expr.properties.length; i++) + this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes) + break + + case "ArrayPattern": + for (var i$1 = 0; i$1 < expr.elements.length; i$1++) { + var elem = expr.elements[i$1] + if (elem) this$1.checkLVal(elem, isBinding, checkClashes) + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes) + break + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes) + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, isBinding, checkClashes) + break + + default: + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") + } +} + +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + +var pp$3 = Parser.prototype + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash) { + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + return + var key = prop.key; + var name + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") + propHash.proto = true + } + return + } + name = "$" + name + var other = propHash[name] + if (other) { + var isGetSet = kind !== "init" + if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) + this.raiseRecoverable(key.start, "Redefinition of property") + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + } + } + other[kind] = true +} + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors) + if (this.type === tt.comma) { + var node = this.startNodeAt(startPos, startLoc) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) return this.parseYield() + + var ownDestructuringErrors = false + if (!refDestructuringErrors) { + refDestructuringErrors = new DestructuringErrors + ownDestructuringErrors = true + } + var startPos = this.start, startLoc = this.startLoc + if (this.type == tt.parenL || this.type == tt.name) + this.potentialArrowAt = this.start + var left = this.parseMaybeConditional(noIn, refDestructuringErrors) + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) + if (this.type.isAssign) { + this.checkPatternErrors(refDestructuringErrors, true) + if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) + var node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.left = this.type === tt.eq ? this.toAssignable(left) : left + refDestructuringErrors.shorthandAssign = 0 // reset because shorthand default was used correctly + this.checkLVal(left) this.next() - this.labels.push(loopLabel) - node.body = this.parseStatement(false) - this.labels.pop() - this.expect(tt._while) - node.test = this.parseParenExpression() - if (this.options.ecmaVersion >= 6) - this.eat(tt.semi) - else - this.semicolon() - return this.finishNode(node, "DoWhileStatement") + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) } + return left +} - // Disambiguating between a `for` and a `for`/`in` or `for`/`of` - // loop is non-trivial. Basically, we have to parse the init `var` - // statement or expression, disallowing the `in` operator (see - // the second parameter to `parseExpression`), and then check - // whether the next token is `in` or `of`. When there is no init - // part (semicolon immediately after the opening parenthesis), it - // is a regular `for` loop. +// Parse a ternary conditional (`?:`) operator. - pp$1.parseForStatement = function(node) { - this.next() - this.labels.push(loopLabel) - this.expect(tt.parenL) - if (this.type === tt.semi) return this.parseFor(node, null) - var isLet = this.isLet() - if (this.type === tt._var || this.type === tt._const || isLet) { - var init$1 = this.startNode(), kind = isLet ? "let" : this.value +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprOps(noIn, refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + if (this.eat(tt.question)) { + var node = this.startNodeAt(startPos, startLoc) + node.test = expr + node.consequent = this.parseMaybeAssign() + this.expect(tt.colon) + node.alternate = this.parseMaybeAssign(noIn) + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +// Start the precedence parser. + +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeUnary(refDestructuringErrors, false) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + return this.parseExprOp(expr, startPos, startLoc, -1, noIn) +} + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop + if (prec != null && (!noIn || this.type !== tt._in)) { + if (prec > minPrec) { + var logical = this.type === tt.logicalOR || this.type === tt.logicalAND + var op = this.value this.next() - this.parseVar(init$1, true, kind) - this.finishNode(init$1, "VariableDeclaration") - if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && - !(kind !== "var" && init$1.declarations[0].init)) - return this.parseForIn(node, init$1) - return this.parseFor(node, init$1) + var startPos = this.start, startLoc = this.startLoc + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +} + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.operator = op + node.right = right + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +} + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, expr + if (this.inAsync && this.isContextual("await")) { + expr = this.parseAwait(refDestructuringErrors) + sawUnary = true + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === tt.incDec + node.operator = this.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(null, true) + this.checkExpressionErrors(refDestructuringErrors, true) + if (update) this.checkLVal(node.argument) + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + this.raiseRecoverable(node.start, "Deleting local variable in strict mode") + else sawUnary = true + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else { + expr = this.parseExprSubscripts(refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.operator = this$1.value + node$1.prefix = false + node$1.argument = expr + this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$1, "UpdateExpression") } - var refDestructuringErrors = new DestructuringErrors - var init = this.parseExpression(true, refDestructuringErrors) - if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - this.checkPatternErrors(refDestructuringErrors, true) - this.toAssignable(init) - this.checkLVal(init) - return this.parseForIn(node, init) + } + + if (!sawUnary && this.eat(tt.starstar)) + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + else + return expr +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprAtom(refDestructuringErrors) + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr + return this.parseSubscripts(expr, startPos, startLoc) +} + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + + for (;;) { + var maybeAsyncArrow = this$1.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && !this$1.canInsertSemicolon() + if (this$1.eat(tt.dot)) { + var node = this$1.startNodeAt(startPos, startLoc) + node.object = base + node.property = this$1.parseIdent(true) + node.computed = false + base = this$1.finishNode(node, "MemberExpression") + } else if (this$1.eat(tt.bracketL)) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.object = base + node$1.property = this$1.parseExpression() + node$1.computed = true + this$1.expect(tt.bracketR) + base = this$1.finishNode(node$1, "MemberExpression") + } else if (!noCalls && this$1.eat(tt.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos + this$1.yieldPos = 0 + this$1.awaitPos = 0 + var exprList = this$1.parseExprList(tt.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors) + if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(tt.arrow)) { + this$1.checkPatternErrors(refDestructuringErrors, true) + this$1.checkYieldAwaitInDefaultParams() + this$1.yieldPos = oldYieldPos + this$1.awaitPos = oldAwaitPos + return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) + } + this$1.checkExpressionErrors(refDestructuringErrors, true) + this$1.yieldPos = oldYieldPos || this$1.yieldPos + this$1.awaitPos = oldAwaitPos || this$1.awaitPos + var node$2 = this$1.startNodeAt(startPos, startLoc) + node$2.callee = base + node$2.arguments = exprList + base = this$1.finishNode(node$2, "CallExpression") + } else if (this$1.type === tt.backQuote) { + var node$3 = this$1.startNodeAt(startPos, startLoc) + node$3.tag = base + node$3.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$3, "TaggedTemplateExpression") } else { - this.checkExpressionErrors(refDestructuringErrors, true) + return base } - return this.parseFor(node, init) } +} - pp$1.parseFunctionStatement = function(node, isAsync) { - this.next() - return this.parseFunction(node, true, false, isAsync) - } +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. - pp$1.isFunction = function() { - return this.type === tt._function || this.isAsyncFunction() - } +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt == this.start + switch (this.type) { + case tt._super: + if (!this.inFunction) + this.raise(this.start, "'super' outside of function or class") - pp$1.parseIfStatement = function(node) { + case tt._this: + var type = this.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() this.next() - node.test = this.parseParenExpression() - // allow function declarations in branches, but only in non-strict mode - node.consequent = this.parseStatement(!this.strict && this.isFunction()) - node.alternate = this.eat(tt._else) ? this.parseStatement(!this.strict && this.isFunction()) : null - return this.finishNode(node, "IfStatement") - } + return this.finishNode(node, type) - pp$1.parseReturnStatement = function(node) { - if (!this.inFunction && !this.options.allowReturnOutsideFunction) - this.raise(this.start, "'return' outside of function") - this.next() + case tt.name: + var startPos = this.start, startLoc = this.startLoc + var id = this.parseIdent(this.type !== tt.name) + if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function)) + return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) { + id = this.parseIdent() + if (this.canInsertSemicolon() || !this.eat(tt.arrow)) + this.unexpected() + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id - // In `return` (and `break`/`continue`), the keywords with - // optional arguments, we eagerly look for a semicolon or the - // possibility to insert one. + case tt.regexp: + var value = this.value + node = this.parseLiteral(value.value) + node.regex = {pattern: value.pattern, flags: value.flags} + return node - if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null - else { node.argument = this.parseExpression(); this.semicolon() } - return this.finishNode(node, "ReturnStatement") - } + case tt.num: case tt.string: + return this.parseLiteral(this.value) - pp$1.parseSwitchStatement = function(node) { - var this$1 = this; + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.type === tt._null ? null : this.type === tt._true + node.raw = this.type.keyword + this.next() + return this.finishNode(node, "Literal") + case tt.parenL: + return this.parseParenAndDistinguishExpression(canBeArrow) + + case tt.bracketL: + node = this.startNode() this.next() - node.discriminant = this.parseParenExpression() - node.cases = [] - this.expect(tt.braceL) - this.labels.push(switchLabel) - - // Statements under must be grouped (by label) in SwitchCase - // nodes. `cur` is used to keep the node that we are currently - // adding statements to. - - for (var cur, sawDefault = false; this.type != tt.braceR;) { - if (this$1.type === tt._case || this$1.type === tt._default) { - var isCase = this$1.type === tt._case - if (cur) this$1.finishNode(cur, "SwitchCase") - node.cases.push(cur = this$1.startNode()) - cur.consequent = [] - this$1.next() - if (isCase) { - cur.test = this$1.parseExpression() - } else { - if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses") - sawDefault = true - cur.test = null - } - this$1.expect(tt.colon) - } else { - if (!cur) this$1.unexpected() - cur.consequent.push(this$1.parseStatement(true)) - } - } - if (cur) this.finishNode(cur, "SwitchCase") - this.next() // Closing brace - this.labels.pop() - return this.finishNode(node, "SwitchStatement") - } + node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj(false, refDestructuringErrors) - pp$1.parseThrowStatement = function(node) { + case tt._function: + node = this.startNode() this.next() - if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) - this.raise(this.lastTokEnd, "Illegal newline after throw") - node.argument = this.parseExpression() - this.semicolon() - return this.finishNode(node, "ThrowStatement") - } + return this.parseFunction(node, false) - // Reused empty array added for node fields that are always empty. + case tt._class: + return this.parseClass(this.startNode(), false) - var empty = [] + case tt._new: + return this.parseNew() - pp$1.parseTryStatement = function(node) { - this.next() - node.block = this.parseBlock() - node.handler = null - if (this.type === tt._catch) { - var clause = this.startNode() - this.next() - this.expect(tt.parenL) - clause.param = this.parseBindingAtom() - this.checkLVal(clause.param, true) - this.expect(tt.parenR) - clause.body = this.parseBlock() - node.handler = this.finishNode(clause, "CatchClause") - } - node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null - if (!node.handler && !node.finalizer) - this.raise(node.start, "Missing catch or finally clause") - return this.finishNode(node, "TryStatement") - } + case tt.backQuote: + return this.parseTemplate() - pp$1.parseVarStatement = function(node, kind) { - this.next() - this.parseVar(node, false, kind) - this.semicolon() - return this.finishNode(node, "VariableDeclaration") + default: + this.unexpected() } +} - pp$1.parseWhileStatement = function(node) { - this.next() - node.test = this.parseParenExpression() - this.labels.push(loopLabel) - node.body = this.parseStatement(false) - this.labels.pop() - return this.finishNode(node, "WhileStatement") - } +pp$3.parseLiteral = function(value) { + var node = this.startNode() + node.value = value + node.raw = this.input.slice(this.start, this.end) + this.next() + return this.finishNode(node, "Literal") +} - pp$1.parseWithStatement = function(node) { - if (this.strict) this.raise(this.start, "'with' in strict mode") - this.next() - node.object = this.parseParenExpression() - node.body = this.parseStatement(false) - return this.finishNode(node, "WithStatement") - } +pp$3.parseParenExpression = function() { + this.expect(tt.parenL) + var val = this.parseExpression() + this.expect(tt.parenR) + return val +} - pp$1.parseEmptyStatement = function(node) { +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8 + if (this.options.ecmaVersion >= 6) { this.next() - return this.finishNode(node, "EmptyStatement") - } - pp$1.parseLabeledStatement = function(node, maybeName, expr) { - var this$1 = this; + var innerStartPos = this.start, innerStartLoc = this.startLoc + var exprList = [], first = true, lastIsComma = false + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart + this.yieldPos = 0 + this.awaitPos = 0 + while (this.type !== tt.parenR) { + first ? first = false : this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(tt.parenR, true)) { + lastIsComma = true + break + } else if (this$1.type === tt.ellipsis) { + spreadStart = this$1.start + exprList.push(this$1.parseParenItem(this$1.parseRest())) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + break + } else { + if (this$1.type === tt.parenL && !innerParenStart) { + innerParenStart = this$1.start + } + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)) + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc + this.expect(tt.parenR) - for (var i = 0; i < this.labels.length; ++i) - if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared") - var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null - for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) { - var label = this$1.labels[i$1] - if (label.statementStart == node.start) { - label.statementStart = this$1.start - label.kind = kind - } else break + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, true) + this.checkYieldAwaitInDefaultParams() + if (innerParenStart) this.unexpected(innerParenStart) + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart) + if (spreadStart) this.unexpected(spreadStart) + this.checkExpressionErrors(refDestructuringErrors, true) + this.yieldPos = oldYieldPos || this.yieldPos + this.awaitPos = oldAwaitPos || this.awaitPos + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc) + val.expressions = exprList + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) + } else { + val = exprList[0] } - this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) - node.body = this.parseStatement(true) - this.labels.pop() - node.label = expr - return this.finishNode(node, "LabeledStatement") + } else { + val = this.parseParenExpression() } - pp$1.parseExpressionStatement = function(node, expr) { - node.expression = expr - this.semicolon() - return this.finishNode(node, "ExpressionStatement") + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc) + par.expression = val + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val } - - // Parse a semicolon-enclosed block of statements, handling `"use - // strict"` declarations when `allowStrict` is true (used for - // function bodies). - - pp$1.parseBlock = function(allowStrict) { - var this$1 = this; - - var node = this.startNode(), first = true, oldStrict - node.body = [] - this.expect(tt.braceL) - while (!this.eat(tt.braceR)) { - var stmt = this$1.parseStatement(true) - node.body.push(stmt) - if (first && allowStrict && this$1.isUseStrict(stmt)) { - oldStrict = this$1.strict - this$1.setStrict(this$1.strict = true) +} + +pp$3.parseParenItem = function(item) { + return item +} + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +} + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = [] + +pp$3.parseNew = function() { + var node = this.startNode() + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + if (node.property.name !== "target") + this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") + if (!this.inFunction) + this.raiseRecoverable(node.start, "new.target can only be used in functions") + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false) + else node.arguments = empty$1 + return this.finishNode(node, "NewExpression") +} + +// Parse template expression. + +pp$3.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), + cooked: this.value + } + this.next() + elem.tail = this.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +pp$3.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.expect(tt.dollarBraceL) + node.expressions.push(this$1.parseExpression()) + this$1.expect(tt.braceR) + node.quasis.push(curElt = this$1.parseTemplateElement()) + } + this.next() + return this.finishNode(node, "TemplateLiteral") +} + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + + var node = this.startNode(), first = true, propHash = {} + node.properties = [] + this.next() + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var prop = this$1.startNode(), isGenerator, isAsync, startPos, startLoc + if (this$1.options.ecmaVersion >= 6) { + prop.method = false + prop.shorthand = false + if (isPattern || refDestructuringErrors) { + startPos = this$1.start + startLoc = this$1.startLoc } - first = false + if (!isPattern) + isGenerator = this$1.eat(tt.star) } - if (oldStrict === false) this.setStrict(false) - return this.finishNode(node, "BlockStatement") - } + this$1.parsePropertyName(prop) + if (!isPattern && this$1.options.ecmaVersion >= 8 && !isGenerator && !prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this$1.type !== tt.parenL && + this$1.type !== tt.colon && !this$1.canInsertSemicolon()) { + isAsync = true + this$1.parsePropertyName(prop, refDestructuringErrors) + } else { + isAsync = false + } + this$1.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) + this$1.checkPropClash(prop, propHash) + node.properties.push(this$1.finishNode(prop, "Property")) + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +} + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) { + if ((isGenerator || isAsync) && this.type === tt.colon) + this.unexpected() + + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) + prop.kind = "init" + } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { + if (isPattern) this.unexpected() + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator, isAsync) + } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != tt.comma && this.type != tt.braceR)) { + if (isGenerator || isAsync || isPattern) this.unexpected() + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + var paramCount = prop.kind === "get" ? 0 : 1 + if (prop.value.params.length !== paramCount) { + var start = prop.value.start + if (prop.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (this.keywords.test(prop.key.name) || + (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) || + (this.inGenerator && prop.key.name == "yield") || + (this.inAsync && prop.key.name == "await")) + this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") + prop.kind = "init" + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else if (this.type === tt.eq && refDestructuringErrors) { + if (!refDestructuringErrors.shorthandAssign) + refDestructuringErrors.shorthandAssign = this.start + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else { + prop.value = prop.key + } + prop.shorthand = true + } else this.unexpected() +} + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseMaybeAssign() + this.expect(tt.bracketR) + return prop.key + } else { + prop.computed = false + } + } + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) +} + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos + + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8) + this.checkYieldAwaitInDefaultParams() + this.parseFunctionBody(node, false) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.finishNode(node, "FunctionExpression") +} + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos + + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = false + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + + node.params = this.toAssignableList(params, true) + this.parseFunctionBody(node, true) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.finishNode(node, "ArrowFunctionExpression") +} + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== tt.braceL + + if (isExpression) { + node.body = this.parseMaybeAssign() + node.expression = true + } else { + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldInFunc = this.inFunction, oldLabels = this.labels + this.inFunction = true; this.labels = [] + node.body = this.parseBlock(true) + node.expression = false + this.inFunction = oldInFunc; this.labels = oldLabels + } + + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + var useStrict = (!isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) ? node.body.body[0] : null + if (useStrict && this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params)) + this.raiseRecoverable(useStrict.start, "Illegal 'use strict' directive in function with non-simple parameter list") + + if (this.strict || useStrict) { + var oldStrict = this.strict + this.strict = true + if (node.id) + this.checkLVal(node.id, true) + this.checkParams(node) + this.strict = oldStrict + } else if (isArrowFunction || !this.isSimpleParamList(node.params)) { + this.checkParams(node) + } +} + +pp$3.isSimpleParamList = function(params) { + for (var i = 0; i < params.length; i++) + if (params[i].type !== "Identifier") return false + return true +} + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node) { + var this$1 = this; + + var nameHash = {} + for (var i = 0; i < node.params.length; i++) this$1.checkLVal(node.params[i], true, nameHash) +} + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (!first) { + this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(close)) break + } else first = false + + var elt + if (allowEmpty && this$1.type === tt.comma) + elt = null + else if (this$1.type === tt.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors) + if (this$1.type === tt.comma && refDestructuringErrors && !refDestructuringErrors.trailingComma) { + refDestructuringErrors.trailingComma = this$1.start + } + } else + elt = this$1.parseMaybeAssign(false, refDestructuringErrors) + elts.push(elt) + } + return elts +} + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal) { + var node = this.startNode() + if (liberal && this.options.allowReserved == "never") liberal = false + if (this.type === tt.name) { + if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && + (this.options.ecmaVersion >= 6 || + this.input.slice(this.start, this.end).indexOf("\\") == -1)) + this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") + if (this.inGenerator && this.value === "yield") + this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") + if (this.inAsync && this.value === "await") + this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function") + node.name = this.value + } else if (liberal && this.type.keyword) { + node.name = this.type.keyword + } else { + this.unexpected() + } + this.next() + return this.finishNode(node, "Identifier") +} + +// Parses yield expression inside generator. + +pp$3.parseYield = function() { + if (!this.yieldPos) this.yieldPos = this.start + + var node = this.startNode() + this.next() + if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") +} + +pp$3.parseAwait = function() { + if (!this.awaitPos) this.awaitPos = this.start + + var node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary(null, true) + return this.finishNode(node, "AwaitExpression") +} + +var pp$4 = Parser.prototype + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos) + message += " (" + loc.line + ":" + loc.column + ")" + var err = new SyntaxError(message) + err.pos = pos; err.loc = loc; err.raisedAt = this.pos + throw err +} + +pp$4.raiseRecoverable = pp$4.raise + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +} + +var Node = function Node(parser, pos, loc) { + this.type = "" + this.start = pos + this.end = 0 + if (parser.options.locations) + this.loc = new SourceLocation(parser, loc) + if (parser.options.directSourceFile) + this.sourceFile = parser.options.directSourceFile + if (parser.options.ranges) + this.range = [pos, 0] +}; + +// Start an AST node, attaching a start offset. + +var pp$5 = Parser.prototype + +pp$5.startNode = function() { + return new Node(this, this.start, this.startLoc) +} + +pp$5.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +} + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type + node.end = pos + if (this.options.locations) + node.loc.end = loc + if (this.options.ranges) + node.range[1] = pos + return node +} + +pp$5.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +} + +// Finish node at given position + +pp$5.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +} + +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + +var TokContext = function TokContext(token, isExpr, preserveSpace, override) { + this.token = token + this.isExpr = !!isExpr + this.preserveSpace = !!preserveSpace + this.override = override +}; + +var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", true), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }), + f_expr: new TokContext("function", true) +} + +var pp$6 = Parser.prototype + +pp$6.initialContext = function() { + return [types.b_stat] +} + +pp$6.braceIsBlock = function(prevType) { + if (prevType === tt.colon) { + var parent = this.curContext() + if (parent === types.b_stat || parent === types.b_expr) + return !parent.isExpr + } + if (prevType === tt._return) + return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) + return true + if (prevType == tt.braceL) + return this.curContext() === types.b_stat + return !this.exprAllowed +} + +pp$6.updateContext = function(prevType) { + var update, type = this.type + if (type.keyword && prevType == tt.dot) + this.exprAllowed = false + else if (update = type.updateContext) + update.call(this, prevType) + else + this.exprAllowed = type.beforeExpr +} - // Parse a regular `for` loop. The disambiguation code in - // `parseStatement` will already have parsed the init statement or - // expression. +// Token-specific context update code - pp$1.parseFor = function(node, init) { - node.init = init - this.expect(tt.semi) - node.test = this.type === tt.semi ? null : this.parseExpression() - this.expect(tt.semi) - node.update = this.type === tt.parenR ? null : this.parseExpression() - this.expect(tt.parenR) - node.body = this.parseStatement(false) - this.labels.pop() - return this.finishNode(node, "ForStatement") +tt.parenR.updateContext = tt.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true + return } - - // Parse a `for`/`in` and `for`/`of` loop, which are almost - // same from parser's perspective. - - pp$1.parseForIn = function(node, init) { - var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" - this.next() - node.left = init - node.right = this.parseExpression() - this.expect(tt.parenR) - node.body = this.parseStatement(false) - this.labels.pop() - return this.finishNode(node, type) + var out = this.context.pop() + if (out === types.b_stat && this.curContext() === types.f_expr) { + this.context.pop() + this.exprAllowed = false + } else if (out === types.b_tmpl) { + this.exprAllowed = true + } else { + this.exprAllowed = !out.isExpr + } +} + +tt.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) + this.exprAllowed = true +} + +tt.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl) + this.exprAllowed = true +} + +tt.parenL.updateContext = function(prevType) { + var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while + this.context.push(statementParens ? types.p_stat : types.p_expr) + this.exprAllowed = true +} + +tt.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +} + +tt._function.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && + !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) + this.context.push(types.f_expr) + this.exprAllowed = false +} + +tt.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + this.context.pop() + else + this.context.push(types.q_tmpl) + this.exprAllowed = false +} + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type + this.value = p.value + this.start = p.start + this.end = p.end + if (p.options.locations) + this.loc = new SourceLocation(p, p.startLoc, p.endLoc) + if (p.options.ranges) + this.range = [p.start, p.end] +}; + +// ## Tokenizer + +var pp$7 = Parser.prototype + +// Are we running under Rhino? +var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" + +// Move to the next token + +pp$7.next = function() { + if (this.options.onToken) + this.options.onToken(new Token(this)) + + this.lastTokEnd = this.end + this.lastTokStart = this.start + this.lastTokEndLoc = this.endLoc + this.lastTokStartLoc = this.startLoc + this.nextToken() +} + +pp$7.getToken = function() { + this.next() + return new Token(this) +} + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + pp$7[Symbol.iterator] = function () { + var self = this + return {next: function () { + var token = self.getToken() + return { + done: token.type === tt.eof, + value: token + } + }} } - // Parse a list of variable declarations. +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). - pp$1.parseVar = function(node, isFor, kind) { - var this$1 = this; +pp$7.setStrict = function(strict) { + var this$1 = this; - node.declarations = [] - node.kind = kind - for (;;) { - var decl = this$1.startNode() - this$1.parseVarId(decl) - if (this$1.eat(tt.eq)) { - decl.init = this$1.parseMaybeAssign(isFor) - } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { - this$1.unexpected() - } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) { - this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value") - } else { - decl.init = null - } - node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) - if (!this$1.eat(tt.comma)) break + this.strict = strict + if (this.type !== tt.num && this.type !== tt.string) return + this.pos = this.start + if (this.options.locations) { + while (this.pos < this.lineStart) { + this$1.lineStart = this$1.input.lastIndexOf("\n", this$1.lineStart - 2) + 1 + --this$1.curLine } - return node - } - - pp$1.parseVarId = function(decl) { - decl.id = this.parseBindingAtom() - this.checkLVal(decl.id, true) } + this.nextToken() +} - // Parse a function declaration or literal (depending on the - // `isStatement` parameter). +pp$7.curContext = function() { + return this.context[this.context.length - 1] +} - pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { - this.initFunction(node) - if (this.options.ecmaVersion >= 6 && !isAsync) - node.generator = this.eat(tt.star) - if (this.options.ecmaVersion >= 8) - node.async = !!isAsync +// Read a single token, updating the parser object's token-related +// properties. - if (isStatement) - node.id = this.parseIdent() +pp$7.nextToken = function() { + var curContext = this.curContext() + if (!curContext || !curContext.preserveSpace) this.skipSpace() - var oldInGen = this.inGenerator, oldInAsync = this.inAsync, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos - this.inGenerator = node.generator - this.inAsync = node.async - this.yieldPos = 0 - this.awaitPos = 0 + this.start = this.pos + if (this.options.locations) this.startLoc = this.curPosition() + if (this.pos >= this.input.length) return this.finishToken(tt.eof) - if (!isStatement && this.type === tt.name) - node.id = this.parseIdent() - this.parseFunctionParams(node) - this.parseFunctionBody(node, allowExpressionBody) + if (curContext.override) return curContext.override(this) + else this.readToken(this.fullCharCodeAtPos()) +} - this.inGenerator = oldInGen - this.inAsync = oldInAsync - this.yieldPos = oldYieldPos - this.awaitPos = oldAwaitPos - return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") - } +pp$7.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + return this.readWord() - pp$1.parseFunctionParams = function(node) { - this.expect(tt.parenL) - node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8, true) - this.checkYieldAwaitInDefaultParams() - } + return this.getTokenFromCode(code) +} - // Parse a class declaration or literal (depending on the - // `isStatement` parameter). +pp$7.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos) + if (code <= 0xd7ff || code >= 0xe000) return code + var next = this.input.charCodeAt(this.pos + 1) + return (code << 10) + next - 0x35fdc00 +} - pp$1.parseClass = function(node, isStatement) { - var this$1 = this; +pp$7.skipBlockComment = function() { + var this$1 = this; - this.next() - this.parseClassId(node, isStatement) - this.parseClassSuper(node) - var classBody = this.startNode() - var hadConstructor = false - classBody.body = [] - this.expect(tt.braceL) - while (!this.eat(tt.braceR)) { - if (this$1.eat(tt.semi)) continue - var method = this$1.startNode() - var isGenerator = this$1.eat(tt.star) - var isAsync = false - var isMaybeStatic = this$1.type === tt.name && this$1.value === "static" - this$1.parsePropertyName(method) - method.static = isMaybeStatic && this$1.type !== tt.parenL - if (method.static) { - if (isGenerator) this$1.unexpected() - isGenerator = this$1.eat(tt.star) - this$1.parsePropertyName(method) - } - if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed && - method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== tt.parenL && - !this$1.canInsertSemicolon()) { - isAsync = true - this$1.parsePropertyName(method) - } - method.kind = "method" - var isGetSet = false - if (!method.computed) { - var key = method.key; - if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) { - isGetSet = true - method.kind = key.name - key = this$1.parsePropertyName(method) - } - if (!method.static && (key.type === "Identifier" && key.name === "constructor" || - key.type === "Literal" && key.value === "constructor")) { - if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class") - if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier") - if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator") - if (isAsync) this$1.raise(key.start, "Constructor can't be an async method") - method.kind = "constructor" - hadConstructor = true - } - } - this$1.parseClassMethod(classBody, method, isGenerator, isAsync) - if (isGetSet) { - var paramCount = method.kind === "get" ? 0 : 1 - if (method.value.params.length !== paramCount) { - var start = method.value.start - if (method.kind === "get") - this$1.raiseRecoverable(start, "getter should have no params") - else - this$1.raiseRecoverable(start, "setter should have exactly one param") - } else { - if (method.kind === "set" && method.value.params[0].type === "RestElement") - this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params") - } - } + var startLoc = this.options.onComment && this.curPosition() + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2) + if (end === -1) this.raise(this.pos - 2, "Unterminated comment") + this.pos = end + 2 + if (this.options.locations) { + lineBreakG.lastIndex = start + var match + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine + this$1.lineStart = match.index + match[0].length } - node.body = this.finishNode(classBody, "ClassBody") - return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") } + if (this.options.onComment) + this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()) +} - pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { - method.value = this.parseMethod(isGenerator, isAsync) - classBody.body.push(this.finishNode(method, "MethodDefinition")) - } +pp$7.skipLineComment = function(startSkip) { + var this$1 = this; - pp$1.parseClassId = function(node, isStatement) { - node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null + var start = this.pos + var startLoc = this.options.onComment && this.curPosition() + var ch = this.input.charCodeAt(this.pos+=startSkip) + while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this$1.pos + ch = this$1.input.charCodeAt(this$1.pos) } + if (this.options.onComment) + this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()) +} - pp$1.parseClassSuper = function(node) { - node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null - } +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. - // Parses module export declaration. +pp$7.skipSpace = function() { + var this$1 = this; - pp$1.parseExport = function(node, exports) { - var this$1 = this; - - this.next() - // export * from '...' - if (this.eat(tt.star)) { - this.expectContextual("from") - node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() - this.semicolon() - return this.finishNode(node, "ExportAllDeclaration") - } - if (this.eat(tt._default)) { // export default ... - this.checkExport(exports, "default", this.lastTokStart) - var parens = this.type == tt.parenL - var expr = this.parseMaybeAssign() - var needsSemi = true - if (!parens && (expr.type == "FunctionExpression" || - expr.type == "ClassExpression")) { - needsSemi = false - if (expr.id) { - expr.type = expr.type == "FunctionExpression" - ? "FunctionDeclaration" - : "ClassDeclaration" - } - } - node.declaration = expr - if (needsSemi) this.semicolon() - return this.finishNode(node, "ExportDefaultDeclaration") - } - // export var|const|let|function|class ... - if (this.shouldParseExportStatement()) { - node.declaration = this.parseStatement(true) - if (node.declaration.type === "VariableDeclaration") - this.checkVariableExport(exports, node.declaration.declarations) - else - this.checkExport(exports, node.declaration.id.name, node.declaration.id.start) - node.specifiers = [] - node.source = null - } else { // export { x, y as z } [from '...'] - node.declaration = null - node.specifiers = this.parseExportSpecifiers(exports) - if (this.eatContextual("from")) { - node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() - } else { - // check for keywords used as local names - for (var i = 0; i < node.specifiers.length; i++) { - if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) { - this$1.unexpected(node.specifiers[i].local.start) - } - } - - node.source = null - } - this.semicolon() - } - return this.finishNode(node, "ExportNamedDeclaration") - } - - pp$1.checkExport = function(exports, name, pos) { - if (!exports) return - if (Object.prototype.hasOwnProperty.call(exports, name)) - this.raiseRecoverable(pos, "Duplicate export '" + name + "'") - exports[name] = true - } - - pp$1.checkPatternExport = function(exports, pat) { - var this$1 = this; - - var type = pat.type - if (type == "Identifier") - this.checkExport(exports, pat.name, pat.start) - else if (type == "ObjectPattern") - for (var i = 0; i < pat.properties.length; ++i) - this$1.checkPatternExport(exports, pat.properties[i].value) - else if (type == "ArrayPattern") - for (var i$1 = 0; i$1 < pat.elements.length; ++i$1) { - var elt = pat.elements[i$1] - if (elt) this$1.checkPatternExport(exports, elt) - } - else if (type == "AssignmentPattern") - this.checkPatternExport(exports, pat.left) - else if (type == "ParenthesizedExpression") - this.checkPatternExport(exports, pat.expression) - } - - pp$1.checkVariableExport = function(exports, decls) { - var this$1 = this; - - if (!exports) return - for (var i = 0; i < decls.length; i++) - this$1.checkPatternExport(exports, decls[i].id) - } - - pp$1.shouldParseExportStatement = function() { - return this.type.keyword || this.isLet() || this.isAsyncFunction() - } - - // Parses a comma-separated list of module exports. - - pp$1.parseExportSpecifiers = function(exports) { - var this$1 = this; - - var nodes = [], first = true - // export { x, y as z } [from '...'] - this.expect(tt.braceL) - while (!this.eat(tt.braceR)) { - if (!first) { - this$1.expect(tt.comma) - if (this$1.afterTrailingComma(tt.braceR)) break - } else first = false - - var node = this$1.startNode() - node.local = this$1.parseIdent(this$1.type === tt._default) - node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local - this$1.checkExport(exports, node.exported.name, node.exported.start) - nodes.push(this$1.finishNode(node, "ExportSpecifier")) - } - return nodes - } - - // Parses import declaration. - - pp$1.parseImport = function(node) { - this.next() - // import '...' - if (this.type === tt.string) { - node.specifiers = empty - node.source = this.parseExprAtom() - } else { - node.specifiers = this.parseImportSpecifiers() - this.expectContextual("from") - node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() - } - this.semicolon() - return this.finishNode(node, "ImportDeclaration") - } - - // Parses a comma-separated list of module imports. - - pp$1.parseImportSpecifiers = function() { - var this$1 = this; - - var nodes = [], first = true - if (this.type === tt.name) { - // import defaultObj, { x, y as z } from '...' - var node = this.startNode() - node.local = this.parseIdent() - this.checkLVal(node.local, true) - nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) - if (!this.eat(tt.comma)) return nodes - } - if (this.type === tt.star) { - var node$1 = this.startNode() - this.next() - this.expectContextual("as") - node$1.local = this.parseIdent() - this.checkLVal(node$1.local, true) - nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")) - return nodes - } - this.expect(tt.braceL) - while (!this.eat(tt.braceR)) { - if (!first) { - this$1.expect(tt.comma) - if (this$1.afterTrailingComma(tt.braceR)) break - } else first = false - - var node$2 = this$1.startNode() - node$2.imported = this$1.parseIdent(true) - if (this$1.eatContextual("as")) { - node$2.local = this$1.parseIdent() - } else { - node$2.local = node$2.imported - if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start) - if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raiseRecoverable(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved") - } - this$1.checkLVal(node$2.local, true) - nodes.push(this$1.finishNode(node$2, "ImportSpecifier")) - } - return nodes - } - - var pp$2 = Parser.prototype - - // Convert existing expression atom to assignable pattern - // if possible. - - pp$2.toAssignable = function(node, isBinding) { - var this$1 = this; - - if (this.options.ecmaVersion >= 6 && node) { - switch (node.type) { - case "Identifier": - if (this.inAsync && node.name === "await") - this.raise(node.start, "Can not use 'await' as identifier inside an async function") - break - - case "ObjectPattern": - case "ArrayPattern": - break - - case "ObjectExpression": - node.type = "ObjectPattern" - for (var i = 0; i < node.properties.length; i++) { - var prop = node.properties[i] - if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter") - this$1.toAssignable(prop.value, isBinding) - } - break - - case "ArrayExpression": - node.type = "ArrayPattern" - this.toAssignableList(node.elements, isBinding) - break - - case "AssignmentExpression": - if (node.operator === "=") { - node.type = "AssignmentPattern" - delete node.operator - this.toAssignable(node.left, isBinding) - // falls through to AssignmentPattern - } else { - this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") - break - } - - case "AssignmentPattern": - break - - case "ParenthesizedExpression": - node.expression = this.toAssignable(node.expression, isBinding) - break - - case "MemberExpression": - if (!isBinding) break - - default: - this.raise(node.start, "Assigning to rvalue") - } - } - return node - } - - // Convert list of expression atoms to binding list. - - pp$2.toAssignableList = function(exprList, isBinding) { - var this$1 = this; - - var end = exprList.length - if (end) { - var last = exprList[end - 1] - if (last && last.type == "RestElement") { - --end - } else if (last && last.type == "SpreadElement") { - last.type = "RestElement" - var arg = last.argument - this.toAssignable(arg, isBinding) - if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") - this.unexpected(arg.start) - --end - } - - if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") - this.unexpected(last.argument.start) - } - for (var i = 0; i < end; i++) { - var elt = exprList[i] - if (elt) this$1.toAssignable(elt, isBinding) - } - return exprList - } - - // Parses spread element. - - pp$2.parseSpread = function(refDestructuringErrors) { - var node = this.startNode() - this.next() - node.argument = this.parseMaybeAssign(false, refDestructuringErrors) - return this.finishNode(node, "SpreadElement") - } - - pp$2.parseRest = function(allowNonIdent) { - var node = this.startNode() - this.next() - - // RestElement inside of a function parameter must be an identifier - if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() - else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() - - return this.finishNode(node, "RestElement") - } - - // Parses lvalue (assignable) atom. - - pp$2.parseBindingAtom = function() { - if (this.options.ecmaVersion < 6) return this.parseIdent() - switch (this.type) { - case tt.name: - return this.parseIdent() - - case tt.bracketL: - var node = this.startNode() - this.next() - node.elements = this.parseBindingList(tt.bracketR, true, true) - return this.finishNode(node, "ArrayPattern") - - case tt.braceL: - return this.parseObj(true) - - default: - this.unexpected() - } - } - - pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { - var this$1 = this; - - var elts = [], first = true - while (!this.eat(close)) { - if (first) first = false - else this$1.expect(tt.comma) - if (allowEmpty && this$1.type === tt.comma) { - elts.push(null) - } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { - break - } else if (this$1.type === tt.ellipsis) { - var rest = this$1.parseRest(allowNonIdent) - this$1.parseBindingListItem(rest) - elts.push(rest) - if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") - this$1.expect(close) - break - } else { - var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc) - this$1.parseBindingListItem(elem) - elts.push(elem) - } - } - return elts - } - - pp$2.parseBindingListItem = function(param) { - return param - } - - // Parses assignment pattern around given atom if possible. - - pp$2.parseMaybeDefault = function(startPos, startLoc, left) { - left = left || this.parseBindingAtom() - if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left - var node = this.startNodeAt(startPos, startLoc) - node.left = left - node.right = this.parseMaybeAssign() - return this.finishNode(node, "AssignmentPattern") - } - - // Verify that a node is an lval — something that can be assigned - // to. - - pp$2.checkLVal = function(expr, isBinding, checkClashes) { - var this$1 = this; - - switch (expr.type) { - case "Identifier": - if (this.strict && this.reservedWordsStrictBind.test(expr.name)) - this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") - if (checkClashes) { - if (has(checkClashes, expr.name)) - this.raiseRecoverable(expr.start, "Argument name clash") - checkClashes[expr.name] = true - } - break - - case "MemberExpression": - if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") - break - - case "ObjectPattern": - for (var i = 0; i < expr.properties.length; i++) - this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes) - break - - case "ArrayPattern": - for (var i$1 = 0; i$1 < expr.elements.length; i$1++) { - var elem = expr.elements[i$1] - if (elem) this$1.checkLVal(elem, isBinding, checkClashes) - } - break - - case "AssignmentPattern": - this.checkLVal(expr.left, isBinding, checkClashes) - break - - case "RestElement": - this.checkLVal(expr.argument, isBinding, checkClashes) - break - - case "ParenthesizedExpression": - this.checkLVal(expr.expression, isBinding, checkClashes) - break - - default: - this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") - } - } - - var pp$3 = Parser.prototype - - // Check if property name clashes with already added. - // Object/class getters and setters are not allowed to clash — - // either with each other or with an init property — and in - // strict mode, init properties are also not allowed to be repeated. - - pp$3.checkPropClash = function(prop, propHash) { - if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) - return - var key = prop.key; - var name - switch (key.type) { - case "Identifier": name = key.name; break - case "Literal": name = String(key.value); break - default: return - } - var kind = prop.kind; - if (this.options.ecmaVersion >= 6) { - if (name === "__proto__" && kind === "init") { - if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") - propHash.proto = true - } - return - } - name = "$" + name - var other = propHash[name] - if (other) { - var isGetSet = kind !== "init" - if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) - this.raiseRecoverable(key.start, "Redefinition of property") - } else { - other = propHash[name] = { - init: false, - get: false, - set: false - } - } - other[kind] = true - } - - // ### Expression parsing - - // These nest, from the most general expression type at the top to - // 'atomic', nondivisible expression types at the bottom. Most of - // the functions will simply let the function(s) below them parse, - // and, *if* the syntactic construct they handle is present, wrap - // the AST node that the inner parser gave them in another node. - - // Parse a full expression. The optional arguments are used to - // forbid the `in` operator (in for loops initalization expressions) - // and provide reference for storing '=' operator inside shorthand - // property assignment in contexts where both object expression - // and object pattern might appear (so it's possible to raise - // delayed syntax error at correct position). - - pp$3.parseExpression = function(noIn, refDestructuringErrors) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc - var expr = this.parseMaybeAssign(noIn, refDestructuringErrors) - if (this.type === tt.comma) { - var node = this.startNodeAt(startPos, startLoc) - node.expressions = [expr] - while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)) - return this.finishNode(node, "SequenceExpression") - } - return expr - } - - // Parse an assignment expression. This includes applications of - // operators like `+=`. - - pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { - if (this.inGenerator && this.isContextual("yield")) return this.parseYield() - - var ownDestructuringErrors = false - if (!refDestructuringErrors) { - refDestructuringErrors = new DestructuringErrors - ownDestructuringErrors = true - } - var startPos = this.start, startLoc = this.startLoc - if (this.type == tt.parenL || this.type == tt.name) - this.potentialArrowAt = this.start - var left = this.parseMaybeConditional(noIn, refDestructuringErrors) - if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) - if (this.type.isAssign) { - this.checkPatternErrors(refDestructuringErrors, true) - if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) - var node = this.startNodeAt(startPos, startLoc) - node.operator = this.value - node.left = this.type === tt.eq ? this.toAssignable(left) : left - refDestructuringErrors.shorthandAssign = 0 // reset because shorthand default was used correctly - this.checkLVal(left) - this.next() - node.right = this.parseMaybeAssign(noIn) - return this.finishNode(node, "AssignmentExpression") - } else { - if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) - } - return left - } - - // Parse a ternary conditional (`?:`) operator. - - pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc - var expr = this.parseExprOps(noIn, refDestructuringErrors) - if (this.checkExpressionErrors(refDestructuringErrors)) return expr - if (this.eat(tt.question)) { - var node = this.startNodeAt(startPos, startLoc) - node.test = expr - node.consequent = this.parseMaybeAssign() - this.expect(tt.colon) - node.alternate = this.parseMaybeAssign(noIn) - return this.finishNode(node, "ConditionalExpression") - } - return expr - } - - // Start the precedence parser. - - pp$3.parseExprOps = function(noIn, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc - var expr = this.parseMaybeUnary(refDestructuringErrors, false) - if (this.checkExpressionErrors(refDestructuringErrors)) return expr - return this.parseExprOp(expr, startPos, startLoc, -1, noIn) - } - - // Parse binary operators with the operator precedence parsing - // algorithm. `left` is the left-hand side of the operator. - // `minPrec` provides context that allows the function to stop and - // defer further parser to one of its callers when it encounters an - // operator that has a lower precedence than the set it is parsing. - - pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { - var prec = this.type.binop - if (prec != null && (!noIn || this.type !== tt._in)) { - if (prec > minPrec) { - var logical = this.type === tt.logicalOR || this.type === tt.logicalAND - var op = this.value - this.next() - var startPos = this.start, startLoc = this.startLoc - var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) - var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) - } - } - return left - } - - pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { - var node = this.startNodeAt(startPos, startLoc) - node.left = left - node.operator = op - node.right = right - return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") - } - - // Parse unary operators, both prefix and postfix. - - pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc, expr - if (this.inAsync && this.isContextual("await")) { - expr = this.parseAwait(refDestructuringErrors) - sawUnary = true - } else if (this.type.prefix) { - var node = this.startNode(), update = this.type === tt.incDec - node.operator = this.value - node.prefix = true - this.next() - node.argument = this.parseMaybeUnary(null, true) - this.checkExpressionErrors(refDestructuringErrors, true) - if (update) this.checkLVal(node.argument) - else if (this.strict && node.operator === "delete" && - node.argument.type === "Identifier") - this.raiseRecoverable(node.start, "Deleting local variable in strict mode") - else sawUnary = true - expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") - } else { - expr = this.parseExprSubscripts(refDestructuringErrors) - if (this.checkExpressionErrors(refDestructuringErrors)) return expr - while (this.type.postfix && !this.canInsertSemicolon()) { - var node$1 = this$1.startNodeAt(startPos, startLoc) - node$1.operator = this$1.value - node$1.prefix = false - node$1.argument = expr - this$1.checkLVal(expr) - this$1.next() - expr = this$1.finishNode(node$1, "UpdateExpression") - } - } - - if (!sawUnary && this.eat(tt.starstar)) - return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) - else - return expr - } - - // Parse call, dot, and `[]`-subscript expressions. - - pp$3.parseExprSubscripts = function(refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc - var expr = this.parseExprAtom(refDestructuringErrors) - var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" - if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr - return this.parseSubscripts(expr, startPos, startLoc) - } - - pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { - var this$1 = this; - - for (;;) { - var maybeAsyncArrow = this$1.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && !this$1.canInsertSemicolon() - if (this$1.eat(tt.dot)) { - var node = this$1.startNodeAt(startPos, startLoc) - node.object = base - node.property = this$1.parseIdent(true) - node.computed = false - base = this$1.finishNode(node, "MemberExpression") - } else if (this$1.eat(tt.bracketL)) { - var node$1 = this$1.startNodeAt(startPos, startLoc) - node$1.object = base - node$1.property = this$1.parseExpression() - node$1.computed = true - this$1.expect(tt.bracketR) - base = this$1.finishNode(node$1, "MemberExpression") - } else if (!noCalls && this$1.eat(tt.parenL)) { - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos - this$1.yieldPos = 0 - this$1.awaitPos = 0 - var exprList = this$1.parseExprList(tt.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors) - if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(tt.arrow)) { - this$1.checkPatternErrors(refDestructuringErrors, true) - this$1.checkYieldAwaitInDefaultParams() - this$1.yieldPos = oldYieldPos - this$1.awaitPos = oldAwaitPos - return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) - } - this$1.checkExpressionErrors(refDestructuringErrors, true) - this$1.yieldPos = oldYieldPos || this$1.yieldPos - this$1.awaitPos = oldAwaitPos || this$1.awaitPos - var node$2 = this$1.startNodeAt(startPos, startLoc) - node$2.callee = base - node$2.arguments = exprList - base = this$1.finishNode(node$2, "CallExpression") - } else if (this$1.type === tt.backQuote) { - var node$3 = this$1.startNodeAt(startPos, startLoc) - node$3.tag = base - node$3.quasi = this$1.parseTemplate() - base = this$1.finishNode(node$3, "TaggedTemplateExpression") - } else { - return base - } - } - } - - // Parse an atomic expression — either a single token that is an - // expression, an expression started by a keyword like `function` or - // `new`, or an expression wrapped in punctuation like `()`, `[]`, - // or `{}`. - - pp$3.parseExprAtom = function(refDestructuringErrors) { - var node, canBeArrow = this.potentialArrowAt == this.start - switch (this.type) { - case tt._super: - if (!this.inFunction) - this.raise(this.start, "'super' outside of function or class") - - case tt._this: - var type = this.type === tt._this ? "ThisExpression" : "Super" - node = this.startNode() - this.next() - return this.finishNode(node, type) - - case tt.name: - var startPos = this.start, startLoc = this.startLoc - var id = this.parseIdent(this.type !== tt.name) - if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function)) - return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) - if (canBeArrow && !this.canInsertSemicolon()) { - if (this.eat(tt.arrow)) - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) - if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) { - id = this.parseIdent() - if (this.canInsertSemicolon() || !this.eat(tt.arrow)) - this.unexpected() - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) - } - } - return id - - case tt.regexp: - var value = this.value - node = this.parseLiteral(value.value) - node.regex = {pattern: value.pattern, flags: value.flags} - return node - - case tt.num: case tt.string: - return this.parseLiteral(this.value) - - case tt._null: case tt._true: case tt._false: - node = this.startNode() - node.value = this.type === tt._null ? null : this.type === tt._true - node.raw = this.type.keyword - this.next() - return this.finishNode(node, "Literal") - - case tt.parenL: - return this.parseParenAndDistinguishExpression(canBeArrow) - - case tt.bracketL: - node = this.startNode() - this.next() - node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) - return this.finishNode(node, "ArrayExpression") - - case tt.braceL: - return this.parseObj(false, refDestructuringErrors) - - case tt._function: - node = this.startNode() - this.next() - return this.parseFunction(node, false) - - case tt._class: - return this.parseClass(this.startNode(), false) - - case tt._new: - return this.parseNew() - - case tt.backQuote: - return this.parseTemplate() - - default: - this.unexpected() - } - } - - pp$3.parseLiteral = function(value) { - var node = this.startNode() - node.value = value - node.raw = this.input.slice(this.start, this.end) - this.next() - return this.finishNode(node, "Literal") - } - - pp$3.parseParenExpression = function() { - this.expect(tt.parenL) - var val = this.parseExpression() - this.expect(tt.parenR) - return val - } - - pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8 - if (this.options.ecmaVersion >= 6) { - this.next() - - var innerStartPos = this.start, innerStartLoc = this.startLoc - var exprList = [], first = true, lastIsComma = false - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart - this.yieldPos = 0 - this.awaitPos = 0 - while (this.type !== tt.parenR) { - first ? first = false : this$1.expect(tt.comma) - if (allowTrailingComma && this$1.afterTrailingComma(tt.parenR, true)) { - lastIsComma = true - break - } else if (this$1.type === tt.ellipsis) { - spreadStart = this$1.start - exprList.push(this$1.parseParenItem(this$1.parseRest())) - if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") - break - } else { - if (this$1.type === tt.parenL && !innerParenStart) { - innerParenStart = this$1.start - } - exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)) - } - } - var innerEndPos = this.start, innerEndLoc = this.startLoc - this.expect(tt.parenR) - - if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { - this.checkPatternErrors(refDestructuringErrors, true) - this.checkYieldAwaitInDefaultParams() - if (innerParenStart) this.unexpected(innerParenStart) - this.yieldPos = oldYieldPos - this.awaitPos = oldAwaitPos - return this.parseParenArrowList(startPos, startLoc, exprList) - } - - if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart) - if (spreadStart) this.unexpected(spreadStart) - this.checkExpressionErrors(refDestructuringErrors, true) - this.yieldPos = oldYieldPos || this.yieldPos - this.awaitPos = oldAwaitPos || this.awaitPos - - if (exprList.length > 1) { - val = this.startNodeAt(innerStartPos, innerStartLoc) - val.expressions = exprList - this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) - } else { - val = exprList[0] - } - } else { - val = this.parseParenExpression() - } - - if (this.options.preserveParens) { - var par = this.startNodeAt(startPos, startLoc) - par.expression = val - return this.finishNode(par, "ParenthesizedExpression") - } else { - return val - } - } - - pp$3.parseParenItem = function(item) { - return item - } - - pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) - } - - // New's precedence is slightly tricky. It must allow its argument to - // be a `[]` or dot subscript expression, but not a call — at least, - // not without wrapping it in parentheses. Thus, it uses the noCalls - // argument to parseSubscripts to prevent it from consuming the - // argument list. - - var empty$1 = [] - - pp$3.parseNew = function() { - var node = this.startNode() - var meta = this.parseIdent(true) - if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { - node.meta = meta - node.property = this.parseIdent(true) - if (node.property.name !== "target") - this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") - if (!this.inFunction) - this.raiseRecoverable(node.start, "new.target can only be used in functions") - return this.finishNode(node, "MetaProperty") - } - var startPos = this.start, startLoc = this.startLoc - node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) - if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false) - else node.arguments = empty$1 - return this.finishNode(node, "NewExpression") - } - - // Parse template expression. - - pp$3.parseTemplateElement = function() { - var elem = this.startNode() - elem.value = { - raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), - cooked: this.value - } - this.next() - elem.tail = this.type === tt.backQuote - return this.finishNode(elem, "TemplateElement") - } - - pp$3.parseTemplate = function() { - var this$1 = this; - - var node = this.startNode() - this.next() - node.expressions = [] - var curElt = this.parseTemplateElement() - node.quasis = [curElt] - while (!curElt.tail) { - this$1.expect(tt.dollarBraceL) - node.expressions.push(this$1.parseExpression()) - this$1.expect(tt.braceR) - node.quasis.push(curElt = this$1.parseTemplateElement()) - } - this.next() - return this.finishNode(node, "TemplateLiteral") - } - - // Parse an object literal or binding pattern. - - pp$3.parseObj = function(isPattern, refDestructuringErrors) { - var this$1 = this; - - var node = this.startNode(), first = true, propHash = {} - node.properties = [] - this.next() - while (!this.eat(tt.braceR)) { - if (!first) { - this$1.expect(tt.comma) - if (this$1.afterTrailingComma(tt.braceR)) break - } else first = false - - var prop = this$1.startNode(), isGenerator, isAsync, startPos, startLoc - if (this$1.options.ecmaVersion >= 6) { - prop.method = false - prop.shorthand = false - if (isPattern || refDestructuringErrors) { - startPos = this$1.start - startLoc = this$1.startLoc - } - if (!isPattern) - isGenerator = this$1.eat(tt.star) - } - this$1.parsePropertyName(prop) - if (!isPattern && this$1.options.ecmaVersion >= 8 && !isGenerator && !prop.computed && - prop.key.type === "Identifier" && prop.key.name === "async" && this$1.type !== tt.parenL && - this$1.type !== tt.colon && !this$1.canInsertSemicolon()) { - isAsync = true - this$1.parsePropertyName(prop, refDestructuringErrors) - } else { - isAsync = false - } - this$1.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) - this$1.checkPropClash(prop, propHash) - node.properties.push(this$1.finishNode(prop, "Property")) - } - return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") - } - - pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) { - if ((isGenerator || isAsync) && this.type === tt.colon) - this.unexpected() - - if (this.eat(tt.colon)) { - prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) - prop.kind = "init" - } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { - if (isPattern) this.unexpected() - prop.kind = "init" - prop.method = true - prop.value = this.parseMethod(isGenerator, isAsync) - } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set") && - (this.type != tt.comma && this.type != tt.braceR)) { - if (isGenerator || isAsync || isPattern) this.unexpected() - prop.kind = prop.key.name - this.parsePropertyName(prop) - prop.value = this.parseMethod(false) - var paramCount = prop.kind === "get" ? 0 : 1 - if (prop.value.params.length !== paramCount) { - var start = prop.value.start - if (prop.kind === "get") - this.raiseRecoverable(start, "getter should have no params") - else - this.raiseRecoverable(start, "setter should have exactly one param") - } else { - if (prop.kind === "set" && prop.value.params[0].type === "RestElement") - this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") - } - } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { - if (this.keywords.test(prop.key.name) || - (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) || - (this.inGenerator && prop.key.name == "yield") || - (this.inAsync && prop.key.name == "await")) - this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") - prop.kind = "init" - if (isPattern) { - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) - } else if (this.type === tt.eq && refDestructuringErrors) { - if (!refDestructuringErrors.shorthandAssign) - refDestructuringErrors.shorthandAssign = this.start - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) - } else { - prop.value = prop.key - } - prop.shorthand = true - } else this.unexpected() - } - - pp$3.parsePropertyName = function(prop) { - if (this.options.ecmaVersion >= 6) { - if (this.eat(tt.bracketL)) { - prop.computed = true - prop.key = this.parseMaybeAssign() - this.expect(tt.bracketR) - return prop.key - } else { - prop.computed = false - } - } - return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) - } - - // Initialize empty function node. - - pp$3.initFunction = function(node) { - node.id = null - if (this.options.ecmaVersion >= 6) { - node.generator = false - node.expression = false - } - if (this.options.ecmaVersion >= 8) - node.async = false - } - - // Parse object or class method. - - pp$3.parseMethod = function(isGenerator, isAsync) { - var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos - - this.initFunction(node) - if (this.options.ecmaVersion >= 6) - node.generator = isGenerator - if (this.options.ecmaVersion >= 8) - node.async = !!isAsync - - this.inGenerator = node.generator - this.inAsync = node.async - this.yieldPos = 0 - this.awaitPos = 0 - - this.expect(tt.parenL) - node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8) - this.checkYieldAwaitInDefaultParams() - this.parseFunctionBody(node, false) - - this.inGenerator = oldInGen - this.inAsync = oldInAsync - this.yieldPos = oldYieldPos - this.awaitPos = oldAwaitPos - return this.finishNode(node, "FunctionExpression") - } - - // Parse arrow function expression with given parameters. - - pp$3.parseArrowExpression = function(node, params, isAsync) { - var oldInGen = this.inGenerator, oldInAsync = this.inAsync, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos - - this.initFunction(node) - if (this.options.ecmaVersion >= 8) - node.async = !!isAsync - - this.inGenerator = false - this.inAsync = node.async - this.yieldPos = 0 - this.awaitPos = 0 - - node.params = this.toAssignableList(params, true) - this.parseFunctionBody(node, true) - - this.inGenerator = oldInGen - this.inAsync = oldInAsync - this.yieldPos = oldYieldPos - this.awaitPos = oldAwaitPos - return this.finishNode(node, "ArrowFunctionExpression") - } - - // Parse function body and check parameters. - - pp$3.parseFunctionBody = function(node, isArrowFunction) { - var isExpression = isArrowFunction && this.type !== tt.braceL - - if (isExpression) { - node.body = this.parseMaybeAssign() - node.expression = true - } else { - // Start a new scope with regard to labels and the `inFunction` - // flag (restore them to their old value afterwards). - var oldInFunc = this.inFunction, oldLabels = this.labels - this.inFunction = true; this.labels = [] - node.body = this.parseBlock(true) - node.expression = false - this.inFunction = oldInFunc; this.labels = oldLabels - } - - // If this is a strict mode function, verify that argument names - // are not repeated, and it does not try to bind the words `eval` - // or `arguments`. - var useStrict = (!isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) ? node.body.body[0] : null - if (useStrict && this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params)) - this.raiseRecoverable(useStrict.start, "Illegal 'use strict' directive in function with non-simple parameter list") - - if (this.strict || useStrict) { - var oldStrict = this.strict - this.strict = true - if (node.id) - this.checkLVal(node.id, true) - this.checkParams(node) - this.strict = oldStrict - } else if (isArrowFunction || !this.isSimpleParamList(node.params)) { - this.checkParams(node) - } - } - - pp$3.isSimpleParamList = function(params) { - for (var i = 0; i < params.length; i++) - if (params[i].type !== "Identifier") return false - return true - } - - // Checks function params for various disallowed patterns such as using "eval" - // or "arguments" and duplicate parameters. - - pp$3.checkParams = function(node) { - var this$1 = this; - - var nameHash = {} - for (var i = 0; i < node.params.length; i++) this$1.checkLVal(node.params[i], true, nameHash) - } - - // Parses a comma-separated list of expressions, and returns them as - // an array. `close` is the token type that ends the list, and - // `allowEmpty` can be turned on to allow subsequent commas with - // nothing in between them to be parsed as `null` (which is needed - // for array literals). - - pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { - var this$1 = this; - - var elts = [], first = true - while (!this.eat(close)) { - if (!first) { - this$1.expect(tt.comma) - if (allowTrailingComma && this$1.afterTrailingComma(close)) break - } else first = false - - var elt - if (allowEmpty && this$1.type === tt.comma) - elt = null - else if (this$1.type === tt.ellipsis) { - elt = this$1.parseSpread(refDestructuringErrors) - if (this$1.type === tt.comma && refDestructuringErrors && !refDestructuringErrors.trailingComma) { - refDestructuringErrors.trailingComma = this$1.start - } - } else - elt = this$1.parseMaybeAssign(false, refDestructuringErrors) - elts.push(elt) - } - return elts - } - - // Parse the next token as an identifier. If `liberal` is true (used - // when parsing properties), it will also convert keywords into - // identifiers. - - pp$3.parseIdent = function(liberal) { - var node = this.startNode() - if (liberal && this.options.allowReserved == "never") liberal = false - if (this.type === tt.name) { - if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && - (this.options.ecmaVersion >= 6 || - this.input.slice(this.start, this.end).indexOf("\\") == -1)) - this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") - if (this.inGenerator && this.value === "yield") - this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") - if (this.inAsync && this.value === "await") - this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function") - node.name = this.value - } else if (liberal && this.type.keyword) { - node.name = this.type.keyword - } else { - this.unexpected() - } - this.next() - return this.finishNode(node, "Identifier") - } - - // Parses yield expression inside generator. - - pp$3.parseYield = function() { - if (!this.yieldPos) this.yieldPos = this.start - - var node = this.startNode() - this.next() - if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { - node.delegate = false - node.argument = null - } else { - node.delegate = this.eat(tt.star) - node.argument = this.parseMaybeAssign() - } - return this.finishNode(node, "YieldExpression") - } - - pp$3.parseAwait = function() { - if (!this.awaitPos) this.awaitPos = this.start - - var node = this.startNode() - this.next() - node.argument = this.parseMaybeUnary(null, true) - return this.finishNode(node, "AwaitExpression") - } - - var pp$4 = Parser.prototype - - // This function is used to raise exceptions on parse errors. It - // takes an offset integer (into the current `input`) to indicate - // the location of the error, attaches the position to the end - // of the error message, and then raises a `SyntaxError` with that - // message. - - pp$4.raise = function(pos, message) { - var loc = getLineInfo(this.input, pos) - message += " (" + loc.line + ":" + loc.column + ")" - var err = new SyntaxError(message) - err.pos = pos; err.loc = loc; err.raisedAt = this.pos - throw err - } - - pp$4.raiseRecoverable = pp$4.raise - - pp$4.curPosition = function() { - if (this.options.locations) { - return new Position(this.curLine, this.pos - this.lineStart) - } - } - - var Node = function Node(parser, pos, loc) { - this.type = "" - this.start = pos - this.end = 0 - if (parser.options.locations) - this.loc = new SourceLocation(parser, loc) - if (parser.options.directSourceFile) - this.sourceFile = parser.options.directSourceFile - if (parser.options.ranges) - this.range = [pos, 0] - }; - - // Start an AST node, attaching a start offset. - - var pp$5 = Parser.prototype - - pp$5.startNode = function() { - return new Node(this, this.start, this.startLoc) - } - - pp$5.startNodeAt = function(pos, loc) { - return new Node(this, pos, loc) - } - - // Finish an AST node, adding `type` and `end` properties. - - function finishNodeAt(node, type, pos, loc) { - node.type = type - node.end = pos - if (this.options.locations) - node.loc.end = loc - if (this.options.ranges) - node.range[1] = pos - return node - } - - pp$5.finishNode = function(node, type) { - return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) - } - - // Finish node at given position - - pp$5.finishNodeAt = function(node, type, pos, loc) { - return finishNodeAt.call(this, node, type, pos, loc) - } - - var TokContext = function TokContext(token, isExpr, preserveSpace, override) { - this.token = token - this.isExpr = !!isExpr - this.preserveSpace = !!preserveSpace - this.override = override - }; - - var types = { - b_stat: new TokContext("{", false), - b_expr: new TokContext("{", true), - b_tmpl: new TokContext("${", true), - p_stat: new TokContext("(", false), - p_expr: new TokContext("(", true), - q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }), - f_expr: new TokContext("function", true) - } - - var pp$6 = Parser.prototype - - pp$6.initialContext = function() { - return [types.b_stat] - } - - pp$6.braceIsBlock = function(prevType) { - if (prevType === tt.colon) { - var parent = this.curContext() - if (parent === types.b_stat || parent === types.b_expr) - return !parent.isExpr - } - if (prevType === tt._return) - return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) - if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) - return true - if (prevType == tt.braceL) - return this.curContext() === types.b_stat - return !this.exprAllowed - } - - pp$6.updateContext = function(prevType) { - var update, type = this.type - if (type.keyword && prevType == tt.dot) - this.exprAllowed = false - else if (update = type.updateContext) - update.call(this, prevType) - else - this.exprAllowed = type.beforeExpr - } - - // Token-specific context update code - - tt.parenR.updateContext = tt.braceR.updateContext = function() { - if (this.context.length == 1) { - this.exprAllowed = true - return - } - var out = this.context.pop() - if (out === types.b_stat && this.curContext() === types.f_expr) { - this.context.pop() - this.exprAllowed = false - } else if (out === types.b_tmpl) { - this.exprAllowed = true - } else { - this.exprAllowed = !out.isExpr - } - } - - tt.braceL.updateContext = function(prevType) { - this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) - this.exprAllowed = true - } - - tt.dollarBraceL.updateContext = function() { - this.context.push(types.b_tmpl) - this.exprAllowed = true - } - - tt.parenL.updateContext = function(prevType) { - var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while - this.context.push(statementParens ? types.p_stat : types.p_expr) - this.exprAllowed = true - } - - tt.incDec.updateContext = function() { - // tokExprAllowed stays unchanged - } - - tt._function.updateContext = function(prevType) { - if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && - !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) - this.context.push(types.f_expr) - this.exprAllowed = false - } - - tt.backQuote.updateContext = function() { - if (this.curContext() === types.q_tmpl) - this.context.pop() - else - this.context.push(types.q_tmpl) - this.exprAllowed = false - } - - // Object type used to represent tokens. Note that normally, tokens - // simply exist as properties on the parser object. This is only - // used for the onToken callback and the external tokenizer. - - var Token = function Token(p) { - this.type = p.type - this.value = p.value - this.start = p.start - this.end = p.end - if (p.options.locations) - this.loc = new SourceLocation(p, p.startLoc, p.endLoc) - if (p.options.ranges) - this.range = [p.start, p.end] - }; - - // ## Tokenizer - - var pp$7 = Parser.prototype - - // Are we running under Rhino? - var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" - - // Move to the next token - - pp$7.next = function() { - if (this.options.onToken) - this.options.onToken(new Token(this)) - - this.lastTokEnd = this.end - this.lastTokStart = this.start - this.lastTokEndLoc = this.endLoc - this.lastTokStartLoc = this.startLoc - this.nextToken() - } - - pp$7.getToken = function() { - this.next() - return new Token(this) - } - - // If we're in an ES6 environment, make parsers iterable - if (typeof Symbol !== "undefined") - pp$7[Symbol.iterator] = function () { - var self = this - return {next: function () { - var token = self.getToken() - return { - done: token.type === tt.eof, - value: token - } - }} - } - - // Toggle strict mode. Re-reads the next number or string to please - // pedantic tests (`"use strict"; 010;` should fail). - - pp$7.setStrict = function(strict) { - var this$1 = this; - - this.strict = strict - if (this.type !== tt.num && this.type !== tt.string) return - this.pos = this.start - if (this.options.locations) { - while (this.pos < this.lineStart) { - this$1.lineStart = this$1.input.lastIndexOf("\n", this$1.lineStart - 2) + 1 - --this$1.curLine - } - } - this.nextToken() - } - - pp$7.curContext = function() { - return this.context[this.context.length - 1] - } - - // Read a single token, updating the parser object's token-related - // properties. - - pp$7.nextToken = function() { - var curContext = this.curContext() - if (!curContext || !curContext.preserveSpace) this.skipSpace() - - this.start = this.pos - if (this.options.locations) this.startLoc = this.curPosition() - if (this.pos >= this.input.length) return this.finishToken(tt.eof) - - if (curContext.override) return curContext.override(this) - else this.readToken(this.fullCharCodeAtPos()) - } - - pp$7.readToken = function(code) { - // Identifier or keyword. '\uXXXX' sequences are allowed in - // identifiers, so '\' also dispatches to that. - if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) - return this.readWord() - - return this.getTokenFromCode(code) - } - - pp$7.fullCharCodeAtPos = function() { - var code = this.input.charCodeAt(this.pos) - if (code <= 0xd7ff || code >= 0xe000) return code - var next = this.input.charCodeAt(this.pos + 1) - return (code << 10) + next - 0x35fdc00 - } - - pp$7.skipBlockComment = function() { - var this$1 = this; - - var startLoc = this.options.onComment && this.curPosition() - var start = this.pos, end = this.input.indexOf("*/", this.pos += 2) - if (end === -1) this.raise(this.pos - 2, "Unterminated comment") - this.pos = end + 2 - if (this.options.locations) { - lineBreakG.lastIndex = start - var match - while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { - ++this$1.curLine - this$1.lineStart = match.index + match[0].length - } - } - if (this.options.onComment) - this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, - startLoc, this.curPosition()) - } - - pp$7.skipLineComment = function(startSkip) { - var this$1 = this; - - var start = this.pos - var startLoc = this.options.onComment && this.curPosition() - var ch = this.input.charCodeAt(this.pos+=startSkip) - while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { - ++this$1.pos - ch = this$1.input.charCodeAt(this$1.pos) - } - if (this.options.onComment) - this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, - startLoc, this.curPosition()) - } - - // Called at the start of the parse and after every token. Skips - // whitespace and comments, and. - - pp$7.skipSpace = function() { - var this$1 = this; - - loop: while (this.pos < this.input.length) { - var ch = this$1.input.charCodeAt(this$1.pos) - switch (ch) { - case 32: case 160: // ' ' - ++this$1.pos - break - case 13: - if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { - ++this$1.pos - } - case 10: case 8232: case 8233: + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos) + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { ++this$1.pos - if (this$1.options.locations) { - ++this$1.curLine - this$1.lineStart = this$1.pos - } - break - case 47: // '/' - switch (this$1.input.charCodeAt(this$1.pos + 1)) { - case 42: // '*' - this$1.skipBlockComment() - break - case 47: - this$1.skipLineComment(2) - break - default: - break loop - } - break - default: - if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { - ++this$1.pos - } else { + } + case 10: case 8232: case 8233: + ++this$1.pos + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment() + break + case 47: + this$1.skipLineComment(2) + break + default: break loop - } - } - } - } - - // Called at the end of every token. Sets `end`, `val`, and - // maintains `context` and `exprAllowed`, and skips the space after - // the token, so that the next one's `start` will point at the - // right position. - - pp$7.finishToken = function(type, val) { - this.end = this.pos - if (this.options.locations) this.endLoc = this.curPosition() - var prevType = this.type - this.type = type - this.value = val - - this.updateContext(prevType) - } - - // ### Token reading - - // This is the function that is called to fetch the next token. It - // is somewhat obscure, because it works in character codes rather - // than characters, and because operator parsing has been inlined - // into it. - // - // All in the name of speed. - // - pp$7.readToken_dot = function() { - var next = this.input.charCodeAt(this.pos + 1) - if (next >= 48 && next <= 57) return this.readNumber(true) - var next2 = this.input.charCodeAt(this.pos + 2) - if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' - this.pos += 3 - return this.finishToken(tt.ellipsis) - } else { - ++this.pos - return this.finishToken(tt.dot) - } - } - - pp$7.readToken_slash = function() { // '/' - var next = this.input.charCodeAt(this.pos + 1) - if (this.exprAllowed) {++this.pos; return this.readRegexp()} - if (next === 61) return this.finishOp(tt.assign, 2) - return this.finishOp(tt.slash, 1) - } - - pp$7.readToken_mult_modulo_exp = function(code) { // '%*' - var next = this.input.charCodeAt(this.pos + 1) - var size = 1 - var tokentype = code === 42 ? tt.star : tt.modulo - - // exponentiation operator ** and **= - if (this.options.ecmaVersion >= 7 && next === 42) { - ++size - tokentype = tt.starstar - next = this.input.charCodeAt(this.pos + 2) - } - - if (next === 61) return this.finishOp(tt.assign, size + 1) - return this.finishOp(tokentype, size) - } - - pp$7.readToken_pipe_amp = function(code) { // '|&' - var next = this.input.charCodeAt(this.pos + 1) - if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2) - if (next === 61) return this.finishOp(tt.assign, 2) - return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1) - } - - pp$7.readToken_caret = function() { // '^' - var next = this.input.charCodeAt(this.pos + 1) - if (next === 61) return this.finishOp(tt.assign, 2) - return this.finishOp(tt.bitwiseXOR, 1) - } - - pp$7.readToken_plus_min = function(code) { // '+-' - var next = this.input.charCodeAt(this.pos + 1) - if (next === code) { - if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && - lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) { - // A `-->` line comment - this.skipLineComment(3) - this.skipSpace() - return this.nextToken() - } - return this.finishOp(tt.incDec, 2) + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos + } else { + break loop + } } - if (next === 61) return this.finishOp(tt.assign, 2) - return this.finishOp(tt.plusMin, 1) } - - pp$7.readToken_lt_gt = function(code) { // '<>' - var next = this.input.charCodeAt(this.pos + 1) - var size = 1 - if (next === code) { - size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 - if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) - return this.finishOp(tt.bitShift, size) - } - if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && - this.input.charCodeAt(this.pos + 3) == 45) { - if (this.inModule) this.unexpected() - // `` line comment + this.skipLineComment(3) this.skipSpace() return this.nextToken() } - if (next === 61) size = 2 - return this.finishOp(tt.relational, size) - } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // ` @@ -163,6 +149,11 @@ target.bundle = function(argsArray) { All commands run synchronously, unless otherwise stated. +All commands accept standard bash globbing characters (`*`, `?`, etc.), +compatible with the [node glob module](https://github.com/isaacs/node-glob). + +For less-commonly used commands and features, please check out our [wiki +page](https://github.com/shelljs/shelljs/wiki). ### cd([dir]) @@ -220,17 +211,21 @@ Available options: + `-f`: force (default behavior) + `-n`: no-clobber -+ `-r, -R`: recursive ++ `-u`: only copy if source is newer than dest ++ `-r`, `-R`: recursive ++ `-L`: follow symlinks ++ `-P`: don't follow symlinks Examples: ```javascript cp('file1', 'dir1'); +cp('-R', 'path/to/dir/', '~/newCopy/'); cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp'); cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above ``` -Copies files. The wildcard `*` is accepted. +Copies files. ### rm([options,] file [, file ...]) @@ -248,7 +243,7 @@ rm('some_file.txt', 'another_file.txt'); rm(['some_file.txt', 'another_file.txt']); // same as above ``` -Removes files. The wildcard `*` is accepted. +Removes files. ### mv([options ,] source [, source ...], dest') @@ -266,7 +261,7 @@ mv('file1', 'file2', 'dir/'); mv(['file1', 'file2'], 'dir/'); // same as above ``` -Moves files. The wildcard `*` is accepted. +Moves files. ### mkdir([options,] dir [, dir ...]) @@ -320,10 +315,44 @@ var str = cat(['file1', 'file2']); // same as above Returns a string containing the given file, or a concatenated string containing the files if more than one file is given (a new line character is -introduced between each file). Wildcard `*` accepted. +introduced between each file). + + +### head([{'-n': \},] file [, file ...]) +### head([{'-n': \},] file_array) +Available options: + ++ `-n `: Show the first `` lines of the files + +Examples: + +```javascript +var str = head({'-n': 1}, 'file*.txt'); +var str = head('file1', 'file2'); +var str = head(['file1', 'file2']); // same as above +``` + +Read the start of a file. + + +### tail([{'-n': \},] file [, file ...]) +### tail([{'-n': \},] file_array) +Available options: + ++ `-n `: Show the last `` lines of the files + +Examples: + +```javascript +var str = tail({'-n': 1}, 'file*.txt'); +var str = tail('file1', 'file2'); +var str = tail(['file1', 'file2']); // same as above +``` + +Read the end of a file. -### 'string'.to(file) +### ShellString.prototype.to(file) Examples: @@ -331,11 +360,12 @@ Examples: cat('input.txt').to('output.txt'); ``` -Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as -those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ +Analogous to the redirection operator `>` in Unix, but works with +ShellStrings (such as those returned by `cat`, `grep`, etc). _Like Unix +redirections, `to()` will overwrite any existing file!_ -### 'string'.toEnd(file) +### ShellString.prototype.toEnd(file) Examples: @@ -343,8 +373,8 @@ Examples: cat('input.txt').toEnd('output.txt'); ``` -Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as -those returned by `cat`, `grep`, etc). +Analogous to the redirect-and-append operator `>>` in Unix, but works with +ShellStrings (such as those returned by `cat`, `grep`, etc). ### sed([options,] search_regex, replacement, file [, file ...]) @@ -364,11 +394,48 @@ Reads an input string from `files` and performs a JavaScript `replace()` on the using the given search regex and replacement string or function. Returns the new string after replacement. +### sort([options,] file [, file ...]) +### sort([options,] file_array) +Available options: + ++ `-r`: Reverse the result of comparisons ++ `-n`: Compare according to numerical value + +Examples: + +```javascript +sort('foo.txt', 'bar.txt'); +sort('-r', 'foo.txt'); +``` + +Return the contents of the files, sorted line-by-line. Sorting multiple +files mixes their content, just like unix sort does. + + +### uniq([options,] [input, [output]]) +Available options: + ++ `-i`: Ignore case while comparing ++ `-c`: Prefix lines by the number of occurrences ++ `-d`: Only print duplicate lines, one for each group of identical lines + +Examples: + +```javascript +uniq('foo.txt'); +uniq('-i', 'foo.txt'); +uniq('-cd', 'foo.txt', 'bar.txt'); +``` + +Filter adjacent matching lines from input + + ### grep([options,] regex_filter, file [, file ...]) ### grep([options,] regex_filter, file_array) Available options: + `-v`: Inverse the sense of the regex and print the lines not matching the criteria. ++ `-l`: Print only filenames of matching files Examples: @@ -378,7 +445,7 @@ grep('GLOBAL_VARIABLE', '*.js'); ``` Reads input string from given files and returns a string containing all lines of the -file that match the given `regex_filter`. Wildcard `*` accepted. +file that match the given `regex_filter`. ### which(command) @@ -394,7 +461,10 @@ Searches for `command` in the system's PATH. On Windows, this uses the Returns string containing the absolute path to the command. -### echo(string [, string ...]) +### echo([options,] string [, string ...]) +Available options: + ++ `-e`: interpret backslash escapes (default) Examples: @@ -517,9 +587,13 @@ exec('some_long_running_process', function(code, stdout, stderr) { ``` Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous -mode returns the object `{ code:..., stdout:... , stderr:... }`, containing the program's -`stdout`, `stderr`, and its exit `code`. Otherwise returns the child process object, -and the `callback` gets the arguments `(code, stdout, stderr)`. +mode, this returns a ShellString (compatible with ShellJS v0.6.x, which returns an object +of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process +object, and the `callback` gets the arguments `(code, stdout, stderr)`. + +Not seeing the behavior you want? `exec()` runs everything through `sh` +by default (or `cmd.exe` on Windows), which differs from `bash`. If you +need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option. **Note:** For long-lived processes, it's best to run `exec()` asynchronously as the current synchronous implementation uses a lot of CPU. This should be getting @@ -553,7 +627,8 @@ Notable exceptions: + There is no "quiet" option since default behavior is to run silent. -### touch([options,] file) +### touch([options,] file [, file ...]) +### touch([options,] file_array) Available options: + `-a`: Change only the access time @@ -580,6 +655,7 @@ Available options: + `+/-e`: exit upon error (`config.fatal`) + `+/-v`: verbose: show all commands (`config.verbose`) ++ `+/-f`: disable filename expansion (globbing) Examples: @@ -607,14 +683,45 @@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.ht ### error() -Tests if error occurred in the last command. Returns `null` if no error occurred, -otherwise returns string explaining the error +Tests if error occurred in the last command. Returns a truthy value if an +error returned and a falsy value otherwise. +**Note**: do not rely on the +return value to be an error message. If you need the last error message, use +the `.stderr` attribute from the last command's return value instead. + + +### ShellString(str) + +Examples: + +```javascript +var foo = ShellString('hello world'); +``` + +Turns a regular string into a string-like object similar to what each +command returns. This has special methods, like `.to()` and `.toEnd()` + + +### Pipes + +Examples: + +```javascript +grep('foo', 'file1.txt', 'file2.txt').sed(/o/g, 'a').to('output.txt'); +echo('files with o\'s in the name:\n' + ls().grep('o')); +cat('test.js').exec('node'); // pipe to exec() call +``` + +Commands can send their output to another command in a pipe-like fashion. +`sed`, `grep`, `cat`, `exec`, `to`, and `toEnd` can appear on the right-hand +side of a pipe. Pipes can be chained. ## Configuration ### config.silent + Example: ```javascript @@ -629,19 +736,22 @@ Suppresses all command output if `true`, except for `echo()` calls. Default is `false`. ### config.fatal + Example: ```javascript require('shelljs/global'); config.fatal = true; // or set('-e'); -cp('this_file_does_not_exist', '/dev/null'); // dies here +cp('this_file_does_not_exist', '/dev/null'); // throws Error here /* more commands... */ ``` -If `true` the script will die on errors. Default is `false`. This is -analogous to Bash's `set -e` +If `true` the script will throw a Javascript error when any shell.js +command encounters an error. Default is `false`. This is analogous to +Bash's `set -e` ### config.verbose + Example: ```javascript @@ -656,3 +766,19 @@ Will print each command as follows: cd dir/ ls subdir/ ``` + +### config.globOptions + +Example: + +```javascript +config.globOptions = {nodir: true}; +``` + +Use this value for calls to `glob.sync()` instead of the default options. + +## Team + +| [![Nate Fischer](https://avatars.githubusercontent.com/u/5801521?s=130)](https://github.com/nfischer) | [![Ari Porad](https://avatars1.githubusercontent.com/u/1817508?v=3&s=130)](http://github.com/ariporad) | +|:---:|:---:| +| [Nate Fischer](https://github.com/nfischer) | [Ari Porad](http://github.com/ariporad) | diff --git a/tools/eslint/node_modules/shelljs/bin/shjs b/tools/eslint/node_modules/shelljs/bin/shjs index aae3bc64ce2b68..75ca58b9d9ac3c 100755 --- a/tools/eslint/node_modules/shelljs/bin/shjs +++ b/tools/eslint/node_modules/shelljs/bin/shjs @@ -32,24 +32,8 @@ for (var i = 0, l = args.length; i < l; i++) { } } -if (scriptName.match(/\.coffee$/)) { - // - // CoffeeScript - // - if (which('coffee')) { - exec('coffee "' + scriptName + '" ' + args.join(' '), function(code) { - process.exit(code); - }); - } else { - console.log('ShellJS: CoffeeScript interpreter not found'); - console.log(); - process.exit(1); - } -} else { - // - // JavaScript - // - exec('node "' + scriptName + '" ' + args.join(' '), function(code) { - process.exit(code); - }); -} +var path = require('path'); +var extensions = require('interpret').extensions; +var rechoir = require('rechoir'); +rechoir.prepare(extensions, scriptName); +require(require.resolve(path.resolve(process.cwd(), scriptName))); diff --git a/tools/eslint/node_modules/shelljs/global.js b/tools/eslint/node_modules/shelljs/global.js index 97f0033cc15303..b232e66d5e9cbc 100644 --- a/tools/eslint/node_modules/shelljs/global.js +++ b/tools/eslint/node_modules/shelljs/global.js @@ -1,3 +1,12 @@ +/* eslint no-extend-native: 0 */ var shell = require('./shell.js'); -for (var cmd in shell) +var common = require('./src/common'); +Object.keys(shell).forEach(function (cmd) { global[cmd] = shell[cmd]; +}); + +var _to = require('./src/to'); +String.prototype.to = common.wrap('to', _to); + +var _toEnd = require('./src/toEnd'); +String.prototype.toEnd = common.wrap('toEnd', _toEnd); diff --git a/tools/eslint/node_modules/shelljs/package.json b/tools/eslint/node_modules/shelljs/package.json index 5dc19b8f524e00..b6cfe9545d9ac0 100644 --- a/tools/eslint/node_modules/shelljs/package.json +++ b/tools/eslint/node_modules/shelljs/package.json @@ -2,53 +2,49 @@ "_args": [ [ { - "raw": "shelljs@^0.6.0", + "raw": "shelljs@^0.7.5", "scope": null, "escapedName": "shelljs", "name": "shelljs", - "rawSpec": "^0.6.0", - "spec": ">=0.6.0 <0.7.0", + "rawSpec": "^0.7.5", + "spec": ">=0.7.5 <0.8.0", "type": "range" }, "/Users/trott/io.js/tools/node_modules/eslint" ] ], - "_from": "shelljs@>=0.6.0 <0.7.0", - "_id": "shelljs@0.6.1", + "_from": "shelljs@>=0.7.5 <0.8.0", + "_id": "shelljs@0.7.5", "_inCache": true, "_location": "/shelljs", - "_nodeVersion": "6.0.0", + "_nodeVersion": "6.7.0", "_npmOperationalInternal": { - "host": "packages-16-east.internal.npmjs.com", - "tmp": "tmp/shelljs-0.6.1.tgz_1470519555022_0.9348916830495" + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/shelljs-0.7.5.tgz_1477547417527_0.3151172921061516" }, "_npmUser": { "name": "nfischer", "email": "ntfschr@gmail.com" }, - "_npmVersion": "3.5.2", + "_npmVersion": "3.10.8", "_phantomChildren": {}, "_requested": { - "raw": "shelljs@^0.6.0", + "raw": "shelljs@^0.7.5", "scope": null, "escapedName": "shelljs", "name": "shelljs", - "rawSpec": "^0.6.0", - "spec": ">=0.6.0 <0.7.0", + "rawSpec": "^0.7.5", + "spec": ">=0.7.5 <0.8.0", "type": "range" }, "_requiredBy": [ "/eslint" ], - "_resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz", - "_shasum": "ec6211bed1920442088fe0f70b2837232ed2c8a8", + "_resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.5.tgz", + "_shasum": "2eef7a50a21e1ccf37da00df767ec69e30ad0675", "_shrinkwrap": null, - "_spec": "shelljs@^0.6.0", + "_spec": "shelljs@^0.7.5", "_where": "/Users/trott/io.js/tools/node_modules/eslint", - "author": { - "name": "Artur Adib", - "email": "arturadib@gmail.com" - }, "bin": { "shjs": "./bin/shjs" }, @@ -63,26 +59,39 @@ }, { "name": "Nate Fischer", - "email": "ntfschr@gmail.com" + "email": "ntfschr@gmail.com", + "url": "https://github.com/nfischer" } ], - "dependencies": {}, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, "description": "Portable Unix shell commands for Node.js", "devDependencies": { "coffee-script": "^1.10.0", - "jshint": "~2.1.11" + "eslint": "^2.0.0", + "eslint-config-airbnb-base": "^3.0.0", + "eslint-plugin-import": "^1.11.1", + "shelljs-changelog": "^0.2.0", + "shelljs-release": "^0.2.0", + "travis-check-changes": "^0.2.0" }, "directories": {}, "dist": { - "shasum": "ec6211bed1920442088fe0f70b2837232ed2c8a8", - "tarball": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz" + "shasum": "2eef7a50a21e1ccf37da00df767ec69e30ad0675", + "tarball": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.5.tgz" }, "engines": { - "node": ">=0.10.0" + "iojs": "*", + "node": ">=0.11.0" }, - "gitHead": "a5b9e2a64ffdf9f837d6ceb15d7f42221875542b", + "gitHead": "1a15022f2747d322d771dd7ae0c00840e469a52a", "homepage": "http://github.com/shelljs/shelljs", "keywords": [ + "shelljs", + "bash", "unix", "shell", "makefile", @@ -114,7 +123,15 @@ "url": "git://github.com/shelljs/shelljs.git" }, "scripts": { + "after-travis": "travis-check-changes", + "changelog": "shelljs-changelog", + "gendocs": "node scripts/generate-docs", + "lint": "eslint .", + "posttest": "npm run lint", + "release:major": "shelljs-release major", + "release:minor": "shelljs-release minor", + "release:patch": "shelljs-release patch", "test": "node scripts/run-tests" }, - "version": "0.6.1" + "version": "0.7.5" } diff --git a/tools/eslint/node_modules/shelljs/plugin.js b/tools/eslint/node_modules/shelljs/plugin.js new file mode 100644 index 00000000000000..f879ab320e666a --- /dev/null +++ b/tools/eslint/node_modules/shelljs/plugin.js @@ -0,0 +1,16 @@ +// Various utilties exposed to plugins + +require('./shell'); // Create the ShellJS instance (mandatory) + +var common = require('./src/common'); + +var exportedAttributes = [ + 'error', // For signaling errors from within commands + 'parseOptions', // For custom option parsing + 'readFromPipe', // For commands with the .canReceivePipe attribute + 'register', // For registering plugins +]; + +exportedAttributes.forEach(function (attr) { + exports[attr] = common[attr]; +}); diff --git a/tools/eslint/node_modules/shelljs/scripts/generate-docs.js b/tools/eslint/node_modules/shelljs/scripts/generate-docs.js index 3a31a91abd2a13..f777c8ad263612 100755 --- a/tools/eslint/node_modules/shelljs/scripts/generate-docs.js +++ b/tools/eslint/node_modules/shelljs/scripts/generate-docs.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -/* globals cat, cd, echo, grep, sed */ +/* globals cat, cd, echo, grep, sed, ShellString */ require('../global'); echo('Appending docs to README.md'); @@ -7,18 +7,19 @@ echo('Appending docs to README.md'); cd(__dirname + '/..'); // Extract docs from shell.js -var docs = grep('//@', 'shell.js'); +var docs = grep('^//@', 'shell.js'); -docs = docs.replace(/\/\/\@include (.+)/g, function(match, path) { - var file = path.match('.js$') ? path : path+'.js'; - return grep('//@', file); +// Now extract docs from the appropriate src/*.js files +docs = docs.replace(/\/\/@include (.+)/g, function (match, path) { + var file = path.match('.js$') ? path : path + '.js'; + return grep('^//@', file); }); // Remove '//@' -docs = docs.replace(/\/\/\@ ?/g, ''); +docs = docs.replace(/\/\/@ ?/g, ''); // Wipe out the old docs -cat('README.md').replace(/## Command reference(.|\n)*/, '## Command reference').to('README.md'); +ShellString(cat('README.md').replace(/## Command reference(.|\n)*\n## Team/, '## Command reference\n## Team')).to('README.md'); // Append new docs to README sed('-i', /## Command reference/, '## Command reference\n\n' + docs, 'README.md'); diff --git a/tools/eslint/node_modules/shelljs/scripts/run-tests.js b/tools/eslint/node_modules/shelljs/scripts/run-tests.js index e8e7ff2f879a82..99205623f9ed6b 100755 --- a/tools/eslint/node_modules/shelljs/scripts/run-tests.js +++ b/tools/eslint/node_modules/shelljs/scripts/run-tests.js @@ -1,55 +1,29 @@ #!/usr/bin/env node -/* globals cd, echo, exec, exit, ls, pwd, test */ +/* globals cd, echo, exec, exit, ls */ require('../global'); -var common = require('../src/common'); var failed = false; -// -// Lint -// -var JSHINT_BIN = 'node_modules/jshint/bin/jshint'; -cd(__dirname + '/..'); - -if (!test('-f', JSHINT_BIN)) { - echo('JSHint not found. Run `npm install` in the root dir first.'); - exit(1); -} - -var jsfiles = common.expand([pwd() + '/*.js', - pwd() + '/scripts/*.js', - pwd() + '/src/*.js', - pwd() + '/test/*.js' - ]).join(' '); -if (exec('node ' + pwd() + '/' + JSHINT_BIN + ' ' + jsfiles).code !== 0) { - failed = true; - echo('*** JSHINT FAILED! (return code != 0)'); - echo(); -} else { - echo('All JSHint tests passed'); - echo(); -} - // // Unit tests // cd(__dirname + '/../test'); -ls('*.js').forEach(function(file) { +ls('*.js').forEach(function (file) { echo('Running test:', file); - if (exec('node ' + file).code !== 123) { // 123 avoids false positives (e.g. premature exit) + if (exec(JSON.stringify(process.execPath) + ' ' + file).code !== 123) { // 123 avoids false positives (e.g. premature exit) failed = true; echo('*** TEST FAILED! (missing exit code "123")'); echo(); } }); +echo(); + if (failed) { - echo(); echo('*******************************************************'); echo('WARNING: Some tests did not pass!'); echo('*******************************************************'); exit(1); } else { - echo(); echo('All tests passed.'); } diff --git a/tools/eslint/node_modules/shelljs/shell.js b/tools/eslint/node_modules/shelljs/shell.js index 93aff709a3931f..9e49ef5e799cdb 100644 --- a/tools/eslint/node_modules/shelljs/shell.js +++ b/tools/eslint/node_modules/shelljs/shell.js @@ -8,86 +8,95 @@ var common = require('./src/common'); - //@ //@ All commands run synchronously, unless otherwise stated. +//@ All commands accept standard bash globbing characters (`*`, `?`, etc.), +//@ compatible with the [node glob module](https://github.com/isaacs/node-glob). +//@ +//@ For less-commonly used commands and features, please check out our [wiki +//@ page](https://github.com/shelljs/shelljs/wiki). //@ +// Boilerplate +// ----------- +// Copy the code block below here & replace variables with appropiate values +// ``` +// //@include ./src/fileName +// var functionName = require('./src/fileName'); +// exports.nameOfCommand = common.wrap(nameOfCommand, functionName, {globStart: firstIndexToExpand}); +// ``` +// +// The //@include includes the docs for that command +// +// firstIndexToExpand should usually be 1 (so, put {globStart: 1}) +// Increase this value if the command takes arguments that shouldn't be expanded +// with wildcards, such as with the regexes for sed & grep + //@include ./src/cd -var _cd = require('./src/cd'); -exports.cd = common.wrap('cd', _cd); +require('./src/cd'); //@include ./src/pwd -var _pwd = require('./src/pwd'); -exports.pwd = common.wrap('pwd', _pwd); +require('./src/pwd'); //@include ./src/ls -var _ls = require('./src/ls'); -exports.ls = common.wrap('ls', _ls); +require('./src/ls'); //@include ./src/find -var _find = require('./src/find'); -exports.find = common.wrap('find', _find); +require('./src/find'); //@include ./src/cp -var _cp = require('./src/cp'); -exports.cp = common.wrap('cp', _cp); +require('./src/cp'); //@include ./src/rm -var _rm = require('./src/rm'); -exports.rm = common.wrap('rm', _rm); +require('./src/rm'); //@include ./src/mv -var _mv = require('./src/mv'); -exports.mv = common.wrap('mv', _mv); +require('./src/mv'); //@include ./src/mkdir -var _mkdir = require('./src/mkdir'); -exports.mkdir = common.wrap('mkdir', _mkdir); +require('./src/mkdir'); //@include ./src/test -var _test = require('./src/test'); -exports.test = common.wrap('test', _test); +require('./src/test'); //@include ./src/cat -var _cat = require('./src/cat'); -exports.cat = common.wrap('cat', _cat); +require('./src/cat'); + +//@include ./src/head +require('./src/head'); + +//@include ./src/tail +require('./src/tail'); //@include ./src/to -var _to = require('./src/to'); -String.prototype.to = common.wrap('to', _to); +require('./src/to'); //@include ./src/toEnd -var _toEnd = require('./src/toEnd'); -String.prototype.toEnd = common.wrap('toEnd', _toEnd); +require('./src/toEnd'); //@include ./src/sed -var _sed = require('./src/sed'); -exports.sed = common.wrap('sed', _sed); +require('./src/sed'); + +//@include ./src/sort +require('./src/sort'); + +//@include ./src/uniq +require('./src/uniq'); //@include ./src/grep -var _grep = require('./src/grep'); -exports.grep = common.wrap('grep', _grep); +require('./src/grep'); //@include ./src/which -var _which = require('./src/which'); -exports.which = common.wrap('which', _which); +require('./src/which'); //@include ./src/echo -var _echo = require('./src/echo'); -exports.echo = _echo; // don't common.wrap() as it could parse '-options' +require('./src/echo'); //@include ./src/dirs -var _dirs = require('./src/dirs').dirs; -exports.dirs = common.wrap("dirs", _dirs); -var _pushd = require('./src/dirs').pushd; -exports.pushd = common.wrap('pushd', _pushd); -var _popd = require('./src/dirs').popd; -exports.popd = common.wrap("popd", _popd); +require('./src/dirs'); //@include ./src/ln -var _ln = require('./src/ln'); -exports.ln = common.wrap('ln', _ln); +require('./src/ln'); //@ //@ ### exit(code) @@ -100,20 +109,16 @@ exports.exit = process.exit; exports.env = process.env; //@include ./src/exec -var _exec = require('./src/exec'); -exports.exec = common.wrap('exec', _exec, {notUnix:true}); +require('./src/exec'); //@include ./src/chmod -var _chmod = require('./src/chmod'); -exports.chmod = common.wrap('chmod', _chmod); +require('./src/chmod'); //@include ./src/touch -var _touch = require('./src/touch'); -exports.touch = common.wrap('touch', _touch); +require('./src/touch'); //@include ./src/set -var _set = require('./src/set'); -exports.set = common.wrap('set', _set); +require('./src/set'); //@ @@ -121,15 +126,29 @@ exports.set = common.wrap('set', _set); //@ //@include ./src/tempdir -var _tempDir = require('./src/tempdir'); -exports.tempdir = common.wrap('tempdir', _tempDir); - +require('./src/tempdir'); //@include ./src/error -var _error = require('./src/error'); -exports.error = _error; +exports.error = require('./src/error'); + +//@include ./src/common +exports.ShellString = common.ShellString; +//@ +//@ ### Pipes +//@ +//@ Examples: +//@ +//@ ```javascript +//@ grep('foo', 'file1.txt', 'file2.txt').sed(/o/g, 'a').to('output.txt'); +//@ echo('files with o\'s in the name:\n' + ls().grep('o')); +//@ cat('test.js').exec('node'); // pipe to exec() call +//@ ``` +//@ +//@ Commands can send their output to another command in a pipe-like fashion. +//@ `sed`, `grep`, `cat`, `exec`, `to`, and `toEnd` can appear on the right-hand +//@ side of a pipe. Pipes can be chained. //@ //@ ## Configuration @@ -139,6 +158,7 @@ exports.config = common.config; //@ //@ ### config.silent +//@ //@ Example: //@ //@ ```javascript @@ -154,20 +174,23 @@ exports.config = common.config; //@ //@ ### config.fatal +//@ //@ Example: //@ //@ ```javascript //@ require('shelljs/global'); //@ config.fatal = true; // or set('-e'); -//@ cp('this_file_does_not_exist', '/dev/null'); // dies here +//@ cp('this_file_does_not_exist', '/dev/null'); // throws Error here //@ /* more commands... */ //@ ``` //@ -//@ If `true` the script will die on errors. Default is `false`. This is -//@ analogous to Bash's `set -e` +//@ If `true` the script will throw a Javascript error when any shell.js +//@ command encounters an error. Default is `false`. This is analogous to +//@ Bash's `set -e` //@ //@ ### config.verbose +//@ //@ Example: //@ //@ ```javascript @@ -182,3 +205,14 @@ exports.config = common.config; //@ cd dir/ //@ ls subdir/ //@ ``` + +//@ +//@ ### config.globOptions +//@ +//@ Example: +//@ +//@ ```javascript +//@ config.globOptions = {nodir: true}; +//@ ``` +//@ +//@ Use this value for calls to `glob.sync()` instead of the default options. diff --git a/tools/eslint/node_modules/shelljs/src/cat.js b/tools/eslint/node_modules/shelljs/src/cat.js index 5840b4ea77b590..a74a25c8424d16 100644 --- a/tools/eslint/node_modules/shelljs/src/cat.js +++ b/tools/eslint/node_modules/shelljs/src/cat.js @@ -1,6 +1,10 @@ var common = require('./common'); var fs = require('fs'); +common.register('cat', _cat, { + canReceivePipe: true, +}); + //@ //@ ### cat(file [, file ...]) //@ ### cat(file_array) @@ -15,26 +19,22 @@ var fs = require('fs'); //@ //@ Returns a string containing the given file, or a concatenated string //@ containing the files if more than one file is given (a new line character is -//@ introduced between each file). Wildcard `*` accepted. +//@ introduced between each file). function _cat(options, files) { - var cat = ''; - - if (!files) - common.error('no paths given'); + var cat = common.readFromPipe(); - if (typeof files === 'string') - files = [].slice.call(arguments, 1); - // if it's array leave it as it is + if (!files && !cat) common.error('no paths given'); - files = common.expand(files); + files = [].slice.call(arguments, 1); - files.forEach(function(file) { - if (!fs.existsSync(file)) + files.forEach(function (file) { + if (!fs.existsSync(file)) { common.error('no such file or directory: ' + file); + } cat += fs.readFileSync(file, 'utf8'); }); - return common.ShellString(cat); + return cat; } module.exports = _cat; diff --git a/tools/eslint/node_modules/shelljs/src/cd.js b/tools/eslint/node_modules/shelljs/src/cd.js index b7b9931b8f41df..634ed835cb0925 100644 --- a/tools/eslint/node_modules/shelljs/src/cd.js +++ b/tools/eslint/node_modules/shelljs/src/cd.js @@ -1,28 +1,38 @@ var fs = require('fs'); var common = require('./common'); +common.register('cd', _cd, {}); + //@ //@ ### cd([dir]) //@ Changes to directory `dir` for the duration of the script. Changes to home //@ directory if no argument is supplied. function _cd(options, dir) { - if (!dir) - dir = common.getUserHome(); + if (!dir) dir = common.getUserHome(); if (dir === '-') { - if (!common.state.previousDir) + if (!process.env.OLDPWD) { common.error('could not find previous directory'); - else - dir = common.state.previousDir; + } else { + dir = process.env.OLDPWD; + } } - if (!fs.existsSync(dir)) - common.error('no such file or directory: ' + dir); - - if (!fs.statSync(dir).isDirectory()) - common.error('not a directory: ' + dir); - - common.state.previousDir = process.cwd(); - process.chdir(dir); + try { + var curDir = process.cwd(); + process.chdir(dir); + process.env.OLDPWD = curDir; + } catch (e) { + // something went wrong, let's figure out the error + var err; + try { + fs.statSync(dir); // if this succeeds, it must be some sort of file + err = 'not a directory: ' + dir; + } catch (e2) { + err = 'no such file or directory: ' + dir; + } + if (err) common.error(err); + } + return ''; } module.exports = _cd; diff --git a/tools/eslint/node_modules/shelljs/src/chmod.js b/tools/eslint/node_modules/shelljs/src/chmod.js index 6c6de10ce12e49..a1afd90e75684f 100644 --- a/tools/eslint/node_modules/shelljs/src/chmod.js +++ b/tools/eslint/node_modules/shelljs/src/chmod.js @@ -4,30 +4,32 @@ var path = require('path'); var PERMS = (function (base) { return { - OTHER_EXEC : base.EXEC, - OTHER_WRITE : base.WRITE, - OTHER_READ : base.READ, + OTHER_EXEC: base.EXEC, + OTHER_WRITE: base.WRITE, + OTHER_READ: base.READ, - GROUP_EXEC : base.EXEC << 3, - GROUP_WRITE : base.WRITE << 3, - GROUP_READ : base.READ << 3, + GROUP_EXEC: base.EXEC << 3, + GROUP_WRITE: base.WRITE << 3, + GROUP_READ: base.READ << 3, - OWNER_EXEC : base.EXEC << 6, - OWNER_WRITE : base.WRITE << 6, - OWNER_READ : base.READ << 6, + OWNER_EXEC: base.EXEC << 6, + OWNER_WRITE: base.WRITE << 6, + OWNER_READ: base.READ << 6, - // Literal octal numbers are apparently not allowed in "strict" javascript. Using parseInt is - // the preferred way, else a jshint warning is thrown. - STICKY : parseInt('01000', 8), - SETGID : parseInt('02000', 8), - SETUID : parseInt('04000', 8), + // Literal octal numbers are apparently not allowed in "strict" javascript. + STICKY: parseInt('01000', 8), + SETGID: parseInt('02000', 8), + SETUID: parseInt('04000', 8), - TYPE_MASK : parseInt('0770000', 8) + TYPE_MASK: parseInt('0770000', 8) }; -})({ - EXEC : 1, - WRITE : 2, - READ : 4 +}({ + EXEC: 1, + WRITE: 2, + READ: 4 +})); + +common.register('chmod', _chmod, { }); //@ @@ -62,11 +64,8 @@ function _chmod(options, mode, filePattern) { // Special case where the specified file permissions started with - to subtract perms, which // get picked up by the option parser as command flags. // If we are down by one argument and options starts with -, shift everything over. - filePattern = mode; - mode = options; - options = ''; - } - else { + [].unshift.call(arguments, ''); + } else { common.error('You must specify a file.'); } } @@ -77,15 +76,14 @@ function _chmod(options, mode, filePattern) { 'v': 'verbose' }); - if (typeof filePattern === 'string') { - filePattern = [ filePattern ]; - } + filePattern = [].slice.call(arguments, 2); var files; + // TODO: replace this with a call to common.expand() if (options.recursive) { files = []; - common.expand(filePattern).forEach(function addFile(expandedFile) { + filePattern.forEach(function addFile(expandedFile) { var stat = fs.lstatSync(expandedFile); if (!stat.isSymbolicLink()) { @@ -98,9 +96,8 @@ function _chmod(options, mode, filePattern) { } } }); - } - else { - files = common.expand(filePattern); + } else { + files = filePattern; } files.forEach(function innerChmod(file) { @@ -124,7 +121,6 @@ function _chmod(options, mode, filePattern) { if (isNaN(parseInt(mode, 8))) { // parse options mode.split(',').forEach(function (symbolicMode) { - /*jshint regexdash:true */ var pattern = /([ugoa]*)([=\+-])([rwxXst]*)/i; var matches = pattern.exec(symbolicMode); @@ -133,19 +129,20 @@ function _chmod(options, mode, filePattern) { var operator = matches[2]; var change = matches[3]; - var changeOwner = applyTo.indexOf('u') != -1 || applyTo === 'a' || applyTo === ''; - var changeGroup = applyTo.indexOf('g') != -1 || applyTo === 'a' || applyTo === ''; - var changeOther = applyTo.indexOf('o') != -1 || applyTo === 'a' || applyTo === ''; + var changeOwner = applyTo.indexOf('u') !== -1 || applyTo === 'a' || applyTo === ''; + var changeGroup = applyTo.indexOf('g') !== -1 || applyTo === 'a' || applyTo === ''; + var changeOther = applyTo.indexOf('o') !== -1 || applyTo === 'a' || applyTo === ''; - var changeRead = change.indexOf('r') != -1; - var changeWrite = change.indexOf('w') != -1; - var changeExec = change.indexOf('x') != -1; - var changeExecDir = change.indexOf('X') != -1; - var changeSticky = change.indexOf('t') != -1; - var changeSetuid = change.indexOf('s') != -1; + var changeRead = change.indexOf('r') !== -1; + var changeWrite = change.indexOf('w') !== -1; + var changeExec = change.indexOf('x') !== -1; + var changeExecDir = change.indexOf('X') !== -1; + var changeSticky = change.indexOf('t') !== -1; + var changeSetuid = change.indexOf('s') !== -1; - if (changeExecDir && isDir) + if (changeExecDir && isDir) { changeExec = true; + } var mask = 0; if (changeOwner) { @@ -175,35 +172,37 @@ function _chmod(options, mode, filePattern) { case '=': newPerms = type + mask; - // According to POSIX, when using = to explicitly set the permissions, setuid and setgid can never be cleared. + // According to POSIX, when using = to explicitly set the + // permissions, setuid and setgid can never be cleared. if (fs.statSync(file).isDirectory()) { newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms; } break; + default: + common.error('Could not recognize operator: `' + operator + '`'); } if (options.verbose) { console.log(file + ' -> ' + newPerms.toString(8)); } - if (perms != newPerms) { + if (perms !== newPerms) { if (!options.verbose && options.changes) { console.log(file + ' -> ' + newPerms.toString(8)); } fs.chmodSync(file, newPerms); perms = newPerms; // for the next round of changes! } - } - else { + } else { common.error('Invalid symbolic mode change: ' + symbolicMode); } }); - } - else { + } else { // they gave us a full number newPerms = type + parseInt(mode, 8); - // POSIX rules are that setuid and setgid can only be added using numeric form, but not cleared. + // POSIX rules are that setuid and setgid can only be added using numeric + // form, but not cleared. if (fs.statSync(file).isDirectory()) { newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms; } @@ -211,5 +210,6 @@ function _chmod(options, mode, filePattern) { fs.chmodSync(file, newPerms); } }); + return ''; } module.exports = _chmod; diff --git a/tools/eslint/node_modules/shelljs/src/common.js b/tools/eslint/node_modules/shelljs/src/common.js index 33198bd8a0a265..8211feff4e4d29 100644 --- a/tools/eslint/node_modules/shelljs/src/common.js +++ b/tools/eslint/node_modules/shelljs/src/common.js @@ -1,68 +1,132 @@ +// Ignore warning about 'new String()' +/* eslint no-new-wrappers: 0 */ +'use strict'; + var os = require('os'); var fs = require('fs'); -var _ls = require('./ls'); +var glob = require('glob'); +var shell = require('..'); + +var shellMethods = Object.create(shell); // Module globals var config = { silent: false, fatal: false, verbose: false, + noglob: false, + globOptions: {}, + maxdepth: 255 }; exports.config = config; var state = { error: null, + errorCode: 0, currentCmd: 'shell.js', - previousDir: null, tempDir: null }; exports.state = state; +delete process.env.OLDPWD; // initially, there's no previous directory + var platform = os.type().match(/^Win/) ? 'win' : 'unix'; exports.platform = platform; +// This is populated by calls to commonl.wrap() +var pipeMethods = []; + function log() { - if (!config.silent) + if (!config.silent) { console.error.apply(console, arguments); + } } exports.log = log; -// Shows error message. Throws unless _continue or config.fatal are true -function error(msg, _continue) { - if (state.error === null) - state.error = ''; - var log_entry = state.currentCmd + ': ' + msg; - if (state.error === '') - state.error = log_entry; - else - state.error += '\n' + log_entry; +// Shows error message. Throws if config.fatal is true +function error(msg, _code, options) { + // Validate input + if (typeof msg !== 'string') throw new Error('msg must be a string'); + + var DEFAULT_OPTIONS = { + continue: false, + code: 1, + prefix: state.currentCmd + ': ', + silent: false, + }; + + if (typeof _code === 'number' && typeof options === 'object') { + options.code = _code; + } else if (typeof _code === 'object') { // no 'code' + options = _code; + } else if (typeof _code === 'number') { // no 'options' + options = { code: _code }; + } else if (typeof _code !== 'number') { // only 'msg' + options = {}; + } + options = objectAssign({}, DEFAULT_OPTIONS, options); + + if (!state.errorCode) state.errorCode = options.code; - if (msg.length > 0) - log(log_entry); + var logEntry = options.prefix + msg; + state.error = state.error ? state.error + '\n' : ''; + state.error += logEntry; - if (config.fatal) - process.exit(1); + // Throw an error, or log the entry + if (config.fatal) throw new Error(logEntry); + if (msg.length > 0 && !options.silent) log(logEntry); - if (!_continue) - throw ''; + if (!options.continue) { + throw { + msg: 'earlyExit', + retValue: (new ShellString('', state.error, state.errorCode)) + }; + } } exports.error = error; -// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings. -// For now, this is a dummy function to bookmark places we need such strings -function ShellString(str) { - return str; +//@ +//@ ### ShellString(str) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var foo = ShellString('hello world'); +//@ ``` +//@ +//@ Turns a regular string into a string-like object similar to what each +//@ command returns. This has special methods, like `.to()` and `.toEnd()` +function ShellString(stdout, stderr, code) { + var that; + if (stdout instanceof Array) { + that = stdout; + that.stdout = stdout.join('\n'); + if (stdout.length > 0) that.stdout += '\n'; + } else { + that = new String(stdout); + that.stdout = stdout; + } + that.stderr = stderr; + that.code = code; + // A list of all commands that can appear on the right-hand side of a pipe + // (populated by calls to common.wrap()) + pipeMethods.forEach(function (cmd) { + that[cmd] = shellMethods[cmd].bind(that); + }); + return that; } + exports.ShellString = ShellString; // Return the home directory in a platform-agnostic way, with consideration for // older versions of node function getUserHome() { var result; - if (os.homedir) + if (os.homedir) { result = os.homedir(); // node 3+ - else + } else { result = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME']; + } return result; } exports.getUserHome = getUserHome; @@ -72,49 +136,50 @@ exports.getUserHome = getUserHome; // Returns {'reference': 'string-value', 'bob': false} when passed two dictionaries of the form: // parseOptions({'-r': 'string-value'}, {'r':'reference', 'b':'bob'}); function parseOptions(opt, map) { - if (!map) - error('parseOptions() internal error: no map given'); + if (!map) error('parseOptions() internal error: no map given'); // All options are false by default var options = {}; - for (var letter in map) { - if (map[letter][0] !== '!') + Object.keys(map).forEach(function (letter) { + if (map[letter][0] !== '!') { options[map[letter]] = false; - } + } + }); - if (!opt) - return options; // defaults + if (!opt) return options; // defaults var optionName; if (typeof opt === 'string') { - if (opt[0] !== '-') + if (opt[0] !== '-') { return options; + } // e.g. chars = ['R', 'f'] var chars = opt.slice(1).split(''); - chars.forEach(function(c) { + chars.forEach(function (c) { if (c in map) { optionName = map[c]; - if (optionName[0] === '!') - options[optionName.slice(1, optionName.length-1)] = false; - else + if (optionName[0] === '!') { + options[optionName.slice(1)] = false; + } else { options[optionName] = true; + } } else { - error('option not recognized: '+c); + error('option not recognized: ' + c); } }); } else if (typeof opt === 'object') { - for (var key in opt) { + Object.keys(opt).forEach(function (key) { // key is a string of the form '-r', '-d', etc. var c = key[1]; if (c in map) { optionName = map[c]; options[optionName] = opt[key]; // assign the given value } else { - error('option not recognized: '+c); + error('option not recognized: ' + c); } - } + }); } else { error('options must be strings or key-value pairs'); } @@ -127,29 +192,18 @@ exports.parseOptions = parseOptions; // expand(['file*.js']) = ['file1.js', 'file2.js', ...] // (if the files 'file1.js', 'file2.js', etc, exist in the current dir) function expand(list) { + if (!Array.isArray(list)) { + throw new TypeError('must be an array'); + } var expanded = []; - list.forEach(function(listEl) { - // Wildcard present on directory names ? - if(listEl.search(/\*[^\/]*\//) > -1 || listEl.search(/\*\*[^\/]*\//) > -1) { - var match = listEl.match(/^([^*]+\/|)(.*)/); - var root = match[1]; - var rest = match[2]; - var restRegex = rest.replace(/\*\*/g, ".*").replace(/\*/g, "[^\\/]*"); - restRegex = new RegExp(restRegex); - - _ls('-R', root).filter(function (e) { - return restRegex.test(e); - }).forEach(function(file) { - expanded.push(file); - }); - } - // Wildcard present on file names ? - else if (listEl.search(/\*/) > -1) { - _ls('', listEl).forEach(function(file) { - expanded.push(file); - }); - } else { + list.forEach(function (listEl) { + // Don't expand non-strings + if (typeof listEl !== 'string') { expanded.push(listEl); + } else { + var ret = glob.sync(listEl, config.globOptions); + // if glob fails, interpret the string literally + expanded = expanded.concat(ret.length > 0 ? ret : [listEl]); } }); return expanded; @@ -161,7 +215,7 @@ exports.expand = expand; function unlinkSync(file) { try { fs.unlinkSync(file); - } catch(e) { + } catch (e) { // Try to override file permission if (e.code === 'EPERM') { fs.chmodSync(file, '0666'); @@ -176,78 +230,133 @@ exports.unlinkSync = unlinkSync; // e.g. 'shelljs_a5f185d0443ca...' function randomFileName() { function randomHash(count) { - if (count === 1) - return parseInt(16*Math.random(), 10).toString(16); - else { - var hash = ''; - for (var i=0; i= common.config.maxdepth) { + // Max depth has been reached, end copy. + return; + } + opts.depth++; + + // Create the directory where all our junk is moving to; read the mode of the + // source directory and mirror it try { + var checkDir = fs.statSync(sourceDir); fs.mkdirSync(destDir, checkDir.mode); } catch (e) { - //if the directory already exists, that's okay + // if the directory already exists, that's okay if (e.code !== 'EEXIST') throw e; } var files = fs.readdirSync(sourceDir); for (var i = 0; i < files.length; i++) { - var srcFile = sourceDir + "/" + files[i]; - var destFile = destDir + "/" + files[i]; + var srcFile = sourceDir + '/' + files[i]; + var destFile = destDir + '/' + files[i]; var srcFileStat = fs.lstatSync(srcFile); + var symlinkFull; + if (opts.followsymlink) { + if (cpcheckcycle(sourceDir, srcFile)) { + // Cycle link found. + console.error('Cycle link found.'); + symlinkFull = fs.readlinkSync(srcFile); + fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null); + continue; + } + } if (srcFileStat.isDirectory()) { /* recursion this thing right on back. */ cpdirSyncRecursive(srcFile, destFile, opts); - } else if (srcFileStat.isSymbolicLink()) { - var symlinkFull = fs.readlinkSync(srcFile); - fs.symlinkSync(symlinkFull, destFile, os.platform() === "win32" ? "junction" : null); + } else if (srcFileStat.isSymbolicLink() && !opts.followsymlink) { + symlinkFull = fs.readlinkSync(srcFile); + try { + fs.lstatSync(destFile); + common.unlinkSync(destFile); // re-link it + } catch (e) { + // it doesn't exist, so no work needs to be done + } + fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null); + } else if (srcFileStat.isSymbolicLink() && opts.followsymlink) { + srcFileStat = fs.statSync(srcFile); + if (srcFileStat.isDirectory()) { + cpdirSyncRecursive(srcFile, destFile, opts); + } else { + copyFileSync(srcFile, destFile, opts); + } } else { /* At this point, we've hit a file actually worth copying... so copy it on over. */ if (fs.existsSync(destFile) && opts.no_force) { common.log('skipping existing file: ' + files[i]); } else { - copyFileSync(srcFile, destFile); + copyFileSync(srcFile, destFile, opts); } } - } // for files } // cpdirSyncRecursive +function cpcheckcycle(sourceDir, srcFile) { + var srcFileStat = fs.lstatSync(srcFile); + if (srcFileStat.isSymbolicLink()) { + // Do cycle check. For example: + // $ mkdir -p 1/2/3/4 + // $ cd 1/2/3/4 + // $ ln -s ../../3 link + // $ cd ../../../.. + // $ cp -RL 1 copy + var cyclecheck = fs.statSync(srcFile); + if (cyclecheck.isDirectory()) { + var sourcerealpath = fs.realpathSync(sourceDir); + var symlinkrealpath = fs.realpathSync(srcFile); + var re = new RegExp(symlinkrealpath); + if (re.test(sourcerealpath)) { + return true; + } + } + } + return false; +} //@ //@ ### cp([options,] source [, source ...], dest) @@ -94,117 +183,92 @@ function cpdirSyncRecursive(sourceDir, destDir, opts) { //@ //@ + `-f`: force (default behavior) //@ + `-n`: no-clobber -//@ + `-r, -R`: recursive +//@ + `-u`: only copy if source is newer than dest +//@ + `-r`, `-R`: recursive +//@ + `-L`: follow symlinks +//@ + `-P`: don't follow symlinks //@ //@ Examples: //@ //@ ```javascript //@ cp('file1', 'dir1'); +//@ cp('-R', 'path/to/dir/', '~/newCopy/'); //@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp'); //@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above //@ ``` //@ -//@ Copies files. The wildcard `*` is accepted. +//@ Copies files. function _cp(options, sources, dest) { - options = common.parseOptions(options, { - 'f': '!no_force', - 'n': 'no_force', - 'R': 'recursive', - 'r': 'recursive' - }); + // If we're missing -R, it actually implies -L (unless -P is explicit) + if (options.followsymlink) { + options.noFollowsymlink = false; + } + if (!options.recursive && !options.noFollowsymlink) { + options.followsymlink = true; + } // Get sources, dest if (arguments.length < 3) { common.error('missing and/or '); - } else if (arguments.length > 3) { + } else { sources = [].slice.call(arguments, 1, arguments.length - 1); dest = arguments[arguments.length - 1]; - } else if (typeof sources === 'string') { - sources = [sources]; - } else if ('length' in sources) { - sources = sources; // no-op for array - } else { - common.error('invalid arguments'); } - var exists = fs.existsSync(dest), - stats = exists && fs.statSync(dest); + var destExists = fs.existsSync(dest); + var destStat = destExists && fs.statSync(dest); // Dest is not existing dir, but multiple sources given - if ((!exists || !stats.isDirectory()) && sources.length > 1) + if ((!destExists || !destStat.isDirectory()) && sources.length > 1) { common.error('dest is not a directory (too many sources)'); - - // Dest is an existing file, but no -f given - if (exists && stats.isFile() && options.no_force) - common.error('dest file already exists: ' + dest); - - if (options.recursive) { - // Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*" - // (see Github issue #15) - sources.forEach(function(src, i) { - if (src[src.length - 1] === '/') { - sources[i] += '*'; - // If src is a directory and dest doesn't exist, 'cp -r src dest' should copy src/* into dest - } else if (fs.statSync(src).isDirectory() && !exists) { - sources[i] += '/*'; - } - }); - - // Create dest - try { - fs.mkdirSync(dest, parseInt('0777', 8)); - } catch (e) { - // like Unix's cp, keep going even if we can't create dest dir - } } - sources = common.expand(sources); + // Dest is an existing file, but -n is given + if (destExists && destStat.isFile() && options.no_force) { + return new common.ShellString('', '', 0); + } - sources.forEach(function(src) { + sources.forEach(function (src) { if (!fs.existsSync(src)) { - common.error('no such file or directory: '+src, true); + common.error('no such file or directory: ' + src, { continue: true }); return; // skip file } - - // If here, src exists - if (fs.statSync(src).isDirectory()) { + var srcStat = fs.statSync(src); + if (!options.noFollowsymlink && srcStat.isDirectory()) { if (!options.recursive) { // Non-Recursive - common.log(src + ' is a directory (not copied)'); + common.error("omitting directory '" + src + "'", { continue: true }); } else { // Recursive // 'cp /a/source dest' should create 'source' in 'dest' - var newDest = path.join(dest, path.basename(src)), - checkDir = fs.statSync(src); + var newDest = (destStat && destStat.isDirectory()) ? + path.join(dest, path.basename(src)) : + dest; + try { - fs.mkdirSync(newDest, checkDir.mode); + fs.statSync(path.dirname(dest)); + cpdirSyncRecursive(src, newDest, { no_force: options.no_force, followsymlink: options.followsymlink }); } catch (e) { - //if the directory already exists, that's okay - if (e.code !== 'EEXIST') { - common.error('dest file no such file or directory: ' + newDest, true); - throw e; - } + common.error("cannot create directory '" + dest + "': No such file or directory"); } - - cpdirSyncRecursive(src, newDest, {no_force: options.no_force}); } - return; // done with dir - } + } else { + // If here, src is a file - // If here, src is a file + // When copying to '/path/dir': + // thisDest = '/path/dir/file1' + var thisDest = dest; + if (destStat && destStat.isDirectory()) { + thisDest = path.normalize(dest + '/' + path.basename(src)); + } - // When copying to '/path/dir': - // thisDest = '/path/dir/file1' - var thisDest = dest; - if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) - thisDest = path.normalize(dest + '/' + path.basename(src)); + if (fs.existsSync(thisDest) && options.no_force) { + return; // skip file + } - if (fs.existsSync(thisDest) && options.no_force) { - common.error('dest file already exists: ' + thisDest, true); - return; // skip file + copyFileSync(src, thisDest, options); } - - copyFileSync(src, thisDest); }); // forEach(src) + return new common.ShellString('', common.state.error, common.state.errorCode); } module.exports = _cp; diff --git a/tools/eslint/node_modules/shelljs/src/dirs.js b/tools/eslint/node_modules/shelljs/src/dirs.js index 58fae8b3c6fae3..cf5fe02f50c593 100644 --- a/tools/eslint/node_modules/shelljs/src/dirs.js +++ b/tools/eslint/node_modules/shelljs/src/dirs.js @@ -2,6 +2,16 @@ var common = require('./common'); var _cd = require('./cd'); var path = require('path'); +common.register('dirs', _dirs, { + wrapOutput: false, +}); +common.register('pushd', _pushd, { + wrapOutput: false, +}); +common.register('popd', _popd, { + wrapOutput: false, +}); + // Pushd/popd/dirs internals var _dirStack = []; @@ -13,9 +23,8 @@ function _parseStackIndex(index) { if (_isStackIndex(index)) { if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd return (/^-/).test(index) ? Number(index) - 1 : Number(index); - } else { - common.error(index + ': directory stack index out of range'); } + common.error(index + ': directory stack index out of range'); } else { common.error(index + ': invalid number'); } @@ -54,7 +63,7 @@ function _pushd(options, dir) { } options = common.parseOptions(options, { - 'n' : 'no-cd' + 'n': 'no-cd' }); var dirs = _actualDirStack(); @@ -120,7 +129,7 @@ function _popd(options, index) { } options = common.parseOptions(options, { - 'n' : 'no-cd' + 'n': 'no-cd' }); if (!_dirStack.length) { @@ -163,10 +172,10 @@ function _dirs(options, index) { } options = common.parseOptions(options, { - 'c' : 'clear' + 'c': 'clear' }); - if (options['clear']) { + if (options.clear) { _dirStack = []; return _dirStack; } diff --git a/tools/eslint/node_modules/shelljs/src/echo.js b/tools/eslint/node_modules/shelljs/src/echo.js index b574adc5c38465..2b0e7d9198186f 100644 --- a/tools/eslint/node_modules/shelljs/src/echo.js +++ b/tools/eslint/node_modules/shelljs/src/echo.js @@ -1,7 +1,14 @@ var common = require('./common'); +common.register('echo', _echo, { + allowGlobbing: false, +}); + +//@ +//@ ### echo([options,] string [, string ...]) +//@ Available options: //@ -//@ ### echo(string [, string ...]) +//@ + `-e`: interpret backslash escapes (default) //@ //@ Examples: //@ @@ -12,9 +19,16 @@ var common = require('./common'); //@ //@ Prints string to stdout, and returns string with additional utility methods //@ like `.to()`. -function _echo() { - var messages = [].slice.call(arguments, 0); +function _echo(opts, messages) { + // allow strings starting with '-', see issue #20 + messages = [].slice.call(arguments, opts ? 0 : 1); + + if (messages[0] === '-e') { + // ignore -e + messages.shift(); + } + console.log.apply(console, messages); - return common.ShellString(messages.join(' ')); + return messages.join(' '); } module.exports = _echo; diff --git a/tools/eslint/node_modules/shelljs/src/error.js b/tools/eslint/node_modules/shelljs/src/error.js index 112563db80311e..507c86ddd7131e 100644 --- a/tools/eslint/node_modules/shelljs/src/error.js +++ b/tools/eslint/node_modules/shelljs/src/error.js @@ -2,8 +2,12 @@ var common = require('./common'); //@ //@ ### error() -//@ Tests if error occurred in the last command. Returns `null` if no error occurred, -//@ otherwise returns string explaining the error +//@ Tests if error occurred in the last command. Returns a truthy value if an +//@ error returned and a falsy value otherwise. +//@ +//@ **Note**: do not rely on the +//@ return value to be an error message. If you need the last error message, use +//@ the `.stderr` attribute from the last command's return value instead. function error() { return common.state.error; } diff --git a/tools/eslint/node_modules/shelljs/src/exec.js b/tools/eslint/node_modules/shelljs/src/exec.js index 4174adbd32d317..f6875b1e5fc4ae 100644 --- a/tools/eslint/node_modules/shelljs/src/exec.js +++ b/tools/eslint/node_modules/shelljs/src/exec.js @@ -5,85 +5,95 @@ var path = require('path'); var fs = require('fs'); var child = require('child_process'); -var DEFAULT_MAXBUFFER_SIZE = 20*1024*1024; +var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024; + +common.register('exec', _exec, { + unix: false, + canReceivePipe: true, + wrapOutput: false, +}); // Hack to run child_process.exec() synchronously (sync avoids callback hell) // Uses a custom wait loop that checks for a flag file, created when the child process is done. // (Can't do a wait loop that checks for internal Node variables/messages as // Node is single-threaded; callbacks and other internal state changes are done in the // event loop). -function execSync(cmd, opts) { +function execSync(cmd, opts, pipe) { var tempDir = _tempDir(); - var stdoutFile = path.resolve(tempDir+'/'+common.randomFileName()), - stderrFile = path.resolve(tempDir+'/'+common.randomFileName()), - codeFile = path.resolve(tempDir+'/'+common.randomFileName()), - scriptFile = path.resolve(tempDir+'/'+common.randomFileName()), - sleepFile = path.resolve(tempDir+'/'+common.randomFileName()); + var stdoutFile = path.resolve(tempDir + '/' + common.randomFileName()); + var stderrFile = path.resolve(tempDir + '/' + common.randomFileName()); + var codeFile = path.resolve(tempDir + '/' + common.randomFileName()); + var scriptFile = path.resolve(tempDir + '/' + common.randomFileName()); + var sleepFile = path.resolve(tempDir + '/' + common.randomFileName()); opts = common.extend({ silent: common.config.silent, - cwd: _pwd(), + cwd: _pwd().toString(), env: process.env, maxBuffer: DEFAULT_MAXBUFFER_SIZE }, opts); - var previousStdoutContent = '', - previousStderrContent = ''; + var previousStdoutContent = ''; + var previousStderrContent = ''; // Echoes stdout and stderr changes from running process, if not silent function updateStream(streamFile) { - if (opts.silent || !fs.existsSync(streamFile)) + if (opts.silent || !fs.existsSync(streamFile)) { return; + } - var previousStreamContent, - proc_stream; + var previousStreamContent; + var procStream; if (streamFile === stdoutFile) { previousStreamContent = previousStdoutContent; - proc_stream = process.stdout; + procStream = process.stdout; } else { // assume stderr previousStreamContent = previousStderrContent; - proc_stream = process.stderr; + procStream = process.stderr; } var streamContent = fs.readFileSync(streamFile, 'utf8'); // No changes since last time? - if (streamContent.length <= previousStreamContent.length) + if (streamContent.length <= previousStreamContent.length) { return; + } - proc_stream.write(streamContent.substr(previousStreamContent.length)); + procStream.write(streamContent.substr(previousStreamContent.length)); previousStreamContent = streamContent; } - function escape(str) { - return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0"); - } - if (fs.existsSync(scriptFile)) common.unlinkSync(scriptFile); if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile); if (fs.existsSync(stderrFile)) common.unlinkSync(stderrFile); if (fs.existsSync(codeFile)) common.unlinkSync(codeFile); - var execCommand = '"'+process.execPath+'" '+scriptFile; + var execCommand = JSON.stringify(process.execPath) + ' ' + JSON.stringify(scriptFile); var script; + opts.cwd = path.resolve(opts.cwd); + var optString = JSON.stringify(opts); + if (typeof child.execSync === 'function') { script = [ "var child = require('child_process')", " , fs = require('fs');", - "var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: "+opts.maxBuffer+"}, function(err) {", - " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');", - "});", - "var stdoutStream = fs.createWriteStream('"+escape(stdoutFile)+"');", - "var stderrStream = fs.createWriteStream('"+escape(stderrFile)+"');", - "childProcess.stdout.pipe(stdoutStream, {end: false});", - "childProcess.stderr.pipe(stderrStream, {end: false});", - "childProcess.stdout.pipe(process.stdout);", - "childProcess.stderr.pipe(process.stderr);", - "var stdoutEnded = false, stderrEnded = false;", - "function tryClosingStdout(){ if(stdoutEnded){ stdoutStream.end(); } }", - "function tryClosingStderr(){ if(stderrEnded){ stderrStream.end(); } }", - "childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosingStdout(); });", - "childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosingStderr(); });" - ].join('\n'); + 'var childProcess = child.exec(' + JSON.stringify(cmd) + ', ' + optString + ', function(err) {', + ' fs.writeFileSync(' + JSON.stringify(codeFile) + ", err ? err.code.toString() : '0');", + '});', + 'var stdoutStream = fs.createWriteStream(' + JSON.stringify(stdoutFile) + ');', + 'var stderrStream = fs.createWriteStream(' + JSON.stringify(stderrFile) + ');', + 'childProcess.stdout.pipe(stdoutStream, {end: false});', + 'childProcess.stderr.pipe(stderrStream, {end: false});', + 'childProcess.stdout.pipe(process.stdout);', + 'childProcess.stderr.pipe(process.stderr);' + ].join('\n') + + (pipe ? '\nchildProcess.stdin.end(' + JSON.stringify(pipe) + ');\n' : '\n') + + [ + 'var stdoutEnded = false, stderrEnded = false;', + 'function tryClosingStdout(){ if(stdoutEnded){ stdoutStream.end(); } }', + 'function tryClosingStderr(){ if(stderrEnded){ stderrStream.end(); } }', + "childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosingStdout(); });", + "childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosingStderr(); });" + ].join('\n'); fs.writeFileSync(scriptFile, script); @@ -94,17 +104,27 @@ function execSync(cmd, opts) { } // Welcome to the future - child.execSync(execCommand, opts); + try { + child.execSync(execCommand, opts); + } catch (e) { + // Clean up immediately if we have an exception + try { common.unlinkSync(scriptFile); } catch (e2) {} + try { common.unlinkSync(stdoutFile); } catch (e2) {} + try { common.unlinkSync(stderrFile); } catch (e2) {} + try { common.unlinkSync(codeFile); } catch (e2) {} + throw e; + } } else { - cmd += ' > '+stdoutFile+' 2> '+stderrFile; // works on both win/unix + cmd += ' > ' + stdoutFile + ' 2> ' + stderrFile; // works on both win/unix script = [ "var child = require('child_process')", " , fs = require('fs');", - "var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: "+opts.maxBuffer+"}, function(err) {", - " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');", - "});" - ].join('\n'); + 'var childProcess = child.exec(' + JSON.stringify(cmd) + ', ' + optString + ', function(err) {', + ' fs.writeFileSync(' + JSON.stringify(codeFile) + ", err ? err.code.toString() : '0');", + '});' + ].join('\n') + + (pipe ? '\nchildProcess.stdin.end(' + JSON.stringify(pipe) + ');\n' : '\n'); fs.writeFileSync(scriptFile, script); @@ -117,6 +137,7 @@ function execSync(cmd, opts) { while (!fs.existsSync(codeFile)) { updateStream(stdoutFile); fs.writeFileSync(sleepFile, 'a'); } while (!fs.existsSync(stdoutFile)) { updateStream(stdoutFile); fs.writeFileSync(sleepFile, 'a'); } while (!fs.existsSync(stderrFile)) { updateStream(stderrFile); fs.writeFileSync(sleepFile, 'a'); } + try { common.unlinkSync(sleepFile); } catch (e) {} } // At this point codeFile exists, but it's not necessarily flushed yet. @@ -130,53 +151,46 @@ function execSync(cmd, opts) { var stderr = fs.readFileSync(stderrFile, 'utf8'); // No biggie if we can't erase the files now -- they're in a temp dir anyway - try { common.unlinkSync(scriptFile); } catch(e) {} - try { common.unlinkSync(stdoutFile); } catch(e) {} - try { common.unlinkSync(stderrFile); } catch(e) {} - try { common.unlinkSync(codeFile); } catch(e) {} - try { common.unlinkSync(sleepFile); } catch(e) {} - - // some shell return codes are defined as errors, per http://tldp.org/LDP/abs/html/exitcodes.html - if (code === 1 || code === 2 || code >= 126) { - common.error('', true); // unix/shell doesn't really give an error message after non-zero exit codes + try { common.unlinkSync(scriptFile); } catch (e) {} + try { common.unlinkSync(stdoutFile); } catch (e) {} + try { common.unlinkSync(stderrFile); } catch (e) {} + try { common.unlinkSync(codeFile); } catch (e) {} + + if (code !== 0) { + common.error('', code, { continue: true }); } - // True if successful, false if not - var obj = { - code: code, - output: stdout, // deprecated - stdout: stdout, - stderr: stderr - }; + var obj = common.ShellString(stdout, stderr, code); return obj; } // execSync() // Wrapper around exec() to enable echoing output to console in real time -function execAsync(cmd, opts, callback) { +function execAsync(cmd, opts, pipe, callback) { var stdout = ''; var stderr = ''; opts = common.extend({ silent: common.config.silent, - cwd: _pwd(), + cwd: _pwd().toString(), env: process.env, maxBuffer: DEFAULT_MAXBUFFER_SIZE }, opts); - var c = child.exec(cmd, opts, function(err) { - if (callback) + var c = child.exec(cmd, opts, function (err) { + if (callback) { callback(err ? err.code : 0, stdout, stderr); + } }); - c.stdout.on('data', function(data) { + if (pipe) c.stdin.end(pipe); + + c.stdout.on('data', function (data) { stdout += data; - if (!opts.silent) - process.stdout.write(data); + if (!opts.silent) process.stdout.write(data); }); - c.stderr.on('data', function(data) { + c.stderr.on('data', function (data) { stderr += data; - if (!opts.silent) - process.stderr.write(data); + if (!opts.silent) process.stderr.write(data); }); return c; @@ -210,16 +224,22 @@ function execAsync(cmd, opts, callback) { //@ ``` //@ //@ Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous -//@ mode returns the object `{ code:..., stdout:... , stderr:... }`, containing the program's -//@ `stdout`, `stderr`, and its exit `code`. Otherwise returns the child process object, -//@ and the `callback` gets the arguments `(code, stdout, stderr)`. +//@ mode, this returns a ShellString (compatible with ShellJS v0.6.x, which returns an object +//@ of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process +//@ object, and the `callback` gets the arguments `(code, stdout, stderr)`. +//@ +//@ Not seeing the behavior you want? `exec()` runs everything through `sh` +//@ by default (or `cmd.exe` on Windows), which differs from `bash`. If you +//@ need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option. //@ //@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as //@ the current synchronous implementation uses a lot of CPU. This should be getting //@ fixed soon. function _exec(command, options, callback) { - if (!command) - common.error('must specify command'); + options = options || {}; + if (!command) common.error('must specify command'); + + var pipe = common.readFromPipe(); // Callback is defined instead of options. if (typeof options === 'function') { @@ -238,10 +258,11 @@ function _exec(command, options, callback) { }, options); try { - if (options.async) - return execAsync(command, options, callback); - else - return execSync(command, options); + if (options.async) { + return execAsync(command, options, pipe, callback); + } else { + return execSync(command, options, pipe); + } } catch (e) { common.error('internal error'); } diff --git a/tools/eslint/node_modules/shelljs/src/find.js b/tools/eslint/node_modules/shelljs/src/find.js index c96fb2f7ad51e7..f96a51e7830a62 100644 --- a/tools/eslint/node_modules/shelljs/src/find.js +++ b/tools/eslint/node_modules/shelljs/src/find.js @@ -1,7 +1,10 @@ var fs = require('fs'); +var path = require('path'); var common = require('./common'); var _ls = require('./ls'); +common.register('find', _find, {}); + //@ //@ ### find(path [, path ...]) //@ ### find(path_array) @@ -18,30 +21,30 @@ var _ls = require('./ls'); //@ The main difference from `ls('-R', path)` is that the resulting file names //@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`. function _find(options, paths) { - if (!paths) + if (!paths) { common.error('no path specified'); - else if (typeof paths === 'object') - paths = paths; // assume array - else if (typeof paths === 'string') + } else if (typeof paths === 'string') { paths = [].slice.call(arguments, 1); + } var list = []; function pushFile(file) { - if (common.platform === 'win') + if (common.platform === 'win') { file = file.replace(/\\/g, '/'); + } list.push(file); } // why not simply do ls('-R', paths)? because the output wouldn't give the base dirs // to get the base dir in the output, we need instead ls('-R', 'dir/*') for every directory - paths.forEach(function(file) { + paths.forEach(function (file) { pushFile(file); if (fs.statSync(file).isDirectory()) { - _ls('-RA', file+'/*').forEach(function(subfile) { - pushFile(subfile); + _ls({ recursive: true, all: true }, file).forEach(function (subfile) { + pushFile(path.join(file, subfile)); }); } }); diff --git a/tools/eslint/node_modules/shelljs/src/grep.js b/tools/eslint/node_modules/shelljs/src/grep.js index 78008ce19e6d2f..30842bcb859441 100644 --- a/tools/eslint/node_modules/shelljs/src/grep.js +++ b/tools/eslint/node_modules/shelljs/src/grep.js @@ -1,12 +1,22 @@ var common = require('./common'); var fs = require('fs'); +common.register('grep', _grep, { + globStart: 2, // don't glob-expand the regex + canReceivePipe: true, + cmdOptions: { + 'v': 'inverse', + 'l': 'nameOnly', + }, +}); + //@ //@ ### grep([options,] regex_filter, file [, file ...]) //@ ### grep([options,] regex_filter, file_array) //@ Available options: //@ //@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria. +//@ + `-l`: Print only filenames of matching files //@ //@ Examples: //@ @@ -16,37 +26,42 @@ var fs = require('fs'); //@ ``` //@ //@ Reads input string from given files and returns a string containing all lines of the -//@ file that match the given `regex_filter`. Wildcard `*` accepted. +//@ file that match the given `regex_filter`. function _grep(options, regex, files) { - options = common.parseOptions(options, { - 'v': 'inverse' - }); + // Check if this is coming from a pipe + var pipe = common.readFromPipe(); - if (!files) - common.error('no paths given'); + if (!files && !pipe) common.error('no paths given', 2); - if (typeof files === 'string') - files = [].slice.call(arguments, 2); - // if it's array leave it as it is + files = [].slice.call(arguments, 2); - files = common.expand(files); + if (pipe) { + files.unshift('-'); + } - var grep = ''; - files.forEach(function(file) { - if (!fs.existsSync(file)) { - common.error('no such file or directory: ' + file, true); + var grep = []; + files.forEach(function (file) { + if (!fs.existsSync(file) && file !== '-') { + common.error('no such file or directory: ' + file, 2, { continue: true }); return; } - var contents = fs.readFileSync(file, 'utf8'), - lines = contents.split(/\r*\n/); - lines.forEach(function(line) { - var matched = line.match(regex); - if ((options.inverse && !matched) || (!options.inverse && matched)) - grep += line + '\n'; - }); + var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8'); + var lines = contents.split(/\r*\n/); + if (options.nameOnly) { + if (contents.match(regex)) { + grep.push(file); + } + } else { + lines.forEach(function (line) { + var matched = line.match(regex); + if ((options.inverse && !matched) || (!options.inverse && matched)) { + grep.push(line); + } + }); + } }); - return common.ShellString(grep); + return grep.join('\n') + '\n'; } module.exports = _grep; diff --git a/tools/eslint/node_modules/shelljs/src/head.js b/tools/eslint/node_modules/shelljs/src/head.js new file mode 100644 index 00000000000000..13d5829775e8b2 --- /dev/null +++ b/tools/eslint/node_modules/shelljs/src/head.js @@ -0,0 +1,104 @@ +var common = require('./common'); +var fs = require('fs'); + +common.register('head', _head, { + canReceivePipe: true, + cmdOptions: { + 'n': 'numLines', + }, +}); + +// This reads n or more lines, or the entire file, whichever is less. +function readSomeLines(file, numLines) { + var BUF_LENGTH = 64 * 1024; + var buf = new Buffer(BUF_LENGTH); + var bytesRead = BUF_LENGTH; + var pos = 0; + var fdr = null; + + try { + fdr = fs.openSync(file, 'r'); + } catch (e) { + common.error('cannot read file: ' + file); + } + + var numLinesRead = 0; + var ret = ''; + while (bytesRead === BUF_LENGTH && numLinesRead < numLines) { + bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos); + var bufStr = buf.toString('utf8', 0, bytesRead); + numLinesRead += bufStr.split('\n').length - 1; + ret += bufStr; + pos += bytesRead; + } + + fs.closeSync(fdr); + return ret; +} +//@ +//@ ### head([{'-n': \},] file [, file ...]) +//@ ### head([{'-n': \},] file_array) +//@ Available options: +//@ +//@ + `-n `: Show the first `` lines of the files +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var str = head({'-n': 1}, 'file*.txt'); +//@ var str = head('file1', 'file2'); +//@ var str = head(['file1', 'file2']); // same as above +//@ ``` +//@ +//@ Read the start of a file. +function _head(options, files) { + var head = []; + var pipe = common.readFromPipe(); + + if (!files && !pipe) common.error('no paths given'); + + var idx = 1; + if (options.numLines === true) { + idx = 2; + options.numLines = Number(arguments[1]); + } else if (options.numLines === false) { + options.numLines = 10; + } + files = [].slice.call(arguments, idx); + + if (pipe) { + files.unshift('-'); + } + + var shouldAppendNewline = false; + files.forEach(function (file) { + if (!fs.existsSync(file) && file !== '-') { + common.error('no such file or directory: ' + file, { continue: true }); + return; + } + + var contents; + if (file === '-') { + contents = pipe; + } else if (options.numLines < 0) { + contents = fs.readFileSync(file, 'utf8'); + } else { + contents = readSomeLines(file, options.numLines); + } + + var lines = contents.split('\n'); + var hasTrailingNewline = (lines[lines.length - 1] === ''); + if (hasTrailingNewline) { + lines.pop(); + } + shouldAppendNewline = (hasTrailingNewline || options.numLines < lines.length); + + head = head.concat(lines.slice(0, options.numLines)); + }); + + if (shouldAppendNewline) { + head.push(''); // to add a trailing newline once we join + } + return head.join('\n'); +} +module.exports = _head; diff --git a/tools/eslint/node_modules/shelljs/src/ln.js b/tools/eslint/node_modules/shelljs/src/ln.js index 878fda13e23d45..7393d9fcdca7d8 100644 --- a/tools/eslint/node_modules/shelljs/src/ln.js +++ b/tools/eslint/node_modules/shelljs/src/ln.js @@ -2,6 +2,13 @@ var fs = require('fs'); var path = require('path'); var common = require('./common'); +common.register('ln', _ln, { + cmdOptions: { + 's': 'symlink', + 'f': 'force', + }, +}); + //@ //@ ### ln([options,] source, dest) //@ Available options: @@ -18,11 +25,6 @@ var common = require('./common'); //@ //@ Links source to dest. Use -f to force the link, should dest already exist. function _ln(options, source, dest) { - options = common.parseOptions(options, { - 's': 'symlink', - 'f': 'force' - }); - if (!source || !dest) { common.error('Missing and/or '); } @@ -34,7 +36,7 @@ function _ln(options, source, dest) { if (fs.existsSync(dest)) { if (!options.force) { - common.error('Destination file exists', true); + common.error('Destination file exists', { continue: true }); } fs.unlinkSync(dest); @@ -45,19 +47,19 @@ function _ln(options, source, dest) { var linkType = isWindows ? 'file' : null; var resolvedSourcePath = isAbsolute ? sourcePath : path.resolve(process.cwd(), path.dirname(dest), source); if (!fs.existsSync(resolvedSourcePath)) { - common.error('Source file does not exist', true); + common.error('Source file does not exist', { continue: true }); } else if (isWindows && fs.statSync(resolvedSourcePath).isDirectory()) { - linkType = 'junction'; + linkType = 'junction'; } try { - fs.symlinkSync(linkType === 'junction' ? resolvedSourcePath: source, dest, linkType); + fs.symlinkSync(linkType === 'junction' ? resolvedSourcePath : source, dest, linkType); } catch (err) { common.error(err.message); } } else { if (!fs.existsSync(source)) { - common.error('Source file does not exist', true); + common.error('Source file does not exist', { continue: true }); } try { fs.linkSync(source, dest); @@ -65,5 +67,6 @@ function _ln(options, source, dest) { common.error(err.message); } } + return ''; } module.exports = _ln; diff --git a/tools/eslint/node_modules/shelljs/src/ls.js b/tools/eslint/node_modules/shelljs/src/ls.js index 6a54b3a8d8426a..7f25056cd34d7a 100644 --- a/tools/eslint/node_modules/shelljs/src/ls.js +++ b/tools/eslint/node_modules/shelljs/src/ls.js @@ -1,8 +1,19 @@ var path = require('path'); var fs = require('fs'); var common = require('./common'); -var _cd = require('./cd'); -var _pwd = require('./pwd'); +var glob = require('glob'); + +var globPatternRecursive = path.sep + '**' + path.sep + '*'; + +common.register('ls', _ls, { + cmdOptions: { + 'R': 'recursive', + 'A': 'all', + 'a': 'all_deprecated', + 'd': 'directory', + 'l': 'long', + }, +}); //@ //@ ### ls([options,] [path, ...]) @@ -28,14 +39,6 @@ var _pwd = require('./pwd'); //@ //@ Returns array of files in the given path, or in current directory if no path provided. function _ls(options, paths) { - options = common.parseOptions(options, { - 'R': 'recursive', - 'A': 'all', - 'a': 'all_deprecated', - 'd': 'directory', - 'l': 'long' - }); - if (options.all_deprecated) { // We won't support the -a option as it's hard to image why it's useful // (it includes '.' and '..' in addition to '.*' files) @@ -44,125 +47,75 @@ function _ls(options, paths) { options.all = true; } - if (!paths) + if (!paths) { paths = ['.']; - else if (typeof paths === 'object') - paths = paths; // assume array - else if (typeof paths === 'string') + } else { paths = [].slice.call(arguments, 1); + } var list = []; - // Conditionally pushes file to list - returns true if pushed, false otherwise - // (e.g. prevents hidden files to be included unless explicitly told so) - function pushFile(file, query) { - var name = file.name || file; - // hidden file? - if (path.basename(name)[0] === '.') { - // not explicitly asking for hidden files? - if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1)) - return false; + function pushFile(abs, relName, stat) { + if (process.platform === 'win32') { + relName = relName.replace(/\\/g, '/'); } - - if (common.platform === 'win') - name = name.replace(/\\/g, '/'); - - if (file.name) { - file.name = name; + if (options.long) { + stat = stat || fs.lstatSync(abs); + list.push(addLsAttributes(relName, stat)); } else { - file = name; + // list.push(path.relative(rel || '.', file)); + list.push(relName); } - list.push(file); - return true; } - paths.forEach(function(p) { - if (fs.existsSync(p)) { - var stats = ls_stat(p); - // Simple file? - if (stats.isFile()) { - if (options.long) { - pushFile(stats, p); - } else { - pushFile(p, p); - } - return; // continue - } + paths.forEach(function (p) { + var stat; - // Simple dir? - if (options.directory) { - pushFile(p, p); - return; - } else if (stats.isDirectory()) { - // Iterate over p contents - fs.readdirSync(p).forEach(function(file) { - var orig_file = file; - if (options.long) - file = ls_stat(path.join(p, file)); - if (!pushFile(file, p)) - return; + try { + stat = fs.lstatSync(p); + } catch (e) { + common.error('no such file or directory: ' + p, 2, { continue: true }); + return; + } - // Recursive? - if (options.recursive) { - var oldDir = _pwd(); - _cd('', p); - if (fs.statSync(orig_file).isDirectory()) - list = list.concat(_ls('-R'+(options.all?'A':''), orig_file+'/*')); - _cd('', oldDir); + // If the stat succeeded + if (stat.isDirectory() && !options.directory) { + if (options.recursive) { + // use glob, because it's simple + glob.sync(p + globPatternRecursive, { dot: options.all }) + .forEach(function (item) { + pushFile(item, path.relative(p, item)); + }); + } else if (options.all) { + // use fs.readdirSync, because it's fast + fs.readdirSync(p).forEach(function (item) { + pushFile(path.join(p, item), item); + }); + } else { + // use fs.readdirSync and then filter out secret files + fs.readdirSync(p).forEach(function (item) { + if (item[0] !== '.') { + pushFile(path.join(p, item), item); } }); - return; // continue } + } else { + pushFile(p, p, stat); } - - // p does not exist - possible wildcard present - - var basename = path.basename(p); - var dirname = path.dirname(p); - // Wildcard present on an existing dir? (e.g. '/tmp/*.js') - if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) { - // Escape special regular expression chars - var regexp = basename.replace(/(\^|\$|\(|\)|<|>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1'); - // Translates wildcard into regex - regexp = '^' + regexp.replace(/\*/g, '.*') + '$'; - // Iterate over directory contents - fs.readdirSync(dirname).forEach(function(file) { - if (file.match(new RegExp(regexp))) { - var file_path = path.join(dirname, file); - file_path = options.long ? ls_stat(file_path) : file_path; - if (file_path.name) - file_path.name = path.normalize(file_path.name); - else - file_path = path.normalize(file_path); - if (!pushFile(file_path, basename)) - return; - - // Recursive? - if (options.recursive) { - var pp = dirname + '/' + file; - if (fs.lstatSync(pp).isDirectory()) - list = list.concat(_ls('-R'+(options.all?'A':''), pp+'/*')); - } // recursive - } // if file matches - }); // forEach - return; - } - - common.error('no such file or directory: ' + p, true); }); + // Add methods, to make this more compatible with ShellStrings return list; } -module.exports = _ls; - -function ls_stat(path) { - var stats = fs.statSync(path); +function addLsAttributes(pathName, stats) { // Note: this object will contain more information than .toString() returns - stats.name = path; - stats.toString = function() { + stats.name = pathName; + stats.toString = function () { // Return a string resembling unix's `ls -l` format return [this.mode, this.nlink, this.uid, this.gid, this.size, this.mtime, this.name].join(' '); }; return stats; } + +module.exports = _ls; diff --git a/tools/eslint/node_modules/shelljs/src/mkdir.js b/tools/eslint/node_modules/shelljs/src/mkdir.js index 8b4fd99075053a..f211bc89b3fbaf 100644 --- a/tools/eslint/node_modules/shelljs/src/mkdir.js +++ b/tools/eslint/node_modules/shelljs/src/mkdir.js @@ -2,10 +2,23 @@ var common = require('./common'); var fs = require('fs'); var path = require('path'); +common.register('mkdir', _mkdir, { + cmdOptions: { + 'p': 'fullpath', + }, +}); + // Recursively creates 'dir' function mkdirSyncRecursive(dir) { var baseDir = path.dirname(dir); + // Prevents some potential problems arising from malformed UNCs or + // insufficient permissions. + /* istanbul ignore next */ + if (baseDir === dir) { + common.error('dirname() failed: [' + dir + ']'); + } + // Base dir exists, no recursion necessary if (fs.existsSync(baseDir)) { fs.mkdirSync(dir, parseInt('0777', 8)); @@ -35,34 +48,45 @@ function mkdirSyncRecursive(dir) { //@ //@ Creates directories. function _mkdir(options, dirs) { - options = common.parseOptions(options, { - 'p': 'fullpath' - }); - if (!dirs) - common.error('no paths given'); + if (!dirs) common.error('no paths given'); - if (typeof dirs === 'string') + if (typeof dirs === 'string') { dirs = [].slice.call(arguments, 1); + } // if it's array leave it as it is - dirs.forEach(function(dir) { - if (fs.existsSync(dir)) { - if (!options.fullpath) - common.error('path already exists: ' + dir, true); + dirs.forEach(function (dir) { + try { + fs.lstatSync(dir); + if (!options.fullpath) { + common.error('path already exists: ' + dir, { continue: true }); + } return; // skip dir + } catch (e) { + // do nothing } // Base dir does not exist, and no -p option given var baseDir = path.dirname(dir); if (!fs.existsSync(baseDir) && !options.fullpath) { - common.error('no such file or directory: ' + baseDir, true); + common.error('no such file or directory: ' + baseDir, { continue: true }); return; // skip dir } - if (options.fullpath) - mkdirSyncRecursive(dir); - else - fs.mkdirSync(dir, parseInt('0777', 8)); + try { + if (options.fullpath) { + mkdirSyncRecursive(dir); + } else { + fs.mkdirSync(dir, parseInt('0777', 8)); + } + } catch (e) { + if (e.code === 'EACCES') { + common.error('cannot create directory ' + dir + ': Permission denied'); + } else { + throw e; + } + } }); + return ''; } // mkdir module.exports = _mkdir; diff --git a/tools/eslint/node_modules/shelljs/src/mv.js b/tools/eslint/node_modules/shelljs/src/mv.js index 69cc03fe1ebe2b..c09bbbc76903c6 100644 --- a/tools/eslint/node_modules/shelljs/src/mv.js +++ b/tools/eslint/node_modules/shelljs/src/mv.js @@ -1,6 +1,15 @@ var fs = require('fs'); var path = require('path'); var common = require('./common'); +var cp = require('./cp'); +var rm = require('./rm'); + +common.register('mv', _mv, { + cmdOptions: { + 'f': '!no_force', + 'n': 'no_force', + }, +}); //@ //@ ### mv([options ,] source [, source ...], dest') @@ -18,13 +27,8 @@ var common = require('./common'); //@ mv(['file1', 'file2'], 'dir/'); // same as above //@ ``` //@ -//@ Moves files. The wildcard `*` is accepted. +//@ Moves files. function _mv(options, sources, dest) { - options = common.parseOptions(options, { - 'f': '!no_force', - 'n': 'no_force' - }); - // Get sources, dest if (arguments.length < 3) { common.error('missing and/or '); @@ -33,28 +37,26 @@ function _mv(options, sources, dest) { dest = arguments[arguments.length - 1]; } else if (typeof sources === 'string') { sources = [sources]; - } else if ('length' in sources) { - sources = sources; // no-op for array } else { common.error('invalid arguments'); } - sources = common.expand(sources); - - var exists = fs.existsSync(dest), - stats = exists && fs.statSync(dest); + var exists = fs.existsSync(dest); + var stats = exists && fs.statSync(dest); // Dest is not existing dir, but multiple sources given - if ((!exists || !stats.isDirectory()) && sources.length > 1) + if ((!exists || !stats.isDirectory()) && sources.length > 1) { common.error('dest is not a directory (too many sources)'); + } // Dest is an existing file, but no -f given - if (exists && stats.isFile() && options.no_force) + if (exists && stats.isFile() && options.no_force) { common.error('dest file already exists: ' + dest); + } - sources.forEach(function(src) { + sources.forEach(function (src) { if (!fs.existsSync(src)) { - common.error('no such file or directory: '+src, true); + common.error('no such file or directory: ' + src, { continue: true }); return; // skip file } @@ -63,20 +65,31 @@ function _mv(options, sources, dest) { // When copying to '/path/dir': // thisDest = '/path/dir/file1' var thisDest = dest; - if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) + if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) { thisDest = path.normalize(dest + '/' + path.basename(src)); + } if (fs.existsSync(thisDest) && options.no_force) { - common.error('dest file already exists: ' + thisDest, true); + common.error('dest file already exists: ' + thisDest, { continue: true }); return; // skip file } if (path.resolve(src) === path.dirname(path.resolve(thisDest))) { - common.error('cannot move to self: '+src, true); + common.error('cannot move to self: ' + src, { continue: true }); return; // skip file } - fs.renameSync(src, thisDest); + try { + fs.renameSync(src, thisDest); + } catch (e) { + if (e.code === 'EXDEV') { // external partition + // if either of these fails, the appropriate error message will bubble + // up to the top level automatically + cp('-r', src, thisDest); + rm('-rf', src); + } + } }); // forEach(src) + return ''; } // mv module.exports = _mv; diff --git a/tools/eslint/node_modules/shelljs/src/popd.js b/tools/eslint/node_modules/shelljs/src/popd.js index 11ea24fa464a04..d9eac3f56d1303 100644 --- a/tools/eslint/node_modules/shelljs/src/popd.js +++ b/tools/eslint/node_modules/shelljs/src/popd.js @@ -1 +1 @@ -// see dirs.js \ No newline at end of file +// see dirs.js diff --git a/tools/eslint/node_modules/shelljs/src/pushd.js b/tools/eslint/node_modules/shelljs/src/pushd.js index 11ea24fa464a04..d9eac3f56d1303 100644 --- a/tools/eslint/node_modules/shelljs/src/pushd.js +++ b/tools/eslint/node_modules/shelljs/src/pushd.js @@ -1 +1 @@ -// see dirs.js \ No newline at end of file +// see dirs.js diff --git a/tools/eslint/node_modules/shelljs/src/pwd.js b/tools/eslint/node_modules/shelljs/src/pwd.js index 26cefe0a0454d0..38618518b549f6 100644 --- a/tools/eslint/node_modules/shelljs/src/pwd.js +++ b/tools/eslint/node_modules/shelljs/src/pwd.js @@ -1,11 +1,15 @@ var path = require('path'); var common = require('./common'); +common.register('pwd', _pwd, { + allowGlobbing: false, +}); + //@ //@ ### pwd() //@ Returns the current directory. function _pwd() { var pwd = path.resolve(process.cwd()); - return common.ShellString(pwd); + return pwd; } module.exports = _pwd; diff --git a/tools/eslint/node_modules/shelljs/src/rm.js b/tools/eslint/node_modules/shelljs/src/rm.js index cf2e95b6d816bc..d6e484a085cfee 100644 --- a/tools/eslint/node_modules/shelljs/src/rm.js +++ b/tools/eslint/node_modules/shelljs/src/rm.js @@ -1,6 +1,14 @@ var common = require('./common'); var fs = require('fs'); +common.register('rm', _rm, { + cmdOptions: { + 'f': 'force', + 'r': 'recursive', + 'R': 'recursive', + }, +}); + // Recursively removes 'dir' // Adapted from https://github.com/ryanmcgrath/wrench-js // @@ -15,32 +23,21 @@ function rmdirSyncRecursive(dir, force) { files = fs.readdirSync(dir); // Loop through and delete everything in the sub-tree after checking it - for(var i = 0; i < files.length; i++) { - var file = dir + "/" + files[i], - currFile = fs.lstatSync(file); + for (var i = 0; i < files.length; i++) { + var file = dir + '/' + files[i]; + var currFile = fs.lstatSync(file); - if(currFile.isDirectory()) { // Recursive function back to the beginning + if (currFile.isDirectory()) { // Recursive function back to the beginning rmdirSyncRecursive(file, force); - } - - else if(currFile.isSymbolicLink()) { // Unlink symlinks + } else { // Assume it's a file - perhaps a try/catch belongs here? if (force || isWriteable(file)) { try { common.unlinkSync(file); } catch (e) { - common.error('could not remove file (code '+e.code+'): ' + file, true); + common.error('could not remove file (code ' + e.code + '): ' + file, { continue: true }); } } } - - else // Assume it's a file - perhaps a try/catch belongs here? - if (force || isWriteable(file)) { - try { - common.unlinkSync(file); - } catch (e) { - common.error('could not remove file (code '+e.code+'): ' + file, true); - } - } } // Now that we know everything in the sub-tree has been deleted, we can delete the main directory. @@ -53,13 +50,13 @@ function rmdirSyncRecursive(dir, force) { while (true) { try { result = fs.rmdirSync(dir); - if (fs.existsSync(dir)) throw { code: "EAGAIN" }; + if (fs.existsSync(dir)) throw { code: 'EAGAIN' }; break; - } catch(er) { + } catch (er) { // In addition to error codes, also check if the directory still exists and loop again if true - if (process.platform === "win32" && (er.code === "ENOTEMPTY" || er.code === "EBUSY" || er.code === "EPERM" || er.code === "EAGAIN")) { + if (process.platform === 'win32' && (er.code === 'ENOTEMPTY' || er.code === 'EBUSY' || er.code === 'EPERM' || er.code === 'EAGAIN')) { if (Date.now() - start > 1000) throw er; - } else if (er.code === "ENOENT") { + } else if (er.code === 'ENOENT') { // Directory did not exist, deletion was successful break; } else { @@ -67,8 +64,8 @@ function rmdirSyncRecursive(dir, force) { } } } - } catch(e) { - common.error('could not remove directory (code '+e.code+'): ' + dir, true); + } catch (e) { + common.error('could not remove directory (code ' + e.code + '): ' + dir, { continue: true }); } return result; @@ -81,7 +78,7 @@ function isWriteable(file) { try { var __fd = fs.openSync(file, 'a'); fs.closeSync(__fd); - } catch(e) { + } catch (e) { writePermission = false; } @@ -104,53 +101,45 @@ function isWriteable(file) { //@ rm(['some_file.txt', 'another_file.txt']); // same as above //@ ``` //@ -//@ Removes files. The wildcard `*` is accepted. +//@ Removes files. function _rm(options, files) { - options = common.parseOptions(options, { - 'f': 'force', - 'r': 'recursive', - 'R': 'recursive' - }); - if (!files) - common.error('no paths given'); - - if (typeof files === 'string') - files = [].slice.call(arguments, 1); - // if it's array leave it as it is + if (!files) common.error('no paths given'); - files = common.expand(files); + // Convert to array + files = [].slice.call(arguments, 1); - files.forEach(function(file) { - if (!fs.existsSync(file)) { + files.forEach(function (file) { + var stats; + try { + stats = fs.lstatSync(file); // test for existence + } catch (e) { // Path does not exist, no force flag given - if (!options.force) - common.error('no such file or directory: '+file, true); - + if (!options.force) { + common.error('no such file or directory: ' + file, { continue: true }); + } return; // skip file } // If here, path exists - - var stats = fs.lstatSync(file); if (stats.isFile() || stats.isSymbolicLink()) { - // Do not check for file writing permissions if (options.force) { common.unlinkSync(file); return; } - if (isWriteable(file)) + if (isWriteable(file)) { common.unlinkSync(file); - else - common.error('permission denied: '+file, true); + } else { + common.error('permission denied: ' + file, { continue: true }); + } return; } // simple file // Path is an existing directory, but no -r flag given if (stats.isDirectory() && !options.recursive) { - common.error('path is a directory', true); + common.error('path is a directory', { continue: true }); return; // skip path } @@ -159,5 +148,6 @@ function _rm(options, files) { rmdirSyncRecursive(file, options.force); } }); // forEach(file) + return ''; } // rm module.exports = _rm; diff --git a/tools/eslint/node_modules/shelljs/src/sed.js b/tools/eslint/node_modules/shelljs/src/sed.js index baa385ba1167d4..590ba74ffca2f7 100644 --- a/tools/eslint/node_modules/shelljs/src/sed.js +++ b/tools/eslint/node_modules/shelljs/src/sed.js @@ -1,6 +1,14 @@ var common = require('./common'); var fs = require('fs'); +common.register('sed', _sed, { + globStart: 3, // don't glob-expand regexes + canReceivePipe: true, + cmdOptions: { + 'i': 'inplace', + }, +}); + //@ //@ ### sed([options,] search_regex, replacement, file [, file ...]) //@ ### sed([options,] search_regex, replacement, file_array) @@ -18,47 +26,52 @@ var fs = require('fs'); //@ Reads an input string from `files` and performs a JavaScript `replace()` on the input //@ using the given search regex and replacement string or function. Returns the new string after replacement. function _sed(options, regex, replacement, files) { - options = common.parseOptions(options, { - 'i': 'inplace' - }); + // Check if this is coming from a pipe + var pipe = common.readFromPipe(); - if (typeof replacement === 'string' || typeof replacement === 'function') - replacement = replacement; // no-op - else if (typeof replacement === 'number') - replacement = replacement.toString(); // fallback - else - common.error('invalid replacement string'); + if (typeof replacement !== 'string' && typeof replacement !== 'function') { + if (typeof replacement === 'number') { + replacement = replacement.toString(); // fallback + } else { + common.error('invalid replacement string'); + } + } // Convert all search strings to RegExp - if (typeof regex === 'string') + if (typeof regex === 'string') { regex = RegExp(regex); + } - if (!files) + if (!files && !pipe) { common.error('no files given'); + } - if (typeof files === 'string') - files = [].slice.call(arguments, 3); - // if it's array leave it as it is + files = [].slice.call(arguments, 3); - files = common.expand(files); + if (pipe) { + files.unshift('-'); + } var sed = []; - files.forEach(function(file) { - if (!fs.existsSync(file)) { - common.error('no such file or directory: ' + file, true); + files.forEach(function (file) { + if (!fs.existsSync(file) && file !== '-') { + common.error('no such file or directory: ' + file, 2, { continue: true }); return; } - var result = fs.readFileSync(file, 'utf8').split('\n').map(function (line) { + var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8'); + var lines = contents.split(/\r*\n/); + var result = lines.map(function (line) { return line.replace(regex, replacement); }).join('\n'); sed.push(result); - if (options.inplace) + if (options.inplace) { fs.writeFileSync(file, result, 'utf8'); + } }); - return common.ShellString(sed.join('\n')); + return sed.join('\n'); } module.exports = _sed; diff --git a/tools/eslint/node_modules/shelljs/src/set.js b/tools/eslint/node_modules/shelljs/src/set.js index 19e26d979d3f4b..3402cd6609b06f 100644 --- a/tools/eslint/node_modules/shelljs/src/set.js +++ b/tools/eslint/node_modules/shelljs/src/set.js @@ -1,11 +1,17 @@ var common = require('./common'); +common.register('set', _set, { + allowGlobbing: false, + wrapOutput: false, +}); + //@ //@ ### set(options) //@ Available options: //@ //@ + `+/-e`: exit upon error (`config.fatal`) //@ + `+/-v`: verbose: show all commands (`config.verbose`) +//@ + `+/-f`: disable filename expansion (globbing) //@ //@ Examples: //@ @@ -18,8 +24,7 @@ var common = require('./common'); function _set(options) { if (!options) { var args = [].slice.call(arguments, 0); - if (args.length < 2) - common.error('must provide an argument'); + if (args.length < 2) common.error('must provide an argument'); options = args[1]; } var negate = (options[0] === '+'); @@ -28,22 +33,23 @@ function _set(options) { } options = common.parseOptions(options, { 'e': 'fatal', - 'v': 'verbose' + 'v': 'verbose', + 'f': 'noglob' }); - var key; if (negate) { - for (key in options) + Object.keys(options).forEach(function (key) { options[key] = !options[key]; + }); } - for (key in options) { + Object.keys(options).forEach(function (key) { // Only change the global config if `negate` is false and the option is true // or if `negate` is true and the option is false (aka negate !== option) if (negate !== options[key]) { common.config[key] = options[key]; } - } + }); return; } module.exports = _set; diff --git a/tools/eslint/node_modules/shelljs/src/sort.js b/tools/eslint/node_modules/shelljs/src/sort.js new file mode 100644 index 00000000000000..041b037725121c --- /dev/null +++ b/tools/eslint/node_modules/shelljs/src/sort.js @@ -0,0 +1,91 @@ +var common = require('./common'); +var fs = require('fs'); + +common.register('sort', _sort, { + canReceivePipe: true, + cmdOptions: { + 'r': 'reverse', + 'n': 'numerical', + }, +}); + +// parse out the number prefix of a line +function parseNumber(str) { + var match = str.match(/^\s*(\d*)\s*(.*)$/); + return { num: Number(match[1]), value: match[2] }; +} + +// compare two strings case-insensitively, but examine case for strings that are +// case-insensitive equivalent +function unixCmp(a, b) { + var aLower = a.toLowerCase(); + var bLower = b.toLowerCase(); + return (aLower === bLower ? + -1 * a.localeCompare(b) : // unix sort treats case opposite how javascript does + aLower.localeCompare(bLower)); +} + +// compare two strings in the fashion that unix sort's -n option works +function numericalCmp(a, b) { + var objA = parseNumber(a); + var objB = parseNumber(b); + if (objA.hasOwnProperty('num') && objB.hasOwnProperty('num')) { + return ((objA.num !== objB.num) ? + (objA.num - objB.num) : + unixCmp(objA.value, objB.value)); + } else { + return unixCmp(objA.value, objB.value); + } +} + +//@ +//@ ### sort([options,] file [, file ...]) +//@ ### sort([options,] file_array) +//@ Available options: +//@ +//@ + `-r`: Reverse the result of comparisons +//@ + `-n`: Compare according to numerical value +//@ +//@ Examples: +//@ +//@ ```javascript +//@ sort('foo.txt', 'bar.txt'); +//@ sort('-r', 'foo.txt'); +//@ ``` +//@ +//@ Return the contents of the files, sorted line-by-line. Sorting multiple +//@ files mixes their content, just like unix sort does. +function _sort(options, files) { + // Check if this is coming from a pipe + var pipe = common.readFromPipe(); + + if (!files && !pipe) common.error('no files given'); + + files = [].slice.call(arguments, 1); + + if (pipe) { + files.unshift('-'); + } + + var lines = []; + files.forEach(function (file) { + if (!fs.existsSync(file) && file !== '-') { + // exit upon any sort of error + common.error('no such file or directory: ' + file); + } + + var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8'); + lines = lines.concat(contents.trimRight().split(/\r*\n/)); + }); + + var sorted; + sorted = lines.sort(options.numerical ? numericalCmp : unixCmp); + + if (options.reverse) { + sorted = sorted.reverse(); + } + + return sorted.join('\n') + '\n'; +} + +module.exports = _sort; diff --git a/tools/eslint/node_modules/shelljs/src/tail.js b/tools/eslint/node_modules/shelljs/src/tail.js new file mode 100644 index 00000000000000..7ece654b1ea3a0 --- /dev/null +++ b/tools/eslint/node_modules/shelljs/src/tail.js @@ -0,0 +1,72 @@ +var common = require('./common'); +var fs = require('fs'); + +common.register('tail', _tail, { + canReceivePipe: true, + cmdOptions: { + 'n': 'numLines', + }, +}); + +//@ +//@ ### tail([{'-n': \},] file [, file ...]) +//@ ### tail([{'-n': \},] file_array) +//@ Available options: +//@ +//@ + `-n `: Show the last `` lines of the files +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var str = tail({'-n': 1}, 'file*.txt'); +//@ var str = tail('file1', 'file2'); +//@ var str = tail(['file1', 'file2']); // same as above +//@ ``` +//@ +//@ Read the end of a file. +function _tail(options, files) { + var tail = []; + var pipe = common.readFromPipe(); + + if (!files && !pipe) common.error('no paths given'); + + var idx = 1; + if (options.numLines === true) { + idx = 2; + options.numLines = Number(arguments[1]); + } else if (options.numLines === false) { + options.numLines = 10; + } + options.numLines = -1 * Math.abs(options.numLines); + files = [].slice.call(arguments, idx); + + if (pipe) { + files.unshift('-'); + } + + var shouldAppendNewline = false; + files.forEach(function (file) { + if (!fs.existsSync(file) && file !== '-') { + common.error('no such file or directory: ' + file, { continue: true }); + return; + } + + var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8'); + + var lines = contents.split('\n'); + if (lines[lines.length - 1] === '') { + lines.pop(); + shouldAppendNewline = true; + } else { + shouldAppendNewline = false; + } + + tail = tail.concat(lines.slice(options.numLines)); + }); + + if (shouldAppendNewline) { + tail.push(''); // to add a trailing newline once we join + } + return tail.join('\n'); +} +module.exports = _tail; diff --git a/tools/eslint/node_modules/shelljs/src/tempdir.js b/tools/eslint/node_modules/shelljs/src/tempdir.js index 79b949f0d4f15b..cfd56b3792e427 100644 --- a/tools/eslint/node_modules/shelljs/src/tempdir.js +++ b/tools/eslint/node_modules/shelljs/src/tempdir.js @@ -2,15 +2,18 @@ var common = require('./common'); var os = require('os'); var fs = require('fs'); +common.register('tempdir', _tempDir, { + allowGlobbing: false, + wrapOutput: false, +}); + // Returns false if 'dir' is not a writeable directory, 'dir' otherwise function writeableDir(dir) { - if (!dir || !fs.existsSync(dir)) - return false; + if (!dir || !fs.existsSync(dir)) return false; - if (!fs.statSync(dir).isDirectory()) - return false; + if (!fs.statSync(dir).isDirectory()) return false; - var testFile = dir+'/'+common.randomFileName(); + var testFile = dir + '/' + common.randomFileName(); try { fs.writeFileSync(testFile, ' '); common.unlinkSync(testFile); @@ -34,15 +37,14 @@ function writeableDir(dir) { //@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). function _tempDir() { var state = common.state; - if (state.tempDir) - return state.tempDir; // from cache + if (state.tempDir) return state.tempDir; // from cache state.tempDir = writeableDir(os.tmpdir && os.tmpdir()) || // node 0.10+ writeableDir(os.tmpDir && os.tmpDir()) || // node 0.8+ - writeableDir(process.env['TMPDIR']) || - writeableDir(process.env['TEMP']) || - writeableDir(process.env['TMP']) || - writeableDir(process.env['Wimp$ScrapDir']) || // RiscOS + writeableDir(process.env.TMPDIR) || + writeableDir(process.env.TEMP) || + writeableDir(process.env.TMP) || + writeableDir(process.env.Wimp$ScrapDir) || // RiscOS writeableDir('C:\\TEMP') || // Windows writeableDir('C:\\TMP') || // Windows writeableDir('\\TEMP') || // Windows diff --git a/tools/eslint/node_modules/shelljs/src/test.js b/tools/eslint/node_modules/shelljs/src/test.js index 068a1ce06ef4c9..3fb38aec43992d 100644 --- a/tools/eslint/node_modules/shelljs/src/test.js +++ b/tools/eslint/node_modules/shelljs/src/test.js @@ -1,6 +1,22 @@ var common = require('./common'); var fs = require('fs'); +common.register('test', _test, { + cmdOptions: { + 'b': 'block', + 'c': 'character', + 'd': 'directory', + 'e': 'exists', + 'f': 'file', + 'L': 'link', + 'p': 'pipe', + 'S': 'socket', + }, + wrapOutput: false, + allowGlobbing: false, +}); + + //@ //@ ### test(expression) //@ Available expression primaries: @@ -23,63 +39,43 @@ var fs = require('fs'); //@ //@ Evaluates expression using the available primaries and returns corresponding value. function _test(options, path) { - if (!path) - common.error('no path given'); - - // hack - only works with unary primaries - options = common.parseOptions(options, { - 'b': 'block', - 'c': 'character', - 'd': 'directory', - 'e': 'exists', - 'f': 'file', - 'L': 'link', - 'p': 'pipe', - 'S': 'socket' - }); + if (!path) common.error('no path given'); var canInterpret = false; - for (var key in options) + Object.keys(options).forEach(function (key) { if (options[key] === true) { canInterpret = true; - break; } + }); - if (!canInterpret) - common.error('could not interpret expression'); + if (!canInterpret) common.error('could not interpret expression'); if (options.link) { try { return fs.lstatSync(path).isSymbolicLink(); - } catch(e) { + } catch (e) { return false; } } - if (!fs.existsSync(path)) - return false; + if (!fs.existsSync(path)) return false; - if (options.exists) - return true; + if (options.exists) return true; var stats = fs.statSync(path); - if (options.block) - return stats.isBlockDevice(); + if (options.block) return stats.isBlockDevice(); + + if (options.character) return stats.isCharacterDevice(); - if (options.character) - return stats.isCharacterDevice(); + if (options.directory) return stats.isDirectory(); - if (options.directory) - return stats.isDirectory(); + if (options.file) return stats.isFile(); - if (options.file) - return stats.isFile(); + if (options.pipe) return stats.isFIFO(); - if (options.pipe) - return stats.isFIFO(); + if (options.socket) return stats.isSocket(); - if (options.socket) - return stats.isSocket(); + return false; // fallback } // test module.exports = _test; diff --git a/tools/eslint/node_modules/shelljs/src/to.js b/tools/eslint/node_modules/shelljs/src/to.js index 65d6d54af90837..99f194e687b460 100644 --- a/tools/eslint/node_modules/shelljs/src/to.js +++ b/tools/eslint/node_modules/shelljs/src/to.js @@ -2,8 +2,13 @@ var common = require('./common'); var fs = require('fs'); var path = require('path'); +common.register('to', _to, { + pipeOnly: true, + wrapOutput: false, +}); + //@ -//@ ### 'string'.to(file) +//@ ### ShellString.prototype.to(file) //@ //@ Examples: //@ @@ -11,20 +16,21 @@ var path = require('path'); //@ cat('input.txt').to('output.txt'); //@ ``` //@ -//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as -//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ +//@ Analogous to the redirection operator `>` in Unix, but works with +//@ ShellStrings (such as those returned by `cat`, `grep`, etc). _Like Unix +//@ redirections, `to()` will overwrite any existing file!_ function _to(options, file) { - if (!file) - common.error('wrong arguments'); + if (!file) common.error('wrong arguments'); - if (!fs.existsSync( path.dirname(file) )) - common.error('no such file or directory: ' + path.dirname(file)); + if (!fs.existsSync(path.dirname(file))) { + common.error('no such file or directory: ' + path.dirname(file)); + } try { - fs.writeFileSync(file, this.toString(), 'utf8'); + fs.writeFileSync(file, this.stdout || this.toString(), 'utf8'); return this; - } catch(e) { - common.error('could not write to file (code '+e.code+'): '+file, true); + } catch (e) { + common.error('could not write to file (code ' + e.code + '): ' + file, { continue: true }); } } module.exports = _to; diff --git a/tools/eslint/node_modules/shelljs/src/toEnd.js b/tools/eslint/node_modules/shelljs/src/toEnd.js index bf29a6526d0f97..cf91c9401c4ced 100644 --- a/tools/eslint/node_modules/shelljs/src/toEnd.js +++ b/tools/eslint/node_modules/shelljs/src/toEnd.js @@ -2,8 +2,13 @@ var common = require('./common'); var fs = require('fs'); var path = require('path'); +common.register('toEnd', _toEnd, { + pipeOnly: true, + wrapOutput: false, +}); + //@ -//@ ### 'string'.toEnd(file) +//@ ### ShellString.prototype.toEnd(file) //@ //@ Examples: //@ @@ -11,20 +16,20 @@ var path = require('path'); //@ cat('input.txt').toEnd('output.txt'); //@ ``` //@ -//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as -//@ those returned by `cat`, `grep`, etc). +//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with +//@ ShellStrings (such as those returned by `cat`, `grep`, etc). function _toEnd(options, file) { - if (!file) - common.error('wrong arguments'); + if (!file) common.error('wrong arguments'); - if (!fs.existsSync( path.dirname(file) )) - common.error('no such file or directory: ' + path.dirname(file)); + if (!fs.existsSync(path.dirname(file))) { + common.error('no such file or directory: ' + path.dirname(file)); + } try { - fs.appendFileSync(file, this.toString(), 'utf8'); + fs.appendFileSync(file, this.stdout || this.toString(), 'utf8'); return this; - } catch(e) { - common.error('could not append to file (code '+e.code+'): '+file, true); + } catch (e) { + common.error('could not append to file (code ' + e.code + '): ' + file, { continue: true }); } } module.exports = _toEnd; diff --git a/tools/eslint/node_modules/shelljs/src/touch.js b/tools/eslint/node_modules/shelljs/src/touch.js index bbc2c1968654ab..b672b2d25528b4 100644 --- a/tools/eslint/node_modules/shelljs/src/touch.js +++ b/tools/eslint/node_modules/shelljs/src/touch.js @@ -1,8 +1,19 @@ var common = require('./common'); var fs = require('fs'); +common.register('touch', _touch, { + cmdOptions: { + 'a': 'atime_only', + 'c': 'no_create', + 'd': 'date', + 'm': 'mtime_only', + 'r': 'reference', + }, +}); + //@ -//@ ### touch([options,] file) +//@ ### touch([options,] file [, file ...]) +//@ ### touch([options,] file_array) //@ Available options: //@ //@ + `-a`: Change only the access time @@ -23,28 +34,18 @@ var fs = require('fs'); //@ A FILE argument that does not exist is created empty, unless -c is supplied. //@ This is a partial implementation of *[touch(1)](http://linux.die.net/man/1/touch)*. function _touch(opts, files) { - opts = common.parseOptions(opts, { - 'a': 'atime_only', - 'c': 'no_create', - 'd': 'date', - 'm': 'mtime_only', - 'r': 'reference', - }); - if (!files) { - common.error('no paths given'); - } - - if (Array.isArray(files)) { - files.forEach(function(f) { - touchFile(opts, f); - }); + common.error('no files given'); } else if (typeof files === 'string') { - touchFile(opts, files); + files = [].slice.call(arguments, 1); } else { common.error('file arg should be a string file path or an Array of string file paths'); } + files.forEach(function (f) { + touchFile(opts, f); + }); + return ''; } function touchFile(opts, file) { diff --git a/tools/eslint/node_modules/shelljs/src/uniq.js b/tools/eslint/node_modules/shelljs/src/uniq.js new file mode 100644 index 00000000000000..8f5da00285a3a5 --- /dev/null +++ b/tools/eslint/node_modules/shelljs/src/uniq.js @@ -0,0 +1,80 @@ +var common = require('./common'); +var fs = require('fs'); + +// add c spaces to the left of str +function lpad(c, str) { + var res = '' + str; + if (res.length < c) { + res = Array((c - res.length) + 1).join(' ') + res; + } + return res; +} + +common.register('uniq', _uniq, { + canReceivePipe: true, + cmdOptions: { + 'i': 'ignoreCase', + 'c': 'count', + 'd': 'duplicates', + }, +}); + +//@ +//@ ### uniq([options,] [input, [output]]) +//@ Available options: +//@ +//@ + `-i`: Ignore case while comparing +//@ + `-c`: Prefix lines by the number of occurrences +//@ + `-d`: Only print duplicate lines, one for each group of identical lines +//@ +//@ Examples: +//@ +//@ ```javascript +//@ uniq('foo.txt'); +//@ uniq('-i', 'foo.txt'); +//@ uniq('-cd', 'foo.txt', 'bar.txt'); +//@ ``` +//@ +//@ Filter adjacent matching lines from input +function _uniq(options, input, output) { + // Check if this is coming from a pipe + var pipe = common.readFromPipe(); + + if (!input && !pipe) common.error('no input given'); + + var lines = (input ? fs.readFileSync(input, 'utf8') : pipe). + trimRight(). + split(/\r*\n/); + + var compare = function (a, b) { + return options.ignoreCase ? + a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()) : + a.localeCompare(b); + }; + var uniqed = lines.reduceRight(function (res, e) { + // Perform uniq -c on the input + if (res.length === 0) { + return [{ count: 1, ln: e }]; + } else if (compare(res[0].ln, e) === 0) { + return [{ count: res[0].count + 1, ln: e }].concat(res.slice(1)); + } else { + return [{ count: 1, ln: e }].concat(res); + } + }, []).filter(function (obj) { + // Do we want only duplicated objects? + return options.duplicates ? obj.count > 1 : true; + }).map(function (obj) { + // Are we tracking the counts of each line? + return (options.count ? (lpad(7, obj.count) + ' ') : '') + obj.ln; + }).join('\n') + '\n'; + + if (output) { + (new common.ShellString(uniqed)).to(output); + // if uniq writes to output, nothing is passed to the next command in the pipeline (if any) + return ''; + } else { + return uniqed; + } +} + +module.exports = _uniq; diff --git a/tools/eslint/node_modules/shelljs/src/which.js b/tools/eslint/node_modules/shelljs/src/which.js index d17634ee941d96..ef5d185eb0e462 100644 --- a/tools/eslint/node_modules/shelljs/src/which.js +++ b/tools/eslint/node_modules/shelljs/src/which.js @@ -2,23 +2,27 @@ var common = require('./common'); var fs = require('fs'); var path = require('path'); +common.register('which', _which, { + allowGlobbing: false, +}); + // XP's system default value for PATHEXT system variable, just in case it's not // set on Windows. var XP_DEFAULT_PATHEXT = '.com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh'; // Cross-platform method for splitting environment PATH variables function splitPath(p) { - if (!p) - return []; + if (!p) return []; - if (common.platform === 'win') + if (common.platform === 'win') { return p.split(';'); - else + } else { return p.split(':'); + } } -function checkPath(path) { - return fs.existsSync(path) && !fs.statSync(path).isDirectory(); +function checkPath(pathName) { + return fs.existsSync(pathName) && !fs.statSync(pathName).isDirectory(); } //@ @@ -34,19 +38,17 @@ function checkPath(path) { //@ `PATHEXT` variable to append the extension if it's not already executable. //@ Returns string containing the absolute path to the command. function _which(options, cmd) { - if (!cmd) - common.error('must specify command'); + if (!cmd) common.error('must specify command'); - var pathEnv = process.env.path || process.env.Path || process.env.PATH, - pathArray = splitPath(pathEnv), - where = null; + var pathEnv = process.env.path || process.env.Path || process.env.PATH; + var pathArray = splitPath(pathEnv); + var where = null; // No relative/absolute paths provided? if (cmd.search(/\//) === -1) { // Search for command in PATH - pathArray.forEach(function(dir) { - if (where) - return; // already found it + pathArray.forEach(function (dir) { + if (where) return; // already found it var attempt = path.resolve(dir, cmd); @@ -88,11 +90,10 @@ function _which(options, cmd) { } // Command not found anywhere? - if (!checkPath(cmd) && !where) - return null; + if (!checkPath(cmd) && !where) return null; where = where || path.resolve(cmd); - return common.ShellString(where); + return where; } module.exports = _which; diff --git a/tools/eslint/node_modules/string-width/package.json b/tools/eslint/node_modules/string-width/package.json index 6fc310fca4230d..b0e9dfdea93cf7 100644 --- a/tools/eslint/node_modules/string-width/package.json +++ b/tools/eslint/node_modules/string-width/package.json @@ -38,8 +38,7 @@ "type": "range" }, "_requiredBy": [ - "/inquirer", - "/table" + "/inquirer" ], "_resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "_shasum": "118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3", diff --git a/tools/eslint/node_modules/strip-ansi/package.json b/tools/eslint/node_modules/strip-ansi/package.json index dced2726e06f26..323a21ebb41a8c 100644 --- a/tools/eslint/node_modules/strip-ansi/package.json +++ b/tools/eslint/node_modules/strip-ansi/package.json @@ -40,7 +40,8 @@ "_requiredBy": [ "/chalk", "/inquirer", - "/string-width" + "/string-width", + "/table/string-width" ], "_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "_shasum": "6a385fb8853d952d5ff05d0e8aaf94278dc63dcf", diff --git a/tools/eslint/node_modules/strip-json-comments/cli.js b/tools/eslint/node_modules/strip-json-comments/cli.js deleted file mode 100755 index aec5aa20e4a073..00000000000000 --- a/tools/eslint/node_modules/strip-json-comments/cli.js +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node -'use strict'; -var fs = require('fs'); -var strip = require('./strip-json-comments'); -var input = process.argv[2]; - - -function getStdin(cb) { - var ret = ''; - - process.stdin.setEncoding('utf8'); - - process.stdin.on('data', function (data) { - ret += data; - }); - - process.stdin.on('end', function () { - cb(ret); - }); -} - -if (process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) { - console.log('strip-json-comments input-file > output-file'); - console.log('or'); - console.log('strip-json-comments < input-file > output-file'); - return; -} - -if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) { - console.log(require('./package').version); - return; -} - -if (input) { - process.stdout.write(strip(fs.readFileSync(input, 'utf8'))); - return; -} - -getStdin(function (data) { - process.stdout.write(strip(data)); -}); diff --git a/tools/eslint/node_modules/strip-json-comments/index.js b/tools/eslint/node_modules/strip-json-comments/index.js new file mode 100644 index 00000000000000..4e6576e6d3c388 --- /dev/null +++ b/tools/eslint/node_modules/strip-json-comments/index.js @@ -0,0 +1,70 @@ +'use strict'; +var singleComment = 1; +var multiComment = 2; + +function stripWithoutWhitespace() { + return ''; +} + +function stripWithWhitespace(str, start, end) { + return str.slice(start, end).replace(/\S/g, ' '); +} + +module.exports = function (str, opts) { + opts = opts || {}; + + var currentChar; + var nextChar; + var insideString = false; + var insideComment = false; + var offset = 0; + var ret = ''; + var strip = opts.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace; + + for (var i = 0; i < str.length; i++) { + currentChar = str[i]; + nextChar = str[i + 1]; + + if (!insideComment && currentChar === '"') { + var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\'; + if (!escaped) { + insideString = !insideString; + } + } + + if (insideString) { + continue; + } + + if (!insideComment && currentChar + nextChar === '//') { + ret += str.slice(offset, i); + offset = i; + insideComment = singleComment; + i++; + } else if (insideComment === singleComment && currentChar + nextChar === '\r\n') { + i++; + insideComment = false; + ret += strip(str, offset, i); + offset = i; + continue; + } else if (insideComment === singleComment && currentChar === '\n') { + insideComment = false; + ret += strip(str, offset, i); + offset = i; + } else if (!insideComment && currentChar + nextChar === '/*') { + ret += str.slice(offset, i); + offset = i; + insideComment = multiComment; + i++; + continue; + } else if (insideComment === multiComment && currentChar + nextChar === '*/') { + i++; + insideComment = false; + ret += strip(str, offset, i + 1); + offset = i + 1; + continue; + } + } + + return ret + (insideComment ? strip(str.substr(offset)) : str.substr(offset)); +}; diff --git a/tools/eslint/node_modules/strip-json-comments/package.json b/tools/eslint/node_modules/strip-json-comments/package.json index de43cb650fbdcb..6bbd9d717fbf7b 100644 --- a/tools/eslint/node_modules/strip-json-comments/package.json +++ b/tools/eslint/node_modules/strip-json-comments/package.json @@ -2,75 +2,76 @@ "_args": [ [ { - "raw": "strip-json-comments@~1.0.1", + "raw": "strip-json-comments@~2.0.1", "scope": null, "escapedName": "strip-json-comments", "name": "strip-json-comments", - "rawSpec": "~1.0.1", - "spec": ">=1.0.1 <1.1.0", + "rawSpec": "~2.0.1", + "spec": ">=2.0.1 <2.1.0", "type": "range" }, "/Users/trott/io.js/tools/node_modules/eslint" ] ], - "_from": "strip-json-comments@>=1.0.1 <1.1.0", - "_id": "strip-json-comments@1.0.4", + "_from": "strip-json-comments@>=2.0.1 <2.1.0", + "_id": "strip-json-comments@2.0.1", "_inCache": true, "_location": "/strip-json-comments", - "_nodeVersion": "0.12.5", + "_nodeVersion": "4.2.4", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/strip-json-comments-2.0.1.tgz_1455006605207_0.8280157081317157" + }, "_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" }, - "_npmVersion": "2.11.2", + "_npmVersion": "3.7.2", "_phantomChildren": {}, "_requested": { - "raw": "strip-json-comments@~1.0.1", + "raw": "strip-json-comments@~2.0.1", "scope": null, "escapedName": "strip-json-comments", "name": "strip-json-comments", - "rawSpec": "~1.0.1", - "spec": ">=1.0.1 <1.1.0", + "rawSpec": "~2.0.1", + "spec": ">=2.0.1 <2.1.0", "type": "range" }, "_requiredBy": [ "/eslint" ], - "_resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "_shasum": "1e15fbcac97d3ee99bf2d73b4c656b082bbafb91", + "_resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "_shasum": "3c531942e908c2697c0ec344858c286c7ca0a60a", "_shrinkwrap": null, - "_spec": "strip-json-comments@~1.0.1", + "_spec": "strip-json-comments@~2.0.1", "_where": "/Users/trott/io.js/tools/node_modules/eslint", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", "url": "sindresorhus.com" }, - "bin": { - "strip-json-comments": "cli.js" - }, "bugs": { "url": "https://github.com/sindresorhus/strip-json-comments/issues" }, "dependencies": {}, "description": "Strip comments from JSON. Lets you use comments in your JSON files!", "devDependencies": { - "mocha": "*" + "ava": "*", + "xo": "*" }, "directories": {}, "dist": { - "shasum": "1e15fbcac97d3ee99bf2d73b4c656b082bbafb91", - "tarball": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz" + "shasum": "3c531942e908c2697c0ec344858c286c7ca0a60a", + "tarball": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" }, "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" }, "files": [ - "cli.js", - "strip-json-comments.js" + "index.js" ], - "gitHead": "f58348696368583cc5bb18525fe31eacc9bd00e1", - "homepage": "https://github.com/sindresorhus/strip-json-comments", + "gitHead": "1aef99eaa70d07981156e8aaa722e750c3b4eaf9", + "homepage": "https://github.com/sindresorhus/strip-json-comments#readme", "keywords": [ "json", "strip", @@ -86,12 +87,9 @@ "settings", "util", "env", - "environment", - "cli", - "bin" + "environment" ], "license": "MIT", - "main": "strip-json-comments", "maintainers": [ { "name": "sindresorhus", @@ -106,7 +104,7 @@ "url": "git+https://github.com/sindresorhus/strip-json-comments.git" }, "scripts": { - "test": "mocha --ui tdd" + "test": "xo && ava" }, - "version": "1.0.4" + "version": "2.0.1" } diff --git a/tools/eslint/node_modules/strip-json-comments/readme.md b/tools/eslint/node_modules/strip-json-comments/readme.md index 63ce165b23809f..5a3447147434d8 100644 --- a/tools/eslint/node_modules/strip-json-comments/readme.md +++ b/tools/eslint/node_modules/strip-json-comments/readme.md @@ -11,34 +11,23 @@ This is now possible: } ``` -It will remove single-line comments `//` and multi-line comments `/**/`. +It will replace single-line comments `//` and multi-line comments `/**/` with whitespace. This allows JSON error positions to remain as close as possible to the original source. Also available as a [gulp](https://github.com/sindresorhus/gulp-strip-json-comments)/[grunt](https://github.com/sindresorhus/grunt-strip-json-comments)/[broccoli](https://github.com/sindresorhus/broccoli-strip-json-comments) plugin. -- - -*There's also [`json-comments`](https://npmjs.org/package/json-comments), but it's only for Node.js, inefficient, bloated as it also minifies, and comes with a `require` hook, which is :(* - ## Install -```sh -$ npm install --save strip-json-comments -``` - -```sh -$ bower install --save strip-json-comments ``` - -```sh -$ component install sindresorhus/strip-json-comments +$ npm install --save strip-json-comments ``` ## Usage ```js -var json = '{/*rainbows*/"unicorn":"cake"}'; +const json = '{/*rainbows*/"unicorn":"cake"}'; + JSON.parse(stripJsonComments(json)); //=> {unicorn: 'cake'} ``` @@ -46,7 +35,7 @@ JSON.parse(stripJsonComments(json)); ## API -### stripJsonComments(input) +### stripJsonComments(input, [options]) #### input @@ -54,25 +43,20 @@ Type: `string` Accepts a string with JSON and returns a string without comments. +#### options -## CLI +##### whitespace -```sh -$ npm install --global strip-json-comments -``` +Type: `boolean` +Default: `true` -```sh -$ strip-json-comments --help - -strip-json-comments input-file > output-file -# or -strip-json-comments < input-file > output-file -``` +Replace comments with whitespace instead of stripping them entirely. ## Related -- [`strip-css-comments`](https://github.com/sindresorhus/strip-css-comments) +- [strip-json-comments-cli](https://github.com/sindresorhus/strip-json-comments-cli) - CLI for this module +- [strip-css-comments](https://github.com/sindresorhus/strip-css-comments) - Strip comments from CSS ## License diff --git a/tools/eslint/node_modules/strip-json-comments/strip-json-comments.js b/tools/eslint/node_modules/strip-json-comments/strip-json-comments.js deleted file mode 100644 index eb77ce7456b8e5..00000000000000 --- a/tools/eslint/node_modules/strip-json-comments/strip-json-comments.js +++ /dev/null @@ -1,73 +0,0 @@ -/*! - strip-json-comments - Strip comments from JSON. Lets you use comments in your JSON files! - https://github.com/sindresorhus/strip-json-comments - by Sindre Sorhus - MIT License -*/ -(function () { - 'use strict'; - - var singleComment = 1; - var multiComment = 2; - - function stripJsonComments(str) { - var currentChar; - var nextChar; - var insideString = false; - var insideComment = false; - var ret = ''; - - for (var i = 0; i < str.length; i++) { - currentChar = str[i]; - nextChar = str[i + 1]; - - if (!insideComment && currentChar === '"') { - var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\'; - if (!insideComment && !escaped && currentChar === '"') { - insideString = !insideString; - } - } - - if (insideString) { - ret += currentChar; - continue; - } - - if (!insideComment && currentChar + nextChar === '//') { - insideComment = singleComment; - i++; - } else if (insideComment === singleComment && currentChar + nextChar === '\r\n') { - insideComment = false; - i++; - ret += currentChar; - ret += nextChar; - continue; - } else if (insideComment === singleComment && currentChar === '\n') { - insideComment = false; - } else if (!insideComment && currentChar + nextChar === '/*') { - insideComment = multiComment; - i++; - continue; - } else if (insideComment === multiComment && currentChar + nextChar === '*/') { - insideComment = false; - i++; - continue; - } - - if (insideComment) { - continue; - } - - ret += currentChar; - } - - return ret; - } - - if (typeof module !== 'undefined' && module.exports) { - module.exports = stripJsonComments; - } else { - window.stripJsonComments = stripJsonComments; - } -})(); diff --git a/tools/eslint/node_modules/table/dist/alignString.js.map b/tools/eslint/node_modules/table/dist/alignString.js.map deleted file mode 100644 index 9d6e8b84e39b13..00000000000000 --- a/tools/eslint/node_modules/table/dist/alignString.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["alignString.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA;;;;;;AAEA,IAAI,oBAAJ;IACI,kBADJ;IAEI,mBAFJ;IAGI,mBAHJ;;AAKA,aAAa,CACT,MADS,EAET,OAFS,EAGT,QAHS,CAAb;;;;;;;AAWA,YAAY,mBAAC,OAAD,EAAU,KAAV,EAAoB;AAC5B,WAAO,UAAU,sBAAS,GAAT,EAAc,KAAd,CAAjB;AACH,CAFD;;;;;;;AASA,aAAa,oBAAC,OAAD,EAAU,KAAV,EAAoB;AAC7B,WAAO,sBAAS,GAAT,EAAc,KAAd,IAAuB,OAA9B;AACH,CAFD;;;;;;;AASA,cAAc,qBAAC,OAAD,EAAU,KAAV,EAAoB;AAC9B,QAAI,kBAAJ;;AAEA,gBAAY,QAAQ,CAApB;;AAEA,QAAI,YAAY,CAAZ,KAAkB,CAAtB,EAAyB;AACrB,eAAO,sBAAS,GAAT,EAAc,SAAd,IAA2B,OAA3B,GAAqC,sBAAS,GAAT,EAAc,SAAd,CAA5C;AACH,KAFD,MAEO;AACH,oBAAY,qBAAQ,SAAR,CAAZ;;AAEA,eAAO,sBAAS,GAAT,EAAc,SAAd,IAA2B,OAA3B,GAAqC,sBAAS,GAAT,EAAc,YAAY,CAA1B,CAA5C;AACH;AACJ,CAZD;;;;;;;;;;;;kBAuBe,UAAC,OAAD,EAAU,cAAV,EAA0B,SAA1B,EAAwC;AACnD,QAAI,uBAAJ;QACI,qBADJ;;AAGA,QAAI,CAAC,wBAAW,OAAX,CAAL,EAA0B;AACtB,cAAM,IAAI,KAAJ,CAAU,2CAAV,CAAN;AACH;;AAED,QAAI,CAAC,wBAAW,cAAX,CAAL,EAAiC;AAC7B,cAAM,IAAI,KAAJ,CAAU,mDAAV,CAAN;AACH;;AAED,mBAAe,2BAAY,OAAZ,CAAf;;AAEA,QAAI,eAAe,cAAnB,EAAmC;;;AAG/B,cAAM,IAAI,KAAJ,CAAU,2EAAV,CAAN;AACH;;AAED,QAAI,CAAC,wBAAW,SAAX,CAAL,EAA4B;AACxB,cAAM,IAAI,KAAJ,CAAU,6CAAV,CAAN;AACH;;AAED,QAAI,WAAW,OAAX,CAAmB,SAAnB,MAAkC,CAAC,CAAvC,EAA0C;AACtC,cAAM,IAAI,KAAJ,CAAU,4FAAV,CAAN;AACH;;AAED,QAAI,iBAAiB,CAArB,EAAwB;AACpB,eAAO,sBAAS,GAAT,EAAc,cAAd,CAAP;AACH;;AAED,qBAAiB,iBAAiB,YAAlC;;AAEA,QAAI,cAAc,MAAlB,EAA0B;AACtB,eAAO,UAAU,OAAV,EAAmB,cAAnB,CAAP;AACH;;AAED,QAAI,cAAc,OAAlB,EAA2B;AACvB,eAAO,WAAW,OAAX,EAAoB,cAApB,CAAP;AACH;;AAED,WAAO,YAAY,OAAZ,EAAqB,cAArB,CAAP;AACH,C","file":"alignString.js","sourcesContent":["import _ from 'lodash';\nimport stringWidth from 'string-width';\n\nlet alignCenter,\n alignLeft,\n alignRight,\n alignments;\n\nalignments = [\n 'left',\n 'right',\n 'center'\n];\n\n/**\n * @param {string} subject\n * @param {number} width\n * @returns {string}\n */\nalignLeft = (subject, width) => {\n return subject + _.repeat(' ', width);\n};\n\n/**\n * @param {string} subject\n * @param {number} width\n * @returns {string}\n */\nalignRight = (subject, width) => {\n return _.repeat(' ', width) + subject;\n};\n\n/**\n * @param {string} subject\n * @param {number} width\n * @returns {string}\n */\nalignCenter = (subject, width) => {\n let halfWidth;\n\n halfWidth = width / 2;\n\n if (halfWidth % 2 === 0) {\n return _.repeat(' ', halfWidth) + subject + _.repeat(' ', halfWidth);\n } else {\n halfWidth = _.floor(halfWidth);\n\n return _.repeat(' ', halfWidth) + subject + _.repeat(' ', halfWidth + 1);\n }\n};\n\n/**\n * Pads a string to the left and/or right to position the subject\n * text in a desired alignment within a container.\n *\n * @param {string} subject\n * @param {number} containerWidth\n * @param {string} alignment One of the valid options (left, right, center).\n * @returns {string}\n */\nexport default (subject, containerWidth, alignment) => {\n let availableWidth,\n subjectWidth;\n\n if (!_.isString(subject)) {\n throw new Error('Subject parameter value must be a string.');\n }\n\n if (!_.isNumber(containerWidth)) {\n throw new Error('Container width parameter value must be a number.');\n }\n\n subjectWidth = stringWidth(subject);\n\n if (subjectWidth > containerWidth) {\n // console.log('subjectWidth', subjectWidth, 'containerWidth', containerWidth, 'subject', subject);\n\n throw new Error('Subject parameter value width cannot be greater than the container width.');\n }\n\n if (!_.isString(alignment)) {\n throw new Error('Alignment parameter value must be a string.');\n }\n\n if (alignments.indexOf(alignment) === -1) {\n throw new Error('Alignment parameter value must be a known alignment parameter value (left, right, center).');\n }\n\n if (subjectWidth === 0) {\n return _.repeat(' ', containerWidth);\n }\n\n availableWidth = containerWidth - subjectWidth;\n\n if (alignment === 'left') {\n return alignLeft(subject, availableWidth);\n }\n\n if (alignment === 'right') {\n return alignRight(subject, availableWidth);\n }\n\n return alignCenter(subject, availableWidth);\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/alignTableData.js.map b/tools/eslint/node_modules/table/dist/alignTableData.js.map deleted file mode 100644 index 45aea74993674f..00000000000000 --- a/tools/eslint/node_modules/table/dist/alignTableData.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["alignTableData.js"],"names":[],"mappings":";;;;;;;;;;AACA;;;;AACA;;;;;;;;;;;;kBAOe,UAAC,IAAD,EAAO,MAAP,EAAkB;AAC7B,WAAO,mBAAM,IAAN,EAAY,UAAC,KAAD,EAAW;AAC1B,eAAO,mBAAM,KAAN,EAAa,UAAC,KAAD,EAAQ,MAAR,EAAmB;AACnC,gBAAI,eAAJ;;AAEA,qBAAS,OAAO,OAAP,CAAe,MAAf,CAAT;;AAEA,gBAAI,2BAAY,KAAZ,MAAuB,OAAO,KAAlC,EAAyC;AACrC,uBAAO,KAAP;AACH,aAFD,MAEO;AACH,uBAAO,2BAAY,KAAZ,EAAmB,OAAO,KAA1B,EAAiC,OAAO,SAAxC,CAAP;AACH;AACJ,SAVM,CAAP;AAWH,KAZM,CAAP;AAaH,C","file":"alignTableData.js","sourcesContent":["import _ from 'lodash';\nimport alignString from './alignString';\nimport stringWidth from 'string-width';\n\n/**\n * @param {table~row[]} rows\n * @param {Object} config\n * @return {table~row[]}\n */\nexport default (rows, config) => {\n return _.map(rows, (cells) => {\n return _.map(cells, (value, index1) => {\n let column;\n\n column = config.columns[index1];\n\n if (stringWidth(value) === column.width) {\n return value;\n } else {\n return alignString(value, column.width, column.alignment);\n }\n });\n });\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/calculateCellHeight.js b/tools/eslint/node_modules/table/dist/calculateCellHeight.js index f90110adb11d51..b5ec6998d58d0e 100644 --- a/tools/eslint/node_modules/table/dist/calculateCellHeight.js +++ b/tools/eslint/node_modules/table/dist/calculateCellHeight.js @@ -25,7 +25,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @returns {number} */ exports.default = function (value, columnWidth) { - let useWrapWord = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; + let useWrapWord = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (!_lodash2.default.isString(value)) { throw new Error('Value must be a string.'); diff --git a/tools/eslint/node_modules/table/dist/calculateCellHeight.js.map b/tools/eslint/node_modules/table/dist/calculateCellHeight.js.map deleted file mode 100644 index 184fdbf02cd47c..00000000000000 --- a/tools/eslint/node_modules/table/dist/calculateCellHeight.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["calculateCellHeight.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AACA;;;;AACA;;;;;;;;;;;;;kBAQe,UAAC,KAAD,EAAQ,WAAR,EAA6C;AAAA,QAAxB,WAAwB,yDAAV,KAAU;;AACxD,QAAI,CAAC,wBAAW,KAAX,CAAL,EAAwB;AACpB,cAAM,IAAI,KAAJ,CAAU,yBAAV,CAAN;AACH;;AAED,QAAI,CAAC,yBAAY,WAAZ,CAAL,EAA+B;AAC3B,cAAM,IAAI,KAAJ,CAAU,kCAAV,CAAN;AACH;;AAED,QAAI,cAAc,CAAlB,EAAqB;AACjB,cAAM,IAAI,KAAJ,CAAU,sCAAV,CAAN;AACH;;AAED,QAAI,WAAJ,EAAiB;AACb,eAAO,wBAAS,KAAT,EAAgB,WAAhB,EAA6B,MAApC;AACH;;AAED,WAAO,oBAAO,2BAAY,KAAZ,IAAqB,WAA5B,CAAP;AACH,C","file":"calculateCellHeight.js","sourcesContent":["import _ from 'lodash';\nimport stringWidth from 'string-width';\nimport wrapWord from './wrapWord';\n\n/**\n * @param {string} value\n * @param {number} columnWidth\n * @param {boolean} useWrapWord\n * @returns {number}\n */\nexport default (value, columnWidth, useWrapWord = false) => {\n if (!_.isString(value)) {\n throw new Error('Value must be a string.');\n }\n\n if (!_.isInteger(columnWidth)) {\n throw new Error('Column width must be an integer.');\n }\n\n if (columnWidth < 1) {\n throw new Error('Column width must be greater than 0.');\n }\n\n if (useWrapWord) {\n return wrapWord(value, columnWidth).length;\n }\n\n return _.ceil(stringWidth(value) / columnWidth);\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/calculateCellWidthIndex.js.map b/tools/eslint/node_modules/table/dist/calculateCellWidthIndex.js.map deleted file mode 100644 index 112a04e8ee6c35..00000000000000 --- a/tools/eslint/node_modules/table/dist/calculateCellWidthIndex.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["calculateCellWidthIndex.js"],"names":[],"mappings":";;;;;;;;;;AACA;;;;;;;;;;;;;kBAQe,UAAC,KAAD,EAAW;AACtB,WAAO,mBAAM,KAAN,EAAa,UAAC,KAAD,EAAW;AAC3B,eAAO,2BAAY,KAAZ,CAAP;AACH,KAFM,CAAP;AAGH,C","file":"calculateCellWidthIndex.js","sourcesContent":["import _ from 'lodash';\nimport stringWidth from 'string-width';\n\n/**\n * Calculates width of each cell contents.\n *\n * @param {string[]} cells\n * @return {number[]}\n */\nexport default (cells) => {\n return _.map(cells, (value) => {\n return stringWidth(value);\n });\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/calculateMaximumColumnWidthIndex.js.map b/tools/eslint/node_modules/table/dist/calculateMaximumColumnWidthIndex.js.map deleted file mode 100644 index ea1e5e9ce49b3e..00000000000000 --- a/tools/eslint/node_modules/table/dist/calculateMaximumColumnWidthIndex.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["calculateMaximumColumnWidthIndex.js"],"names":[],"mappings":";;;;;;;;;;;;;;AACA;;;;;;;;;;;;;kBAQe,UAAC,IAAD,EAAU;AACrB,QAAI,gBAAJ;;AAEA,QAAI,CAAC,KAAK,CAAL,CAAL,EAAc;AACV,cAAM,IAAI,KAAJ,CAAU,qCAAV,CAAN;AACH;;AAED,cAAU,oBAAO,MAAM,KAAK,CAAL,EAAQ,MAAd,CAAP,EAA8B,CAA9B,CAAV;;AAEA,2BAAU,IAAV,EAAgB,UAAC,GAAD,EAAS;AACrB,YAAI,yBAAJ;;AAEA,2BAAmB,uCAAwB,GAAxB,CAAnB;;AAEA,+BAAU,gBAAV,EAA4B,UAAC,UAAD,EAAa,MAAb,EAAwB;AAChD,gBAAI,QAAQ,MAAR,IAAkB,UAAtB,EAAkC;AAC9B,wBAAQ,MAAR,IAAkB,UAAlB;AACH;AACJ,SAJD;AAKH,KAVD;;AAYA,WAAO,OAAP;AACH,C","file":"calculateMaximumColumnWidthIndex.js","sourcesContent":["import _ from 'lodash';\nimport calculateCellWidthIndex from './calculateCellWidthIndex';\n\n/**\n * Produces an array of values that describe the largest value length (width) in every column.\n *\n * @param {Array[]} rows\n * @return {number[]}\n */\nexport default (rows) => {\n let columns;\n\n if (!rows[0]) {\n throw new Error('Dataset must have at least one row.');\n }\n\n columns = _.fill(Array(rows[0].length), 0);\n\n _.forEach(rows, (row) => {\n let columnWidthIndex;\n\n columnWidthIndex = calculateCellWidthIndex(row);\n\n _.forEach(columnWidthIndex, (valueWidth, index0) => {\n if (columns[index0] < valueWidth) {\n columns[index0] = valueWidth;\n }\n });\n });\n\n return columns;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/calculateRowHeightIndex.js.map b/tools/eslint/node_modules/table/dist/calculateRowHeightIndex.js.map deleted file mode 100644 index 9816a50a9a99a9..00000000000000 --- a/tools/eslint/node_modules/table/dist/calculateRowHeightIndex.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["calculateRowHeightIndex.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA;;;;;;;;;;;;;;kBASe,UAAC,IAAD,EAAO,MAAP,EAAkB;AAC7B,QAAI,qBAAJ;QACI,mBADJ;;AAGA,iBAAa,KAAK,CAAL,EAAQ,MAArB;;AAEA,mBAAe,EAAf;;AAEA,2BAAU,IAAV,EAAgB,UAAC,KAAD,EAAW;AACvB,YAAI,wBAAJ;;AAEA,0BAAkB,oBAAO,MAAM,UAAN,CAAP,EAA0B,CAA1B,CAAlB;;AAEA,+BAAU,KAAV,EAAiB,UAAC,KAAD,EAAQ,MAAR,EAAmB;AAChC,gBAAI,CAAC,wBAAW,OAAO,OAAP,CAAe,MAAf,EAAuB,KAAlC,CAAL,EAA+C;AAC3C,sBAAM,IAAI,KAAJ,CAAU,uCAAV,CAAN;AACH;;AAED,gBAAI,CAAC,yBAAY,OAAO,OAAP,CAAe,MAAf,EAAuB,QAAnC,CAAL,EAAmD;AAC/C,sBAAM,IAAI,KAAJ,CAAU,2CAAV,CAAN;AACH;;AAED,4BAAgB,MAAhB,IAA0B,mCAAoB,KAApB,EAA2B,OAAO,OAAP,CAAe,MAAf,EAAuB,KAAlD,EAAyD,OAAO,OAAP,CAAe,MAAf,EAAuB,QAAhF,CAA1B;AACH,SAVD;;AAYA,qBAAa,IAAb,CAAkB,mBAAM,eAAN,CAAlB;AACH,KAlBD;;AAoBA,WAAO,YAAP;AACH,C","file":"calculateRowHeightIndex.js","sourcesContent":["import _ from 'lodash';\nimport calculateCellHeight from './calculateCellHeight';\n\n/**\n * Calculates the vertical row span index.\n *\n * @param {Array[]} rows\n * @param {Object} config\n * @return {number[]}\n */\nexport default (rows, config) => {\n let rowSpanIndex,\n tableWidth;\n\n tableWidth = rows[0].length;\n\n rowSpanIndex = [];\n\n _.forEach(rows, (cells) => {\n let cellHeightIndex;\n\n cellHeightIndex = _.fill(Array(tableWidth), 1);\n\n _.forEach(cells, (value, index1) => {\n if (!_.isNumber(config.columns[index1].width)) {\n throw new Error('column[index].width must be a number.');\n }\n\n if (!_.isBoolean(config.columns[index1].wrapWord)) {\n throw new Error('column[index].wrapWord must be a boolean.');\n }\n\n cellHeightIndex[index1] = calculateCellHeight(value, config.columns[index1].width, config.columns[index1].wrapWord);\n });\n\n rowSpanIndex.push(_.max(cellHeightIndex));\n });\n\n return rowSpanIndex;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/createStream.js b/tools/eslint/node_modules/table/dist/createStream.js index 1175ec66538da7..f9c3df5035be45 100644 --- a/tools/eslint/node_modules/table/dist/createStream.js +++ b/tools/eslint/node_modules/table/dist/createStream.js @@ -123,7 +123,7 @@ const append = (row, columnWidthIndex, config) => { */ exports.default = function () { - let userConfig = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + let userConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; const config = (0, _makeStreamConfig2.default)(userConfig); diff --git a/tools/eslint/node_modules/table/dist/createStream.js.map b/tools/eslint/node_modules/table/dist/createStream.js.map deleted file mode 100644 index b3a2563cda052a..00000000000000 --- a/tools/eslint/node_modules/table/dist/createStream.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["createStream.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA;;;;AACA;;;;AACA;;AAOA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAI,eAAJ;IACI,eADJ;IAEI,oBAFJ;;;;;;;;AAUA,SAAS,gBAAC,GAAD,EAAM,gBAAN,EAAwB,MAAxB,EAAmC;AACxC,QAAI,aAAJ;QACI,eADJ;QAEI,aAFJ;;AAIA,WAAO,YAAY,CAAC,GAAD,CAAZ,EAAmB,MAAnB,CAAP;;AAEA,WAAO,mBAAM,IAAN,EAAY,UAAC,UAAD,EAAgB;AAC/B,eAAO,uBAAQ,UAAR,EAAoB,OAAO,MAA3B,CAAP;AACH,KAFM,EAEJ,IAFI,CAEC,EAFD,CAAP;;AAIA,aAAS,EAAT;AACA,cAAU,+BAAc,gBAAd,EAAgC,OAAO,MAAvC,CAAV;AACA,cAAU,IAAV;AACA,cAAU,kCAAiB,gBAAjB,EAAmC,OAAO,MAA1C,CAAV;;AAEA,aAAS,uBAAU,MAAV,CAAT;;AAEA,YAAQ,MAAR,CAAe,KAAf,CAAqB,MAArB;AACH,CAnBD;;;;;;;;AA2BA,SAAS,gBAAC,GAAD,EAAM,gBAAN,EAAwB,MAAxB,EAAmC;AACxC,QAAI,aAAJ;QACI,eADJ;QAEI,aAFJ;;AAIA,WAAO,YAAY,CAAC,GAAD,CAAZ,EAAmB,MAAnB,CAAP;;;;AAIA,WAAO,mBAAM,IAAN,EAAY,UAAC,UAAD,EAAgB;AAC/B,eAAO,uBAAQ,UAAR,EAAoB,OAAO,MAA3B,CAAP;AACH,KAFM,EAEJ,IAFI,CAEC,EAFD,CAAP;;AAIA,aAAS,UAAT;AACA,cAAU,gCAAe,gBAAf,EAAiC,OAAO,MAAxC,CAAV;AACA,cAAU,IAAV;AACA,cAAU,kCAAiB,gBAAjB,EAAmC,OAAO,MAA1C,CAAV;;AAEA,aAAS,uBAAU,MAAV,CAAT;;AAEA,YAAQ,MAAR,CAAe,KAAf,CAAqB,MAArB;AACH,CArBD;;;;;;;AA4BA,cAAc,qBAAC,IAAD,EAAO,MAAP,EAAkB;AAC5B,QAAI,uBAAJ;QACI,aADJ;;AAGA,WAAO,kCAAmB,IAAnB,CAAP;;AAEA,WAAO,iCAAkB,IAAlB,EAAwB,MAAxB,CAAP;;AAEA,qBAAiB,uCAAwB,IAAxB,EAA8B,MAA9B,CAAjB;;AAEA,WAAO,0CAA2B,IAA3B,EAAiC,cAAjC,EAAiD,MAAjD,CAAP;AACA,WAAO,8BAAe,IAAf,EAAqB,MAArB,CAAP;AACA,WAAO,4BAAa,IAAb,EAAmB,MAAnB,CAAP;;AAEA,WAAO,IAAP;AACH,CAfD;;;;;;;kBAqBe,YAAqB;AAAA,QAApB,UAAoB,yDAAP,EAAO;;AAChC,QAAI,yBAAJ;QACI,eADJ;QAEI,cAFJ;;AAIA,aAAS,gCAAiB,UAAjB,CAAT;;AAEA,uBAAmB,yBAAY,OAAO,OAAnB,EAA4B,UAAC,MAAD,EAAY;AACvD,eAAO,OAAO,KAAP,GAAe,OAAO,WAAtB,GAAoC,OAAO,YAAlD;AACH,KAFkB,CAAnB;;AAIA,YAAQ,IAAR;;AAEA,WAAO;;;;;AAKH,eAAO,eAAC,GAAD,EAAS;AACZ,gBAAI,IAAI,MAAJ,KAAe,OAAO,WAA1B,EAAuC;AACnC,sBAAM,IAAI,KAAJ,CAAU,uDAAV,CAAN;AACH;;AAED,gBAAI,KAAJ,EAAW;AACP,wBAAQ,KAAR;;AAEA,uBAAO,OAAO,GAAP,EAAY,gBAAZ,EAA8B,MAA9B,CAAP;AACH,aAJD,MAIO;AACH,uBAAO,OAAO,GAAP,EAAY,gBAAZ,EAA8B,MAA9B,CAAP;AACH;AACJ;AAjBE,KAAP;AAmBH,C","file":"createStream.js","sourcesContent":["import makeStreamConfig from './makeStreamConfig';\nimport drawRow from './drawRow';\nimport {\n drawBorderBottom,\n drawBorderJoin,\n drawBorderTop\n} from './drawBorder';\nimport _ from 'lodash';\n\nimport stringifyTableData from './stringifyTableData';\nimport truncateTableData from './truncateTableData';\nimport mapDataUsingRowHeightIndex from './mapDataUsingRowHeightIndex';\nimport alignTableData from './alignTableData';\nimport padTableData from './padTableData';\nimport calculateRowHeightIndex from './calculateRowHeightIndex';\n\nlet append,\n create,\n prepareData;\n\n/**\n * @param {string[]} row\n * @param {number[]} columnWidthIndex\n * @param {Object} config\n * @returns {undefined}\n */\ncreate = (row, columnWidthIndex, config) => {\n let body,\n output,\n rows;\n\n rows = prepareData([row], config);\n\n body = _.map(rows, (literalRow) => {\n return drawRow(literalRow, config.border);\n }).join('');\n\n output = '';\n output += drawBorderTop(columnWidthIndex, config.border);\n output += body;\n output += drawBorderBottom(columnWidthIndex, config.border);\n\n output = _.trimEnd(output);\n\n process.stdout.write(output);\n};\n\n/**\n * @param {string[]} row\n * @param {number[]} columnWidthIndex\n * @param {Object} config\n * @returns {undefined}\n */\nappend = (row, columnWidthIndex, config) => {\n let body,\n output,\n rows;\n\n rows = prepareData([row], config);\n\n // console.log('rows', rows);\n\n body = _.map(rows, (literalRow) => {\n return drawRow(literalRow, config.border);\n }).join('');\n\n output = '\\r\\x1b[K';\n output += drawBorderJoin(columnWidthIndex, config.border);\n output += body;\n output += drawBorderBottom(columnWidthIndex, config.border);\n\n output = _.trimEnd(output);\n\n process.stdout.write(output);\n};\n\n/**\n * @param {Array} data\n * @param {Object} config\n * @returns {Array}\n */\nprepareData = (data, config) => {\n let rowHeightIndex,\n rows;\n\n rows = stringifyTableData(data);\n\n rows = truncateTableData(data, config);\n\n rowHeightIndex = calculateRowHeightIndex(rows, config);\n\n rows = mapDataUsingRowHeightIndex(rows, rowHeightIndex, config);\n rows = alignTableData(rows, config);\n rows = padTableData(rows, config);\n\n return rows;\n};\n\n/**\n * @param {Object} userConfig\n * @return {Object}\n */\nexport default (userConfig = {}) => {\n let columnWidthIndex,\n config,\n empty;\n\n config = makeStreamConfig(userConfig);\n\n columnWidthIndex = _.mapValues(config.columns, (column) => {\n return column.width + column.paddingLeft + column.paddingRight;\n });\n\n empty = true;\n\n return {\n /**\n * @param {string[]} row\n * @returns {undefined}\n */\n write: (row) => {\n if (row.length !== config.columnCount) {\n throw new Error('Row cell count does not match the config.columnCount.');\n }\n\n if (empty) {\n empty = false;\n\n return create(row, columnWidthIndex, config);\n } else {\n return append(row, columnWidthIndex, config);\n }\n }\n };\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/drawBorder.js.map b/tools/eslint/node_modules/table/dist/drawBorder.js.map deleted file mode 100644 index adbf9d7403d2f9..00000000000000 --- a/tools/eslint/node_modules/table/dist/drawBorder.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["drawBorder.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,IAAI,mBAAJ;IACI,yBADJ;IAEI,uBAFJ;IAGI,sBAHJ;;;;;;;;;;;;;;;AAkBA,QA+EI,UA/EJ,gBAAa,oBAAC,eAAD,EAAkB,KAAlB,EAA4B;AACrC,QAAI,gBAAJ;;AAEA,cAAU,mBAAM,eAAN,EAAuB,UAAC,IAAD,EAAU;AACvC,eAAO,sBAAS,MAAM,IAAf,EAAqB,IAArB,CAAP;AACH,KAFS,CAAV;;AAIA,cAAU,QAAQ,IAAR,CAAa,MAAM,IAAnB,CAAV;;AAEA,WAAO,MAAM,IAAN,GAAa,OAAb,GAAuB,MAAM,KAA7B,GAAqC,IAA5C;AACH,CAVD;;;;;;;;;;;;;;;AAyBA,QAuDI,aAvDJ,mBAAgB,uBAAC,eAAD,EAAkB,KAAlB,EAA4B;AACxC,WAAO,WAAW,eAAX,EAA4B;AAC/B,cAAM,MAAM,OADmB;AAE/B,eAAO,MAAM,QAFkB;AAG/B,cAAM,MAAM,OAHmB;AAI/B,cAAM,MAAM;AAJmB,KAA5B,CAAP;AAMH,CAPD;;;;;;;;;;;;;;;AAsBA,QAkCI,cAlCJ,oBAAiB,wBAAC,eAAD,EAAkB,KAAlB,EAA4B;AACzC,WAAO,WAAW,eAAX,EAA4B;AAC/B,cAAM,MAAM,QADmB;AAE/B,eAAO,MAAM,SAFkB;AAG/B,cAAM,MAAM,QAHmB;AAI/B,cAAM,MAAM;AAJmB,KAA5B,CAAP;AAMH,CAPD;;;;;;;;;;;;;;;AAsBA,QAaI,gBAbJ,sBAAmB,0BAAC,eAAD,EAAkB,KAAlB,EAA4B;AAC3C,WAAO,WAAW,eAAX,EAA4B;AAC/B,cAAM,MAAM,UADmB;AAE/B,eAAO,MAAM,WAFkB;AAG/B,cAAM,MAAM,UAHmB;AAI/B,cAAM,MAAM;AAJmB,KAA5B,CAAP;AAMH,CAPD;;QAUI,U,GAAA,U;QACA,a,GAAA,a;QACA,c,GAAA,c;QACA,gB,GAAA,gB","file":"drawBorder.js","sourcesContent":["import _ from 'lodash';\n\nlet drawBorder,\n drawBorderBottom,\n drawBorderJoin,\n drawBorderTop;\n\n/**\n * @typedef drawBorder~parts\n * @property {string} left\n * @property {string} right\n * @property {string} body\n * @property {string} join\n */\n\n/**\n * @param {number[]} columnSizeIndex\n * @param {drawBorder~parts} parts\n * @returns {string}\n */\ndrawBorder = (columnSizeIndex, parts) => {\n let columns;\n\n columns = _.map(columnSizeIndex, (size) => {\n return _.repeat(parts.body, size);\n });\n\n columns = columns.join(parts.join);\n\n return parts.left + columns + parts.right + '\\n';\n};\n\n/**\n * @typedef drawBorderTop~parts\n * @property {string} topLeft\n * @property {string} topRight\n * @property {string} topBody\n * @property {string} topJoin\n */\n\n/**\n * @param {number[]} columnSizeIndex\n * @param {drawBorderTop~parts} parts\n * @return {string}\n */\ndrawBorderTop = (columnSizeIndex, parts) => {\n return drawBorder(columnSizeIndex, {\n left: parts.topLeft,\n right: parts.topRight,\n body: parts.topBody,\n join: parts.topJoin\n });\n};\n\n/**\n * @typedef drawBorderJoin~parts\n * @property {string} joinLeft\n * @property {string} joinRight\n * @property {string} joinBody\n * @property {string} joinJoin\n */\n\n/**\n * @param {number[]} columnSizeIndex\n * @param {drawBorderJoin~parts} parts\n * @returns {string}\n */\ndrawBorderJoin = (columnSizeIndex, parts) => {\n return drawBorder(columnSizeIndex, {\n left: parts.joinLeft,\n right: parts.joinRight,\n body: parts.joinBody,\n join: parts.joinJoin\n });\n};\n\n/**\n * @typedef drawBorderBottom~parts\n * @property {string} topLeft\n * @property {string} topRight\n * @property {string} topBody\n * @property {string} topJoin\n */\n\n/**\n * @param {number[]} columnSizeIndex\n * @param {drawBorderBottom~parts} parts\n * @returns {string}\n */\ndrawBorderBottom = (columnSizeIndex, parts) => {\n return drawBorder(columnSizeIndex, {\n left: parts.bottomLeft,\n right: parts.bottomRight,\n body: parts.bottomBody,\n join: parts.bottomJoin\n });\n};\n\nexport {\n drawBorder,\n drawBorderTop,\n drawBorderJoin,\n drawBorderBottom\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/drawRow.js.map b/tools/eslint/node_modules/table/dist/drawRow.js.map deleted file mode 100644 index 5cef8565f4cc23..00000000000000 --- a/tools/eslint/node_modules/table/dist/drawRow.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["drawRow.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;kBAYe,UAAC,OAAD,EAAU,MAAV,EAAqB;AAChC,SAAO,OAAO,QAAP,GAAkB,QAAQ,IAAR,CAAa,OAAO,QAApB,CAAlB,GAAkD,OAAO,SAAzD,GAAqE,IAA5E;AACH,C","file":"drawRow.js","sourcesContent":["/**\n * @typedef {Object} drawRow~border\n * @property {string} bodyLeft\n * @property {string} bodyRight\n * @property {string} bodyJoin\n */\n\n/**\n * @param {number[]} columns\n * @param {drawRow~border} border\n * @return {string}\n */\nexport default (columns, border) => {\n return border.bodyLeft + columns.join(border.bodyJoin) + border.bodyRight + '\\n';\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/drawTable.js.map b/tools/eslint/node_modules/table/dist/drawTable.js.map deleted file mode 100644 index 8534c44da3fad4..00000000000000 --- a/tools/eslint/node_modules/table/dist/drawTable.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["drawTable.js"],"names":[],"mappings":";;;;;;;;;;AACA;;AAKA;;;;;;;;;;;;;;;kBAUe,UAAC,IAAD,EAAO,MAAP,EAAe,eAAf,EAAgC,YAAhC,EAA8C,kBAA9C,EAAqE;AAChF,QAAI,eAAJ;QACI,qBADJ;QAEI,iBAFJ;QAGI,kBAHJ;;AAKA,eAAW,KAAK,MAAhB;;AAEA,mBAAe,CAAf;;AAEA,aAAS,EAAT;;AAEA,QAAI,mBAAmB,YAAnB,EAAiC,QAAjC,CAAJ,EAAgD;AAC5C,kBAAU,+BAAc,eAAd,EAA+B,MAA/B,CAAV;AACH;;AAED,2BAAU,IAAV,EAAgB,UAAC,GAAD,EAAM,MAAN,EAAiB;AAC7B,kBAAU,uBAAQ,GAAR,EAAa,MAAb,CAAV;;AAEA,YAAI,CAAC,SAAL,EAAgB;AACZ,wBAAY,aAAa,YAAb,CAAZ;;AAEA;AACH;;AAED;;AAEA,YAAI,cAAc,CAAd,IAAmB,WAAW,WAAW,CAAzC,IAA8C,mBAAmB,YAAnB,EAAiC,QAAjC,CAAlD,EAA8F;AAC1F,sBAAU,gCAAe,eAAf,EAAgC,MAAhC,CAAV;AACH;AACJ,KAdD;;AAgBA,QAAI,mBAAmB,YAAnB,EAAiC,QAAjC,CAAJ,EAAgD;AAC5C,kBAAU,kCAAiB,eAAjB,EAAkC,MAAlC,CAAV;AACH;;AAED,WAAO,MAAP;AACH,C","file":"drawTable.js","sourcesContent":["import _ from 'lodash';\nimport {\n drawBorderTop,\n drawBorderJoin,\n drawBorderBottom\n} from './drawBorder';\nimport drawRow from './drawRow';\n\n/**\n * @param {Array} rows\n * @param {Object} border\n * @param {Array} columnSizeIndex\n * @param {Array} rowSpanIndex\n * @param {Function} drawHorizontalLine\n * @returns {string}\n */\nexport default (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine) => {\n let output,\n realRowIndex,\n rowCount,\n rowHeight;\n\n rowCount = rows.length;\n\n realRowIndex = 0;\n\n output = '';\n\n if (drawHorizontalLine(realRowIndex, rowCount)) {\n output += drawBorderTop(columnSizeIndex, border);\n }\n\n _.forEach(rows, (row, index0) => {\n output += drawRow(row, border);\n\n if (!rowHeight) {\n rowHeight = rowSpanIndex[realRowIndex];\n\n realRowIndex++;\n }\n\n rowHeight--;\n\n if (rowHeight === 0 && index0 !== rowCount - 1 && drawHorizontalLine(realRowIndex, rowCount)) {\n output += drawBorderJoin(columnSizeIndex, border);\n }\n });\n\n if (drawHorizontalLine(realRowIndex, rowCount)) {\n output += drawBorderBottom(columnSizeIndex, border);\n }\n\n return output;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/getBorderCharacters.js.map b/tools/eslint/node_modules/table/dist/getBorderCharacters.js.map deleted file mode 100644 index 36ba03bf8c00e4..00000000000000 --- a/tools/eslint/node_modules/table/dist/getBorderCharacters.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getBorderCharacters.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAyBe,UAAC,IAAD,EAAU;AACrB,QAAI,SAAS,WAAb,EAA0B;AACtB,eAAO;AACH,qBAAS,GADN;AAEH,qBAAS,GAFN;AAGH,qBAAS,GAHN;AAIH,sBAAU,GAJP;;AAMH,wBAAY,GANT;AAOH,wBAAY,GAPT;AAQH,wBAAY,GART;AASH,yBAAa,GATV;;AAWH,sBAAU,GAXP;AAYH,uBAAW,GAZR;AAaH,sBAAU,GAbP;;AAeH,sBAAU,GAfP;AAgBH,sBAAU,GAhBP;AAiBH,uBAAW,GAjBR;AAkBH,sBAAU;AAlBP,SAAP;AAoBH;;AAED,QAAI,SAAS,MAAb,EAAqB;AACjB,eAAO;AACH,qBAAS,GADN;AAEH,qBAAS,GAFN;AAGH,qBAAS,GAHN;AAIH,sBAAU,GAJP;;AAMH,wBAAY,GANT;AAOH,wBAAY,GAPT;AAQH,wBAAY,GART;AASH,yBAAa,GATV;;AAWH,sBAAU,GAXP;AAYH,uBAAW,GAZR;AAaH,sBAAU,GAbP;;AAeH,sBAAU,GAfP;AAgBH,sBAAU,GAhBP;AAiBH,uBAAW,GAjBR;AAkBH,sBAAU;AAlBP,SAAP;AAoBH;;AAED,QAAI,SAAS,OAAb,EAAsB;AAClB,eAAO;AACH,qBAAS,GADN;AAEH,qBAAS,GAFN;AAGH,qBAAS,GAHN;AAIH,sBAAU,GAJP;;AAMH,wBAAY,GANT;AAOH,wBAAY,GAPT;AAQH,wBAAY,GART;AASH,yBAAa,GATV;;AAWH,sBAAU,GAXP;AAYH,uBAAW,GAZR;AAaH,sBAAU,GAbP;;AAeH,sBAAU,GAfP;AAgBH,sBAAU,GAhBP;AAiBH,uBAAW,GAjBR;AAkBH,sBAAU;AAlBP,SAAP;AAoBH;;AAED,QAAI,SAAS,MAAb,EAAqB;AACjB,eAAO;AACH,qBAAS,EADN;AAEH,qBAAS,EAFN;AAGH,qBAAS,EAHN;AAIH,sBAAU,EAJP;;AAMH,wBAAY,EANT;AAOH,wBAAY,EAPT;AAQH,wBAAY,EART;AASH,yBAAa,EATV;;AAWH,sBAAU,EAXP;AAYH,uBAAW,EAZR;AAaH,sBAAU,EAbP;;AAeH,sBAAU,EAfP;AAgBH,sBAAU,EAhBP;AAiBH,uBAAW,EAjBR;AAkBH,sBAAU;AAlBP,SAAP;AAoBH;;AAED,UAAM,IAAI,KAAJ,CAAU,oCAAV,CAAN;AACH,C","file":"getBorderCharacters.js","sourcesContent":["/* eslint-disable sorting/sort-object-props */\n\n/**\n * @typedef border\n * @property {string} topBody\n * @property {string} topJoin\n * @property {string} topLeft\n * @property {string} topRight\n * @property {string} bottomBody\n * @property {string} bottomJoin\n * @property {string} bottomLeft\n * @property {string} bottomRight\n * @property {string} bodyLeft\n * @property {string} bodyRight\n * @property {string} bodyJoin\n * @property {string} joinBody\n * @property {string} joinLeft\n * @property {string} joinRight\n * @property {string} joinJoin\n */\n\n/**\n * @param {string} name\n * @returns {border}\n */\nexport default (name) => {\n if (name === 'honeywell') {\n return {\n topBody: '═',\n topJoin: '╤',\n topLeft: '╔',\n topRight: '╗',\n\n bottomBody: '═',\n bottomJoin: '╧',\n bottomLeft: '╚',\n bottomRight: '╝',\n\n bodyLeft: '║',\n bodyRight: '║',\n bodyJoin: '│',\n\n joinBody: '─',\n joinLeft: '╟',\n joinRight: '╢',\n joinJoin: '┼'\n };\n }\n\n if (name === 'norc') {\n return {\n topBody: '─',\n topJoin: '┬',\n topLeft: '┌',\n topRight: '┐',\n\n bottomBody: '─',\n bottomJoin: '┴',\n bottomLeft: '└',\n bottomRight: '┘',\n\n bodyLeft: '│',\n bodyRight: '│',\n bodyJoin: '│',\n\n joinBody: '─',\n joinLeft: '├',\n joinRight: '┤',\n joinJoin: '┼'\n };\n }\n\n if (name === 'ramac') {\n return {\n topBody: '-',\n topJoin: '+',\n topLeft: '+',\n topRight: '+',\n\n bottomBody: '-',\n bottomJoin: '+',\n bottomLeft: '+',\n bottomRight: '+',\n\n bodyLeft: '|',\n bodyRight: '|',\n bodyJoin: '|',\n\n joinBody: '-',\n joinLeft: '|',\n joinRight: '|',\n joinJoin: '|'\n };\n }\n\n if (name === 'void') {\n return {\n topBody: '',\n topJoin: '',\n topLeft: '',\n topRight: '',\n\n bottomBody: '',\n bottomJoin: '',\n bottomLeft: '',\n bottomRight: '',\n\n bodyLeft: '',\n bodyRight: '',\n bodyJoin: '',\n\n joinBody: '',\n joinLeft: '',\n joinRight: '',\n joinJoin: ''\n };\n }\n\n throw new Error('Unknown border template \"${name}\".');\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/index.js.map b/tools/eslint/node_modules/table/dist/index.js.map deleted file mode 100644 index dcf5ef8d344cad..00000000000000 --- a/tools/eslint/node_modules/table/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;AAAA;;;;AACA;;;;AACA;;;;;;QAGI,Y;QACA,mB","file":"index.js","sourcesContent":["import table from './table';\nimport createStream from './createStream';\nimport getBorderCharacters from './getBorderCharacters';\n\nexport {\n createStream,\n getBorderCharacters\n};\n\nexport default table;\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/makeConfig.js b/tools/eslint/node_modules/table/dist/makeConfig.js index 830ece67ef10ff..45ad8e899ce4be 100644 --- a/tools/eslint/node_modules/table/dist/makeConfig.js +++ b/tools/eslint/node_modules/table/dist/makeConfig.js @@ -29,7 +29,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @returns {Object} */ const makeBorder = function makeBorder() { - let border = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + let border = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return _lodash2.default.assign({}, (0, _getBorderCharacters2.default)('honeywell'), border); }; @@ -44,8 +44,8 @@ const makeBorder = function makeBorder() { * @returns {Object} */ const makeColumns = function makeColumns(rows) { - let columns = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - let columnDefault = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; + let columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let columnDefault = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; const maximumColumnWidthIndex = (0, _calculateMaximumColumnWidthIndex2.default)(rows); @@ -77,7 +77,7 @@ const makeColumns = function makeColumns(rows) { */ exports.default = function (rows) { - let userConfig = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + let userConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; (0, _validateConfig2.default)('config.json', userConfig); diff --git a/tools/eslint/node_modules/table/dist/makeConfig.js.map b/tools/eslint/node_modules/table/dist/makeConfig.js.map deleted file mode 100644 index 25c7051d2758e4..00000000000000 --- a/tools/eslint/node_modules/table/dist/makeConfig.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["makeConfig.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAI,mBAAJ;IACI,oBADJ;;;;;;;;AASA,aAAa,sBAAiB;AAAA,QAAhB,MAAgB,yDAAP,EAAO;;AAC1B,WAAO,sBAAS,EAAT,EAAa,mCAAoB,WAApB,CAAb,EAA+C,MAA/C,CAAP;AACH,CAFD;;;;;;;;;;;AAaA,cAAc,qBAAC,IAAD,EAA4C;AAAA,QAArC,OAAqC,yDAA3B,EAA2B;AAAA,QAAvB,aAAuB,yDAAP,EAAO;;AACtD,QAAI,gCAAJ;;AAEA,8BAA0B,gDAAiC,IAAjC,CAA1B;;AAEA,yBAAQ,KAAK,CAAL,EAAQ,MAAhB,EAAwB,UAAC,KAAD,EAAW;AAC/B,YAAI,2BAAc,QAAQ,KAAR,CAAd,CAAJ,EAAmC;AAC/B,oBAAQ,KAAR,IAAiB,EAAjB;AACH;;AAED,gBAAQ,KAAR,IAAiB,sBAAS;AACtB,uBAAW,MADW;AAEtB,mBAAO,wBAAwB,KAAxB,CAFe;AAGtB,sBAAU,KAHY;AAItB,sBAAU,QAJY;AAKtB,yBAAa,CALS;AAMtB,0BAAc;AANQ,SAAT,EAOd,aAPc,EAOC,QAAQ,KAAR,CAPD,CAAjB;AAQH,KAbD;;AAeA,WAAO,OAAP;AACH,CArBD;;;;;;;;;;;kBA+Be,UAAC,IAAD,EAA2B;AAAA,QAApB,UAAoB,yDAAP,EAAO;;AACtC,QAAI,eAAJ;;AAEA,kCAAe,UAAf;;AAEA,aAAS,yBAAY,UAAZ,CAAT;;AAEA,WAAO,MAAP,GAAgB,WAAW,OAAO,MAAlB,CAAhB;AACA,WAAO,OAAP,GAAiB,YAAY,IAAZ,EAAkB,OAAO,OAAzB,EAAkC,OAAO,aAAzC,CAAjB;;AAEA,QAAI,CAAC,OAAO,kBAAZ,EAAgC;;;;AAI5B,eAAO,kBAAP,GAA4B,YAAM;AAC9B,mBAAO,IAAP;AACH,SAFD;AAGH;;AAED,WAAO,MAAP;AACH,C","file":"makeConfig.js","sourcesContent":["import _ from 'lodash';\nimport getBorderCharacters from './getBorderCharacters';\nimport validateConfig from './validateConfig';\nimport calculateMaximumColumnWidthIndex from './calculateMaximumColumnWidthIndex';\n\nlet makeBorder,\n makeColumns;\n\n/**\n * Merges user provided border characters with the default border (\"honeywell\") characters.\n *\n * @param {Object} border\n * @returns {Object}\n */\nmakeBorder = (border = {}) => {\n return _.assign({}, getBorderCharacters('honeywell'), border);\n};\n\n/**\n * Creates a configuration for every column using default\n * values for the missing configuration properties.\n *\n * @param {Array[]} rows\n * @param {Object} columns\n * @param {Object} columnDefault\n * @returns {Object}\n */\nmakeColumns = (rows, columns = {}, columnDefault = {}) => {\n let maximumColumnWidthIndex;\n\n maximumColumnWidthIndex = calculateMaximumColumnWidthIndex(rows);\n\n _.times(rows[0].length, (index) => {\n if (_.isUndefined(columns[index])) {\n columns[index] = {};\n }\n\n columns[index] = _.assign({\n alignment: 'left',\n width: maximumColumnWidthIndex[index],\n wrapWord: false,\n truncate: Infinity,\n paddingLeft: 1,\n paddingRight: 1\n }, columnDefault, columns[index]);\n });\n\n return columns;\n};\n\n/**\n * Makes a new configuration object out of the userConfig object\n * using default values for the missing configuration properties.\n *\n * @param {Array[]} rows\n * @param {Object} userConfig\n * @returns {Object}\n */\nexport default (rows, userConfig = {}) => {\n let config;\n\n validateConfig(userConfig);\n\n config = _.cloneDeep(userConfig);\n\n config.border = makeBorder(config.border);\n config.columns = makeColumns(rows, config.columns, config.columnDefault);\n\n if (!config.drawHorizontalLine) {\n /**\n * @returns {boolean}\n */\n config.drawHorizontalLine = () => {\n return true;\n };\n }\n\n return config;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/makeStreamConfig.js b/tools/eslint/node_modules/table/dist/makeStreamConfig.js index 06e212adbfe498..1482dae079ec0d 100644 --- a/tools/eslint/node_modules/table/dist/makeStreamConfig.js +++ b/tools/eslint/node_modules/table/dist/makeStreamConfig.js @@ -25,7 +25,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @returns {Object} */ const makeBorder = function makeBorder() { - let border = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + let border = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return _lodash2.default.assign({}, (0, _getBorderCharacters2.default)('honeywell'), border); }; @@ -40,8 +40,8 @@ const makeBorder = function makeBorder() { * @returns {Object} */ const makeColumns = function makeColumns(columnCount) { - let columns = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - let columnDefault = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; + let columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let columnDefault = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; _lodash2.default.times(columnCount, index => { if (_lodash2.default.isUndefined(columns[index])) { @@ -86,7 +86,7 @@ const makeColumns = function makeColumns(columnCount) { */ exports.default = function () { - let userConfig = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + let userConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; (0, _validateConfig2.default)('streamConfig.json', userConfig); diff --git a/tools/eslint/node_modules/table/dist/makeStreamConfig.js.map b/tools/eslint/node_modules/table/dist/makeStreamConfig.js.map deleted file mode 100644 index c3c0437ec1e42a..00000000000000 --- a/tools/eslint/node_modules/table/dist/makeStreamConfig.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["makeStreamConfig.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA;;;;AACA;;;;;;AAEA,IAAI,mBAAJ;IACI,oBADJ;;;;;;;;AASA,aAAa,sBAAiB;AAAA,QAAhB,MAAgB,yDAAP,EAAO;;AAC1B,WAAO,sBAAS,EAAT,EAAa,mCAAoB,WAApB,CAAb,EAA+C,MAA/C,CAAP;AACH,CAFD;;;;;;;;;;;AAaA,cAAc,qBAAC,WAAD,EAAmD;AAAA,QAArC,OAAqC,yDAA3B,EAA2B;AAAA,QAAvB,aAAuB,yDAAP,EAAO;;AAC7D,yBAAQ,WAAR,EAAqB,UAAC,KAAD,EAAW;AAC5B,YAAI,2BAAc,QAAQ,KAAR,CAAd,CAAJ,EAAmC;AAC/B,oBAAQ,KAAR,IAAiB,EAAjB;AACH;;AAED,gBAAQ,KAAR,IAAiB,sBAAS;AACtB,uBAAW,MADW;;AAGtB,sBAAU,KAHY;AAItB,sBAAU,QAJY;AAKtB,yBAAa,CALS;AAMtB,0BAAc;AANQ,SAAT,EAOd,aAPc,EAOC,QAAQ,KAAR,CAPD,CAAjB;AAQH,KAbD;;AAeA,WAAO,OAAP;AACH,CAjBD;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA2Ce,YAAqB;AAAA,QAApB,UAAoB,yDAAP,EAAO;;AAChC,QAAI,eAAJ;;AAEA,wCAAqB,UAArB;;AAEA,aAAS,yBAAY,UAAZ,CAAT;;AAEA,QAAI,CAAC,OAAO,aAAR,IAAyB,CAAC,OAAO,aAAP,CAAqB,KAAnD,EAA0D;AACtD,cAAM,IAAI,KAAJ,CAAU,iEAAV,CAAN;AACH;;AAED,QAAI,CAAC,OAAO,WAAZ,EAAyB;AACrB,cAAM,IAAI,KAAJ,CAAU,kCAAV,CAAN;AACH;;AAED,WAAO,MAAP,GAAgB,WAAW,OAAO,MAAlB,CAAhB;AACA,WAAO,OAAP,GAAiB,YAAY,OAAO,WAAnB,EAAgC,OAAO,OAAvC,EAAgD,OAAO,aAAvD,CAAjB;;AAEA,WAAO,MAAP;AACH,C","file":"makeStreamConfig.js","sourcesContent":["import _ from 'lodash';\nimport getBorderCharacters from './getBorderCharacters';\nimport validateStreamConfig from './validateStreamConfig';\n\nlet makeBorder,\n makeColumns;\n\n/**\n * Merges user provided border characters with the default border (\"honeywell\") characters.\n *\n * @param {Object} border\n * @returns {Object}\n */\nmakeBorder = (border = {}) => {\n return _.assign({}, getBorderCharacters('honeywell'), border);\n};\n\n/**\n * Creates a configuration for every column using default\n * values for the missing configuration properties.\n *\n * @param {number} columnCount\n * @param {Object} columns\n * @param {Object} columnDefault\n * @returns {Object}\n */\nmakeColumns = (columnCount, columns = {}, columnDefault = {}) => {\n _.times(columnCount, (index) => {\n if (_.isUndefined(columns[index])) {\n columns[index] = {};\n }\n\n columns[index] = _.assign({\n alignment: 'left',\n // width: columnDefault.width,\n wrapWord: false,\n truncate: Infinity,\n paddingLeft: 1,\n paddingRight: 1\n }, columnDefault, columns[index]);\n });\n\n return columns;\n};\n\n/**\n * @typedef {Object} columnConfig\n * @property {string} alignment\n * @property {number} width\n * @property {number} truncate\n * @property {number} paddingLeft\n * @property {number} paddingRight\n */\n\n/**\n * @typedef {Object} streamConfig\n * @property {columnConfig} columnDefault\n * @property {Object} border\n * @property {columnConfig[]}\n * @property {number} columnCount Number of columns in the table (required).\n */\n\n/**\n * Makes a new configuration object out of the userConfig object\n * using default values for the missing configuration properties.\n *\n * @param {streamConfig} userConfig\n * @returns {Object}\n */\nexport default (userConfig = {}) => {\n let config;\n\n validateStreamConfig(userConfig);\n\n config = _.cloneDeep(userConfig);\n\n if (!config.columnDefault || !config.columnDefault.width) {\n throw new Error('Must provide config.columnDefault.width when creating a stream.');\n }\n\n if (!config.columnCount) {\n throw new Error('Must provide config.columnCount.');\n }\n\n config.border = makeBorder(config.border);\n config.columns = makeColumns(config.columnCount, config.columns, config.columnDefault);\n\n return config;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/mapDataUsingRowHeightIndex.js.map b/tools/eslint/node_modules/table/dist/mapDataUsingRowHeightIndex.js.map deleted file mode 100644 index 4b11dec7deceb3..00000000000000 --- a/tools/eslint/node_modules/table/dist/mapDataUsingRowHeightIndex.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["mapDataUsingRowHeightIndex.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA;;;;AACA;;;;;;;;;;;;;kBAQe,UAAC,YAAD,EAAe,cAAf,EAA+B,MAA/B,EAA0C;AACrD,QAAI,mBAAJ;QACI,mBADJ;;AAGA,iBAAa,aAAa,CAAb,EAAgB,MAA7B;;;;AAIA,iBAAa,mBAAM,YAAN,EAAoB,UAAC,KAAD,EAAQ,MAAR,EAAmB;AAChD,YAAI,kBAAJ;;AAEA,oBAAY,mBAAM,MAAM,eAAe,MAAf,CAAN,CAAN,EAAqC,YAAM;AACnD,mBAAO,oBAAO,MAAM,UAAN,CAAP,EAA0B,EAA1B,CAAP;AACH,SAFW,CAAZ;;;;;;;;AAUA,+BAAU,KAAV,EAAiB,UAAC,KAAD,EAAQ,MAAR,EAAmB;AAChC,gBAAI,qBAAJ;;AAEA,gBAAI,OAAO,OAAP,CAAe,MAAf,EAAuB,QAA3B,EAAqC;AACjC,+BAAe,wBAAS,KAAT,EAAgB,OAAO,OAAP,CAAe,MAAf,EAAuB,KAAvC,CAAf;AACH,aAFD,MAEO;AACH,+BAAe,0BAAW,KAAX,EAAkB,OAAO,OAAP,CAAe,MAAf,EAAuB,KAAzC,CAAf;AACH;;;;AAID,mCAAU,YAAV,EAAwB,UAAC,IAAD,EAAO,MAAP,EAAkB;;;AAGtC,0BAAU,MAAV,EAAkB,MAAlB,IAA4B,IAA5B;AACH,aAJD;AAKH,SAhBD;;AAkBA,eAAO,SAAP;AACH,KAhCY,CAAb;;AAkCA,WAAO,uBAAU,UAAV,CAAP;AACH,C","file":"mapDataUsingRowHeightIndex.js","sourcesContent":["import _ from 'lodash';\nimport wrapString from './wrapString';\nimport wrapWord from './wrapWord';\n\n/**\n * @param {Array} unmappedRows\n * @param {number[]} rowHeightIndex\n * @param {Object} config\n * @return {Array}\n */\nexport default (unmappedRows, rowHeightIndex, config) => {\n let mappedRows,\n tableWidth;\n\n tableWidth = unmappedRows[0].length;\n\n // console.log('unmappedRows', unmappedRows, 'rowHeightIndex', rowHeightIndex, 'config', config, 'tableWidth', tableWidth);\n\n mappedRows = _.map(unmappedRows, (cells, index0) => {\n let rowHeight;\n\n rowHeight = _.map(Array(rowHeightIndex[index0]), () => {\n return _.fill(Array(tableWidth), '');\n });\n\n // console.log('rowHeight', rowHeight);\n\n // rowHeight\n // [{row index within rowSaw; index2}]\n // [{cell index within a virtual row; index1}]\n\n _.forEach(cells, (value, index1) => {\n let chunkedValue;\n\n if (config.columns[index1].wrapWord) {\n chunkedValue = wrapWord(value, config.columns[index1].width);\n } else {\n chunkedValue = wrapString(value, config.columns[index1].width);\n }\n\n // console.log('chunkedValue', chunkedValue.length, 'rowHeight', rowHeight.length);\n\n _.forEach(chunkedValue, (part, index2) => {\n // console.log(rowHeight[index2]);\n\n rowHeight[index2][index1] = part;\n });\n });\n\n return rowHeight;\n });\n\n return _.flatten(mappedRows);\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/padTableData.js.map b/tools/eslint/node_modules/table/dist/padTableData.js.map deleted file mode 100644 index e900566a567aa3..00000000000000 --- a/tools/eslint/node_modules/table/dist/padTableData.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["padTableData.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;kBAOe,UAAC,IAAD,EAAO,MAAP,EAAkB;AAC7B,WAAO,mBAAM,IAAN,EAAY,UAAC,KAAD,EAAW;AAC1B,eAAO,mBAAM,KAAN,EAAa,UAAC,KAAD,EAAQ,MAAR,EAAmB;AACnC,gBAAI,eAAJ;;AAEA,qBAAS,OAAO,OAAP,CAAe,MAAf,CAAT;;AAEA,mBAAO,sBAAS,GAAT,EAAc,OAAO,WAArB,IAAoC,KAApC,GAA4C,sBAAS,GAAT,EAAc,OAAO,YAArB,CAAnD;AACH,SANM,CAAP;AAOH,KARM,CAAP;AASH,C","file":"padTableData.js","sourcesContent":["import _ from 'lodash';\n\n/**\n * @param {table~row[]} rows\n * @param {Object} config\n * @return {table~row[]}\n */\nexport default (rows, config) => {\n return _.map(rows, (cells) => {\n return _.map(cells, (value, index1) => {\n let column;\n\n column = config.columns[index1];\n\n return _.repeat(' ', column.paddingLeft) + value + _.repeat(' ', column.paddingRight);\n });\n });\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/stringifyTableData.js.map b/tools/eslint/node_modules/table/dist/stringifyTableData.js.map deleted file mode 100644 index c38e20fa838218..00000000000000 --- a/tools/eslint/node_modules/table/dist/stringifyTableData.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["stringifyTableData.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;kBAQe,UAAC,IAAD,EAAU;AACrB,WAAO,mBAAM,IAAN,EAAY,UAAC,KAAD,EAAW;AAC1B,eAAO,mBAAM,KAAN,EAAa,MAAb,CAAP;AACH,KAFM,CAAP;AAGH,C","file":"stringifyTableData.js","sourcesContent":["import _ from 'lodash';\n\n/**\n * Casts all cell values to a string.\n *\n * @param {table~row[]} rows\n * @return {table~row[]}\n */\nexport default (rows) => {\n return _.map(rows, (cells) => {\n return _.map(cells, String);\n });\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/table.js b/tools/eslint/node_modules/table/dist/table.js index 9066efaee82854..b62ffd2b747c8f 100644 --- a/tools/eslint/node_modules/table/dist/table.js +++ b/tools/eslint/node_modules/table/dist/table.js @@ -109,7 +109,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @returns {string} */ exports.default = function (data) { - let userConfig = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + let userConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; let rows; diff --git a/tools/eslint/node_modules/table/dist/table.js.map b/tools/eslint/node_modules/table/dist/table.js.map deleted file mode 100644 index 843d2e105c9f17..00000000000000 --- a/tools/eslint/node_modules/table/dist/table.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["table.js"],"names":[],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgEe,UAAC,IAAD,EAA2B;AAAA,MAApB,UAAoB,yDAAP,EAAO;;AACtC,MAAI,uBAAJ;MACI,eADJ;MAEI,uBAFJ;MAGI,aAHJ;;AAKA,mCAAkB,IAAlB;;AAEA,SAAO,kCAAmB,IAAnB,CAAP;;AAEA,WAAS,0BAAW,IAAX,EAAiB,UAAjB,CAAT;;AAEA,SAAO,iCAAkB,IAAlB,EAAwB,MAAxB,CAAP;;AAEA,mBAAiB,uCAAwB,IAAxB,EAA8B,MAA9B,CAAjB;;AAEA,SAAO,0CAA2B,IAA3B,EAAiC,cAAjC,EAAiD,MAAjD,CAAP;AACA,SAAO,8BAAe,IAAf,EAAqB,MAArB,CAAP;AACA,SAAO,4BAAa,IAAb,EAAmB,MAAnB,CAAP;;AAEA,mBAAiB,uCAAwB,KAAK,CAAL,CAAxB,CAAjB;;AAEA,SAAO,yBAAU,IAAV,EAAgB,OAAO,MAAvB,EAA+B,cAA/B,EAA+C,cAA/C,EAA+D,OAAO,kBAAtE,CAAP;AACH,C","file":"table.js","sourcesContent":["import drawTable from './drawTable';\nimport calculateCellWidthIndex from './calculateCellWidthIndex';\nimport makeConfig from './makeConfig';\nimport calculateRowHeightIndex from './calculateRowHeightIndex';\nimport mapDataUsingRowHeightIndex from './mapDataUsingRowHeightIndex';\nimport alignTableData from './alignTableData';\nimport padTableData from './padTableData';\nimport validateTableData from './validateTableData';\nimport stringifyTableData from './stringifyTableData';\nimport truncateTableData from './truncateTableData';\n\n/**\n * @typedef {string} table~cell\n */\n\n/**\n * @typedef {table~cell[]} table~row\n */\n\n/**\n * @typedef {Object} table~columns\n * @property {string} alignment Cell content alignment (enum: left, center, right) (default: left).\n * @property {number} width Column width (default: auto).\n * @property {number} truncate Number of characters are which the content will be truncated (default: Infinity).\n * @property {number} paddingLeft Cell content padding width left (default: 1).\n * @property {number} paddingRight Cell content padding width right (default: 1).\n */\n\n/**\n * @typedef {Object} table~border\n * @property {string} topBody\n * @property {string} topJoin\n * @property {string} topLeft\n * @property {string} topRight\n * @property {string} bottomBody\n * @property {string} bottomJoin\n * @property {string} bottomLeft\n * @property {string} bottomRight\n * @property {string} bodyLeft\n * @property {string} bodyRight\n * @property {string} bodyJoin\n * @property {string} joinBody\n * @property {string} joinLeft\n * @property {string} joinRight\n * @property {string} joinJoin\n */\n\n/**\n * Used to tell whether to draw a horizontal line.\n * This callback is called for each non-content line of the table.\n * The default behavior is to always return true.\n *\n * @typedef {Function} drawHorizontalLine\n * @param {number} index\n * @param {number} size\n * @return {boolean}\n */\n\n/**\n * @typedef {Object} table~config\n * @property {table~border} border\n * @property {table~columns[]} columns Column specific configuration.\n * @property {table~columns} columnDefault Default values for all columns. Column specific settings overwrite the default values.\n * @property {table~drawHorizontalLine} drawHorizontalLine\n */\n\n/**\n * Generates a text table.\n *\n * @param {table~row[]} data\n * @param {table~config} userConfig\n * @return {string}\n */\nexport default (data, userConfig = {}) => {\n let cellWidthIndex,\n config,\n rowHeightIndex,\n rows;\n\n validateTableData(data);\n\n rows = stringifyTableData(data);\n\n config = makeConfig(rows, userConfig);\n\n rows = truncateTableData(data, config);\n\n rowHeightIndex = calculateRowHeightIndex(rows, config);\n\n rows = mapDataUsingRowHeightIndex(rows, rowHeightIndex, config);\n rows = alignTableData(rows, config);\n rows = padTableData(rows, config);\n\n cellWidthIndex = calculateCellWidthIndex(rows[0]);\n\n return drawTable(rows, config.border, cellWidthIndex, rowHeightIndex, config.drawHorizontalLine);\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/truncateTableData.js.map b/tools/eslint/node_modules/table/dist/truncateTableData.js.map deleted file mode 100644 index dca05c3b51cdce..00000000000000 --- a/tools/eslint/node_modules/table/dist/truncateTableData.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["truncateTableData.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;kBAQe,UAAC,IAAD,EAAO,MAAP,EAAkB;AAC7B,WAAO,mBAAM,IAAN,EAAY,UAAC,KAAD,EAAW;AAC1B,eAAO,mBAAM,KAAN,EAAa,UAAC,OAAD,EAAU,KAAV,EAAoB;AACpC,mBAAO,wBAAW,OAAX,EAAoB;AACvB,wBAAQ,OAAO,OAAP,CAAe,KAAf,EAAsB;AADP,aAApB,CAAP;AAGH,SAJM,CAAP;AAKH,KANM,CAAP;AAOH,C","file":"truncateTableData.js","sourcesContent":["import _ from 'lodash';\n\n/**\n * @todo Make it work with ASCII content.\n * @param {table~row[]} rows\n * @param {Object} config\n * @return {table~row[]}\n */\nexport default (rows, config) => {\n return _.map(rows, (cells) => {\n return _.map(cells, (content, index) => {\n return _.truncate(content, {\n length: config.columns[index].truncate\n });\n });\n });\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/validateConfig.js b/tools/eslint/node_modules/table/dist/validateConfig.js index 965ddc5db4654c..caba30134de2e6 100644 --- a/tools/eslint/node_modules/table/dist/validateConfig.js +++ b/tools/eslint/node_modules/table/dist/validateConfig.js @@ -1,62 +1,756 @@ 'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _ajv = require('ajv'); - -var _ajv2 = _interopRequireDefault(_ajv); - -var _ajvKeywords = require('ajv-keywords'); - -var _ajvKeywords2 = _interopRequireDefault(_ajvKeywords); - -var _config = require('./schemas/config.json'); - -var _config2 = _interopRequireDefault(_config); - -var _streamConfig = require('./schemas/streamConfig.json'); - -var _streamConfig2 = _interopRequireDefault(_streamConfig); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const ajv = new _ajv2.default({ - allErrors: true -}); - -(0, _ajvKeywords2.default)(ajv, 'typeof'); - -ajv.addSchema(_config2.default); -ajv.addSchema(_streamConfig2.default); - -/** - * @param {string} schemaId - * @param {formatData~config} config - * @returns {undefined} - */ - -exports.default = function (schemaId) { - let config = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - - if (!ajv.validate(schemaId, config)) { - const errors = ajv.errors.map(error => { - return { - dataPath: error.dataPath, - message: error.message, - params: error.params, - schemaPath: error.schemaPath +var equal = require('ajv/lib/compile/equal'); +var validate = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + var refVal = []; + var refVal1 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || validate.schema.properties[key0]); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + if (data.topBody !== undefined) { + var errs_1 = errors; + if (!refVal2(data.topBody, (dataPath || '') + '.topBody', data, 'topBody', rootData)) { + if (vErrors === null) vErrors = refVal2.errors; + else vErrors = vErrors.concat(refVal2.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.topJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.topJoin, (dataPath || '') + '.topJoin', data, 'topJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.topLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.topLeft, (dataPath || '') + '.topLeft', data, 'topLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.topRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.topRight, (dataPath || '') + '.topRight', data, 'topRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomBody !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomBody, (dataPath || '') + '.bottomBody', data, 'bottomBody', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomJoin, (dataPath || '') + '.bottomJoin', data, 'bottomJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomLeft, (dataPath || '') + '.bottomLeft', data, 'bottomLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomRight, (dataPath || '') + '.bottomRight', data, 'bottomRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bodyLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bodyLeft, (dataPath || '') + '.bodyLeft', data, 'bodyLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bodyRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bodyRight, (dataPath || '') + '.bodyRight', data, 'bodyRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bodyJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bodyJoin, (dataPath || '') + '.bodyJoin', data, 'bodyJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinBody !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinBody, (dataPath || '') + '.joinBody', data, 'joinBody', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinLeft, (dataPath || '') + '.joinLeft', data, 'joinLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinRight, (dataPath || '') + '.joinRight', data, 'joinRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinJoin, (dataPath || '') + '.joinJoin', data, 'joinJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal1.schema = { + "type": "object", + "properties": { + "topBody": { + "$ref": "#/definitions/border" + }, + "topJoin": { + "$ref": "#/definitions/border" + }, + "topLeft": { + "$ref": "#/definitions/border" + }, + "topRight": { + "$ref": "#/definitions/border" + }, + "bottomBody": { + "$ref": "#/definitions/border" + }, + "bottomJoin": { + "$ref": "#/definitions/border" + }, + "bottomLeft": { + "$ref": "#/definitions/border" + }, + "bottomRight": { + "$ref": "#/definitions/border" + }, + "bodyLeft": { + "$ref": "#/definitions/border" + }, + "bodyRight": { + "$ref": "#/definitions/border" + }, + "bodyJoin": { + "$ref": "#/definitions/border" + }, + "joinBody": { + "$ref": "#/definitions/border" + }, + "joinLeft": { + "$ref": "#/definitions/border" + }, + "joinRight": { + "$ref": "#/definitions/border" + }, + "joinJoin": { + "$ref": "#/definitions/border" + } + }, + "additionalProperties": false + }; + refVal1.errors = null; + refVal[1] = refVal1; + var refVal2 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if (typeof data !== "string") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'string' + }, + message: 'should be string' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal2.schema = { + "type": "string" + }; + refVal2.errors = null; + refVal[2] = refVal2; + var refVal3 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || pattern0.test(key0)); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + for (var key0 in data) { + if (pattern0.test(key0)) { + var errs_1 = errors; + if (!refVal4(data[key0], (dataPath || '') + '[\'' + key0 + '\']', data, key0, rootData)) { + if (vErrors === null) vErrors = refVal4.errors; + else vErrors = vErrors.concat(refVal4.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal3.schema = { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "$ref": "#/definitions/column" + } + }, + "additionalProperties": false + }; + refVal3.errors = null; + refVal[3] = refVal3; + var refVal4 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || validate.schema.properties[key0]); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + var data1 = data.alignment; + if (data1 !== undefined) { + var errs_1 = errors; + var schema1 = validate.schema.properties.alignment.enum; + var valid1; + valid1 = false; + for (var i1 = 0; i1 < schema1.length; i1++) + if (equal(data1, schema1[i1])) { + valid1 = true; + break; + } + if (!valid1) { + var err = { + keyword: 'enum', + dataPath: (dataPath || '') + '.alignment', + schemaPath: '#/properties/alignment/enum', + params: { + allowedValues: schema1 + }, + message: 'should be equal to one of the allowed values' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + if (typeof data1 !== "string") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.alignment', + schemaPath: '#/properties/alignment/type', + params: { + type: 'string' + }, + message: 'should be string' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.width !== undefined) { + var errs_1 = errors; + if (typeof data.width !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.width', + schemaPath: '#/properties/width/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.wrapWord !== undefined) { + var errs_1 = errors; + if (typeof data.wrapWord !== "boolean") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.wrapWord', + schemaPath: '#/properties/wrapWord/type', + params: { + type: 'boolean' + }, + message: 'should be boolean' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.truncate !== undefined) { + var errs_1 = errors; + if (typeof data.truncate !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.truncate', + schemaPath: '#/properties/truncate/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.paddingLeft !== undefined) { + var errs_1 = errors; + if (typeof data.paddingLeft !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.paddingLeft', + schemaPath: '#/properties/paddingLeft/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.paddingRight !== undefined) { + var errs_1 = errors; + if (typeof data.paddingRight !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.paddingRight', + schemaPath: '#/properties/paddingRight/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal4.schema = { + "type": "object", + "properties": { + "alignment": { + "type": "string", + "enum": ["left", "right", "center"] + }, + "width": { + "type": "number" + }, + "wrapWord": { + "type": "boolean" + }, + "truncate": { + "type": "number" + }, + "paddingLeft": { + "type": "number" + }, + "paddingRight": { + "type": "number" + } + }, + "additionalProperties": false + }; + refVal4.errors = null; + refVal[4] = refVal4; + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || key0 == 'border' || key0 == 'columns' || key0 == 'columnDefault' || key0 == 'drawHorizontalLine'); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + if (data.border !== undefined) { + var errs_1 = errors; + if (!refVal1(data.border, (dataPath || '') + '.border', data, 'border', rootData)) { + if (vErrors === null) vErrors = refVal1.errors; + else vErrors = vErrors.concat(refVal1.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.columns !== undefined) { + var errs_1 = errors; + if (!refVal3(data.columns, (dataPath || '') + '.columns', data, 'columns', rootData)) { + if (vErrors === null) vErrors = refVal3.errors; + else vErrors = vErrors.concat(refVal3.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.columnDefault !== undefined) { + var errs_1 = errors; + if (!refVal[4](data.columnDefault, (dataPath || '') + '.columnDefault', data, 'columnDefault', rootData)) { + if (vErrors === null) vErrors = refVal[4].errors; + else vErrors = vErrors.concat(refVal[4].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.drawHorizontalLine !== undefined) { + var errs_1 = errors; + var errs__1 = errors; + var valid1; + if (!(typeof data.drawHorizontalLine == "function")) { + if (errs__1 == errors) { + var err = { + keyword: 'typeof', + dataPath: (dataPath || '') + '.drawHorizontalLine', + schemaPath: '#/properties/drawHorizontalLine/typeof', + params: { + keyword: 'typeof' + }, + message: 'should pass "typeof" keyword validation' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } else { + for (var i1 = errs__1; i1 < errors; i1++) { + var ruleErr1 = vErrors[i1]; + if (ruleErr1.dataPath === undefined) { + ruleErr1.dataPath = (dataPath || '') + '.drawHorizontalLine'; + } + if (ruleErr1.schemaPath === undefined) { + ruleErr1.schemaPath = "#/properties/drawHorizontalLine/typeof"; + } + } + } + } + var valid1 = errors === errs_1; + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' }; - }); - - /* eslint-disable no-console */ - console.log('config', config); - console.log('errors', errors); - /* eslint-enable no-console */ - - throw new Error('Invalid config.'); + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; +})(); +validate.schema = { + "id": "config.json", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "border": { + "$ref": "#/definitions/borders" + }, + "columns": { + "$ref": "#/definitions/columns" + }, + "columnDefault": { + "$ref": "#/definitions/column" + }, + "drawHorizontalLine": { + "typeof": "function" + } + }, + "additionalProperties": false, + "definitions": { + "columns": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "$ref": "#/definitions/column" + } + }, + "additionalProperties": false + }, + "column": { + "type": "object", + "properties": { + "alignment": { + "type": "string", + "enum": ["left", "right", "center"] + }, + "width": { + "type": "number" + }, + "wrapWord": { + "type": "boolean" + }, + "truncate": { + "type": "number" + }, + "paddingLeft": { + "type": "number" + }, + "paddingRight": { + "type": "number" + } + }, + "additionalProperties": false + }, + "borders": { + "type": "object", + "properties": { + "topBody": { + "$ref": "#/definitions/border" + }, + "topJoin": { + "$ref": "#/definitions/border" + }, + "topLeft": { + "$ref": "#/definitions/border" + }, + "topRight": { + "$ref": "#/definitions/border" + }, + "bottomBody": { + "$ref": "#/definitions/border" + }, + "bottomJoin": { + "$ref": "#/definitions/border" + }, + "bottomLeft": { + "$ref": "#/definitions/border" + }, + "bottomRight": { + "$ref": "#/definitions/border" + }, + "bodyLeft": { + "$ref": "#/definitions/border" + }, + "bodyRight": { + "$ref": "#/definitions/border" + }, + "bodyJoin": { + "$ref": "#/definitions/border" + }, + "joinBody": { + "$ref": "#/definitions/border" + }, + "joinLeft": { + "$ref": "#/definitions/border" + }, + "joinRight": { + "$ref": "#/definitions/border" + }, + "joinJoin": { + "$ref": "#/definitions/border" + } + }, + "additionalProperties": false + }, + "border": { + "type": "string" + } } }; - -module.exports = exports['default']; \ No newline at end of file +validate.errors = null; +module.exports = validate; \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/validateConfig.js.map b/tools/eslint/node_modules/table/dist/validateConfig.js.map deleted file mode 100644 index ad5e82b80bd67e..00000000000000 --- a/tools/eslint/node_modules/table/dist/validateConfig.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["validateConfig.js"],"names":[],"mappings":";;;;;;AAAA;;;;AACA;;;;;;;;;;;;;;;;;;;kBAce,YAAiB;AAAA,QAAhB,MAAgB,yDAAP,EAAO;;AAC5B,QAAI,eAAJ;;AAEA,aAAS,aAAI,cAAJ,CAAmB,MAAnB,mBAAT;;AAEA,QAAI,CAAC,OAAO,KAAZ,EAAmB;;AAEf,gBAAQ,GAAR,CAAY,QAAZ,EAAsB,MAAtB;AACA,gBAAQ,GAAR,CAAY,OAAZ,EAAqB;AACjB,qBAAS,OAAO,KAAP,CAAa,OADL;AAEjB,oBAAQ,OAAO,KAAP,CAAa,MAFJ;AAGjB,sBAAU,OAAO,KAAP,CAAa,QAHN;AAIjB,wBAAY,OAAO,KAAP,CAAa;AAJR,SAArB;;;AAQA,cAAM,IAAI,KAAJ,CAAU,iBAAV,CAAN;AACH;AACJ,C","file":"validateConfig.js","sourcesContent":["import schema from './schemas/config.json';\nimport tv4 from 'tv4';\n\n/**\n * @typedef {string} cell\n */\n\n/**\n * @typedef {cell[]} validateData~column\n */\n\n/**\n * @param {formatData~config} config\n * @returns {undefined}\n */\nexport default (config = {}) => {\n let result;\n\n result = tv4.validateResult(config, schema);\n\n if (!result.valid) {\n /* eslint-disable no-console */\n console.log('config', config);\n console.log('error', {\n message: result.error.message,\n params: result.error.params,\n dataPath: result.error.dataPath,\n schemaPath: result.error.schemaPath\n });\n /* eslint-enable no-console */\n\n throw new Error('Invalid config.');\n }\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/validateStreamConfig.js b/tools/eslint/node_modules/table/dist/validateStreamConfig.js index e5cc85e3046282..09ea2aac925158 100644 --- a/tools/eslint/node_modules/table/dist/validateStreamConfig.js +++ b/tools/eslint/node_modules/table/dist/validateStreamConfig.js @@ -1,53 +1,742 @@ 'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _streamConfig = require('./schemas/streamConfig.json'); - -var _streamConfig2 = _interopRequireDefault(_streamConfig); - -var _tv = require('tv4'); - -var _tv2 = _interopRequireDefault(_tv); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * @typedef {string} cell - */ - -/** - * @typedef {cell[]} validateData~column - */ - -/** - * @param {formatData~config} config - * @returns {undefined} - */ - -exports.default = function () { - var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - var result = void 0; - - result = _tv2.default.validateResult(config, _streamConfig2.default); - - if (!result.valid) { - /* eslint-disable no-console */ - console.log('config', config); - console.log('error', { - message: result.error.message, - params: result.error.params, - dataPath: result.error.dataPath, - schemaPath: result.error.schemaPath - }); - /* eslint-enable no-console */ - - throw new Error('Invalid config.'); +var equal = require('ajv/lib/compile/equal'); +var validate = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + var refVal = []; + var refVal1 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || validate.schema.properties[key0]); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + if (data.topBody !== undefined) { + var errs_1 = errors; + if (!refVal2(data.topBody, (dataPath || '') + '.topBody', data, 'topBody', rootData)) { + if (vErrors === null) vErrors = refVal2.errors; + else vErrors = vErrors.concat(refVal2.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.topJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.topJoin, (dataPath || '') + '.topJoin', data, 'topJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.topLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.topLeft, (dataPath || '') + '.topLeft', data, 'topLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.topRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.topRight, (dataPath || '') + '.topRight', data, 'topRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomBody !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomBody, (dataPath || '') + '.bottomBody', data, 'bottomBody', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomJoin, (dataPath || '') + '.bottomJoin', data, 'bottomJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomLeft, (dataPath || '') + '.bottomLeft', data, 'bottomLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bottomRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bottomRight, (dataPath || '') + '.bottomRight', data, 'bottomRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bodyLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bodyLeft, (dataPath || '') + '.bodyLeft', data, 'bodyLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bodyRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bodyRight, (dataPath || '') + '.bodyRight', data, 'bodyRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.bodyJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.bodyJoin, (dataPath || '') + '.bodyJoin', data, 'bodyJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinBody !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinBody, (dataPath || '') + '.joinBody', data, 'joinBody', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinLeft !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinLeft, (dataPath || '') + '.joinLeft', data, 'joinLeft', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinRight !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinRight, (dataPath || '') + '.joinRight', data, 'joinRight', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.joinJoin !== undefined) { + var errs_1 = errors; + if (!refVal[2](data.joinJoin, (dataPath || '') + '.joinJoin', data, 'joinJoin', rootData)) { + if (vErrors === null) vErrors = refVal[2].errors; + else vErrors = vErrors.concat(refVal[2].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal1.schema = { + "type": "object", + "properties": { + "topBody": { + "$ref": "#/definitions/border" + }, + "topJoin": { + "$ref": "#/definitions/border" + }, + "topLeft": { + "$ref": "#/definitions/border" + }, + "topRight": { + "$ref": "#/definitions/border" + }, + "bottomBody": { + "$ref": "#/definitions/border" + }, + "bottomJoin": { + "$ref": "#/definitions/border" + }, + "bottomLeft": { + "$ref": "#/definitions/border" + }, + "bottomRight": { + "$ref": "#/definitions/border" + }, + "bodyLeft": { + "$ref": "#/definitions/border" + }, + "bodyRight": { + "$ref": "#/definitions/border" + }, + "bodyJoin": { + "$ref": "#/definitions/border" + }, + "joinBody": { + "$ref": "#/definitions/border" + }, + "joinLeft": { + "$ref": "#/definitions/border" + }, + "joinRight": { + "$ref": "#/definitions/border" + }, + "joinJoin": { + "$ref": "#/definitions/border" + } + }, + "additionalProperties": false + }; + refVal1.errors = null; + refVal[1] = refVal1; + var refVal2 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if (typeof data !== "string") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'string' + }, + message: 'should be string' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal2.schema = { + "type": "string" + }; + refVal2.errors = null; + refVal[2] = refVal2; + var refVal3 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || pattern0.test(key0)); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + for (var key0 in data) { + if (pattern0.test(key0)) { + var errs_1 = errors; + if (!refVal4(data[key0], (dataPath || '') + '[\'' + key0 + '\']', data, key0, rootData)) { + if (vErrors === null) vErrors = refVal4.errors; + else vErrors = vErrors.concat(refVal4.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal3.schema = { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "$ref": "#/definitions/column" + } + }, + "additionalProperties": false + }; + refVal3.errors = null; + refVal[3] = refVal3; + var refVal4 = (function() { + var pattern0 = new RegExp('^[0-9]+$'); + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || validate.schema.properties[key0]); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + var data1 = data.alignment; + if (data1 !== undefined) { + var errs_1 = errors; + var schema1 = validate.schema.properties.alignment.enum; + var valid1; + valid1 = false; + for (var i1 = 0; i1 < schema1.length; i1++) + if (equal(data1, schema1[i1])) { + valid1 = true; + break; + } + if (!valid1) { + var err = { + keyword: 'enum', + dataPath: (dataPath || '') + '.alignment', + schemaPath: '#/properties/alignment/enum', + params: { + allowedValues: schema1 + }, + message: 'should be equal to one of the allowed values' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + if (typeof data1 !== "string") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.alignment', + schemaPath: '#/properties/alignment/type', + params: { + type: 'string' + }, + message: 'should be string' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.width !== undefined) { + var errs_1 = errors; + if (typeof data.width !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.width', + schemaPath: '#/properties/width/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.wrapWord !== undefined) { + var errs_1 = errors; + if (typeof data.wrapWord !== "boolean") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.wrapWord', + schemaPath: '#/properties/wrapWord/type', + params: { + type: 'boolean' + }, + message: 'should be boolean' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.truncate !== undefined) { + var errs_1 = errors; + if (typeof data.truncate !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.truncate', + schemaPath: '#/properties/truncate/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.paddingLeft !== undefined) { + var errs_1 = errors; + if (typeof data.paddingLeft !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.paddingLeft', + schemaPath: '#/properties/paddingLeft/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + if (data.paddingRight !== undefined) { + var errs_1 = errors; + if (typeof data.paddingRight !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.paddingRight', + schemaPath: '#/properties/paddingRight/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + validate.errors = vErrors; + return errors === 0; + }; + })(); + refVal4.schema = { + "type": "object", + "properties": { + "alignment": { + "type": "string", + "enum": ["left", "right", "center"] + }, + "width": { + "type": "number" + }, + "wrapWord": { + "type": "boolean" + }, + "truncate": { + "type": "number" + }, + "paddingLeft": { + "type": "number" + }, + "paddingRight": { + "type": "number" + } + }, + "additionalProperties": false + }; + refVal4.errors = null; + refVal[4] = refVal4; + return function validate(data, dataPath, parentData, parentDataProperty, rootData) { + 'use strict'; + var vErrors = null; + var errors = 0; + if (rootData === undefined) rootData = data; + if ((data && typeof data === "object" && !Array.isArray(data))) { + var errs__0 = errors; + var valid1 = true; + for (var key0 in data) { + var isAdditional0 = !(false || key0 == 'border' || key0 == 'columns' || key0 == 'columnDefault' || key0 == 'columnCount'); + if (isAdditional0) { + valid1 = false; + var err = { + keyword: 'additionalProperties', + dataPath: (dataPath || '') + "", + schemaPath: '#/additionalProperties', + params: { + additionalProperty: '' + key0 + '' + }, + message: 'should NOT have additional properties' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + } + if (data.border !== undefined) { + var errs_1 = errors; + if (!refVal1(data.border, (dataPath || '') + '.border', data, 'border', rootData)) { + if (vErrors === null) vErrors = refVal1.errors; + else vErrors = vErrors.concat(refVal1.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.columns !== undefined) { + var errs_1 = errors; + if (!refVal3(data.columns, (dataPath || '') + '.columns', data, 'columns', rootData)) { + if (vErrors === null) vErrors = refVal3.errors; + else vErrors = vErrors.concat(refVal3.errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.columnDefault !== undefined) { + var errs_1 = errors; + if (!refVal[4](data.columnDefault, (dataPath || '') + '.columnDefault', data, 'columnDefault', rootData)) { + if (vErrors === null) vErrors = refVal[4].errors; + else vErrors = vErrors.concat(refVal[4].errors); + errors = vErrors.length; + } + var valid1 = errors === errs_1; + } + if (data.columnCount !== undefined) { + var errs_1 = errors; + if (typeof data.columnCount !== "number") { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + '.columnCount', + schemaPath: '#/properties/columnCount/type', + params: { + type: 'number' + }, + message: 'should be number' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; + } + var valid1 = errors === errs_1; + } + } else { + var err = { + keyword: 'type', + dataPath: (dataPath || '') + "", + schemaPath: '#/type', + params: { + type: 'object' + }, + message: 'should be object' + }; + if (vErrors === null) vErrors = [err]; + else vErrors.push(err); + errors++; } + validate.errors = vErrors; + return errors === 0; + }; +})(); +validate.schema = { + "id": "streamConfig.json", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "border": { + "$ref": "#/definitions/borders" + }, + "columns": { + "$ref": "#/definitions/columns" + }, + "columnDefault": { + "$ref": "#/definitions/column" + }, + "columnCount": { + "type": "number" + } + }, + "additionalProperties": false, + "definitions": { + "columns": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "$ref": "#/definitions/column" + } + }, + "additionalProperties": false + }, + "column": { + "type": "object", + "properties": { + "alignment": { + "type": "string", + "enum": ["left", "right", "center"] + }, + "width": { + "type": "number" + }, + "wrapWord": { + "type": "boolean" + }, + "truncate": { + "type": "number" + }, + "paddingLeft": { + "type": "number" + }, + "paddingRight": { + "type": "number" + } + }, + "additionalProperties": false + }, + "borders": { + "type": "object", + "properties": { + "topBody": { + "$ref": "#/definitions/border" + }, + "topJoin": { + "$ref": "#/definitions/border" + }, + "topLeft": { + "$ref": "#/definitions/border" + }, + "topRight": { + "$ref": "#/definitions/border" + }, + "bottomBody": { + "$ref": "#/definitions/border" + }, + "bottomJoin": { + "$ref": "#/definitions/border" + }, + "bottomLeft": { + "$ref": "#/definitions/border" + }, + "bottomRight": { + "$ref": "#/definitions/border" + }, + "bodyLeft": { + "$ref": "#/definitions/border" + }, + "bodyRight": { + "$ref": "#/definitions/border" + }, + "bodyJoin": { + "$ref": "#/definitions/border" + }, + "joinBody": { + "$ref": "#/definitions/border" + }, + "joinLeft": { + "$ref": "#/definitions/border" + }, + "joinRight": { + "$ref": "#/definitions/border" + }, + "joinJoin": { + "$ref": "#/definitions/border" + } + }, + "additionalProperties": false + }, + "border": { + "type": "string" + } + } }; - -module.exports = exports['default']; -//# sourceMappingURL=validateStreamConfig.js.map +validate.errors = null; +module.exports = validate; \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/validateStreamConfig.js.map b/tools/eslint/node_modules/table/dist/validateStreamConfig.js.map deleted file mode 100644 index c43bee9d5f1e1e..00000000000000 --- a/tools/eslint/node_modules/table/dist/validateStreamConfig.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["validateStreamConfig.js"],"names":[],"mappings":";;;;;;AAAA;;;;AACA;;;;;;;;;;;;;;;;;;;kBAce,YAAiB;AAAA,QAAhB,MAAgB,yDAAP,EAAO;;AAC5B,QAAI,eAAJ;;AAEA,aAAS,aAAI,cAAJ,CAAmB,MAAnB,yBAAT;;AAEA,QAAI,CAAC,OAAO,KAAZ,EAAmB;;AAEf,gBAAQ,GAAR,CAAY,QAAZ,EAAsB,MAAtB;AACA,gBAAQ,GAAR,CAAY,OAAZ,EAAqB;AACjB,qBAAS,OAAO,KAAP,CAAa,OADL;AAEjB,oBAAQ,OAAO,KAAP,CAAa,MAFJ;AAGjB,sBAAU,OAAO,KAAP,CAAa,QAHN;AAIjB,wBAAY,OAAO,KAAP,CAAa;AAJR,SAArB;;;AAQA,cAAM,IAAI,KAAJ,CAAU,iBAAV,CAAN;AACH;AACJ,C","file":"validateStreamConfig.js","sourcesContent":["import schema from './schemas/streamConfig.json';\nimport tv4 from 'tv4';\n\n/**\n * @typedef {string} cell\n */\n\n/**\n * @typedef {cell[]} validateData~column\n */\n\n/**\n * @param {formatData~config} config\n * @returns {undefined}\n */\nexport default (config = {}) => {\n let result;\n\n result = tv4.validateResult(config, schema);\n\n if (!result.valid) {\n /* eslint-disable no-console */\n console.log('config', config);\n console.log('error', {\n message: result.error.message,\n params: result.error.params,\n dataPath: result.error.dataPath,\n schemaPath: result.error.schemaPath\n });\n /* eslint-enable no-console */\n\n throw new Error('Invalid config.');\n }\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/validateTableData.js.map b/tools/eslint/node_modules/table/dist/validateTableData.js.map deleted file mode 100644 index 92092051fad066..00000000000000 --- a/tools/eslint/node_modules/table/dist/validateTableData.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["validateTableData.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAce,UAAC,IAAD,EAAU;AACrB,QAAI,qBAAJ;;AAEA,QAAI,CAAC,uBAAU,IAAV,CAAL,EAAsB;AAClB,cAAM,IAAI,KAAJ,CAAU,8BAAV,CAAN;AACH;;AAED,QAAI,KAAK,MAAL,KAAgB,CAApB,EAAuB;AACnB,cAAM,IAAI,KAAJ,CAAU,qCAAV,CAAN;AACH;;AAED,QAAI,KAAK,CAAL,EAAQ,MAAR,KAAmB,CAAvB,EAA0B;AACtB,cAAM,IAAI,KAAJ,CAAU,wCAAV,CAAN;AACH;;AAED,mBAAe,KAAK,CAAL,EAAQ,MAAvB;;AAEA,2BAAU,IAAV,EAAgB,UAAC,KAAD,EAAW;AACvB,YAAI,CAAC,uBAAU,KAAV,CAAL,EAAuB;AACnB,kBAAM,IAAI,KAAJ,CAAU,kCAAV,CAAN;AACH;;AAED,YAAI,MAAM,MAAN,KAAiB,YAArB,EAAmC;AAC/B,kBAAM,IAAI,KAAJ,CAAU,+CAAV,CAAN;AACH;;;;AAID,+BAAU,KAAV,EAAiB,UAAC,IAAD,EAAU;AACvB,gBAAI,cAAc,IAAd,CAAmB,IAAnB,CAAJ,EAA8B;AAC1B,sBAAM,IAAI,KAAJ,CAAU,iDAAV,CAAN;AACH;AACJ,SAJD;AAKH,KAhBD;AAiBH,C","file":"validateTableData.js","sourcesContent":["import _ from 'lodash';\n\n/**\n * @typedef {string} cell\n */\n\n/**\n * @typedef {cell[]} validateData~column\n */\n\n/**\n * @param {column[]} rows\n * @returns {undefined}\n */\nexport default (rows) => {\n let columnNumber;\n\n if (!_.isArray(rows)) {\n throw new Error('Table data must be an array.');\n }\n\n if (rows.length === 0) {\n throw new Error('Table must define at least one row.');\n }\n\n if (rows[0].length === 0) {\n throw new Error('Table must define at least one column.');\n }\n\n columnNumber = rows[0].length;\n\n _.forEach(rows, (cells) => {\n if (!_.isArray(cells)) {\n throw new Error('Table row data must be an array.');\n }\n\n if (cells.length !== columnNumber) {\n throw new Error('Table must have a consistent number of cells.');\n }\n\n // @todo Make an exception for newline characters.\n // @see https://github.com/gajus/table/issues/9\n _.forEach(cells, (cell) => {\n if (/[\\x01-\\x1A]/.test(cell)) {\n throw new Error('Table data must not contain control characters.');\n }\n });\n });\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/wrapString.js.map b/tools/eslint/node_modules/table/dist/wrapString.js.map deleted file mode 100644 index 0ba89f7ddd6406..00000000000000 --- a/tools/eslint/node_modules/table/dist/wrapString.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["wrapString.js"],"names":[],"mappings":";;;;;;;;;;AACA;;;;AACA;;;;;;;;;;;;;;;;;;kBAae,UAAC,OAAD,EAAU,IAAV,EAAmB;AAC9B,QAAI,eAAJ;QACI,qBADJ;;AAGA,mBAAe,OAAf;;AAEA,aAAS,EAAT;;AAEA,OAAG;AACC,eAAO,IAAP,CAAY,yBAAM,YAAN,EAAoB,CAApB,EAAuB,IAAvB,CAAZ;;AAEA,uBAAe,oBAAO,yBAAM,YAAN,EAAoB,IAApB,CAAP,CAAf;AACH,KAJD,QAIS,2BAAY,YAAZ,CAJT;;AAMA,WAAO,MAAP;AACH,C","file":"wrapString.js","sourcesContent":["import _ from 'lodash';\nimport slice from 'slice-ansi';\nimport stringWidth from 'string-width';\n\n/**\n * Creates an array of strings split into groups the length of size.\n * This function works with strings that contain ASCII characters.\n *\n * wrapText is different from would-be \"chunk\" implementation\n * in that whitespace characters that occur on a chunk size limit are trimmed.\n *\n * @param {string} subject\n * @param {number} size\n * @returns {Array}\n */\nexport default (subject, size) => {\n let chunks,\n subjectSlice;\n\n subjectSlice = subject;\n\n chunks = [];\n\n do {\n chunks.push(slice(subjectSlice, 0, size));\n\n subjectSlice = _.trim(slice(subjectSlice, size));\n } while (stringWidth(subjectSlice));\n\n return chunks;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/dist/wrapWord.js.map b/tools/eslint/node_modules/table/dist/wrapWord.js.map deleted file mode 100644 index 92e36ba776c864..00000000000000 --- a/tools/eslint/node_modules/table/dist/wrapWord.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["wrapWord.js"],"names":[],"mappings":";;;;;;;;;;AACA;;;;AACA;;;;;;;;;;;;kBAOe,UAAC,KAAD,EAAQ,IAAR,EAAiB;AAC5B,QAAI,cAAJ;QACI,eADJ;QAEI,WAFJ;QAGI,gBAHJ;;AAKA,cAAU,KAAV;;AAEA,aAAS,EAAT;;;AAGA,SAAK,IAAI,MAAJ,CAAW,WAAW,IAAX,GAAkB,mBAAlB,IAAyC,OAAO,CAAhD,IAAqD,yBAAhE,CAAL;;AAEA,OAAG;AACC,gBAAQ,QAAQ,KAAR,CAAc,EAAd,CAAR;;;;AAIA,YAAI,KAAJ,EAAW;AACP,oBAAQ,MAAM,CAAN,CAAR;;AAEA,sBAAU,yBAAM,OAAN,EAAe,2BAAY,KAAZ,CAAf,CAAV;;AAEA,oBAAQ,oBAAO,KAAP,CAAR;AACH,SAND,MAMO;AACH,oBAAQ,yBAAM,OAAN,EAAe,CAAf,EAAkB,IAAlB,CAAR;AACA,sBAAU,yBAAM,OAAN,EAAe,IAAf,CAAV;AACH;;AAED,eAAO,IAAP,CAAY,KAAZ;AACH,KAjBD,QAiBS,2BAAY,OAAZ,CAjBT;;AAmBA,WAAO,MAAP;AACH,C","file":"wrapWord.js","sourcesContent":["import _ from 'lodash';\nimport slice from 'slice-ansi';\nimport stringWidth from 'string-width';\n\n/**\n * @param {string} input\n * @param {number} size\n * @returns {Array}\n */\nexport default (input, size) => {\n let chunk,\n chunks,\n re,\n subject;\n\n subject = input;\n\n chunks = [];\n\n // https://regex101.com/r/gY5kZ1/1\n re = new RegExp('(^.{1,' + size + '}(\\\\s+|$))|(^.{1,' + (size - 1) + '}(\\\\\\\\|/|_|\\\\.|,|;|\\-))');\n\n do {\n chunk = subject.match(re);\n\n // console.log('chunk', chunk, re);\n\n if (chunk) {\n chunk = chunk[0];\n\n subject = slice(subject, stringWidth(chunk));\n\n chunk = _.trim(chunk);\n } else {\n chunk = slice(subject, 0, size);\n subject = slice(subject, size);\n }\n\n chunks.push(chunk);\n } while (stringWidth(subject));\n\n return chunks;\n};\n"]} \ No newline at end of file diff --git a/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/index.js b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/index.js new file mode 100644 index 00000000000000..d506327c3e5576 --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/index.js @@ -0,0 +1,46 @@ +'use strict'; +/* eslint-disable yoda */ +module.exports = x => { + if (Number.isNaN(x)) { + return false; + } + + // code points are derived from: + // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt + if ( + x >= 0x1100 && ( + x <= 0x115f || // Hangul Jamo + x === 0x2329 || // LEFT-POINTING ANGLE BRACKET + x === 0x232a || // RIGHT-POINTING ANGLE BRACKET + // CJK Radicals Supplement .. Enclosed CJK Letters and Months + (0x2e80 <= x && x <= 0x3247 && x !== 0x303f) || + // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A + (0x3250 <= x && x <= 0x4dbf) || + // CJK Unified Ideographs .. Yi Radicals + (0x4e00 <= x && x <= 0xa4c6) || + // Hangul Jamo Extended-A + (0xa960 <= x && x <= 0xa97c) || + // Hangul Syllables + (0xac00 <= x && x <= 0xd7a3) || + // CJK Compatibility Ideographs + (0xf900 <= x && x <= 0xfaff) || + // Vertical Forms + (0xfe10 <= x && x <= 0xfe19) || + // CJK Compatibility Forms .. Small Form Variants + (0xfe30 <= x && x <= 0xfe6b) || + // Halfwidth and Fullwidth Forms + (0xff01 <= x && x <= 0xff60) || + (0xffe0 <= x && x <= 0xffe6) || + // Kana Supplement + (0x1b000 <= x && x <= 0x1b001) || + // Enclosed Ideographic Supplement + (0x1f200 <= x && x <= 0x1f251) || + // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane + (0x20000 <= x && x <= 0x3fffd) + ) + ) { + return true; + } + + return false; +}; diff --git a/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/license b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/license new file mode 100644 index 00000000000000..654d0bfe943437 --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/package.json b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/package.json new file mode 100644 index 00000000000000..4f2674f067ec32 --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "is-fullwidth-code-point@^2.0.0", + "scope": null, + "escapedName": "is-fullwidth-code-point", + "name": "is-fullwidth-code-point", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/Users/trott/io.js/tools/node_modules/table/node_modules/string-width" + ] + ], + "_from": "is-fullwidth-code-point@>=2.0.0 <3.0.0", + "_id": "is-fullwidth-code-point@2.0.0", + "_inCache": true, + "_location": "/table/is-fullwidth-code-point", + "_nodeVersion": "4.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/is-fullwidth-code-point-2.0.0.tgz_1474526567505_0.299921662081033" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "is-fullwidth-code-point@^2.0.0", + "scope": null, + "escapedName": "is-fullwidth-code-point", + "name": "is-fullwidth-code-point", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/table/string-width" + ], + "_resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "_shasum": "a3b30a5c4f199183167aaab93beefae3ddfb654f", + "_shrinkwrap": null, + "_spec": "is-fullwidth-code-point@^2.0.0", + "_where": "/Users/trott/io.js/tools/node_modules/table/node_modules/string-width", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-fullwidth-code-point/issues" + }, + "dependencies": {}, + "description": "Check if the character represented by a given Unicode code point is fullwidth", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "a3b30a5c4f199183167aaab93beefae3ddfb654f", + "tarball": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js" + ], + "gitHead": "e94a78056056c5546f2bf4c4cf812a2163a46dae", + "homepage": "https://github.com/sindresorhus/is-fullwidth-code-point#readme", + "keywords": [ + "fullwidth", + "full-width", + "full", + "width", + "unicode", + "character", + "char", + "string", + "str", + "codepoint", + "code", + "point", + "is", + "detect", + "check" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-fullwidth-code-point", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-fullwidth-code-point.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.0.0", + "xo": { + "esnext": true + } +} diff --git a/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/readme.md b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/readme.md new file mode 100644 index 00000000000000..093b0281b2c46b --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/is-fullwidth-code-point/readme.md @@ -0,0 +1,39 @@ +# is-fullwidth-code-point [![Build Status](https://travis-ci.org/sindresorhus/is-fullwidth-code-point.svg?branch=master)](https://travis-ci.org/sindresorhus/is-fullwidth-code-point) + +> Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) + + +## Install + +``` +$ npm install --save is-fullwidth-code-point +``` + + +## Usage + +```js +const isFullwidthCodePoint = require('is-fullwidth-code-point'); + +isFullwidthCodePoint('谢'.codePointAt()); +//=> true + +isFullwidthCodePoint('a'.codePointAt()); +//=> false +``` + + +## API + +### isFullwidthCodePoint(input) + +#### input + +Type: `number` + +[Code point](https://en.wikipedia.org/wiki/Code_point) of a character. + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/eslint/node_modules/table/node_modules/string-width/index.js b/tools/eslint/node_modules/table/node_modules/string-width/index.js new file mode 100644 index 00000000000000..25a8943c1dcad6 --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/string-width/index.js @@ -0,0 +1,35 @@ +'use strict'; +const stripAnsi = require('strip-ansi'); +const isFullwidthCodePoint = require('is-fullwidth-code-point'); + +module.exports = str => { + if (typeof str !== 'string' || str.length === 0) { + return 0; + } + + let width = 0; + + str = stripAnsi(str); + + for (let i = 0; i < str.length; i++) { + const code = str.codePointAt(i); + + // ignore control characters + if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) { + continue; + } + + // surrogates + if (code >= 0x10000) { + i++; + } + + if (isFullwidthCodePoint(code)) { + width += 2; + } else { + width++; + } + } + + return width; +}; diff --git a/tools/eslint/node_modules/table/node_modules/string-width/license b/tools/eslint/node_modules/table/node_modules/string-width/license new file mode 100644 index 00000000000000..654d0bfe943437 --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/string-width/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tools/eslint/node_modules/table/node_modules/string-width/package.json b/tools/eslint/node_modules/table/node_modules/string-width/package.json new file mode 100644 index 00000000000000..2fd6a297eb8855 --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/string-width/package.json @@ -0,0 +1,125 @@ +{ + "_args": [ + [ + { + "raw": "string-width@^2.0.0", + "scope": null, + "escapedName": "string-width", + "name": "string-width", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/Users/trott/io.js/tools/node_modules/table" + ] + ], + "_from": "string-width@>=2.0.0 <3.0.0", + "_id": "string-width@2.0.0", + "_inCache": true, + "_location": "/table/string-width", + "_nodeVersion": "4.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/string-width-2.0.0.tgz_1474527284011_0.7386264291126281" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "string-width@^2.0.0", + "scope": null, + "escapedName": "string-width", + "name": "string-width", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/table" + ], + "_resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "_shasum": "635c5436cc72a6e0c387ceca278d4e2eec52687e", + "_shrinkwrap": null, + "_spec": "string-width@^2.0.0", + "_where": "/Users/trott/io.js/tools/node_modules/table", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/string-width/issues" + }, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^3.0.0" + }, + "description": "Get the visual width of a string - the number of columns required to display it", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "635c5436cc72a6e0c387ceca278d4e2eec52687e", + "tarball": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js" + ], + "gitHead": "523d7ba4dbb24d40cde88d2c36bb1c7124ab6f82", + "homepage": "https://github.com/sindresorhus/string-width#readme", + "keywords": [ + "string", + "str", + "character", + "char", + "unicode", + "width", + "visual", + "column", + "columns", + "fullwidth", + "full-width", + "full", + "ansi", + "escape", + "codes", + "cli", + "command-line", + "terminal", + "console", + "cjk", + "chinese", + "japanese", + "korean", + "fixed-width" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "string-width", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/string-width.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.0.0", + "xo": { + "esnext": true + } +} diff --git a/tools/eslint/node_modules/table/node_modules/string-width/readme.md b/tools/eslint/node_modules/table/node_modules/string-width/readme.md new file mode 100644 index 00000000000000..1ab42c93580ecb --- /dev/null +++ b/tools/eslint/node_modules/table/node_modules/string-width/readme.md @@ -0,0 +1,42 @@ +# string-width [![Build Status](https://travis-ci.org/sindresorhus/string-width.svg?branch=master)](https://travis-ci.org/sindresorhus/string-width) + +> Get the visual width of a string - the number of columns required to display it + +Some Unicode characters are [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) and use double the normal width. [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) are stripped and doesn't affect the width. + +Useful to be able to measure the actual width of command-line output. + + +## Install + +``` +$ npm install --save string-width +``` + + +## Usage + +```js +const stringWidth = require('string-width'); + +stringWidth('古'); +//=> 2 + +stringWidth('\u001b[1m古\u001b[22m'); +//=> 2 + +stringWidth('a'); +//=> 1 +``` + + +## Related + +- [string-width-cli](https://github.com/sindresorhus/string-width-cli) - CLI for this module +- [string-length](https://github.com/sindresorhus/string-length) - Get the real length of a string +- [widest-line](https://github.com/sindresorhus/widest-line) - Get the visual width of the widest line in a string + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/eslint/node_modules/table/package.json b/tools/eslint/node_modules/table/package.json index fb2f250fa08068..33c29ec498b7ce 100644 --- a/tools/eslint/node_modules/table/package.json +++ b/tools/eslint/node_modules/table/package.json @@ -14,20 +14,22 @@ ] ], "_from": "table@>=3.7.8 <4.0.0", - "_id": "table@3.8.0", + "_id": "table@3.8.3", "_inCache": true, "_location": "/table", - "_nodeVersion": "6.4.0", + "_nodeVersion": "6.8.1", "_npmOperationalInternal": { "host": "packages-16-east.internal.npmjs.com", - "tmp": "tmp/table-3.8.0.tgz_1474139512457_0.8613335366826504" + "tmp": "tmp/table-3.8.3.tgz_1476810452789_0.6529890382662416" }, "_npmUser": { "name": "gajus", "email": "gajus@gajus.com" }, - "_npmVersion": "3.10.3", - "_phantomChildren": {}, + "_npmVersion": "3.10.8", + "_phantomChildren": { + "strip-ansi": "3.0.1" + }, "_requested": { "raw": "table@^3.7.8", "scope": null, @@ -40,8 +42,8 @@ "_requiredBy": [ "/eslint" ], - "_resolved": "https://registry.npmjs.org/table/-/table-3.8.0.tgz", - "_shasum": "252166c7f3286684a9d561b0f3a8929caf3a997b", + "_resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "_shasum": "2bbc542f0fda9861a755d3947fefd8b3f513855f", "_shrinkwrap": null, "_spec": "table@^3.7.8", "_where": "/Users/trott/io.js/tools/node_modules/eslint", @@ -59,28 +61,33 @@ "chalk": "^1.1.1", "lodash": "^4.0.0", "slice-ansi": "0.0.4", - "string-width": "^1.0.1" + "string-width": "^2.0.0" }, "description": "Formats data into a string table.", "devDependencies": { + "ajv-cli": "^1.1.0", "babel": "^6.5.2", "babel-cli": "^6.14.0", + "babel-core": "^6.14.0", "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-istanbul": "^2.0.3", "babel-preset-es2015-node4": "^2.1.0", "babel-register": "^6.14.0", "chai": "^3.4.1", "eslint": "^3.5.0", "eslint-config-canonical": "^1.8.6", "gitdown": "^2.4.0", + "husky": "^0.11.7", "mocha": "^3.0.2", + "nyc": "^8.3.1", "sinon": "^1.17.2" }, "directories": {}, "dist": { - "shasum": "252166c7f3286684a9d561b0f3a8929caf3a997b", - "tarball": "https://registry.npmjs.org/table/-/table-3.8.0.tgz" + "shasum": "2bbc542f0fda9861a755d3947fefd8b3f513855f", + "tarball": "https://registry.npmjs.org/table/-/table-3.8.3.tgz" }, - "gitHead": "076dd77627213007a989b2c845fa2f3a38896eeb", + "gitHead": "2d1c0d9ebad31f9c76e784e6a88f701de8705005", "homepage": "https://github.com/gajus/table#readme", "keywords": [ "ascii", @@ -98,6 +105,17 @@ } ], "name": "table", + "nyc": { + "include": [ + "src/*.js" + ], + "instrument": false, + "lines": 70, + "require": [ + "babel-register" + ], + "sourceMap": false + }, "optionalDependencies": {}, "readme": "ERROR: No README data found!", "repository": { @@ -105,10 +123,13 @@ "url": "git+https://github.com/gajus/table.git" }, "scripts": { - "build": "babel --copy-files ./src --out-dir ./dist", - "lint": "eslint ./src ./tests", - "readme": "gitdown ./.README/README.md --output-file ./README.md", - "test": "mocha --compilers js:babel-register" + "build": "rm -fr ./dist && babel --copy-files ./src --out-dir ./dist && npm run make-validators", + "lint": "npm run build && eslint ./src ./tests", + "make-readme": "gitdown ./.README/README.md --output-file ./README.md", + "make-validators": "ajv compile --all-errors --inline-refs=false -s src/schemas/config -c ajv-keywords/keywords/typeof -o dist/validateConfig.js && ajv compile --all-errors --inline-refs=false -s src/schemas/streamConfig -c ajv-keywords/keywords/typeof -o dist/validateStreamConfig.js", + "precommit": "npm run lint && npm run test", + "prepublish": "NODE_ENV=production npm run build", + "test": "npm run build && nyc --check-coverage mocha" }, - "version": "3.8.0" + "version": "3.8.3" } diff --git a/tools/eslint/node_modules/tryit/package.json b/tools/eslint/node_modules/tryit/package.json index 7a7a28b076f45c..e0b4e1b8dac03e 100644 --- a/tools/eslint/node_modules/tryit/package.json +++ b/tools/eslint/node_modules/tryit/package.json @@ -14,15 +14,19 @@ ] ], "_from": "tryit@>=1.0.1 <2.0.0", - "_id": "tryit@1.0.2", + "_id": "tryit@1.0.3", "_inCache": true, "_location": "/tryit", - "_nodeVersion": "4.1.0", + "_nodeVersion": "6.8.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/tryit-1.0.3.tgz_1477606530482_0.8131801665294915" + }, "_npmUser": { "name": "henrikjoreteg", "email": "henrik@joreteg.com" }, - "_npmVersion": "3.3.8", + "_npmVersion": "3.10.8", "_phantomChildren": {}, "_requested": { "raw": "tryit@^1.0.1", @@ -36,8 +40,8 @@ "_requiredBy": [ "/is-resolvable" ], - "_resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.2.tgz", - "_shasum": "c196b0073e6b1c595d93c9c830855b7acc32a453", + "_resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "_shasum": "393be730a9446fd1ead6da59a014308f36c289cb", "_shrinkwrap": null, "_spec": "tryit@^1.0.1", "_where": "/Users/trott/io.js/tools/node_modules/is-resolvable", @@ -56,10 +60,13 @@ }, "directories": {}, "dist": { - "shasum": "c196b0073e6b1c595d93c9c830855b7acc32a453", - "tarball": "https://registry.npmjs.org/tryit/-/tryit-1.0.2.tgz" + "shasum": "393be730a9446fd1ead6da59a014308f36c289cb", + "tarball": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz" }, - "gitHead": "b567b4feb491e2ee89addd3d06f66d6ec2217cf5", + "files": [ + "tryit.js" + ], + "gitHead": "706147151922a456988a641b08984b2d1fcf2a86", "homepage": "https://github.com/HenrikJoreteg/tryit#readme", "keywords": [ "errors", @@ -84,5 +91,5 @@ "scripts": { "test": "node test/test.js | tap-spec" }, - "version": "1.0.2" + "version": "1.0.3" } diff --git a/tools/eslint/node_modules/typedarray/package.json b/tools/eslint/node_modules/typedarray/package.json index ab02da539baf7a..19821370412450 100644 --- a/tools/eslint/node_modules/typedarray/package.json +++ b/tools/eslint/node_modules/typedarray/package.json @@ -2,18 +2,18 @@ "_args": [ [ { - "raw": "typedarray@~0.0.5", + "raw": "typedarray@^0.0.6", "scope": null, "escapedName": "typedarray", "name": "typedarray", - "rawSpec": "~0.0.5", - "spec": ">=0.0.5 <0.1.0", + "rawSpec": "^0.0.6", + "spec": ">=0.0.6 <0.0.7", "type": "range" }, "/Users/trott/io.js/tools/node_modules/concat-stream" ] ], - "_from": "typedarray@>=0.0.5 <0.1.0", + "_from": "typedarray@>=0.0.6 <0.0.7", "_id": "typedarray@0.0.6", "_inCache": true, "_location": "/typedarray", @@ -24,12 +24,12 @@ "_npmVersion": "1.4.3", "_phantomChildren": {}, "_requested": { - "raw": "typedarray@~0.0.5", + "raw": "typedarray@^0.0.6", "scope": null, "escapedName": "typedarray", "name": "typedarray", - "rawSpec": "~0.0.5", - "spec": ">=0.0.5 <0.1.0", + "rawSpec": "^0.0.6", + "spec": ">=0.0.6 <0.0.7", "type": "range" }, "_requiredBy": [ @@ -38,7 +38,7 @@ "_resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "_shasum": "867ac74e3864187b1d3d47d996a78ec5c8830777", "_shrinkwrap": null, - "_spec": "typedarray@~0.0.5", + "_spec": "typedarray@^0.0.6", "_where": "/Users/trott/io.js/tools/node_modules/concat-stream", "author": { "name": "James Halliday", diff --git a/tools/eslint/package.json b/tools/eslint/package.json index f0155d89330b9c..d6c8d488cb5dfa 100644 --- a/tools/eslint/package.json +++ b/tools/eslint/package.json @@ -2,25 +2,25 @@ "_args": [ [ { - "raw": "eslint", + "raw": "eslint@3.13.0", "scope": null, "escapedName": "eslint", "name": "eslint", - "rawSpec": "", - "spec": "latest", - "type": "tag" + "rawSpec": "3.13.0", + "spec": "3.13.0", + "type": "version" }, "/Users/trott/io.js/tools" ] ], - "_from": "eslint@latest", - "_id": "eslint@3.8.0", + "_from": "eslint@3.13.0", + "_id": "eslint@3.13.0", "_inCache": true, "_location": "/eslint", "_nodeVersion": "4.4.7", "_npmOperationalInternal": { "host": "packages-12-west.internal.npmjs.com", - "tmp": "tmp/eslint-3.8.0.tgz_1476481030547_0.1366094599943608" + "tmp": "tmp/eslint-3.13.0.tgz_1483735229408_0.023912116652354598" }, "_npmUser": { "name": "eslint", @@ -29,21 +29,21 @@ "_npmVersion": "2.15.8", "_phantomChildren": {}, "_requested": { - "raw": "eslint", + "raw": "eslint@3.13.0", "scope": null, "escapedName": "eslint", "name": "eslint", - "rawSpec": "", - "spec": "latest", - "type": "tag" + "rawSpec": "3.13.0", + "spec": "3.13.0", + "type": "version" }, "_requiredBy": [ "#USER" ], - "_resolved": "https://registry.npmjs.org/eslint/-/eslint-3.8.0.tgz", - "_shasum": "4fbbf6833d66654860c23a099c47a0f086de34b7", + "_resolved": "https://registry.npmjs.org/eslint/-/eslint-3.13.0.tgz", + "_shasum": "636925fd163c9babe2e8be7ae43caf518d469577", "_shrinkwrap": null, - "_spec": "eslint", + "_spec": "eslint@3.13.0", "_where": "/Users/trott/io.js/tools", "author": { "name": "Nicholas C. Zakas", @@ -56,6 +56,7 @@ "url": "https://github.com/eslint/eslint/issues/" }, "dependencies": { + "babel-code-frame": "^6.16.0", "chalk": "^1.1.3", "concat-stream": "^1.4.6", "debug": "^2.1.1", @@ -66,8 +67,8 @@ "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "glob": "^7.0.3", - "globals": "^9.2.0", - "ignore": "^3.1.5", + "globals": "^9.14.0", + "ignore": "^3.2.0", "imurmurhash": "^0.1.4", "inquirer": "^0.12.0", "is-my-json-valid": "^2.10.0", @@ -83,9 +84,9 @@ "pluralize": "^1.2.1", "progress": "^1.1.8", "require-uncached": "^1.0.2", - "shelljs": "^0.6.0", + "shelljs": "^0.7.5", "strip-bom": "^3.0.0", - "strip-json-comments": "~1.0.1", + "strip-json-comments": "~2.0.1", "table": "^3.7.8", "text-table": "~0.2.0", "user-home": "^2.0.0" @@ -118,9 +119,9 @@ "leche": "^2.1.1", "linefix": "^0.1.1", "load-perf": "^0.2.0", - "markdownlint": "^0.2.0", + "markdownlint": "^0.3.1", "mocha": "^2.4.5", - "mock-fs": "^3.10.0", + "mock-fs": "^3.12.1", "npm-license": "^0.3.2", "phantomjs-prebuilt": "^2.1.7", "proxyquire": "^1.7.10", @@ -132,8 +133,8 @@ }, "directories": {}, "dist": { - "shasum": "4fbbf6833d66654860c23a099c47a0f086de34b7", - "tarball": "https://registry.npmjs.org/eslint/-/eslint-3.8.0.tgz" + "shasum": "636925fd163c9babe2e8be7ae43caf518d469577", + "tarball": "https://registry.npmjs.org/eslint/-/eslint-3.13.0.tgz" }, "engines": { "node": ">=4" @@ -146,7 +147,7 @@ "lib", "messages" ], - "gitHead": "82220042725dd0e86b5ddbeac4166e1eb147aa04", + "gitHead": "8571ab82af1d86bf4aa6a9be79ece42493607c69", "homepage": "http://eslint.org", "keywords": [ "ast", @@ -193,5 +194,5 @@ "release": "node Makefile.js release", "test": "node Makefile.js test" }, - "version": "3.8.0" + "version": "3.13.0" } diff --git a/tools/gyp/pylib/gyp/generator/compile_commands_json.py b/tools/gyp/pylib/gyp/generator/compile_commands_json.py new file mode 100644 index 00000000000000..575db63c4e1943 --- /dev/null +++ b/tools/gyp/pylib/gyp/generator/compile_commands_json.py @@ -0,0 +1,115 @@ +# Copyright (c) 2016 Ben Noordhuis . All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import gyp.common +import gyp.xcode_emulation +import json +import os + +generator_additional_non_configuration_keys = [] +generator_additional_path_sections = [] +generator_extra_sources_for_rules = [] +generator_filelist_paths = None +generator_supports_multiple_toolsets = True +generator_wants_sorted_dependencies = False + +# Lifted from make.py. The actual values don't matter much. +generator_default_variables = { + 'CONFIGURATION_NAME': '$(BUILDTYPE)', + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/$(TARGET)/geni', + 'PRODUCT_DIR': '$(builddir)', + 'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s', + 'RULE_INPUT_EXT': '$(suffix $<)', + 'RULE_INPUT_NAME': '$(notdir $<)', + 'RULE_INPUT_PATH': '$(abspath $<)', + 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', + 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', + 'SHARED_LIB_PREFIX': 'lib', + 'STATIC_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', +} + + +def IsMac(params): + return 'mac' == gyp.common.GetFlavor(params) + + +def CalculateVariables(default_variables, params): + default_variables.setdefault('OS', gyp.common.GetFlavor(params)) + + +def AddCommandsForTarget(cwd, target, params, per_config_commands): + output_dir = params['generator_flags']['output_dir'] + for configuration_name, configuration in target['configurations'].iteritems(): + builddir_name = os.path.join(output_dir, configuration_name) + + if IsMac(params): + xcode_settings = gyp.xcode_emulation.XcodeSettings(target) + cflags = xcode_settings.GetCflags(configuration_name) + cflags_c = xcode_settings.GetCflagsC(configuration_name) + cflags_cc = xcode_settings.GetCflagsCC(configuration_name) + else: + cflags = configuration.get('cflags', []) + cflags_c = configuration.get('cflags_c', []) + cflags_cc = configuration.get('cflags_cc', []) + + cflags_c = cflags + cflags_c + cflags_cc = cflags + cflags_cc + + defines = configuration.get('defines', []) + defines = ['-D' + s for s in defines] + + # TODO(bnoordhuis) Handle generated source files. + sources = target.get('sources', []) + sources = [s for s in sources if s.endswith('.c') or s.endswith('.cc')] + + def resolve(filename): + return os.path.abspath(os.path.join(cwd, filename)) + + # TODO(bnoordhuis) Handle generated header files. + include_dirs = configuration.get('include_dirs', []) + include_dirs = [s for s in include_dirs if not s.startswith('$(obj)')] + includes = ['-I' + resolve(s) for s in include_dirs] + + defines = gyp.common.EncodePOSIXShellList(defines) + includes = gyp.common.EncodePOSIXShellList(includes) + cflags_c = gyp.common.EncodePOSIXShellList(cflags_c) + cflags_cc = gyp.common.EncodePOSIXShellList(cflags_cc) + + commands = per_config_commands.setdefault(configuration_name, []) + for source in sources: + file = resolve(source) + isc = source.endswith('.c') + cc = 'cc' if isc else 'c++' + cflags = cflags_c if isc else cflags_cc + command = ' '.join((cc, defines, includes, cflags, + '-c', gyp.common.EncodePOSIXShellArgument(file))) + commands.append(dict(command=command, directory=output_dir, file=file)) + + +def GenerateOutput(target_list, target_dicts, data, params): + per_config_commands = {} + for qualified_target, target in target_dicts.iteritems(): + build_file, target_name, toolset = ( + gyp.common.ParseQualifiedTarget(qualified_target)) + if IsMac(params): + settings = data[build_file] + gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(settings, target) + cwd = os.path.dirname(build_file) + AddCommandsForTarget(cwd, target, params, per_config_commands) + + output_dir = params['generator_flags']['output_dir'] + for configuration_name, commands in per_config_commands.iteritems(): + filename = os.path.join(output_dir, + configuration_name, + 'compile_commands.json') + gyp.common.EnsureDirExists(filename) + fp = open(filename, 'w') + json.dump(commands, fp=fp, indent=0, check_circular=False) + + +def PerformBuild(data, configurations, params): + pass diff --git a/tools/js2c.py b/tools/js2c.py index 4808c56813ce17..f7951617d34064 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -37,13 +37,16 @@ import string -def ToCString(contents): - step = 20 - slices = (contents[i:i+step] for i in xrange(0, len(contents), step)) - slices = map(lambda s: ','.join(str(ord(c)) for c in s), slices) +def ToCArray(elements, step=10): + slices = (elements[i:i+step] for i in xrange(0, len(elements), step)) + slices = map(lambda s: ','.join(str(x) for x in s), slices) return ',\n'.join(slices) +def ToCString(contents): + return ToCArray(map(ord, contents), step=20) + + def ReadFile(filename): file = open(filename, "rt") try: @@ -161,34 +164,72 @@ def ReadMacros(lines): return (constants, macros) -HEADER_TEMPLATE = """\ -#ifndef NODE_NATIVES_H_ -#define NODE_NATIVES_H_ +TEMPLATE = """ +#include "node.h" +#include "node_javascript.h" +#include "v8.h" +#include "env.h" +#include "env-inl.h" -#include +namespace node {{ -#define NODE_NATIVES_MAP(V) \\ -{node_natives_map} +{definitions} + +v8::Local MainSource(Environment* env) {{ + return internal_bootstrap_node_value.ToStringChecked(env->isolate()); +}} + +void DefineJavaScript(Environment* env, v8::Local target) {{ + {initializers} +}} -namespace node {{ -{sources} }} // namespace node +""" -#endif // NODE_NATIVES_H_ +ONE_BYTE_STRING = """ +static const uint8_t raw_{var}[] = {{ {data} }}; +static struct : public v8::String::ExternalOneByteStringResource {{ + const char* data() const override {{ + return reinterpret_cast(raw_{var}); + }} + size_t length() const override {{ return arraysize(raw_{var}); }} + void Dispose() override {{ /* Default calls `delete this`. */ }} + v8::Local ToStringChecked(v8::Isolate* isolate) {{ + return v8::String::NewExternalOneByte(isolate, this).ToLocalChecked(); + }} +}} {var}; """ +TWO_BYTE_STRING = """ +static const uint16_t raw_{var}[] = {{ {data} }}; +static struct : public v8::String::ExternalStringResource {{ + const uint16_t* data() const override {{ return raw_{var}; }} + size_t length() const override {{ return arraysize(raw_{var}); }} + void Dispose() override {{ /* Default calls `delete this`. */ }} + v8::Local ToStringChecked(v8::Isolate* isolate) {{ + return v8::String::NewExternalTwoByte(isolate, this).ToLocalChecked(); + }} +}} {var}; +""" -NODE_NATIVES_MAP = """\ - V({escaped_id}) \\ +INITIALIZER = """\ +CHECK(target->Set(env->context(), + {key}.ToStringChecked(env->isolate()), + {value}.ToStringChecked(env->isolate())).FromJust()); """ -SOURCES = """\ -static const uint8_t {escaped_id}_name[] = {{ -{name}}}; -static const uint8_t {escaped_id}_data[] = {{ -{data}}}; -""" +def Render(var, data): + # Treat non-ASCII as UTF-8 and convert it to UTF-16. + if any(ord(c) > 127 for c in data): + template = TWO_BYTE_STRING + data = map(ord, data.decode('utf-8').encode('utf-16be')) + data = [data[i] * 256 + data[i+1] for i in xrange(0, len(data), 2)] + data = ToCArray(data) + else: + template = ONE_BYTE_STRING + data = ToCString(data) + return template.format(var=var, data=data) def JS2C(source, target): @@ -207,36 +248,32 @@ def JS2C(source, target): (consts, macros) = ReadMacros(macro_lines) # Build source code lines - node_natives_map = [] - sources = [] + definitions = [] + initializers = [] - for s in modules: - lines = ReadFile(str(s)) + for name in modules: + lines = ReadFile(str(name)) lines = ExpandConstants(lines, consts) lines = ExpandMacros(lines, macros) - data = ToCString(lines) # On Windows, "./foo.bar" in the .gyp file is passed as "foo.bar" # so don't assume there is always a slash in the file path. - if '/' in s or '\\' in s: - id = '/'.join(re.split('/|\\\\', s)[1:]) - else: - id = s - - if '.' in id: - id = id.split('.', 1)[0] + if '/' in name or '\\' in name: + name = '/'.join(re.split('/|\\\\', name)[1:]) - name = ToCString(id) - escaped_id = id.replace('-', '_').replace('/', '_') - node_natives_map.append(NODE_NATIVES_MAP.format(**locals())) - sources.append(SOURCES.format(**locals())) + name = name.split('.', 1)[0] + var = name.replace('-', '_').replace('/', '_') + key = '%s_key' % var + value = '%s_value' % var - node_natives_map = ''.join(node_natives_map) - sources = ''.join(sources) + definitions.append(Render(key, name)) + definitions.append(Render(value, lines)) + initializers.append(INITIALIZER.format(key=key, value=value)) # Emit result output = open(str(target[0]), "w") - output.write(HEADER_TEMPLATE.format(**locals())) + output.write(TEMPLATE.format(definitions=''.join(definitions), + initializers=''.join(initializers))) output.close() def main(): diff --git a/tools/license2rtf.js b/tools/license2rtf.js index 694e1c60501414..4b3d71fe5b99e9 100644 --- a/tools/license2rtf.js +++ b/tools/license2rtf.js @@ -122,7 +122,7 @@ function ParagraphParser() { // Detect separator "lines" within a block. These mark a paragraph break // and are stripped from the output. - if (/^\s*[=*\-]{5,}\s*$/.test(line)) { + if (/^\s*[=*-]{5,}\s*$/.test(line)) { flushParagraph(); return; } @@ -286,7 +286,7 @@ function RtfGenerator() { function rtfEscape(string) { return string - .replace(/[\\\{\}]/g, function(m) { + .replace(/[\\{}]/g, function(m) { return '\\' + m; }) .replace(/\t/g, function() { diff --git a/tools/test.py b/tools/test.py index ebc755e0c484d6..f46b13fa30a66a 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1644,9 +1644,9 @@ def Main(): tempdir = os.environ.get('NODE_TEST_DIR') or options.temp_dir if tempdir: + os.environ['NODE_TEST_DIR'] = tempdir try: os.makedirs(tempdir) - os.environ['NODE_TEST_DIR'] = tempdir except OSError as exception: if exception.errno != errno.EEXIST: print "Could not create the temporary directory", options.temp_dir