commit 87d22a45162a2b436c874b644630a36af5017d58 Author: Thomas Fuhrmann Date: Mon Oct 2 15:04:02 2023 +0200 First commit diff --git a/cdconfig.json b/cdconfig.json new file mode 100644 index 0000000..b6ffb46 --- /dev/null +++ b/cdconfig.json @@ -0,0 +1,12 @@ +{ + "name": "tethys-data-provider", + "arcgisVersion": "11.1.0", + "parentServiceType": "FeatureServer", + "customdataRuntimeVersion": "1", + "type": "provider", + "properties": { + "hosts": false, + "disableIdParam": true + }, + "fileName": "tethys-data-provider.cdpk" +} diff --git a/config/default.json b/config/default.json new file mode 100644 index 0000000..0a63634 --- /dev/null +++ b/config/default.json @@ -0,0 +1,6 @@ +{ + "tethys": { + "url": "https://www.tethys.at/oai?verb=ListRecords&metadataPrefix=oai_datacite", + "resumptionUrl": "https://www.tethys.at/oai?verb=ListRecords&resumptionToken=" + } +} diff --git a/node_modules/.bin/json5 b/node_modules/.bin/json5 new file mode 100644 index 0000000..977b750 --- /dev/null +++ b/node_modules/.bin/json5 @@ -0,0 +1,12 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../json5/lib/cli.js" "$@" +else + exec node "$basedir/../json5/lib/cli.js" "$@" +fi diff --git a/node_modules/.bin/json5.cmd b/node_modules/.bin/json5.cmd new file mode 100644 index 0000000..95c137f --- /dev/null +++ b/node_modules/.bin/json5.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\json5\lib\cli.js" %* diff --git a/node_modules/.bin/json5.ps1 b/node_modules/.bin/json5.ps1 new file mode 100644 index 0000000..8700ddb --- /dev/null +++ b/node_modules/.bin/json5.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../json5/lib/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../json5/lib/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../json5/lib/cli.js" $args + } else { + & "node$exe" "$basedir/../json5/lib/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/xml-js b/node_modules/.bin/xml-js new file mode 100644 index 0000000..b4fd970 --- /dev/null +++ b/node_modules/.bin/xml-js @@ -0,0 +1,12 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../xml-js/bin/cli.js" "$@" +else + exec node "$basedir/../xml-js/bin/cli.js" "$@" +fi diff --git a/node_modules/.bin/xml-js.cmd b/node_modules/.bin/xml-js.cmd new file mode 100644 index 0000000..9ed1a53 --- /dev/null +++ b/node_modules/.bin/xml-js.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\xml-js\bin\cli.js" %* diff --git a/node_modules/.bin/xml-js.ps1 b/node_modules/.bin/xml-js.ps1 new file mode 100644 index 0000000..0fce225 --- /dev/null +++ b/node_modules/.bin/xml-js.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../xml-js/bin/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../xml-js/bin/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../xml-js/bin/cli.js" $args + } else { + & "node$exe" "$basedir/../xml-js/bin/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..0f8f50d --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,101 @@ +{ + "lockfileVersion": 2, + "requires": true, + "packages": { + "node_modules/config": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", + "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", + "dependencies": { + "json5": "^2.2.3" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mgrs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz", + "integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==" + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/proj4": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.9.0.tgz", + "integrity": "sha512-BoDXEzCVnRJVZoOKA0QHTFtYoE8lUxtX1jST38DJ8U+v1ixY70Kpwi0Llu6YqSWEH2xqu4XMEBNGcgeRIEywoA==", + "dependencies": { + "mgrs": "1.0.0", + "wkt-parser": "^1.3.1" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wkt-parser": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.3.3.tgz", + "integrity": "sha512-ZnV3yH8/k58ZPACOXeiHaMuXIiaTk1t0hSUVisbO0t4RjA5wPpUytcxeyiN2h+LZRrmuHIh/1UlrR9e7DHDvTw==" + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + } + } +} diff --git a/node_modules/config/History.md b/node_modules/config/History.md new file mode 100644 index 0000000..dbc19a4 --- /dev/null +++ b/node_modules/config/History.md @@ -0,0 +1,710 @@ +Beyond 3.3.7 +============ +We've moved this content to [Github Releases](https://github.com/node-config/node-config/releases). + +Future release notes are managed there. + +3.3.7 / 2022-01-11 +================== + + * No new changes. 3.3.6 was not published to NPM in versioning mix-up. + * Release notes are moving to Github Releases page going forward. + +3.3.6 / 2021-03-08 +================== + +* Added publishConfig element to package.json to prevent publishing to the wrong repository - @lorenwest + +3.3.5 / 2021-03-05 +================== + +* FIX [#628](https://github.com/node-config/node-config/issues/628) Uncaught ReferenceError: node_env_var_name is not defined @prnake + +3.3.4 / 2021-02-26 +================== + +* FIX #517 0 loadFileConfigs incorrectly adds to getConfigSources @NguyenMatthieu + +3.3.3 / 2020-11-26 +================== + +* FIX #460 - Strict mode warning refer to appropriate env variable @iCodeOkay +* Use Buffer.alloc and Buffer.from instead of contrsuctor @Fcmam5 +* Add support for experimental .cjs modules @lenkan + + +3.3.2 / 2020-09-24 +================== + +* Fixed issue with Buffers in config throwing error in util.makeImmutable (#608) - Michal Wadas +* Added boolean and numeric types to custom environment variables - Ankur Narkhede @ankurnarkhede + +3.3.1 / 2020-03-25 +================== + + * Fix security vulnerability in json5 dependency - @twkel + +3.3.0 / 2020-02-26 +================== + + * Allow all defined values in `substituteDeep` - @fostyfost + +3.2.6 / 2020-02-21 +================== + + * Updated copyright date ranges + +3.2.5 / 2020-01-16 +================== + + * Fixed issue with getCustomEnvVars and multiple config dirs #585 - @dekelev + +3.2.4 / 2019-10-25 +================== + + * Improved error handling of env variables value parse - @leonardovillela + +3.2.3 / 2019-10-03 +================== + + * Fixed strict mode warning #460 - @fedulovivan + +3.2.2 / 2019-07-20 +================== + + * Fixed delimiter bug in configDirs to match O/S delimiter - @iMoses + +3.2.1 / 2019-07-18 +================== + + * Fixed TypeError: obj.toString is not a function - @leosuncin + +3.2.0 / 2019-07-11 +================== + + * Asynchronous configs - @iMoses + * Multiple config directories - @iMoses + * Improved parser support - @iMoses + +3.1.0 / 2019-04-07 +================== + + * Support of module.exports syntax for TS config files @keenondrums + +3.0.1 / 2018-12-16 +================== + + * Fixed bug where dot notation extended own key @exogen + +3.0.0 / 2018-11-20 +================== + + * Ensure config array items and objects are sealed @fgheorghe + - This required a major version bump in case someone + - relied on the ability to mutate non-sealed data. + + +2.0.2 / 2018-08-28 +================== + + * Added dot notation to setModuleDefaults - bertho-zero + * Updated copyright year - JemiloII + +2.0.1 / 2018-07-26 +================== + + * Removed deprecated code - jpwilliams + +2.0.0 / 2018-07-26 +================== + +Potential for backward incompatibility requiring a major version bump. + +Safe to upgrade to major version 2 if you're using a recent NodeJS version +and you're not trying to mutate config arrays. + + * Added array immutability - jacobemerick + * Removed Node V.4 support + +1.31.0 / 2018-05-22 +=================== + + * Load new coffeescript module instead of coffee-script - bastbijl + +1.30.0 / 2018-02-26 +=================== + + * Support for nested raw() in javascript configurations - patrickpilch + +1.29.4 / 2018-02-03 +=================== + + * Re-publish - last changes didn't make it to npm + +1.29.3 / 2018-02-03 +=================== + + * Added soft dependencies so transpilers don't include everything - gewentao + +1.29.2 / 2018-01-12 +=================== + + * Patch, and added a test to ts-node - electroma + +1.29.1 / 2018-01-07 +=================== + + * Prevent re-registration of ts-node - electroma + * Fixed bug in contributor table tool - lorenwest + +1.29.0 / 2017-12-26 +=================== + + * Update docs for JavaScript-formatted config files and link them from the README - markstos + * Fixed 'hostname' value selection when there is no environment variable for that - wmangelardo + + +1.28.1 / 2017-11-09 +=================== + + * add nodejs9 to travisci - jfelege + +1.28.0 / 2017-11-07 +=================== + + * allow overrides of `NODE_ENV` with `NODE_CONFIG_ENV` - jfelege + +1.27.0 / 2017-10-17 +=================== + + * Add method to output plain JS object - willsoto + * Updated Node versions in Travis CI - lorenwest + +1.26.2 / 2017-08-11 +=================== + + * Update supported nodejs platforms - jfelege + +1.26.1 / 2017-05-03 +=================== + + * Fix: failed while merging from RegExp @XadillaX + * Chore: reduce package size. @evilebottnawi + +1.26.0 / 2017-03-30 +=================== + + * Added tests for extendDeep @IvanVergiliev + * Added TypeScript support @cypherq + * Update config.js with correctly cased type def @ScionOfBytes + +1.25.1 / 2017-02-01 +=================== + + * Fixed undefined CONFIG_SKIP_GITCRYPT variable @lorenwest + +1.25.0 / 2017-01-31 +=================== + + * Add support for configuration files stored with git-crypt @cunneen + +1.24.0 / 2016-11-02 +=================== + + * Prevent accidental publish to private repository + +1.23.0 / 2016-11-02 +=================== + + * Re-publishing because npmjs didn't see 1.22 + +1.22.0 / 2016-10-25 +=================== + + * original/previous value for deferredConfig @simon-scherzinger + * util.loadFileConfigs: support optional source dir @wmertens + * Adding raw wrapper to prevent object modification in config @patrickpilch + +1.21.0 / 2016-06-01 +=================== + + * Added XML configuration @tusharmath + +1.20.4 / 2016-05-23 +=================== + + * Fixed a regression with extending prototype methods @tahoemph + +1.20.3 / 2016-05-18 +=================== + + * Fixed a regression with 1.20.2 @kgoerlitz + * Added test to prevent this in the future @kgoerlitz + +1.20.2 / 2016-05-17 +=================== + + * node v6 compatiblity: remove deprecated __lookupGetter__ use - @thetalecrafter + * node v6 compatiblity: handle different SyntaxError format - @pwwolf + +1.20.1 / 2016-04-08 +=================== + + * Simplify truthiness check - @markstos + * Remove errant console.log - @markstos + +1.20.0 / 2016-04-06 +=================== + + * Typo fix @jchip + * Handle null sub-object @wmertens + * Bug fix for NODE_CONFIG_STRICT_MODE check @markstos + * Ran node security check on 4/6/2016 with the following output + + $ nsp check + (+) No known vulnerabilities found + +1.19.0 / 2016-01-08 +=================== + + * Resolve defered values in predictable order for consistent results. + Fixes #265 @elliotttf @markstos + +1.18.0 / 2015-11-17 +=================== + + * More robust handling of JSON @elliotttf + +1.17.1 / 2015-11-17 +=================== + + * Patch release for regex bugfix + +1.17.0 / 2015-11-17 +=================== + + * Update warning about missing configuration files to mention how to disable the warning #245 @markstos + * Upgrade to run CI with travis containers @lorenwest + * Fixed bug with comments and inline json @elliotttf + +1.16.0 / 2015-09-03 +=================== + + * Change == to === to tighten equality tests #242 @wgpsutherland + * Fix attachProtoDeep for setModuleDefaults #243 @benkroeger + +1.15.0 / 2015-07-30 +=================== + + * Added full hostname in addition to first segment @vicary + +1.14.0 / 2015-06-02 +=================== + + * Added JSON parsing to custom environment variables @leachiM2k + * Handle unicode BOM characters @johndkane + +1.13.0 / 2015-05-05 +=================== + + * Updated CSON library @dsimidzija + +1.12.0 / 2015-02-19 +=================== + + * Better date merging @axelhzf + +1.11.0 / 2015-01-14 +=================== + + * Added Hjson support @laktak + +1.10.0 / 2015-01-06 +=================== + + * Added TOML support (@jasonhansel) + * Another year - changed copyright messages for 2015 + * Updated contributors list + * New Strict Mode added in 1.9.0 is now documented. (@markstos) + * has() now returns false when given an undefined or null key to look up. Previously it threw an exception. (@markstos) + * When get() is given an undefined or null key to look up, it now throws a more helpful diagnostic (@robludwig, @markstos) + +1.9.0 / 2014-12-08 +================== + + * New strictness checks have been added to ensure the expected configuration has been loaded. Warnings are now thrown in these cases. If NODE_CONFIG_STRICT_MODE is set, exceptions are thrown instead. (@markstos) + * There must be an explicit config file matching `NODE_ENV` if `NODE_ENV` is set. + * There must be an explicit config file matching `NODE_APP_INSTANCE` if `NODE_APP_INSTANCE` is set + * `NODE_ENV` must not match 'default' or 'local' to avoid ambiguity. + + * Added .iced extension support (@arthanzel) + + * Highlight `config.has()` in the README. Use it to check to if a value exists, since `config.get()` + throws exceptions on undefined values. (@markstos) + + * API Change: getConfigSources() now starts to return data on config files that are valid-but-empty. (@markstos) + +1.8.1 / 2014-11-14 +================== + + * Simplify syntax for defer() functions. The 'this' value in the functions is now bound + to the main configuration object, so it doesn't have to be passed into the function. (@markstos) + * new defer sub-module introduced in 1.8.0 can now be accessed by require('config/defer') + For usage, see: https://github.com/node-config/node-config/wiki/Configuration-Files#javascript-module---js + * Add test coverage for array merging cases. (@markstos) + * Bump dependency on cson package to 1.6.1 (@markstos) + +1.8.0 / 2014-11-13 +================== + + * Added deferred function for evaluating configs after load (@markstos) + For details, see: https://github.com/node-config/node-config/wiki/Configuration-Files#javascript-module---js + * Bumped js-yaml dependency (@markstos) + +1.7.0 / 2014-10-30 +================== + + * Added variable substitution in .properties files (@ncuillery) + +1.6.0 / 2014-10-22 +================== + + * Added support for property accessors in configs (@jaylynch) + +1.5.0 / 2014-10-20 +================== + + * Added support for .json5 config files (@bertrandom) + +1.4.0 / 2014-10-16 +================== + + * Added support for .properties config files (@superoven) + +1.3.0 / 2014-10-15 +================== + + * Added support for CSON configuration files (@superoven) + +1.2.4 / 2014-10-10 +================== + + * Repaired the 1.2.3 fix to work both before and after the first get() + +1.2.3 / 2014-10-03 +================== + + * Changed test suite to verify a bug in util.setModuleDefaults() + * Fixed util.setModuleDefaults() to work after a get() (and pass the new test) + +1.2.2 / 2014-10-03 +================== + + * Added support for regexp and date configurations (@diversario) + +1.2.1 / 2014-09-23 +================== + + * Wrote test to prove setModuleDefaults() was broken in 1.2.0 + * Fixed setModuleDefaults() to not rely on immutable configs + +1.2.0 / 2014-09-15 +================== + + * Feature release + * Delaying immutability until after first get() - for external configs + * Allowing immutability override with $ALLOW_CONFIG_MUTATIONS=Y + + +1.1.1 / 2014-09-03 +================== + + * @th507 - Update support for Coffee-script >=1.7.0 + +1.1.0 / 2014-09-03 +================== + + * Feature release + * @bradboro - Custom environment variables + * @supersheep - Catch error when requiring visionmedia yaml module + +1.0.2 / 2014-07-30 +=================== + + * @bradobro - Fixed a variable from leaking into global + * @tilfin - Removed un-necessary YAML comment filtering for js-yaml + +1.0.1 / 2014-07-25 +=================== + + * Removed test directory from npm install + +1.0.0 / 2014-07-23 +=================== + + * Major revision. Upgrade notes: + https://github.com/node-config/node-config/wiki/Upgrading-From-Config-0.x + * Update to semver versioning + * Change load ordering + from hostname.EXT --> deployment.EXT + to deployment.EXT --> hostname.EXT + * Allow makeImmutable to accept an array of attributes + * Allow makeImmutable to accept no attrs, making all attributes immutable + * Allow recursion in makeImmutable, if an attribute is an object + * Change node-config behavior to make all configurations immutable + * Removed getOriginalConfig as no longer necessary post-immutable + * Removed runtime.json file writing and monitoring + * Removed previously deprecated $CONFIG_* environment configurations + * Deprecated the attribute watch functionality + * Added error output if no configurations found + * Exposed config loading for alternate configurations + * Added config.get() and config.has() methods & tests + * Removed reliance on global.NODE_CONFIG so older versions can work with 1.x + * Fix empty YAML file causing crash with latest js-yaml + * Added SUPPRESS_NO_CONFIG_WARNING for better sub-module support + * Moved all documentation [to the wiki](https://github.com/node-config/node-config/wiki). + +0.4.37 / 2014-07-22 +=================== + + * Fix empty YAML file causing crash with latest js-yaml + +0.4.36 / 2014-05-27 +=================== + + * Not writing runtime.json if not used + +0.4.35 / 2014-01-16 +=================== + + * NODE_CONFIG_DIR can now contain a relative path for .js and .coffee configurations + +0.4.34 / 2014-01-06 +=================== + + * Updated copyright year + +0.4.33 / 2013-10-25 +=================== + + * Assure writes to runtime.json are atomic + +0.4.32 / 2013-10-24 +=================== + + * Don't freak out if running without a config directory + * Don't be so chatty if runtime.json doesn't exist + +0.4.31 / 2013-10-18 +=================== + + * Changed getConfigSources to copy array vs. object + +0.4.30 / 2013-09-12 +=================== + + * More consistent array extension + * No longer requiring a config directory + * Not erroneously writing runtime.json + * Exposing the original configuration sources + * Added --NODE_CONFIG={json} command line overrides + * Added $NODE_CONFIG={json} environment variable overrides + * Consistent handling of environment variables and command line parameters + * Reached 100 regression tests + +0.4.29 / 2013-08-07 +=================== + + * Added flag for disabling the write of runtime.json + +0.4.28 / 2013-07-31 +=================== + + * Eliminated a totally annoying install warning in newer versions of NPM + +0.4.27 / 2013-06-18 +=================== + + * Fixed a bug preventing double underscores in config environment variables + +0.4.26 / 2013-06-10 +=================== + + * Re-watch file on rename (allows editing runtime.json with vi) + * Allow runtime.json file watch disable via NODE_CONFIG_DISABLE_FILE_WATCH=Y + * Change no yaml parser error message to suggest using js-yaml + * Changed default clone depth from 6 to 20 to allow for deeper configurations + +0.4.25 / 2013-05-24 +=================== + + * Dont fail if config directory doesnt exist + +0.4.24 / 2013-04-13 +=================== + + * Added resetRuntime() to reset the runtime.json file + * Updated docs to reflect the new public method + +0.4.23 / 2013-04-13 +=================== + + * Multiple application instance support via $NODE_APP_INSTANCE + * Multi-app testing & documentation + +0.4.22 / 2013-03-29 +=================== + + * Added configuration $CONFIG_* environment variables + * Added $CONFIG_* documentation and tests + * Added NodeJS 0.10 integration test + +0.4.21 / 2013-03-06 +=================== + + * Triggering file.watch when an editor saves a file - rename vs. change + * Installed Travis-CI continuous integration testing framework + +0.4.20 / 2013-02-21 +=================== + + * Merged _diffDeep fix + +0.4.19 / 2013-02-21 +=================== + + * Added discovery of .yml in addition to .yaml for YAML configs (w/doc) + * Added testing of .yml file discovery + * Removed licensing inconsistencies + +0.4.18 / 2012-10-30 +=================== + + * Moved coffee-script and js-yaml from optionalDependencies back to + devDependencies to trim the install size for those not needing + these packages. + * Promoted $HOSTNAME and $HOST above OS.hostname() + +0.4.17 / 2012-09-26 +=================== + + * Allow the location of runtime.json to be picked up from the environment + * Added documentation for the NODE_CONFIG_RUNTIME_JSON environment variable + * package.json cleanup - created optionalDependencies and devDependencies + +0.4.16 / 2012-08-09 +=================== + + * Allowing a zero interval in watchForConfigFileChanges() to disable file watching. + * Fixed a comparator bug in _equalsDeep() + * Added a test to confirm deep extending array functionality + +0.4.15 / 2012-06-04 +=================== + + * Placed YAML and Coffee-Script libraries back into the download. Still lazy loading into memory. + +0.4.14 / 2012-06-01 +=================== + + * Added the local.EXT and local-deployment.EXT configs. + * Removed unnecessary debug output + * Added retry logic on file parse to reduce read/write collisions + * Added support for a better YAML parser + * Fixed problems with null configuration values + +0.4.13 / 2012-04-25 +=================== + + * Assuring the runtime.json file exists. Undocumented fs.watch() requirement. + +0.4.12 / 2012-04-25 +=================== + + * Removed all external dependencies + * Lazy loading of yaml and coffee-script only if these file types are used + * Added new style file watching if available (retaining pre 6.0 compatibility) + * Windows compatibility - file watching changes were required + +0.4.11 / 2012-02-15 +=================== + + * Automatically watching runtime.json for changes + * Fixed a date comparison bug during file watching + * Changed require('sys') to require('util') + +0.4.10 / 2012-01-18 +=================== + + * Made sure the CONFIG object is a shared singleton + * Added NODE_CONFIG_DIR environment variable to point to a different directory + * Added tests and documentation for the above + +0.4.9 / 2012-01-06 +================== + + * Added coffee-script file type support with extension .coffee + * Added an example coffee-script configuration file + * Added coffee-script module dependency + * Added a test for coffee-script configuration files + * Documented coffee-script support, regenerated documentation + +0.4.8 / 2011-12-20 +================== + + * Fixed a bug where changes to module default configs weren't persisted + * Added a test to validate the bugfix + +0.4.7 / 2011-12-16 +================== + + * Created the makeHidden method to hide a property of an object + * Added a value argument to makeImmutable for creating new properties + * Fixed setModuleDefaults to hide injected prototype methods + * Added documentation and unit tests + +0.4.6 / 2011-11-29 +================== + + * Updated vows from 0.5.8 to 0.5.13 + +0.4.5 / 2011-11-16 +================== + + * Updated YAML dependency from "0.1.x" to ">=0.2.2" + * Added stripping of comment-only and whitespace-only lines in YAML files for backward compatibility + * Added more tests for YAML edge cases + * Added a homepage link in package.json to the online documentation + * Added History.md + +0.4.4 / 2011-11-08 +================== + + * Removed deprecated modules from package.json + +0.4.3 / 2011-08-02 +================== + + * Made watchForConfigFileChanges public + +0.4.2 / 2011-07-11 +================== + + * Added comment stripping from JSON configuration files + +0.4.1 / 2011-07-07 +================== + + * Added more tests + * Return the module config in setModuleDefaults + +0.4.0 / 2011-07-06 +================== + + * Update to version 0.4.0 + + * Online documentation + * Runtime configuration changes + * Configuration value watching + * Multi-instance node deployments + * Better module developer support diff --git a/node_modules/config/LICENSE b/node_modules/config/LICENSE new file mode 100644 index 0000000..e331b7a --- /dev/null +++ b/node_modules/config/LICENSE @@ -0,0 +1,19 @@ +// Copyright 2010-2022, Loren West 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. diff --git a/node_modules/config/README.md b/node_modules/config/README.md new file mode 100644 index 0000000..4b6f445 --- /dev/null +++ b/node_modules/config/README.md @@ -0,0 +1,176 @@ +Configure your Node.js Applications +=================================== + +[![NPM](https://nodei.co/npm/config.svg?downloads=true&downloadRank=true)](https://nodei.co/npm/config/)   +[![Build Status](https://secure.travis-ci.org/node-config/node-config.svg?branch=master)](https://travis-ci.org/lorenwest/node-config)   +[release notes](https://github.com/node-config/node-config/blob/master/History.md) + +Introduction +------------ + +Node-config organizes hierarchical configurations for your app deployments. + +It lets you define a set of default parameters, +and extend them for different deployment environments (development, qa, +staging, production, etc.). + +Configurations are stored in [configuration files](https://github.com/node-config/node-config/wiki/Configuration-Files) within your application, and can be overridden and extended by [environment variables](https://github.com/lorenwest/node-config/wiki/Environment-Variables), + [command line parameters](https://github.com/node-config/node-config/wiki/Command-Line-Overrides), or [external sources](https://github.com/lorenwest/node-config/wiki/Configuring-from-an-External-Source). + +This gives your application a consistent configuration interface shared among a +[growing list of npm modules](https://www.npmjs.org/browse/depended/config) also using node-config. + +Project Guidelines +------------------ + +* *Simple* - Get started fast +* *Powerful* - For multi-node enterprise deployment +* *Flexible* - Supporting multiple config file formats +* *Lightweight* - Small file and memory footprint +* *Predictable* - Well tested foundation for module and app developers + +Quick Start +--------------- +The following examples are in JSON format, but configurations can be in other [file formats](https://github.com/node-config/node-config/wiki/Configuration-Files#file-formats). + +**Install in your app directory, and edit the default config file.** + +```shell +$ npm install config +$ mkdir config +$ vi config/default.json +``` +```js +{ + // Customer module configs + "Customer": { + "dbConfig": { + "host": "localhost", + "port": 5984, + "dbName": "customers" + }, + "credit": { + "initialLimit": 100, + // Set low for development + "initialDays": 1 + } + } +} +``` + +**Edit config overrides for production deployment:** + +```shell + $ vi config/production.json +``` + +```json +{ + "Customer": { + "dbConfig": { + "host": "prod-db-server" + }, + "credit": { + "initialDays": 30 + } + } +} +``` + +**Use configs in your code:** + +```js +const config = require('config'); +//... +const dbConfig = config.get('Customer.dbConfig'); +db.connect(dbConfig, ...); + +if (config.has('optionalFeature.detail')) { + const detail = config.get('optionalFeature.detail'); + //... +} +``` + +`config.get()` will throw an exception for undefined keys to help catch typos and missing values. +Use `config.has()` to test if a configuration value is defined. + +**Start your app server:** + +```shell +$ export NODE_ENV=production +$ node my-app.js +``` + +Running in this configuration, the `port` and `dbName` elements of `dbConfig` +will come from the `default.json` file, and the `host` element will +come from the `production.json` override file. + +Articles +-------- + +* [Configuration Files](https://github.com/node-config/node-config/wiki/Configuration-Files) + * [Special features for JavaScript configuration files](https://github.com/node-config/node-config/wiki/Special-features-for-JavaScript-configuration-files) +* [Common Usage](https://github.com/node-config/node-config/wiki/Common-Usage) +* [Environment Variables](https://github.com/node-config/node-config/wiki/Environment-Variables) +* [Reserved Words](https://github.com/node-config/node-config/wiki/Reserved-Words) +* [Command Line Overrides](https://github.com/node-config/node-config/wiki/Command-Line-Overrides) +* [Multiple Node Instances](https://github.com/node-config/node-config/wiki/Multiple-Node-Instances) +* [Sub-Module Configuration](https://github.com/node-config/node-config/wiki/Sub-Module-Configuration) +* [Configuring from a DB / External Source](https://github.com/node-config/node-config/wiki/Configuring-from-an-External-Source) +* [Securing Production Config Files](https://github.com/node-config/node-config/wiki/Securing-Production-Config-Files) +* [External Configuration Management Tools](https://github.com/node-config/node-config/wiki/External-Configuration-Management-Tools) +* [Examining Configuration Sources](https://github.com/node-config/node-config/wiki/Examining-Configuration-Sources) +* [Using Config Utilities](https://github.com/node-config/node-config/wiki/Using-Config-Utilities) +* [Upgrading from Config 0.x](https://github.com/node-config/node-config/wiki/Upgrading-From-Config-0.x) +* [Webpack usage](https://github.com/node-config/node-config/wiki/Webpack-Usage) + +Further Information +--------------------- +If you still don't see what you are looking for, here are some more resources to check: + + * The [wiki may have more pages](https://github.com/node-config/node-config/wiki) which are not directly linked from here. + * Review [questions tagged with node-config](https://stackexchange.com/filters/207096/node-config) on StackExchange. These are monitored by `node-config` contributors. + * [Search the issue tracker](https://github.com/node-config/node-config/issues). Hundreds of issues have already been discussed and resolved there. + +Contributors +------------ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
lorenwestmarkstosiMoseselliotttfjfelegeleachiM2k
josxenyoleosuncinarthanzeleheikesth507
OsterjourcunneennsabovicBadgerBadgerBadgerBadgersimon-scherzingerleonardovillela
axelhzfbenkroegerfgheorgheIvanVergilievjpwilliamsjaylynch
jberrischkgoerlitzbertho-zeroNguyenMatthieunitzan-shakedrobertrossmann
+ +License +------- + +May be freely distributed under the [MIT license](https://raw.githubusercontent.com/node-config/node-config/master/LICENSE). + +Copyright (c) 2010-2022 Loren West +[and other contributors](https://github.com/node-config/node-config/graphs/contributors) + diff --git a/node_modules/config/async.js b/node_modules/config/async.js new file mode 100644 index 0000000..8aa55ec --- /dev/null +++ b/node_modules/config/async.js @@ -0,0 +1,70 @@ +var asyncSymbol = Symbol('asyncSymbol'); +var deferConfig = require('./defer').deferConfig; + +/** + * @param promiseOrFunc the promise will determine a property's value once resolved + * can also be a function to defer which resolves to a promise + * @returns {Promise} a marked promise to be resolve later using `resolveAsyncConfigs` + */ +function asyncConfig(promiseOrFunc) { + if (typeof promiseOrFunc === 'function') { // also acts as deferConfig + return deferConfig(function (config, original) { + var release; + function registerRelease(resolve) { release = resolve; } + function callFunc() { return promiseOrFunc.call(config, config, original); } + var promise = asyncConfig(new Promise(registerRelease).then(callFunc)); + promise.release = release; + return promise; + }); + } + var promise = promiseOrFunc; + promise.async = asyncSymbol; + promise.prepare = function(config, prop, property) { + if (promise.release) { + promise.release(); + } + return function() { + return promise.then(function(value) { + Object.defineProperty(prop, property, {value: value}); + }); + }; + }; + return promise; +} + +/** + * Do not use `config.get` before executing this method, it will freeze the config object + * @param config the main config object, returned from require('config') + * @returns {Promise} once all promises are resolved, return the original config object + */ +function resolveAsyncConfigs(config) { + var promises = []; + var resolvers = []; + (function iterate(prop) { + var propsToSort = []; + for (var property in prop) { + if (Object.hasOwnProperty.call(prop, property) && prop[property] != null) { + propsToSort.push(property); + } + } + propsToSort.sort().forEach(function(property) { + if (prop[property].constructor === Object) { + iterate(prop[property]); + } + else if (prop[property].constructor === Array) { + prop[property].forEach(iterate); + } + else if (prop[property] && prop[property].async === asyncSymbol) { + resolvers.push(prop[property].prepare(config, prop, property)); + promises.push(prop[property]); + } + }); + })(config); + return Promise.all(promises).then(function() { + resolvers.forEach(function(resolve) { resolve(); }); + return config; + }); +} + +module.exports.asyncConfig = asyncConfig; +module.exports.resolveAsyncConfigs = resolveAsyncConfigs; diff --git a/node_modules/config/defer.js b/node_modules/config/defer.js new file mode 100644 index 0000000..35758d8 --- /dev/null +++ b/node_modules/config/defer.js @@ -0,0 +1,23 @@ +// Create a deferredConfig prototype so that we can check for it when reviewing the configs later. +function DeferredConfig() {} +DeferredConfig.prototype.prepare = function() {}; +DeferredConfig.prototype.resolve = function() {}; + +// Accept a function that we'll use to resolve this value later and return a 'deferred' configuration value to resolve it later. +function deferConfig(func) { + var obj = Object.create(DeferredConfig.prototype); + obj.prepare = function(config, prop, property) { + var original = prop[property]._original; + obj.resolve = function() { + var value = func.call(config, config, original); + Object.defineProperty(prop, property, {value: value}); + return value; + }; + Object.defineProperty(prop, property, {get: function() { return obj.resolve(); }}); + return obj; + }; + return obj; +} + +module.exports.deferConfig = deferConfig; +module.exports.DeferredConfig = DeferredConfig; diff --git a/node_modules/config/lib/config.js b/node_modules/config/lib/config.js new file mode 100644 index 0000000..0132170 --- /dev/null +++ b/node_modules/config/lib/config.js @@ -0,0 +1,1521 @@ +// config.js (c) 2010-2022 Loren West and other contributors +// May be freely distributed under the MIT license. +// For further details and documentation: +// http://lorenwest.github.com/node-config + +// Dependencies +var DeferredConfig = require('../defer').DeferredConfig, + RawConfig = require('../raw').RawConfig, + Parser = require('../parser'), + Utils = require('util'), + Path = require('path'), + FileSystem = require('fs'); + +// Static members +var DEFAULT_CLONE_DEPTH = 20, + CONFIG_DIR, NODE_ENV, APP_INSTANCE, + CONFIG_SKIP_GITCRYPT, NODE_ENV_VAR_NAME, + NODE_CONFIG_PARSER, + env = {}, + configSources = [], // Configuration sources - array of {name, original, parsed} + checkMutability = true, // Check for mutability/immutability on first get + gitCryptTestRegex = /^.GITCRYPT/; // regular expression to test for gitcrypt files. + +/** + *

Application Configurations

+ * + *

+ * The config module exports a singleton object representing all + * configurations for this application deployment. + *

+ * + *

+ * Application configurations are stored in files within the config directory + * of your application. The default configuration file is loaded, followed + * by files specific to the deployment type (development, testing, staging, + * production, etc.). + *

+ * + *

+ * For example, with the following config/default.yaml file: + *

+ * + *
+ *   ...
+ *   customer:
+ *       initialCredit: 500
+ *       db:
+ *           name: customer
+ *           port: 5984
+ *   ...
+ * 
+ * + *

+ * The following code loads the customer section into the CONFIG variable: + *

+ * + *

+ *   var CONFIG = require('config').customer;
+ *   ...
+ *   newCustomer.creditLimit = CONFIG.initialCredit;
+ *   database.open(CONFIG.db.name, CONFIG.db.port);
+ *   ...
+ * 
+ * + * @module config + * @class Config + */ + +/** + *

Get the configuration object.

+ * + *

+ * The configuration object is a shared singleton object within the application, + * attained by calling require('config'). + *

+ * + *

+ * Usually you'll specify a CONFIG variable at the top of your .js file + * for file/module scope. If you want the root of the object, you can do this: + *

+ *
+ * var CONFIG = require('config');
+ * 
+ * + *

+ * Sometimes you only care about a specific sub-object within the CONFIG + * object. In that case you could do this at the top of your file: + *

+ *
+ * var CONFIG = require('config').customer;
+ * or
+ * var CUSTOMER_CONFIG = require('config').customer;
+ * 
+ * + * + * + * @method constructor + * @return CONFIG {object} - The top level configuration object + */ +var Config = function() { + var t = this; + + // Bind all utility functions to this + for (var fnName in util) { + if (typeof util[fnName] === 'function') { + util[fnName] = util[fnName].bind(t); + } + } + + // Merge configurations into this + util.extendDeep(t, util.loadFileConfigs()); + util.attachProtoDeep(t); + + // Perform strictness checks and possibly throw an exception. + util.runStrictnessChecks(t); +}; + +/** + * Utilities are under the util namespace vs. at the top level + */ +var util = Config.prototype.util = {}; + +/** + * Underlying get mechanism + * + * @private + * @method getImpl + * @param object {object} - Object to get the property for + * @param property {string|string[]} - The property name to get (as an array or '.' delimited string) + * @return value {*} - Property value, including undefined if not defined. + */ +var getImpl= function(object, property) { + var t = this, + elems = Array.isArray(property) ? property : property.split('.'), + name = elems[0], + value = object[name]; + if (elems.length <= 1) { + return value; + } + // Note that typeof null === 'object' + if (value === null || typeof value !== 'object') { + return undefined; + } + return getImpl(value, elems.slice(1)); +}; + +/** + *

Get a configuration value

+ * + *

+ * This will return the specified property value, throwing an exception if the + * configuration isn't defined. It is used to assure configurations are defined + * before being used, and to prevent typos. + *

+ * + * @method get + * @param property {string} - The configuration property to get. Can include '.' sub-properties. + * @return value {*} - The property value + */ +Config.prototype.get = function(property) { + if(property === null || property === undefined){ + throw new Error("Calling config.get with null or undefined argument"); + } + + // Make configurations immutable after first get (unless disabled) + if (checkMutability) { + if (!util.initParam('ALLOW_CONFIG_MUTATIONS', false)) { + util.makeImmutable(config); + } + checkMutability = false; + } + var t = this, + value = getImpl(t, property); + + // Produce an exception if the property doesn't exist + if (value === undefined) { + throw new Error('Configuration property "' + property + '" is not defined'); + } + + // Return the value + return value; +}; + +/** + * Test that a configuration parameter exists + * + *
+ *    var config = require('config');
+ *    if (config.has('customer.dbName')) {
+ *      console.log('Customer database name: ' + config.customer.dbName);
+ *    }
+ * 
+ * + * @method has + * @param property {string} - The configuration property to test. Can include '.' sub-properties. + * @return isPresent {boolean} - True if the property is defined, false if not defined. + */ +Config.prototype.has = function(property) { + // While get() throws an exception for undefined input, has() is designed to test validity, so false is appropriate + if(property === null || property === undefined){ + return false; + } + var t = this; + return (getImpl(t, property) !== undefined); +}; + +/** + *

+ * Set default configurations for a node.js module. + *

+ * + *

+ * This allows module developers to attach their configurations onto the + * default configuration object so they can be configured by the consumers + * of the module. + *

+ * + *

Using the function within your module:

+ *
+ *   var CONFIG = require("config");
+ *   CONFIG.util.setModuleDefaults("MyModule", {
+ *     templateName: "t-50",
+ *     colorScheme: "green"
+ *   });
+ * 
+ * // Template name may be overridden by application config files + * console.log("Template: " + CONFIG.MyModule.templateName); + *
+ * + *

+ * The above example results in a "MyModule" element of the configuration + * object, containing an object with the specified default values. + *

+ * + * @method setModuleDefaults + * @param moduleName {string} - Name of your module. + * @param defaultProperties {object} - The default module configuration. + * @return moduleConfig {object} - The module level configuration object. + */ +util.setModuleDefaults = function (moduleName, defaultProperties) { + + // Copy the properties into a new object + var t = this, + moduleConfig = util.cloneDeep(defaultProperties); + + // Set module defaults into the first sources element + if (configSources.length === 0 || configSources[0].name !== 'Module Defaults') { + configSources.splice(0, 0, { + name: 'Module Defaults', + parsed: {} + }); + } + util.setPath(configSources[0].parsed, moduleName.split('.'), {}); + util.extendDeep(getImpl(configSources[0].parsed, moduleName), defaultProperties); + + // Create a top level config for this module if it doesn't exist + util.setPath(t, moduleName.split('.'), getImpl(t, moduleName) || {}); + + // Extend local configurations into the module config + util.extendDeep(moduleConfig, getImpl(t, moduleName)); + + // Merge the extended configs without replacing the original + util.extendDeep(getImpl(t, moduleName), moduleConfig); + + // reset the mutability check for "config.get" method. + // we are not making t[moduleName] immutable immediately, + // since there might be more modifications before the first config.get + if (!util.initParam('ALLOW_CONFIG_MUTATIONS', false)) { + checkMutability = true; + } + + // Attach handlers & watchers onto the module config object + return util.attachProtoDeep(getImpl(t, moduleName)); +}; + +/** + *

Make a configuration property hidden so it doesn't appear when enumerating + * elements of the object.

+ * + *

+ * The property still exists and can be read from and written to, but it won't + * show up in for ... in loops, Object.keys(), or JSON.stringify() type methods. + *

+ * + *

+ * If the property already exists, it will be made hidden. Otherwise it will + * be created as a hidden property with the specified value. + *

+ * + *

+ * This method was built for hiding configuration values, but it can be applied + * to any javascript object. + *

+ * + *

Example:

+ *
+ *   var CONFIG = require('config');
+ *   ...
+ *
+ *   // Hide the Amazon S3 credentials
+ *   CONFIG.util.makeHidden(CONFIG.amazonS3, 'access_id');
+ *   CONFIG.util.makeHidden(CONFIG.amazonS3, 'secret_key');
+ * 
+ * + * @method makeHidden + * @param object {object} - The object to make a hidden property into. + * @param property {string} - The name of the property to make hidden. + * @param value {*} - (optional) Set the property value to this (otherwise leave alone) + * @return object {object} - The original object is returned - for chaining. + */ +util.makeHidden = function(object, property, value) { + + // If the new value isn't specified, just mark the property as hidden + if (typeof value === 'undefined') { + Object.defineProperty(object, property, { + enumerable : false + }); + } + // Otherwise set the value and mark it as hidden + else { + Object.defineProperty(object, property, { + value : value, + enumerable : false + }); + } + + return object; +} + +/** + *

Make a javascript object property immutable (assuring it cannot be changed + * from the current value).

+ *

+ * If the specified property is an object, all attributes of that object are + * made immutable, including properties of contained objects, recursively. + * If a property name isn't supplied, all properties of the object are made + * immutable. + *

+ *

+ * + *

+ *

+ * New properties can be added to the object and those properties will not be + * immutable unless this method is called on those new properties. + *

+ *

+ * This operation cannot be undone. + *

+ * + *

Example:

+ *
+ *   var config = require('config');
+ *   var myObject = {hello:'world'};
+ *   config.util.makeImmutable(myObject);
+ * 
+ * + * @method makeImmutable + * @param object {object} - The object to specify immutable properties for + * @param [property] {string | [string]} - The name of the property (or array of names) to make immutable. + * If not provided, all owned properties of the object are made immutable. + * @param [value] {* | [*]} - Property value (or array of values) to set + * the property to before making immutable. Only used when setting a single + * property. Retained for backward compatibility. + * @return object {object} - The original object is returned - for chaining. + */ +util.makeImmutable = function(object, property, value) { + if (Buffer.isBuffer(object)) { + return object; + } + var properties = null; + + // Backwards compatibility mode where property/value can be specified + if (typeof property === 'string') { + return Object.defineProperty(object, property, { + value : (typeof value === 'undefined') ? object[property] : value, + writable : false, + configurable: false + }); + } + + // Get the list of properties to work with + if (Array.isArray(property)) { + properties = property; + } + else { + properties = Object.keys(object); + } + + // Process each property + for (var i = 0; i < properties.length; i++) { + var propertyName = properties[i], + value = object[propertyName]; + + if (value instanceof RawConfig) { + Object.defineProperty(object, propertyName, { + value: value.resolve(), + writable: false, + configurable: false + }); + } else if (Array.isArray(value)) { + // Ensure object items of this array are also immutable. + value.forEach((item, index) => { if (util.isObject(item) || Array.isArray(item)) util.makeImmutable(item) }) + + Object.defineProperty(object, propertyName, { + value: Object.freeze(value) + }); + } else { + // Call recursively if an object. + if (util.isObject(value)) { + // Create a proxy, to capture user updates of configuration options, and throw an exception for awareness, as per: + // https://github.com/lorenwest/node-config/issues/514 + value = new Proxy(util.makeImmutable(value), { + set (target, name) { + const message = (Reflect.has(target, name) ? 'update' : 'add'); + // Notify the user. + throw Error(`Can not ${message} runtime configuration property: "${name}". Configuration objects are immutable unless ALLOW_CONFIG_MUTATIONS is set.`) + } + }) + } + + Object.defineProperty(object, propertyName, { + value: value, + writable : false, + configurable: false + }); + + // Ensure new properties can not be added, as per: + // https://github.com/lorenwest/node-config/issues/505 + Object.preventExtensions(object[propertyName]) + } + } + + return object; +}; + +/** + * Return the sources for the configurations + * + *

+ * All sources for configurations are stored in an array of objects containing + * the source name (usually the filename), the original source (as a string), + * and the parsed source as an object. + *

+ * + * @method getConfigSources + * @return configSources {Array[Object]} - An array of objects containing + * name, original, and parsed elements + */ +util.getConfigSources = function() { + var t = this; + return configSources.slice(0); +}; + +/** + * Looks into an options object for a specific attribute + * + *

+ * This method looks into the options object, and if an attribute is defined, returns it, + * and if not, returns the default value + *

+ * + * @method getOption + * @param options {Object | undefined} the options object + * @param optionName {string} the attribute name to look for + * @param defaultValue { any } the default in case the options object is empty, or the attribute does not exist. + * @return options[optionName] if defined, defaultValue if not. + */ +util.getOption = function(options, optionName, defaultValue) { + if (options !== undefined && options[optionName] !== undefined){ + return options[optionName]; + } else { + return defaultValue; + } +}; + + +/** + * Load the individual file configurations. + * + *

+ * This method builds a map of filename to the configuration object defined + * by the file. The search order is: + *

+ * + *
+ *   default.EXT
+ *   (deployment).EXT
+ *   (hostname).EXT
+ *   (hostname)-(deployment).EXT
+ *   local.EXT
+ *   local-(deployment).EXT
+ *   runtime.json
+ * 
+ * + *

+ * EXT can be yml, yaml, coffee, iced, json, cson or js signifying the file type. + * yaml (and yml) is in YAML format, coffee is a coffee-script, iced is iced-coffee-script, + * json is in JSON format, cson is in CSON format, properties is in .properties format + * (http://en.wikipedia.org/wiki/.properties), and js is a javascript executable file that is + * require()'d with module.exports being the config object. + *

+ * + *

+ * hostname is the $HOST environment variable (or --HOST command line parameter) + * if set, otherwise the $HOSTNAME environment variable (or --HOSTNAME command + * line parameter) if set, otherwise the hostname found from + * require('os').hostname(). + *

+ * + *

+ * Once a hostname is found, everything from the first period ('.') onwards + * is removed. For example, abc.example.com becomes abc + *

+ * + *

+ * (deployment) is the deployment type, found in the $NODE_ENV environment + * variable (which can be overridden by using $NODE_CONFIG_ENV + * environment variable). Defaults to 'development'. + *

+ * + *

+ * The runtime.json file contains configuration changes made at runtime either + * manually, or by the application setting a configuration value. + *

+ * + *

+ * If the $NODE_APP_INSTANCE environment variable (or --NODE_APP_INSTANCE + * command line parameter) is set, then files with this appendage will be loaded. + * See the Multiple Application Instances section of the main documentation page + * for more information. + *

+ * + * @protected + * @method loadFileConfigs + * @param configDir { string | null } the path to the directory containing the configurations to load + * @param options { object | undefined } parsing options. Current supported option: skipConfigSources: true|false + * @return config {Object} The configuration object + */ +util.loadFileConfigs = function(configDir, options) { + + // Initialize + var t = this, + config = {}; + + // Specify variables that can be used to define the environment + var node_env_var_names = ['NODE_CONFIG_ENV', 'NODE_ENV']; + + // Loop through the variables to try and set environment + for (const node_env_var_name of node_env_var_names) { + NODE_ENV = util.initParam(node_env_var_name); + if (!!NODE_ENV) { + NODE_ENV_VAR_NAME = node_env_var_name; + break; + } + } + + // If we haven't successfully set the environment using the variables, we'll default it + if (!NODE_ENV) { + NODE_ENV = 'development'; + } + + node_env_var_names.forEach(node_env_var_name => { + env[node_env_var_name] = NODE_ENV; + }); + + // Split files name, for loading multiple files. + NODE_ENV = NODE_ENV.split(','); + + var dir = configDir || util.initParam('NODE_CONFIG_DIR', Path.join( process.cwd(), 'config') ); + dir = _toAbsolutePath(dir); + + APP_INSTANCE = util.initParam('NODE_APP_INSTANCE'); + CONFIG_SKIP_GITCRYPT = util.initParam('CONFIG_SKIP_GITCRYPT'); + + // This is for backward compatibility + var runtimeFilename = util.initParam('NODE_CONFIG_RUNTIME_JSON', Path.join(dir , 'runtime.json') ); + + NODE_CONFIG_PARSER = util.initParam('NODE_CONFIG_PARSER'); + if (NODE_CONFIG_PARSER) { + try { + var parserModule = Path.isAbsolute(NODE_CONFIG_PARSER) + ? NODE_CONFIG_PARSER + : Path.join(dir, NODE_CONFIG_PARSER); + Parser = require(parserModule); + } + catch (e) { + console.warn('Failed to load config parser from ' + NODE_CONFIG_PARSER); + console.log(e); + } + } + + var HOST = util.initParam('HOST'); + var HOSTNAME = util.initParam('HOSTNAME'); + + // Determine the host name from the OS module, $HOST, or $HOSTNAME + // Remove any . appendages, and default to null if not set + try { + var hostName = HOST || HOSTNAME; + + if (!hostName) { + var OS = require('os'); + hostName = OS.hostname(); + } + } catch (e) { + hostName = ''; + } + + // Store the hostname that won. + env.HOSTNAME = hostName; + + // Read each file in turn + var baseNames = ['default'].concat(NODE_ENV); + + // #236: Also add full hostname when they are different. + if (hostName) { + var firstDomain = hostName.split('.')[0]; + + NODE_ENV.forEach(function(env) { + // Backward compatibility + baseNames.push(firstDomain, firstDomain + '-' + env); + + // Add full hostname when it is not the same + if (hostName !== firstDomain) { + baseNames.push(hostName, hostName + '-' + env); + } + }); + } + + NODE_ENV.forEach(function(env) { + baseNames.push('local', 'local-' + env); + }); + + var allowedFiles = {}; + var resolutionIndex = 1; + var extNames = Parser.getFilesOrder(); + baseNames.forEach(function(baseName) { + extNames.forEach(function(extName) { + allowedFiles[baseName + '.' + extName] = resolutionIndex++; + if (APP_INSTANCE) { + allowedFiles[baseName + '-' + APP_INSTANCE + '.' + extName] = resolutionIndex++; + } + }); + }); + + var locatedFiles = util.locateMatchingFiles(dir, allowedFiles); + locatedFiles.forEach(function(fullFilename) { + var configObj = util.parseFile(fullFilename, options); + if (configObj) { + util.extendDeep(config, configObj); + } + }); + + // Override configurations from the $NODE_CONFIG environment variable + // NODE_CONFIG only applies to the base config + if (!configDir) { + var envConfig = {}; + + CONFIG_DIR = dir; + + if (process.env.NODE_CONFIG) { + try { + envConfig = JSON.parse(process.env.NODE_CONFIG); + } catch(e) { + console.error('The $NODE_CONFIG environment variable is malformed JSON'); + } + util.extendDeep(config, envConfig); + var skipConfigSources = util.getOption(options,'skipConfigSources', false); + if (!skipConfigSources){ + configSources.push({ + name: "$NODE_CONFIG", + parsed: envConfig, + }); + } + } + + // Override configurations from the --NODE_CONFIG command line + var cmdLineConfig = util.getCmdLineArg('NODE_CONFIG'); + if (cmdLineConfig) { + try { + cmdLineConfig = JSON.parse(cmdLineConfig); + } catch(e) { + console.error('The --NODE_CONFIG={json} command line argument is malformed JSON'); + } + util.extendDeep(config, cmdLineConfig); + var skipConfigSources = util.getOption(options,'skipConfigSources', false); + if (!skipConfigSources){ + configSources.push({ + name: "--NODE_CONFIG argument", + parsed: cmdLineConfig, + }); + } + } + + // Place the mixed NODE_CONFIG into the environment + env['NODE_CONFIG'] = JSON.stringify(util.extendDeep(envConfig, cmdLineConfig, {})); + } + + // Override with environment variables if there is a custom-environment-variables.EXT mapping file + var customEnvVars = util.getCustomEnvVars(dir, extNames); + util.extendDeep(config, customEnvVars); + + // Extend the original config with the contents of runtime.json (backwards compatibility) + var runtimeJson = util.parseFile(runtimeFilename) || {}; + util.extendDeep(config, runtimeJson); + + util.resolveDeferredConfigs(config); + + // Return the configuration object + return config; +}; + +/** + * Return a list of fullFilenames who exists in allowedFiles + * Ordered according to allowedFiles argument specifications + * + * @protected + * @method locateMatchingFiles + * @param configDirs {string} the config dir, or multiple dirs separated by a column (:) + * @param allowedFiles {object} an object. keys and supported filenames + * and values are the position in the resolution order + * @returns {string[]} fullFilenames - path + filename + */ +util.locateMatchingFiles = function(configDirs, allowedFiles) { + return configDirs.split(Path.delimiter) + .reduce(function(files, configDir) { + if (configDir) { + configDir = _toAbsolutePath(configDir); + try { + FileSystem.readdirSync(configDir).forEach(function(file) { + if (allowedFiles[file]) { + files.push([allowedFiles[file], Path.join(configDir, file)]); + } + }); + } + catch(e) {} + return files; + } + }, []) + .sort(function(a, b) { return a[0] - b[0]; }) + .map(function(file) { return file[1]; }); +}; + +// Using basic recursion pattern, find all the deferred values and resolve them. +util.resolveDeferredConfigs = function (config) { + var deferred = []; + + function _iterate (prop) { + + // We put the properties we are going to look it in an array to keep the order predictable + var propsToSort = []; + + // First step is to put the properties of interest in an array + for (var property in prop) { + if (Object.hasOwnProperty.call(prop, property) && prop[property] != null) { + propsToSort.push(property); + } + } + + // Second step is to iterate of the elements in a predictable (sorted) order + propsToSort.sort().forEach(function (property) { + if (prop[property].constructor === Object) { + _iterate(prop[property]); + } else if (prop[property].constructor === Array) { + for (var i = 0; i < prop[property].length; i++) { + if (prop[property][i] instanceof DeferredConfig) { + deferred.push(prop[property][i].prepare(config, prop[property], i)); + } + else { + _iterate(prop[property][i]); + } + } + } else { + if (prop[property] instanceof DeferredConfig) { + deferred.push(prop[property].prepare(config, prop, property)); + } + // else: Nothing to do. Keep the property how it is. + } + }); + } + + _iterate(config); + + deferred.forEach(function (defer) { defer.resolve(); }); +}; + +/** + * Parse and return the specified configuration file. + * + * If the file exists in the application config directory, it will + * parse and return it as a JavaScript object. + * + * The file extension determines the parser to use. + * + * .js = File to run that has a module.exports containing the config object + * .coffee = File to run that has a module.exports with coffee-script containing the config object + * .iced = File to run that has a module.exports with iced-coffee-script containing the config object + * All other supported file types (yaml, toml, json, cson, hjson, json5, properties, xml) + * are parsed with util.parseString. + * + * If the file doesn't exist, a null will be returned. If the file can't be + * parsed, an exception will be thrown. + * + * This method performs synchronous file operations, and should not be called + * after synchronous module loading. + * + * @protected + * @method parseFile + * @param fullFilename {string} The full file path and name + * @param options { object | undefined } parsing options. Current supported option: skipConfigSources: true|false + * @return configObject {object|null} The configuration object parsed from the file + */ +util.parseFile = function(fullFilename, options) { + var t = this, // Initialize + configObject = null, + fileContent = null, + stat = null; + + // Note that all methods here are the Sync versions. This is appropriate during + // module loading (which is a synchronous operation), but not thereafter. + + try { + // Try loading the file. + fileContent = FileSystem.readFileSync(fullFilename, 'utf-8'); + fileContent = fileContent.replace(/^\uFEFF/, ''); + } + catch (e2) { + if (e2.code !== 'ENOENT') { + throw new Error('Config file ' + fullFilename + ' cannot be read. Error code is: '+e2.code + +'. Error message is: '+e2.message); + } + return null; // file doesn't exists + } + + // Parse the file based on extension + try { + + // skip if it's a gitcrypt file and CONFIG_SKIP_GITCRYPT is true + if (CONFIG_SKIP_GITCRYPT) { + if (gitCryptTestRegex.test(fileContent)) { + console.error('WARNING: ' + fullFilename + ' is a git-crypt file and CONFIG_SKIP_GITCRYPT is set. skipping.'); + return null; + } + } + + configObject = Parser.parse(fullFilename, fileContent); + } + catch (e3) { + if (gitCryptTestRegex.test(fileContent)) { + console.error('ERROR: ' + fullFilename + ' is a git-crypt file and CONFIG_SKIP_GITCRYPT is not set.'); + } + throw new Error("Cannot parse config file: '" + fullFilename + "': " + e3); + } + + // Keep track of this configuration sources, including empty ones, unless the skipConfigSources flag is set to true in the options + var skipConfigSources = util.getOption(options,'skipConfigSources', false); + if (typeof configObject === 'object' && !skipConfigSources) { + configSources.push({ + name: fullFilename, + original: fileContent, + parsed: configObject, + }); + } + + return configObject; +}; + +/** + * Parse and return the specified string with the specified format. + * + * The format determines the parser to use. + * + * json = File is parsed using JSON.parse() + * yaml (or yml) = Parsed with a YAML parser + * toml = Parsed with a TOML parser + * cson = Parsed with a CSON parser + * hjson = Parsed with a HJSON parser + * json5 = Parsed with a JSON5 parser + * properties = Parsed with the 'properties' node package + * xml = Parsed with a XML parser + * + * If the file doesn't exist, a null will be returned. If the file can't be + * parsed, an exception will be thrown. + * + * This method performs synchronous file operations, and should not be called + * after synchronous module loading. + * + * @protected + * @method parseString + * @param content {string} The full content + * @param format {string} The format to be parsed + * @return {configObject} The configuration object parsed from the string + */ +util.parseString = function (content, format) { + var parser = Parser.getParser(format); + if (typeof parser === 'function') { + return parser(null, content); + } +}; + +/** + * Attach the Config class prototype to all config objects recursively. + * + *

+ * This allows you to do anything with CONFIG sub-objects as you can do with + * the top-level CONFIG object. It's so you can do this: + *

+ * + *
+ *   var CUST_CONFIG = require('config').Customer;
+ *   CUST_CONFIG.get(...)
+ * 
+ * + * @protected + * @method attachProtoDeep + * @param toObject + * @param depth + * @return toObject + */ +util.attachProtoDeep = function(toObject, depth) { + if (toObject instanceof RawConfig) { + return toObject; + } + + // Recursion detection + var t = this; + depth = (depth === null ? DEFAULT_CLONE_DEPTH : depth); + if (depth < 0) { + return toObject; + } + + // Adding Config.prototype methods directly to toObject as hidden properties + // because adding to toObject.__proto__ exposes the function in toObject + for (var fnName in Config.prototype) { + if (!toObject[fnName]) { + util.makeHidden(toObject, fnName, Config.prototype[fnName]); + } + } + + // Add prototypes to sub-objects + for (var prop in toObject) { + if (util.isObject(toObject[prop])) { + util.attachProtoDeep(toObject[prop], depth - 1); + } + } + + // Return the original object + return toObject; +}; + +/** + * Return a deep copy of the specified object. + * + * This returns a new object with all elements copied from the specified + * object. Deep copies are made of objects and arrays so you can do anything + * with the returned object without affecting the input object. + * + * @protected + * @method cloneDeep + * @param parent {object} The original object to copy from + * @param [depth=20] {Integer} Maximum depth (default 20) + * @return {object} A new object with the elements copied from the copyFrom object + * + * This method is copied from https://github.com/pvorb/node-clone/blob/17eea36140d61d97a9954c53417d0e04a00525d9/clone.js + * + * Copyright © 2011-2014 Paul Vorbach and 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. + */ +util.cloneDeep = function cloneDeep(parent, depth, circular, prototype) { + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular === 'undefined') + circular = true; + + if (typeof depth === 'undefined') + depth = 20; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth === 0) + return parent; + + var child; + if (typeof parent != 'object') { + return parent; + } + + if (Utils.isArray(parent)) { + child = []; + } else if (Utils.isRegExp(parent)) { + child = new RegExp(parent.source, util.getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (Utils.isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + child = Buffer.alloc(parent.length); + parent.copy(child); + return child; + } else { + if (typeof prototype === 'undefined') child = Object.create(Object.getPrototypeOf(parent)); + else child = Object.create(prototype); + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + for (var i in parent) { + var propDescriptor = Object.getOwnPropertyDescriptor(parent,i); + var hasGetter = ((propDescriptor !== undefined) && (propDescriptor.get !== undefined)); + + if (hasGetter){ + Object.defineProperty(child,i,propDescriptor); + } else if (util.isPromise(parent[i])) { + child[i] = parent[i]; + } else { + child[i] = _clone(parent[i], depth - 1); + } + } + + return child; + } + + return _clone(parent, depth); +}; + +/** + * Set objects given a path as a string list + * + * @protected + * @method setPath + * @param object {object} - Object to set the property on + * @param path {array[string]} - Array path to the property + * @param value {*} - value to set, ignoring null + */ +util.setPath = function (object, path, value) { + var nextKey = null; + if (value === null || path.length === 0) { + return; + } + else if (path.length === 1) { // no more keys to make, so set the value + object[path.shift()] = value; + } + else { + nextKey = path.shift(); + if (!Object.hasOwnProperty.call(object, nextKey)) { + object[nextKey] = {}; + } + util.setPath(object[nextKey], path, value); + } +}; + +/** + * Create a new object patterned after substitutionMap, where: + * 1. Terminal string values in substitutionMap are used as keys + * 2. To look up values in a key-value store, variables + * 3. And parent keys are created as necessary to retain the structure of substitutionMap. + * + * @protected + * @method substituteDeep + * @param substitutionMap {object} - an object whose terminal (non-subobject) values are strings + * @param variables {object[string:value]} - usually process.env, a flat object used to transform + * terminal values in a copy of substitutionMap. + * @returns {object} - deep copy of substitutionMap with only those paths whose terminal values + * corresponded to a key in `variables` + */ +util.substituteDeep = function (substitutionMap, variables) { + var result = {}; + + function _substituteVars(map, vars, pathTo) { + for (var prop in map) { + var value = map[prop]; + if (typeof(value) === 'string') { // We found a leaf variable name + if (vars[value] !== undefined && vars[value] !== '') { // if the vars provide a value set the value in the result map + util.setPath(result, pathTo.concat(prop), vars[value]); + } + } + else if (util.isObject(value)) { // work on the subtree, giving it a clone of the pathTo + if ('__name' in value && '__format' in value && vars[value.__name] !== undefined && vars[value.__name] !== '') { + try { + var parsedValue = util.parseString(vars[value.__name], value.__format); + } catch(err) { + err.message = '__format parser error in ' + value.__name + ': ' + err.message; + throw err; + } + util.setPath(result, pathTo.concat(prop), parsedValue); + } else { + _substituteVars(value, vars, pathTo.concat(prop)); + } + } + else { + msg = "Illegal key type for substitution map at " + pathTo.join('.') + ': ' + typeof(value); + throw Error(msg); + } + } + } + + _substituteVars(substitutionMap, variables, []); + return result; + +}; + +/* Map environment variables into the configuration if a mapping file, + * `custom-environment-variables.EXT` exists. + * + * @protected + * @method getCustomEnvVars + * @param configDir {string} - the passed configuration directory + * @param extNames {Array[string]} - acceptable configuration file extension names. + * @returns {object} - mapped environment variables or {} if there are none + */ +util.getCustomEnvVars = function (configDir, extNames) { + var result = {}; + var resolutionIndex = 1; + var allowedFiles = {}; + extNames.forEach(function (extName) { + allowedFiles['custom-environment-variables' + '.' + extName] = resolutionIndex++; + }); + var locatedFiles = util.locateMatchingFiles(configDir, allowedFiles); + locatedFiles.forEach(function (fullFilename) { + var configObj = util.parseFile(fullFilename); + if (configObj) { + var environmentSubstitutions = util.substituteDeep(configObj, process.env); + util.extendDeep(result, environmentSubstitutions); + } + }); + return result; +}; + +/** + * Return true if two objects have equal contents. + * + * @protected + * @method equalsDeep + * @param object1 {object} The object to compare from + * @param object2 {object} The object to compare with + * @param depth {integer} An optional depth to prevent recursion. Default: 20. + * @return {boolean} True if both objects have equivalent contents + */ +util.equalsDeep = function(object1, object2, depth) { + + // Recursion detection + var t = this; + depth = (depth === null ? DEFAULT_CLONE_DEPTH : depth); + if (depth < 0) { + return {}; + } + + // Fast comparisons + if (!object1 || !object2) { + return false; + } + if (object1 === object2) { + return true; + } + if (typeof(object1) != 'object' || typeof(object2) != 'object') { + return false; + } + + // They must have the same keys. If their length isn't the same + // then they're not equal. If the keys aren't the same, the value + // comparisons will fail. + if (Object.keys(object1).length != Object.keys(object2).length) { + return false; + } + + // Compare the values + for (var prop in object1) { + + // Call recursively if an object or array + if (object1[prop] && typeof(object1[prop]) === 'object') { + if (!util.equalsDeep(object1[prop], object2[prop], depth - 1)) { + return false; + } + } + else { + if (object1[prop] !== object2[prop]) { + return false; + } + } + } + + // Test passed. + return true; +}; + +/** + * Returns an object containing all elements that differ between two objects. + *

+ * This method was designed to be used to create the runtime.json file + * contents, but can be used to get the diffs between any two Javascript objects. + *

+ *

+ * It works best when object2 originated by deep copying object1, then + * changes were made to object2, and you want an object that would give you + * the changes made to object1 which resulted in object2. + *

+ * + * @protected + * @method diffDeep + * @param object1 {object} The base object to compare to + * @param object2 {object} The object to compare with + * @param depth {integer} An optional depth to prevent recursion. Default: 20. + * @return {object} A differential object, which if extended onto object1 would + * result in object2. + */ +util.diffDeep = function(object1, object2, depth) { + + // Recursion detection + var t = this, diff = {}; + depth = (depth === null ? DEFAULT_CLONE_DEPTH : depth); + if (depth < 0) { + return {}; + } + + // Process each element from object2, adding any element that's different + // from object 1. + for (var parm in object2) { + var value1 = object1[parm]; + var value2 = object2[parm]; + if (value1 && value2 && util.isObject(value2)) { + if (!(util.equalsDeep(value1, value2))) { + diff[parm] = util.diffDeep(value1, value2, depth - 1); + } + } + else if (Array.isArray(value1) && Array.isArray(value2)) { + if(!util.equalsDeep(value1, value2)) { + diff[parm] = value2; + } + } + else if (value1 !== value2){ + diff[parm] = value2; + } + } + + // Return the diff object + return diff; + +}; + +/** + * Extend an object, and any object it contains. + * + * This does not replace deep objects, but dives into them + * replacing individual elements instead. + * + * @protected + * @method extendDeep + * @param mergeInto {object} The object to merge into + * @param mergeFrom... {object...} - Any number of objects to merge from + * @param depth {integer} An optional depth to prevent recursion. Default: 20. + * @return {object} The altered mergeInto object is returned + */ +util.extendDeep = function(mergeInto) { + + // Initialize + var t = this; + var vargs = Array.prototype.slice.call(arguments, 1); + var depth = vargs.pop(); + if (typeof(depth) != 'number') { + vargs.push(depth); + depth = DEFAULT_CLONE_DEPTH; + } + + // Recursion detection + if (depth < 0) { + return mergeInto; + } + + // Cycle through each object to extend + vargs.forEach(function(mergeFrom) { + + // Cycle through each element of the object to merge from + for (var prop in mergeFrom) { + + // save original value in deferred elements + var fromIsDeferredFunc = mergeFrom[prop] instanceof DeferredConfig; + var isDeferredFunc = mergeInto[prop] instanceof DeferredConfig; + + if (fromIsDeferredFunc && Object.hasOwnProperty.call(mergeInto, prop)) { + mergeFrom[prop]._original = isDeferredFunc ? mergeInto[prop]._original : mergeInto[prop]; + } + // Extend recursively if both elements are objects and target is not really a deferred function + if (mergeFrom[prop] instanceof Date) { + mergeInto[prop] = mergeFrom[prop]; + } if (mergeFrom[prop] instanceof RegExp) { + mergeInto[prop] = mergeFrom[prop]; + } else if (util.isObject(mergeInto[prop]) && util.isObject(mergeFrom[prop]) && !isDeferredFunc) { + util.extendDeep(mergeInto[prop], mergeFrom[prop], depth - 1); + } + else if (util.isPromise(mergeFrom[prop])) { + mergeInto[prop] = mergeFrom[prop]; + } + // Copy recursively if the mergeFrom element is an object (or array or fn) + else if (mergeFrom[prop] && typeof mergeFrom[prop] === 'object') { + mergeInto[prop] = util.cloneDeep(mergeFrom[prop], depth -1); + } + + // Copy property descriptor otherwise, preserving accessors + else if (Object.getOwnPropertyDescriptor(Object(mergeFrom), prop)){ + Object.defineProperty(mergeInto, prop, Object.getOwnPropertyDescriptor(Object(mergeFrom), prop)); + } else { + mergeInto[prop] = mergeFrom[prop]; + } + } + }); + + // Chain + return mergeInto; + +}; + +/** + * Is the specified argument a regular javascript object? + * + * The argument is an object if it's a JS object, but not an array. + * + * @protected + * @method isObject + * @param obj {*} An argument of any type. + * @return {boolean} TRUE if the arg is an object, FALSE if not + */ +util.isObject = function(obj) { + return (obj !== null) && (typeof obj === 'object') && !(Array.isArray(obj)); +}; + +/** + * Is the specified argument a javascript promise? + * + * @protected + * @method isPromise + * @param obj {*} An argument of any type. + * @returns {boolean} + */ +util.isPromise = function(obj) { + return Object.prototype.toString.call(obj) === '[object Promise]'; +}; + +/** + *

Initialize a parameter from the command line or process environment

+ * + *

+ * This method looks for the parameter from the command line in the format + * --PARAMETER=VALUE, then from the process environment, then from the + * default specified as an argument. + *

+ * + * @method initParam + * @param paramName {String} Name of the parameter + * @param [defaultValue] {Any} Default value of the parameter + * @return {Any} The found value, or default value + */ +util.initParam = function (paramName, defaultValue) { + var t = this; + + // Record and return the value + var value = util.getCmdLineArg(paramName) || process.env[paramName] || defaultValue; + env[paramName] = value; + return value; +} + +/** + *

Get Command Line Arguments

+ * + *

+ * This method allows you to retrieve the value of the specified command line argument. + *

+ * + *

+ * The argument is case sensitive, and must be of the form '--ARG_NAME=value' + *

+ * + * @method getCmdLineArg + * @param searchFor {String} The argument name to search for + * @return {*} false if the argument was not found, the argument value if found + */ +util.getCmdLineArg = function (searchFor) { + var cmdLineArgs = process.argv.slice(2, process.argv.length), + argName = '--' + searchFor + '='; + + for (var argvIt = 0; argvIt < cmdLineArgs.length; argvIt++) { + if (cmdLineArgs[argvIt].indexOf(argName) === 0) { + return cmdLineArgs[argvIt].substr(argName.length); + } + } + + return false; +} + +/** + *

Get a Config Environment Variable Value

+ * + *

+ * This method returns the value of the specified config environment variable, + * including any defaults or overrides. + *

+ * + * @method getEnv + * @param varName {String} The environment variable name + * @return {String} The value of the environment variable + */ +util.getEnv = function (varName) { + return env[varName]; +} + + + +/** + * Returns a string of flags for regular expression `re`. + * + * @param {RegExp} re Regular expression + * @returns {string} Flags + */ +util.getRegExpFlags = function (re) { + var flags = ''; + re.global && (flags += 'g'); + re.ignoreCase && (flags += 'i'); + re.multiline && (flags += 'm'); + return flags; +}; + +/** + * Returns a new deep copy of the current config object, or any part of the config if provided. + * + * @param {Object} config The part of the config to copy and serialize. Omit this argument to return the entire config. + * @returns {Object} The cloned config or part of the config + */ +util.toObject = function(config) { + return JSON.parse(JSON.stringify(config || this)); +}; + +// Run strictness checks on NODE_ENV and NODE_APP_INSTANCE and throw an error if there's a problem. +util.runStrictnessChecks = function (config) { + var sources = config.util.getConfigSources(); + + var sourceFilenames = sources.map(function (src) { + return Path.basename(src.name); + }); + + NODE_ENV.forEach(function(env) { + // Throw an exception if there's no explicit config file for NODE_ENV + var anyFilesMatchEnv = sourceFilenames.some(function (filename) { + return filename.match(env); + }); + // development is special-cased because it's the default value + if (env && (env !== 'development') && !anyFilesMatchEnv) { + _warnOrThrow(NODE_ENV_VAR_NAME+" value of '"+env+"' did not match any deployment config file names."); + } + // Throw if NODE_ENV matches' default' or 'local' + if ((env === 'default') || (env === 'local')) { + _warnOrThrow(NODE_ENV_VAR_NAME+" value of '"+env+"' is ambiguous."); + } + }); + + // Throw an exception if there's no explicit config file for NODE_APP_INSTANCE + var anyFilesMatchInstance = sourceFilenames.some(function (filename) { + return filename.match(APP_INSTANCE); + }); + if (APP_INSTANCE && !anyFilesMatchInstance) { + _warnOrThrow("NODE_APP_INSTANCE value of '"+APP_INSTANCE+"' did not match any instance config file names."); + } + + function _warnOrThrow (msg) { + var beStrict = process.env.NODE_CONFIG_STRICT_MODE; + var prefix = beStrict ? 'FATAL: ' : 'WARNING: '; + var seeURL = 'See https://github.com/node-config/node-config/wiki/Strict-Mode'; + + console.error(prefix+msg); + console.error(prefix+seeURL); + + // Accept 1 and true as truthy values. When set via process.env, Node.js casts them to strings. + if (["true", "1"].indexOf(beStrict) >= 0) { + throw new Error(prefix+msg+' '+seeURL); + } + } +}; + +// Helper functions shared accross object members +function _toAbsolutePath (configDir) { + if (configDir.indexOf('.') === 0) { + return Path.join(process.cwd(), configDir); + } + + return configDir; +} + +// Instantiate and export the configuration +var config = module.exports = new Config(); + +// copy methods to util for backwards compatibility +util.stripComments = Parser.stripComments; +util.stripYamlComments = Parser.stripYamlComments; + +// Produce warnings if the configuration is empty +var showWarnings = !(util.initParam('SUPPRESS_NO_CONFIG_WARNING')); +if (showWarnings && Object.keys(config).length === 0) { + console.error('WARNING: No configurations found in configuration directory:' +CONFIG_DIR); + console.error('WARNING: To disable this warning set SUPPRESS_NO_CONFIG_WARNING in the environment.'); +} diff --git a/node_modules/config/package.json b/node_modules/config/package.json new file mode 100644 index 0000000..a03804a --- /dev/null +++ b/node_modules/config/package.json @@ -0,0 +1,52 @@ +{ + "name": "config", + "version": "3.3.9", + "main": "./lib/config.js", + "description": "Configuration control for production node deployments", + "author": "Loren West ", + "homepage": "http://github.com/node-config/node-config.git", + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "keywords": [ + "conf", + "config", + "configuration", + "node-config", + "config-node", + "env", + "environment" + ], + "directories": { + "lib": "./lib" + }, + "license": "MIT", + "dependencies": { + "json5": "^2.2.3" + }, + "devDependencies": { + "@types/node": "^7.0.8", + "coffeescript": "2.2.4", + "cson": "^3.0.1", + "hjson": "^1.2.0", + "js-yaml": "^3.2.2", + "properties": "~1.2.1", + "semver": "5.3.0", + "toml": "^2.0.6", + "ts-node": "^3.3.0", + "typescript": "^2.4.2", + "underscore": "^1.8.3", + "vows": ">=0.8.1", + "x2js": "^2.0.1" + }, + "repository": { + "type": "git", + "url": "http://github.com/node-config/node-config.git" + }, + "engines": { + "node": ">= 10.0.0" + }, + "scripts": { + "test": "./node_modules/vows/bin/vows test/*.js --spec" + } +} diff --git a/node_modules/config/parser.js b/node_modules/config/parser.js new file mode 100644 index 0000000..4f438bd --- /dev/null +++ b/node_modules/config/parser.js @@ -0,0 +1,368 @@ +// External libraries are lazy-loaded only if these file types exist. +const util = require("util"); +var Yaml = null, + VisionmediaYaml = null, + Coffee = null, + Iced = null, + CSON = null, + PPARSER = null, + JSON5 = null, + TOML = null, + HJSON = null, + XML = null; + +// Define soft dependencies so transpilers don't include everything +var COFFEE_2_DEP = 'coffeescript', + COFFEE_DEP = 'coffee-script', + ICED_DEP = 'iced-coffee-script', + JS_YAML_DEP = 'js-yaml', + YAML_DEP = 'yaml', + JSON5_DEP = 'json5', + HJSON_DEP = 'hjson', + TOML_DEP = 'toml', + CSON_DEP = 'cson', + PPARSER_DEP = 'properties', + XML_DEP = 'x2js', + TS_DEP = 'ts-node'; + +var Parser = module.exports; + +Parser.parse = function(filename, content) { + var parserName = filename.substr(filename.lastIndexOf('.') +1); // file extension + if (typeof definitions[parserName] === 'function') { + return definitions[parserName](filename, content); + } + // TODO: decide what to do in case of a missing parser +}; + +Parser.xmlParser = function(filename, content) { + if (!XML) { + XML = require(XML_DEP); + } + var x2js = new XML(); + var configObject = x2js.xml2js(content); + var rootKeys = Object.keys(configObject); + if(rootKeys.length === 1) { + return configObject[rootKeys[0]]; + } + return configObject; +}; + +Parser.jsParser = function(filename, content) { + var configObject = require(filename); + + if (configObject.__esModule && util.isObject(configObject.default)) { + return configObject.default + } + return configObject; +}; + +Parser.tsParser = function(filename, content) { + if (!require.extensions['.ts']) { + require(TS_DEP).register({ + lazy: true, + transpileOnly: true, + compilerOptions: { + allowJs: true, + } + }); + } + + // Imports config if it is exported via module.exports = ... + // See https://github.com/node-config/node-config/issues/524 + var configObject = require(filename); + + // Because of ES6 modules usage, `default` is treated as named export (like any other) + // Therefore config is a value of `default` key. + if (configObject.default) { + return configObject.default + } + return configObject; +}; + +Parser.coffeeParser = function(filename, content) { + // .coffee files can be loaded with either coffee-script or iced-coffee-script. + // Prefer iced-coffee-script, if it exists. + // Lazy load the appropriate extension + if (!Coffee) { + Coffee = {}; + + // The following enables iced-coffee-script on .coffee files, if iced-coffee-script is available. + // This is commented as per a decision on a pull request. + //try { + // Coffee = require('iced-coffee-script'); + //} + //catch (e) { + // Coffee = require('coffee-script'); + //} + try { + // Try to load coffeescript + Coffee = require(COFFEE_2_DEP); + } + catch (e) { + // If it doesn't exist, try to load it using the deprecated module name + Coffee = require(COFFEE_DEP); + } + // coffee-script >= 1.7.0 requires explicit registration for require() to work + if (Coffee.register) { + Coffee.register(); + } + } + // Use the built-in parser for .coffee files with coffee-script + return require(filename); +}; + +Parser.icedParser = function(filename, content) { + Iced = require(ICED_DEP); + + // coffee-script >= 1.7.0 requires explicit registration for require() to work + if (Iced.register) { + Iced.register(); + } +}; + +Parser.yamlParser = function(filename, content) { + if (!Yaml && !VisionmediaYaml) { + // Lazy loading + try { + // Try to load the better js-yaml module + Yaml = require(JS_YAML_DEP); + } + catch (e) { + try { + // If it doesn't exist, load the fallback visionmedia yaml module. + VisionmediaYaml = require(YAML_DEP); + } + catch (e) { } + } + } + if (Yaml) { + return Yaml.load(content); + } + else if (VisionmediaYaml) { + // The yaml library doesn't like strings that have newlines but don't + // end in a newline: https://github.com/visionmedia/js-yaml/issues/issue/13 + content += '\n'; + if (typeof VisionmediaYaml.eval === 'function') { + return VisionmediaYaml.eval(Parser.stripYamlComments(content)); + } + return VisionmediaYaml.parse(Parser.stripYamlComments(content)); + } + else { + console.error('No YAML parser loaded. Suggest adding js-yaml dependency to your package.json file.') + } +}; + +Parser.jsonParser = function(filename, content) { + try { + return JSON.parse(content); + } + catch (e) { + // All JS Style comments will begin with /, so all JSON parse errors that + // encountered a syntax error will complain about this character. + if (e.name !== 'SyntaxError' || e.message.indexOf('Unexpected token /') !== 0) { + throw e; + } + if (!JSON5) { + JSON5 = require(JSON5_DEP); + } + return JSON5.parse(content); + } +}; + +Parser.json5Parser = function(filename, content) { + if (!JSON5) { + JSON5 = require(JSON5_DEP); + } + return JSON5.parse(content); +}; + +Parser.hjsonParser = function(filename, content) { + if (!HJSON) { + HJSON = require(HJSON_DEP); + } + return HJSON.parse(content); +}; + +Parser.tomlParser = function(filename, content) { + if(!TOML) { + TOML = require(TOML_DEP); + } + return TOML.parse(content); +}; + +Parser.csonParser = function(filename, content) { + if (!CSON) { + CSON = require(CSON_DEP); + } + // Allow comments in CSON files + if (typeof CSON.parseSync === 'function') { + return CSON.parseSync(Parser.stripComments(content)); + } + return CSON.parse(Parser.stripComments(content)); +}; + +Parser.propertiesParser = function(filename, content) { + if (!PPARSER) { + PPARSER = require(PPARSER_DEP); + } + return PPARSER.parse(content, { namespaces: true, variables: true, sections: true }); +}; + +/** + * Strip all Javascript type comments from the string. + * + * The string is usually a file loaded from the O/S, containing + * newlines and javascript type comments. + * + * Thanks to James Padolsey, and all who contributed to this implementation. + * http://james.padolsey.com/javascript/javascript-comment-removal-revisted/ + * + * @protected + * @method stripComments + * @param fileStr {string} The string to strip comments from + * @param stringRegex {RegExp} Optional regular expression to match strings that + * make up the config file + * @return {string} The string with comments stripped. + */ +Parser.stripComments = function(fileStr, stringRegex) { + stringRegex = stringRegex || /(['"])(\\\1|.)+?\1/g; + + var uid = '_' + +new Date(), + primitives = [], + primIndex = 0; + + return ( + fileStr + + /* Remove strings */ + .replace(stringRegex, function(match){ + primitives[primIndex] = match; + return (uid + '') + primIndex++; + }) + + /* Remove Regexes */ + .replace(/([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g, function(match, $1, $2){ + primitives[primIndex] = $2; + return $1 + (uid + '') + primIndex++; + }) + + /* + - Remove single-line comments that contain would-be multi-line delimiters + E.g. // Comment /* <-- + - Remove multi-line comments that contain would be single-line delimiters + E.g. /* // <-- + */ + .replace(/\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g, '') + + /* + Remove single and multi-line comments, + no consideration of inner-contents + */ + .replace(/\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g, '') + + /* + Remove multi-line comments that have a replaced ending (string/regex) + Greedy, so no inner strings/regexes will stop it. + */ + .replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), '') + + /* Bring back strings & regexes */ + .replace(RegExp(uid + '(\\d+)', 'g'), function(match, n){ + return primitives[n]; + }) + ); + +}; + +/** + * Strip YAML comments from the string + * + * The 2.0 yaml parser doesn't allow comment-only or blank lines. Strip them. + * + * @protected + * @method stripYamlComments + * @param fileStr {string} The string to strip comments from + * @return {string} The string with comments stripped. + */ +Parser.stripYamlComments = function(fileStr) { + // First replace removes comment-only lines + // Second replace removes blank lines + return fileStr.replace(/^\s*#.*/mg,'').replace(/^\s*[\n|\r]+/mg,''); +}; + +/** + * Parses the environment variable to the boolean equivalent. + * Defaults to false + * + * @param {String} content - Environment variable value + * @return {boolean} - Boolean value fo the passed variable value + */ +Parser.booleanParser = function(filename, content) { + return content === 'true'; +}; + +/** + * Parses the environment variable to the number equivalent. + * Defaults to undefined + * + * @param {String} content - Environment variable value + * @return {Number} - Number value fo the passed variable value + */ +Parser.numberParser = function(filename, content) { + const numberValue = Number(content); + return Number.isNaN(numberValue) ? undefined : numberValue; +}; + +var order = ['js', 'cjs', 'ts', 'json', 'json5', 'hjson', 'toml', 'coffee', 'iced', 'yaml', 'yml', 'cson', 'properties', 'xml', + 'boolean', 'number']; +var definitions = { + cjs: Parser.jsParser, + coffee: Parser.coffeeParser, + cson: Parser.csonParser, + hjson: Parser.hjsonParser, + iced: Parser.icedParser, + js: Parser.jsParser, + json: Parser.jsonParser, + json5: Parser.json5Parser, + properties: Parser.propertiesParser, + toml: Parser.tomlParser, + ts: Parser.tsParser, + xml: Parser.xmlParser, + yaml: Parser.yamlParser, + yml: Parser.yamlParser, + boolean: Parser.booleanParser, + number: Parser.numberParser +}; + +Parser.getParser = function(name) { + return definitions[name]; +}; + +Parser.setParser = function(name, parser) { + definitions[name] = parser; + if (order.indexOf(name) === -1) { + order.push(name); + } +}; + +Parser.getFilesOrder = function(name) { + if (name) { + return order.indexOf(name); + } + return order; +}; + +Parser.setFilesOrder = function(name, newIndex) { + if (Array.isArray(name)) { + return order = name; + } + if (typeof newIndex === 'number') { + var index = order.indexOf(name); + order.splice(newIndex, 0, name); + if (index > -1) { + order.splice(index >= newIndex ? index +1 : index, 1); + } + } + return order; +}; diff --git a/node_modules/config/raw.js b/node_modules/config/raw.js new file mode 100644 index 0000000..8adce23 --- /dev/null +++ b/node_modules/config/raw.js @@ -0,0 +1,15 @@ +/** + * This is meant to wrap configuration objects that should be left as is, + * meaning that the object or its prototype will not be modified in any way + */ +function RawConfig () { +} + +function raw(rawObj) { + var obj = Object.create(RawConfig.prototype); + obj.resolve = function () { return rawObj; } + return obj; +} + +module.exports.RawConfig = RawConfig; +module.exports.raw = raw; diff --git a/node_modules/json5/LICENSE.md b/node_modules/json5/LICENSE.md new file mode 100644 index 0000000..2171aca --- /dev/null +++ b/node_modules/json5/LICENSE.md @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2012-2018 Aseem Kishore, and [others]. + +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. + +[others]: https://github.com/json5/json5/contributors diff --git a/node_modules/json5/README.md b/node_modules/json5/README.md new file mode 100644 index 0000000..00ee793 --- /dev/null +++ b/node_modules/json5/README.md @@ -0,0 +1,282 @@ +# JSON5 – JSON for Humans + +[![Build Status](https://app.travis-ci.com/json5/json5.svg?branch=main)][Build +Status] [![Coverage +Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage +Status] + +JSON5 is an extension to the popular [JSON] file format that aims to be +easier to **write and maintain _by hand_ (e.g. for config files)**. +It is _not intended_ to be used for machine-to-machine communication. +(Keep using JSON or other file formats for that. 🙂) + +JSON5 was started in 2012, and as of 2022, now gets **[>65M downloads/week](https://www.npmjs.com/package/json5)**, +ranks in the **[top 0.1%](https://gist.github.com/anvaka/8e8fa57c7ee1350e3491)** of the most depended-upon packages on npm, +and has been adopted by major projects like +**[Chromium](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=5de823b36e68fd99009a29281b17bc3a1d6b329c), +[Next.js](https://github.com/vercel/next.js/blob/b88f20c90bf4659b8ad5cb2a27956005eac2c7e8/packages/next/lib/find-config.ts#L43-L46), +[Babel](https://babeljs.io/docs/en/config-files#supported-file-extensions), +[Retool](https://community.retool.com/t/i-am-attempting-to-append-several-text-fields-to-a-google-sheet-but-receiving-a-json5-invalid-character-error/7626), +[WebStorm](https://www.jetbrains.com/help/webstorm/json.html), +and [more](https://github.com/json5/json5/wiki/In-the-Wild)**. +It's also natively supported on **[Apple platforms](https://developer.apple.com/documentation/foundation/jsondecoder/3766916-allowsjson5)** +like **MacOS** and **iOS**. + +Formally, the **[JSON5 Data Interchange Format](https://spec.json5.org/)** is a superset of JSON +(so valid JSON files will always be valid JSON5 files) +that expands its syntax to include some productions from [ECMAScript 5.1] (ES5). +It's also a strict _subset_ of ES5, so valid JSON5 files will always be valid ES5. + +This JavaScript library is a reference implementation for JSON5 parsing and serialization, +and is directly used in many of the popular projects mentioned above +(where e.g. extreme performance isn't necessary), +but others have created [many other libraries](https://github.com/json5/json5/wiki/In-the-Wild) +across many other platforms. + +[Build Status]: https://app.travis-ci.com/json5/json5 + +[Coverage Status]: https://coveralls.io/github/json5/json5 + +[JSON]: https://tools.ietf.org/html/rfc7159 + +[ECMAScript 5.1]: https://www.ecma-international.org/ecma-262/5.1/ + +## Summary of Features +The following ECMAScript 5.1 features, which are not supported in JSON, have +been extended to JSON5. + +### Objects +- Object keys may be an ECMAScript 5.1 _[IdentifierName]_. +- Objects may have a single trailing comma. + +### Arrays +- Arrays may have a single trailing comma. + +### Strings +- Strings may be single quoted. +- Strings may span multiple lines by escaping new line characters. +- Strings may include character escapes. + +### Numbers +- Numbers may be hexadecimal. +- Numbers may have a leading or trailing decimal point. +- Numbers may be [IEEE 754] positive infinity, negative infinity, and NaN. +- Numbers may begin with an explicit plus sign. + +### Comments +- Single and multi-line comments are allowed. + +### White Space +- Additional white space characters are allowed. + +[IdentifierName]: https://www.ecma-international.org/ecma-262/5.1/#sec-7.6 + +[IEEE 754]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933 + +## Example +Kitchen-sink example: + +```js +{ + // comments + unquoted: 'and you can quote me on that', + singleQuotes: 'I can use "double quotes" here', + lineBreaks: "Look, Mom! \ +No \\n's!", + hexadecimal: 0xdecaf, + leadingDecimalPoint: .8675309, andTrailing: 8675309., + positiveSign: +1, + trailingComma: 'in objects', andIn: ['arrays',], + "backwardsCompatible": "with JSON", +} +``` + +A more real-world example is [this config file](https://github.com/chromium/chromium/blob/feb3c9f670515edf9a88f185301cbd7794ee3e52/third_party/blink/renderer/platform/runtime_enabled_features.json5) +from the Chromium/Blink project. + +## Specification +For a detailed explanation of the JSON5 format, please read the [official +specification](https://json5.github.io/json5-spec/). + +## Installation and Usage +### Node.js +```sh +npm install json5 +``` + +#### CommonJS +```js +const JSON5 = require('json5') +``` + +#### Modules +```js +import JSON5 from 'json5' +``` + +### Browsers +#### UMD +```html + + +``` + +#### Modules +```html + +``` + +## API +The JSON5 API is compatible with the [JSON API]. + +[JSON API]: +https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON + +### JSON5.parse() +Parses a JSON5 string, constructing the JavaScript value or object described by +the string. An optional reviver function can be provided to perform a +transformation on the resulting object before it is returned. + +#### Syntax + JSON5.parse(text[, reviver]) + +#### Parameters +- `text`: The string to parse as JSON5. +- `reviver`: If a function, this prescribes how the value originally produced by + parsing is transformed, before being returned. + +#### Return value +The object corresponding to the given JSON5 text. + +### JSON5.stringify() +Converts a JavaScript value to a JSON5 string, optionally replacing values if a +replacer function is specified, or optionally including only the specified +properties if a replacer array is specified. + +#### Syntax + JSON5.stringify(value[, replacer[, space]]) + JSON5.stringify(value[, options]) + +#### Parameters +- `value`: The value to convert to a JSON5 string. +- `replacer`: A function that alters the behavior of the stringification + process, or an array of String and Number objects that serve as a whitelist + for selecting/filtering the properties of the value object to be included in + the JSON5 string. If this value is null or not provided, all properties of the + object are included in the resulting JSON5 string. +- `space`: A String or Number object that's used to insert white space into the + output JSON5 string for readability purposes. If this is a Number, it + indicates the number of space characters to use as white space; this number is + capped at 10 (if it is greater, the value is just 10). Values less than 1 + indicate that no space should be used. If this is a String, the string (or the + first 10 characters of the string, if it's longer than that) is used as white + space. If this parameter is not provided (or is null), no white space is used. + If white space is used, trailing commas will be used in objects and arrays. +- `options`: An object with the following properties: + - `replacer`: Same as the `replacer` parameter. + - `space`: Same as the `space` parameter. + - `quote`: A String representing the quote character to use when serializing + strings. + +#### Return value +A JSON5 string representing the value. + +### Node.js `require()` JSON5 files +When using Node.js, you can `require()` JSON5 files by adding the following +statement. + +```js +require('json5/lib/register') +``` + +Then you can load a JSON5 file with a Node.js `require()` statement. For +example: + +```js +const config = require('./config.json5') +``` + +## CLI +Since JSON is more widely used than JSON5, this package includes a CLI for +converting JSON5 to JSON and for validating the syntax of JSON5 documents. + +### Installation +```sh +npm install --global json5 +``` + +### Usage +```sh +json5 [options] +``` + +If `` is not provided, then STDIN is used. + +#### Options: +- `-s`, `--space`: The number of spaces to indent or `t` for tabs +- `-o`, `--out-file [file]`: Output to the specified file, otherwise STDOUT +- `-v`, `--validate`: Validate JSON5 but do not output JSON +- `-V`, `--version`: Output the version number +- `-h`, `--help`: Output usage information + +## Contributing +### Development +```sh +git clone https://github.com/json5/json5 +cd json5 +npm install +``` + +When contributing code, please write relevant tests and run `npm test` and `npm +run lint` before submitting pull requests. Please use an editor that supports +[EditorConfig](http://editorconfig.org/). + +### Issues +To report bugs or request features regarding the JSON5 **data format**, +please submit an issue to the official +**[_specification_ repository](https://github.com/json5/json5-spec)**. + +Note that we will never add any features that make JSON5 incompatible with ES5; +that compatibility is a fundamental premise of JSON5. + +To report bugs or request features regarding this **JavaScript implementation** +of JSON5, please submit an issue to **_this_ repository**. + +### Security Vulnerabilities and Disclosures +To report a security vulnerability, please follow the follow the guidelines +described in our [security policy](./SECURITY.md). + +## License +MIT. See [LICENSE.md](./LICENSE.md) for details. + +## Credits +[Aseem Kishore](https://github.com/aseemk) founded this project. +He wrote a [blog post](https://aseemk.substack.com/p/ignore-the-f-ing-haters-json5) +about the journey and lessons learned 10 years in. + +[Michael Bolin](http://bolinfest.com/) independently arrived at and published +some of these same ideas with awesome explanations and detail. Recommended +reading: [Suggested Improvements to JSON](http://bolinfest.com/essays/json.html) + +[Douglas Crockford](http://www.crockford.com/) of course designed and built +JSON, but his state machine diagrams on the [JSON website](http://json.org/), as +cheesy as it may sound, gave us motivation and confidence that building a new +parser to implement these ideas was within reach! The original +implementation of JSON5 was also modeled directly off of Doug’s open-source +[json_parse.js] parser. We’re grateful for that clean and well-documented +code. + +[json_parse.js]: +https://github.com/douglascrockford/JSON-js/blob/03157639c7a7cddd2e9f032537f346f1a87c0f6d/json_parse.js + +[Max Nanasy](https://github.com/MaxNanasy) has been an early and prolific +supporter, contributing multiple patches and ideas. + +[Andrew Eisenberg](https://github.com/aeisenberg) contributed the original +`stringify` method. + +[Jordan Tucker](https://github.com/jordanbtucker) has aligned JSON5 more closely +with ES5, wrote the official JSON5 specification, completely rewrote the +codebase from the ground up, and is actively maintaining this project. diff --git a/node_modules/json5/dist/index.js b/node_modules/json5/dist/index.js new file mode 100644 index 0000000..bf86533 --- /dev/null +++ b/node_modules/json5/dist/index.js @@ -0,0 +1,1737 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.JSON5 = factory()); +}(this, (function () { 'use strict'; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var _global = createCommonjsModule(function (module) { + // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 + var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); + if (typeof __g == 'number') { __g = global; } // eslint-disable-line no-undef + }); + + var _core = createCommonjsModule(function (module) { + var core = module.exports = { version: '2.6.5' }; + if (typeof __e == 'number') { __e = core; } // eslint-disable-line no-undef + }); + var _core_1 = _core.version; + + var _isObject = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; + }; + + var _anObject = function (it) { + if (!_isObject(it)) { throw TypeError(it + ' is not an object!'); } + return it; + }; + + var _fails = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } + }; + + // Thank's IE8 for his funny defineProperty + var _descriptors = !_fails(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; + }); + + var document = _global.document; + // typeof document.createElement is 'object' in old IE + var is = _isObject(document) && _isObject(document.createElement); + var _domCreate = function (it) { + return is ? document.createElement(it) : {}; + }; + + var _ie8DomDefine = !_descriptors && !_fails(function () { + return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7; + }); + + // 7.1.1 ToPrimitive(input [, PreferredType]) + + // instead of the ES6 spec version, we didn't implement @@toPrimitive case + // and the second argument - flag - preferred type is a string + var _toPrimitive = function (it, S) { + if (!_isObject(it)) { return it; } + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; } + if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) { return val; } + if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; } + throw TypeError("Can't convert object to primitive value"); + }; + + var dP = Object.defineProperty; + + var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) { + _anObject(O); + P = _toPrimitive(P, true); + _anObject(Attributes); + if (_ie8DomDefine) { try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } } + if ('get' in Attributes || 'set' in Attributes) { throw TypeError('Accessors not supported!'); } + if ('value' in Attributes) { O[P] = Attributes.value; } + return O; + }; + + var _objectDp = { + f: f + }; + + var _propertyDesc = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; + }; + + var _hide = _descriptors ? function (object, key, value) { + return _objectDp.f(object, key, _propertyDesc(1, value)); + } : function (object, key, value) { + object[key] = value; + return object; + }; + + var hasOwnProperty = {}.hasOwnProperty; + var _has = function (it, key) { + return hasOwnProperty.call(it, key); + }; + + var id = 0; + var px = Math.random(); + var _uid = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); + }; + + var _library = false; + + var _shared = createCommonjsModule(function (module) { + var SHARED = '__core-js_shared__'; + var store = _global[SHARED] || (_global[SHARED] = {}); + + (module.exports = function (key, value) { + return store[key] || (store[key] = value !== undefined ? value : {}); + })('versions', []).push({ + version: _core.version, + mode: _library ? 'pure' : 'global', + copyright: '© 2019 Denis Pushkarev (zloirock.ru)' + }); + }); + + var _functionToString = _shared('native-function-to-string', Function.toString); + + var _redefine = createCommonjsModule(function (module) { + var SRC = _uid('src'); + + var TO_STRING = 'toString'; + var TPL = ('' + _functionToString).split(TO_STRING); + + _core.inspectSource = function (it) { + return _functionToString.call(it); + }; + + (module.exports = function (O, key, val, safe) { + var isFunction = typeof val == 'function'; + if (isFunction) { _has(val, 'name') || _hide(val, 'name', key); } + if (O[key] === val) { return; } + if (isFunction) { _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); } + if (O === _global) { + O[key] = val; + } else if (!safe) { + delete O[key]; + _hide(O, key, val); + } else if (O[key]) { + O[key] = val; + } else { + _hide(O, key, val); + } + // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative + })(Function.prototype, TO_STRING, function toString() { + return typeof this == 'function' && this[SRC] || _functionToString.call(this); + }); + }); + + var _aFunction = function (it) { + if (typeof it != 'function') { throw TypeError(it + ' is not a function!'); } + return it; + }; + + // optional / simple context binding + + var _ctx = function (fn, that, length) { + _aFunction(fn); + if (that === undefined) { return fn; } + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; + }; + + var PROTOTYPE = 'prototype'; + + var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE]; + var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {}); + var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); + var key, own, out, exp; + if (IS_GLOBAL) { source = name; } + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + // export native or passed + out = (own ? target : source)[key]; + // bind timers to global for call from export context + exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; + // extend global + if (target) { _redefine(target, key, out, type & $export.U); } + // export + if (exports[key] != out) { _hide(exports, key, exp); } + if (IS_PROTO && expProto[key] != out) { expProto[key] = out; } + } + }; + _global.core = _core; + // type bitmap + $export.F = 1; // forced + $export.G = 2; // global + $export.S = 4; // static + $export.P = 8; // proto + $export.B = 16; // bind + $export.W = 32; // wrap + $export.U = 64; // safe + $export.R = 128; // real proto method for `library` + var _export = $export; + + // 7.1.4 ToInteger + var ceil = Math.ceil; + var floor = Math.floor; + var _toInteger = function (it) { + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); + }; + + // 7.2.1 RequireObjectCoercible(argument) + var _defined = function (it) { + if (it == undefined) { throw TypeError("Can't call method on " + it); } + return it; + }; + + // true -> String#at + // false -> String#codePointAt + var _stringAt = function (TO_STRING) { + return function (that, pos) { + var s = String(_defined(that)); + var i = _toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) { return TO_STRING ? '' : undefined; } + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; + }; + + var $at = _stringAt(false); + _export(_export.P, 'String', { + // 21.1.3.3 String.prototype.codePointAt(pos) + codePointAt: function codePointAt(pos) { + return $at(this, pos); + } + }); + + var codePointAt = _core.String.codePointAt; + + var max = Math.max; + var min = Math.min; + var _toAbsoluteIndex = function (index, length) { + index = _toInteger(index); + return index < 0 ? max(index + length, 0) : min(index, length); + }; + + var fromCharCode = String.fromCharCode; + var $fromCodePoint = String.fromCodePoint; + + // length should be 1, old FF problem + _export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', { + // 21.1.2.2 String.fromCodePoint(...codePoints) + fromCodePoint: function fromCodePoint(x) { + var arguments$1 = arguments; + // eslint-disable-line no-unused-vars + var res = []; + var aLen = arguments.length; + var i = 0; + var code; + while (aLen > i) { + code = +arguments$1[i++]; + if (_toAbsoluteIndex(code, 0x10ffff) !== code) { throw RangeError(code + ' is not a valid code point'); } + res.push(code < 0x10000 + ? fromCharCode(code) + : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00) + ); + } return res.join(''); + } + }); + + var fromCodePoint = _core.String.fromCodePoint; + + // This is a generated file. Do not edit. + var Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/; + var ID_Start = /[\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\u0860-\u086A\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\u09FC\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-\u1884\u1887-\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\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\uDCE0-\uDCF2\uDCF4\uDCF5\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\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\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\uDD00-\uDD43]|\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\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/; + var ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\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\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\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\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\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\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\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\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\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\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\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\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/; + + var unicode = { + Space_Separator: Space_Separator, + ID_Start: ID_Start, + ID_Continue: ID_Continue + }; + + var util = { + isSpaceSeparator: function isSpaceSeparator (c) { + return typeof c === 'string' && unicode.Space_Separator.test(c) + }, + + isIdStartChar: function isIdStartChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === '$') || (c === '_') || + unicode.ID_Start.test(c) + ) + }, + + isIdContinueChar: function isIdContinueChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c === '$') || (c === '_') || + (c === '\u200C') || (c === '\u200D') || + unicode.ID_Continue.test(c) + ) + }, + + isDigit: function isDigit (c) { + return typeof c === 'string' && /[0-9]/.test(c) + }, + + isHexDigit: function isHexDigit (c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) + }, + }; + + var source; + var parseState; + var stack; + var pos; + var line; + var column; + var token; + var key; + var root; + + var parse = function parse (text, reviver) { + source = String(text); + parseState = 'start'; + stack = []; + pos = 0; + line = 1; + column = 0; + token = undefined; + key = undefined; + root = undefined; + + do { + token = lex(); + + // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } + + parseStates[parseState](); + } while (token.type !== 'eof') + + if (typeof reviver === 'function') { + return internalize({'': root}, '', reviver) + } + + return root + }; + + function internalize (holder, name, reviver) { + var value = holder[name]; + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (var i = 0; i < value.length; i++) { + var key = String(i); + var replacement = internalize(value, key, reviver); + if (replacement === undefined) { + delete value[key]; + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } else { + for (var key$1 in value) { + var replacement$1 = internalize(value, key$1, reviver); + if (replacement$1 === undefined) { + delete value[key$1]; + } else { + Object.defineProperty(value, key$1, { + value: replacement$1, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } + } + + return reviver.call(holder, name, value) + } + + var lexState; + var buffer; + var doubleQuote; + var sign; + var c; + + function lex () { + lexState = 'default'; + buffer = ''; + doubleQuote = false; + sign = 1; + + for (;;) { + c = peek(); + + // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } + + var token = lexStates[lexState](); + if (token) { + return token + } + } + } + + function peek () { + if (source[pos]) { + return String.fromCodePoint(source.codePointAt(pos)) + } + } + + function read () { + var c = peek(); + + if (c === '\n') { + line++; + column = 0; + } else if (c) { + column += c.length; + } else { + column++; + } + + if (c) { + pos += c.length; + } + + return c + } + + var lexStates = { + default: function default$1 () { + switch (c) { + case '\t': + case '\v': + case '\f': + case ' ': + case '\u00A0': + case '\uFEFF': + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + return + + case '/': + read(); + lexState = 'comment'; + return + + case undefined: + read(); + return newToken('eof') + } + + if (util.isSpaceSeparator(c)) { + read(); + return + } + + // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } + + return lexStates[parseState]() + }, + + comment: function comment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineComment'; + return + + case '/': + read(); + lexState = 'singleLineComment'; + return + } + + throw invalidChar(read()) + }, + + multiLineComment: function multiLineComment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineCommentAsterisk'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + }, + + multiLineCommentAsterisk: function multiLineCommentAsterisk () { + switch (c) { + case '*': + read(); + return + + case '/': + read(); + lexState = 'default'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + lexState = 'multiLineComment'; + }, + + singleLineComment: function singleLineComment () { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + lexState = 'default'; + return + + case undefined: + read(); + return newToken('eof') + } + + read(); + }, + + value: function value () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + case 'n': + read(); + literal('ull'); + return newToken('null', null) + + case 't': + read(); + literal('rue'); + return newToken('boolean', true) + + case 'f': + read(); + literal('alse'); + return newToken('boolean', false) + + case '-': + case '+': + if (read() === '-') { + sign = -1; + } + + lexState = 'sign'; + return + + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + + case '"': + case "'": + doubleQuote = (read() === '"'); + buffer = ''; + lexState = 'string'; + return + } + + throw invalidChar(read()) + }, + + identifierNameStartEscape: function identifierNameStartEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + var u = unicodeEscape(); + switch (u) { + case '$': + case '_': + break + + default: + if (!util.isIdStartChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + identifierName: function identifierName () { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read(); + return + + case '\\': + read(); + lexState = 'identifierNameEscape'; + return + } + + if (util.isIdContinueChar(c)) { + buffer += read(); + return + } + + return newToken('identifier', buffer) + }, + + identifierNameEscape: function identifierNameEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + var u = unicodeEscape(); + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break + + default: + if (!util.isIdContinueChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + sign: function sign$1 () { + switch (c) { + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', sign * Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + } + + throw invalidChar(read()) + }, + + zero: function zero () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + + case 'x': + case 'X': + buffer += read(); + lexState = 'hexadecimal'; + return + } + + return newToken('numeric', sign * 0) + }, + + decimalInteger: function decimalInteger () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalPointLeading: function decimalPointLeading () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + throw invalidChar(read()) + }, + + decimalPoint: function decimalPoint () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalFraction: function decimalFraction () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalExponent: function decimalExponent () { + switch (c) { + case '+': + case '-': + buffer += read(); + lexState = 'decimalExponentSign'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentSign: function decimalExponentSign () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentInteger: function decimalExponentInteger () { + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + hexadecimal: function hexadecimal () { + if (util.isHexDigit(c)) { + buffer += read(); + lexState = 'hexadecimalInteger'; + return + } + + throw invalidChar(read()) + }, + + hexadecimalInteger: function hexadecimalInteger () { + if (util.isHexDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + string: function string () { + switch (c) { + case '\\': + read(); + buffer += escape(); + return + + case '"': + if (doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case "'": + if (!doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case '\n': + case '\r': + throw invalidChar(read()) + + case '\u2028': + case '\u2029': + separatorChar(c); + break + + case undefined: + throw invalidChar(read()) + } + + buffer += read(); + }, + + start: function start () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } + + lexState = 'value'; + }, + + beforePropertyName: function beforePropertyName () { + switch (c) { + case '$': + case '_': + buffer = read(); + lexState = 'identifierName'; + return + + case '\\': + read(); + lexState = 'identifierNameStartEscape'; + return + + case '}': + return newToken('punctuator', read()) + + case '"': + case "'": + doubleQuote = (read() === '"'); + lexState = 'string'; + return + } + + if (util.isIdStartChar(c)) { + buffer += read(); + lexState = 'identifierName'; + return + } + + throw invalidChar(read()) + }, + + afterPropertyName: function afterPropertyName () { + if (c === ':') { + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforePropertyValue: function beforePropertyValue () { + lexState = 'value'; + }, + + afterPropertyValue: function afterPropertyValue () { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforeArrayValue: function beforeArrayValue () { + if (c === ']') { + return newToken('punctuator', read()) + } + + lexState = 'value'; + }, + + afterArrayValue: function afterArrayValue () { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + end: function end () { + // This code is unreachable since it's handled by the default lexState. + // if (c === undefined) { + // read() + // return newToken('eof') + // } + + throw invalidChar(read()) + }, + }; + + function newToken (type, value) { + return { + type: type, + value: value, + line: line, + column: column, + } + } + + function literal (s) { + for (var i = 0, list = s; i < list.length; i += 1) { + var c = list[i]; + + var p = peek(); + + if (p !== c) { + throw invalidChar(read()) + } + + read(); + } + } + + function escape () { + var c = peek(); + switch (c) { + case 'b': + read(); + return '\b' + + case 'f': + read(); + return '\f' + + case 'n': + read(); + return '\n' + + case 'r': + read(); + return '\r' + + case 't': + read(); + return '\t' + + case 'v': + read(); + return '\v' + + case '0': + read(); + if (util.isDigit(peek())) { + throw invalidChar(read()) + } + + return '\0' + + case 'x': + read(); + return hexEscape() + + case 'u': + read(); + return unicodeEscape() + + case '\n': + case '\u2028': + case '\u2029': + read(); + return '' + + case '\r': + read(); + if (peek() === '\n') { + read(); + } + + return '' + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()) + + case undefined: + throw invalidChar(read()) + } + + return read() + } + + function hexEscape () { + var buffer = ''; + var c = peek(); + + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + return String.fromCodePoint(parseInt(buffer, 16)) + } + + function unicodeEscape () { + var buffer = ''; + var count = 4; + + while (count-- > 0) { + var c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + } + + return String.fromCodePoint(parseInt(buffer, 16)) + } + + var parseStates = { + start: function start () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforePropertyName: function beforePropertyName () { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value; + parseState = 'afterPropertyName'; + return + + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + + pop(); + return + + case 'eof': + throw invalidEOF() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterPropertyName: function afterPropertyName () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator' || token.value !== ':') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + parseState = 'beforePropertyValue'; + }, + + beforePropertyValue: function beforePropertyValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforeArrayValue: function beforeArrayValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + if (token.type === 'punctuator' && token.value === ']') { + pop(); + return + } + + push(); + }, + + afterPropertyValue: function afterPropertyValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforePropertyName'; + return + + case '}': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterArrayValue: function afterArrayValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforeArrayValue'; + return + + case ']': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + end: function end () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } + }, + }; + + function push () { + var value; + + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {}; + break + + case '[': + value = []; + break + } + + break + + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value; + break + + // This code is unreachable. + // default: + // throw invalidToken() + } + + if (root === undefined) { + root = value; + } else { + var parent = stack[stack.length - 1]; + if (Array.isArray(parent)) { + parent.push(value); + } else { + Object.defineProperty(parent, key, { + value: value, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + + if (value !== null && typeof value === 'object') { + stack.push(value); + + if (Array.isArray(value)) { + parseState = 'beforeArrayValue'; + } else { + parseState = 'beforePropertyName'; + } + } else { + var current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } + } + + function pop () { + stack.pop(); + + var current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } + + // This code is unreachable. + // function invalidParseState () { + // return new Error(`JSON5: invalid parse state '${parseState}'`) + // } + + // This code is unreachable. + // function invalidLexState (state) { + // return new Error(`JSON5: invalid lex state '${state}'`) + // } + + function invalidChar (c) { + if (c === undefined) { + return syntaxError(("JSON5: invalid end of input at " + line + ":" + column)) + } + + return syntaxError(("JSON5: invalid character '" + (formatChar(c)) + "' at " + line + ":" + column)) + } + + function invalidEOF () { + return syntaxError(("JSON5: invalid end of input at " + line + ":" + column)) + } + + // This code is unreachable. + // function invalidToken () { + // if (token.type === 'eof') { + // return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) + // } + + // const c = String.fromCodePoint(token.value.codePointAt(0)) + // return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) + // } + + function invalidIdentifier () { + column -= 5; + return syntaxError(("JSON5: invalid identifier character at " + line + ":" + column)) + } + + function separatorChar (c) { + console.warn(("JSON5: '" + (formatChar(c)) + "' in strings is not valid ECMAScript; consider escaping")); + } + + function formatChar (c) { + var replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + if (replacements[c]) { + return replacements[c] + } + + if (c < ' ') { + var hexString = c.charCodeAt(0).toString(16); + return '\\x' + ('00' + hexString).substring(hexString.length) + } + + return c + } + + function syntaxError (message) { + var err = new SyntaxError(message); + err.lineNumber = line; + err.columnNumber = column; + return err + } + + var stringify = function stringify (value, replacer, space) { + var stack = []; + var indent = ''; + var propertyList; + var replacerFunc; + var gap = ''; + var quote; + + if ( + replacer != null && + typeof replacer === 'object' && + !Array.isArray(replacer) + ) { + space = replacer.space; + quote = replacer.quote; + replacer = replacer.replacer; + } + + if (typeof replacer === 'function') { + replacerFunc = replacer; + } else if (Array.isArray(replacer)) { + propertyList = []; + for (var i = 0, list = replacer; i < list.length; i += 1) { + var v = list[i]; + + var item = (void 0); + + if (typeof v === 'string') { + item = v; + } else if ( + typeof v === 'number' || + v instanceof String || + v instanceof Number + ) { + item = String(v); + } + + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item); + } + } + } + + if (space instanceof Number) { + space = Number(space); + } else if (space instanceof String) { + space = String(space); + } + + if (typeof space === 'number') { + if (space > 0) { + space = Math.min(10, Math.floor(space)); + gap = ' '.substr(0, space); + } + } else if (typeof space === 'string') { + gap = space.substr(0, 10); + } + + return serializeProperty('', {'': value}) + + function serializeProperty (key, holder) { + var value = holder[key]; + if (value != null) { + if (typeof value.toJSON5 === 'function') { + value = value.toJSON5(key); + } else if (typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + } + + if (replacerFunc) { + value = replacerFunc.call(holder, key, value); + } + + if (value instanceof Number) { + value = Number(value); + } else if (value instanceof String) { + value = String(value); + } else if (value instanceof Boolean) { + value = value.valueOf(); + } + + switch (value) { + case null: return 'null' + case true: return 'true' + case false: return 'false' + } + + if (typeof value === 'string') { + return quoteString(value, false) + } + + if (typeof value === 'number') { + return String(value) + } + + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value) + } + + return undefined + } + + function quoteString (value) { + var quotes = { + "'": 0.1, + '"': 0.2, + }; + + var replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + var product = ''; + + for (var i = 0; i < value.length; i++) { + var c = value[i]; + switch (c) { + case "'": + case '"': + quotes[c]++; + product += c; + continue + + case '\0': + if (util.isDigit(value[i + 1])) { + product += '\\x00'; + continue + } + } + + if (replacements[c]) { + product += replacements[c]; + continue + } + + if (c < ' ') { + var hexString = c.charCodeAt(0).toString(16); + product += '\\x' + ('00' + hexString).substring(hexString.length); + continue + } + + product += c; + } + + var quoteChar = quote || Object.keys(quotes).reduce(function (a, b) { return (quotes[a] < quotes[b]) ? a : b; }); + + product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]); + + return quoteChar + product + quoteChar + } + + function serializeObject (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + var stepback = indent; + indent = indent + gap; + + var keys = propertyList || Object.keys(value); + var partial = []; + for (var i = 0, list = keys; i < list.length; i += 1) { + var key = list[i]; + + var propertyString = serializeProperty(key, value); + if (propertyString !== undefined) { + var member = serializeKey(key) + ':'; + if (gap !== '') { + member += ' '; + } + member += propertyString; + partial.push(member); + } + } + + var final; + if (partial.length === 0) { + final = '{}'; + } else { + var properties; + if (gap === '') { + properties = partial.join(','); + final = '{' + properties + '}'; + } else { + var separator = ',\n' + indent; + properties = partial.join(separator); + final = '{\n' + indent + properties + ',\n' + stepback + '}'; + } + } + + stack.pop(); + indent = stepback; + return final + } + + function serializeKey (key) { + if (key.length === 0) { + return quoteString(key, true) + } + + var firstChar = String.fromCodePoint(key.codePointAt(0)); + if (!util.isIdStartChar(firstChar)) { + return quoteString(key, true) + } + + for (var i = firstChar.length; i < key.length; i++) { + if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key, true) + } + } + + return key + } + + function serializeArray (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + var stepback = indent; + indent = indent + gap; + + var partial = []; + for (var i = 0; i < value.length; i++) { + var propertyString = serializeProperty(String(i), value); + partial.push((propertyString !== undefined) ? propertyString : 'null'); + } + + var final; + if (partial.length === 0) { + final = '[]'; + } else { + if (gap === '') { + var properties = partial.join(','); + final = '[' + properties + ']'; + } else { + var separator = ',\n' + indent; + var properties$1 = partial.join(separator); + final = '[\n' + indent + properties$1 + ',\n' + stepback + ']'; + } + } + + stack.pop(); + indent = stepback; + return final + } + }; + + var JSON5 = { + parse: parse, + stringify: stringify, + }; + + var lib = JSON5; + + var es5 = lib; + + return es5; + +}))); diff --git a/node_modules/json5/dist/index.min.js b/node_modules/json5/dist/index.min.js new file mode 100644 index 0000000..ddce3e2 --- /dev/null +++ b/node_modules/json5/dist/index.min.js @@ -0,0 +1 @@ +!function(u,D){"object"==typeof exports&&"undefined"!=typeof module?module.exports=D():"function"==typeof define&&define.amd?define(D):u.JSON5=D()}(this,function(){"use strict";function u(u,D){return u(D={exports:{}},D.exports),D.exports}var D=u(function(u){var D=u.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=D)}),e=u(function(u){var D=u.exports={version:"2.6.5"};"number"==typeof __e&&(__e=D)}),r=(e.version,function(u){return"object"==typeof u?null!==u:"function"==typeof u}),t=function(u){if(!r(u))throw TypeError(u+" is not an object!");return u},n=function(u){try{return!!u()}catch(u){return!0}},F=!n(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),C=D.document,A=r(C)&&r(C.createElement),i=!F&&!n(function(){return 7!=Object.defineProperty((u="div",A?C.createElement(u):{}),"a",{get:function(){return 7}}).a;var u}),E=Object.defineProperty,o={f:F?Object.defineProperty:function(u,D,e){if(t(u),D=function(u,D){if(!r(u))return u;var e,t;if(D&&"function"==typeof(e=u.toString)&&!r(t=e.call(u)))return t;if("function"==typeof(e=u.valueOf)&&!r(t=e.call(u)))return t;if(!D&&"function"==typeof(e=u.toString)&&!r(t=e.call(u)))return t;throw TypeError("Can't convert object to primitive value")}(D,!0),t(e),i)try{return E(u,D,e)}catch(u){}if("get"in e||"set"in e)throw TypeError("Accessors not supported!");return"value"in e&&(u[D]=e.value),u}},a=F?function(u,D,e){return o.f(u,D,function(u,D){return{enumerable:!(1&u),configurable:!(2&u),writable:!(4&u),value:D}}(1,e))}:function(u,D,e){return u[D]=e,u},c={}.hasOwnProperty,B=function(u,D){return c.call(u,D)},s=0,f=Math.random(),l=u(function(u){var r=D["__core-js_shared__"]||(D["__core-js_shared__"]={});(u.exports=function(u,D){return r[u]||(r[u]=void 0!==D?D:{})})("versions",[]).push({version:e.version,mode:"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})})("native-function-to-string",Function.toString),d=u(function(u){var r,t="Symbol(".concat(void 0===(r="src")?"":r,")_",(++s+f).toString(36)),n=(""+l).split("toString");e.inspectSource=function(u){return l.call(u)},(u.exports=function(u,e,r,F){var C="function"==typeof r;C&&(B(r,"name")||a(r,"name",e)),u[e]!==r&&(C&&(B(r,t)||a(r,t,u[e]?""+u[e]:n.join(String(e)))),u===D?u[e]=r:F?u[e]?u[e]=r:a(u,e,r):(delete u[e],a(u,e,r)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[t]||l.call(this)})}),v=function(u,D,e){if(function(u){if("function"!=typeof u)throw TypeError(u+" is not a function!")}(u),void 0===D)return u;switch(e){case 1:return function(e){return u.call(D,e)};case 2:return function(e,r){return u.call(D,e,r)};case 3:return function(e,r,t){return u.call(D,e,r,t)}}return function(){return u.apply(D,arguments)}},p=function(u,r,t){var n,F,C,A,i=u&p.F,E=u&p.G,o=u&p.S,c=u&p.P,B=u&p.B,s=E?D:o?D[r]||(D[r]={}):(D[r]||{}).prototype,f=E?e:e[r]||(e[r]={}),l=f.prototype||(f.prototype={});for(n in E&&(t=r),t)C=((F=!i&&s&&void 0!==s[n])?s:t)[n],A=B&&F?v(C,D):c&&"function"==typeof C?v(Function.call,C):C,s&&d(s,n,C,u&p.U),f[n]!=C&&a(f,n,A),c&&l[n]!=C&&(l[n]=C)};D.core=e,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,p.U=64,p.R=128;var h,m=p,g=Math.ceil,y=Math.floor,w=function(u){return isNaN(u=+u)?0:(u>0?y:g)(u)},b=(h=!1,function(u,D){var e,r,t=String(function(u){if(null==u)throw TypeError("Can't call method on "+u);return u}(u)),n=w(D),F=t.length;return n<0||n>=F?h?"":void 0:(e=t.charCodeAt(n))<55296||e>56319||n+1===F||(r=t.charCodeAt(n+1))<56320||r>57343?h?t.charAt(n):e:h?t.slice(n,n+2):r-56320+(e-55296<<10)+65536});m(m.P,"String",{codePointAt:function(u){return b(this,u)}});e.String.codePointAt;var S=Math.max,x=Math.min,N=String.fromCharCode,P=String.fromCodePoint;m(m.S+m.F*(!!P&&1!=P.length),"String",{fromCodePoint:function(u){for(var D,e,r,t=arguments,n=[],F=arguments.length,C=0;F>C;){if(D=+t[C++],r=1114111,((e=w(e=D))<0?S(e+r,0):x(e,r))!==D)throw RangeError(D+" is not a valid code point");n.push(D<65536?N(D):N(55296+((D-=65536)>>10),D%1024+56320))}return n.join("")}});e.String.fromCodePoint;var _,O,j,I,V,J,M,k,L,T,z,H,$,R,G={Space_Separator:/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ID_Start:/[\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\u0860-\u086A\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\u09FC\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-\u1884\u1887-\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\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\uDCE0-\uDCF2\uDCF4\uDCF5\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\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\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\uDD00-\uDD43]|\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\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ID_Continue:/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\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\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\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\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\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\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\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\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\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\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\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\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/},U={isSpaceSeparator:function(u){return"string"==typeof u&&G.Space_Separator.test(u)},isIdStartChar:function(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||G.ID_Start.test(u))},isIdContinueChar:function(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||G.ID_Continue.test(u))},isDigit:function(u){return"string"==typeof u&&/[0-9]/.test(u)},isHexDigit:function(u){return"string"==typeof u&&/[0-9A-Fa-f]/.test(u)}};function Z(){for(T="default",z="",H=!1,$=1;;){R=q();var u=X[T]();if(u)return u}}function q(){if(_[I])return String.fromCodePoint(_.codePointAt(I))}function W(){var u=q();return"\n"===u?(V++,J=0):u?J+=u.length:J++,u&&(I+=u.length),u}var X={default:function(){switch(R){case"\t":case"\v":case"\f":case" ":case" ":case"\ufeff":case"\n":case"\r":case"\u2028":case"\u2029":return void W();case"/":return W(),void(T="comment");case void 0:return W(),K("eof")}if(!U.isSpaceSeparator(R))return X[O]();W()},comment:function(){switch(R){case"*":return W(),void(T="multiLineComment");case"/":return W(),void(T="singleLineComment")}throw ru(W())},multiLineComment:function(){switch(R){case"*":return W(),void(T="multiLineCommentAsterisk");case void 0:throw ru(W())}W()},multiLineCommentAsterisk:function(){switch(R){case"*":return void W();case"/":return W(),void(T="default");case void 0:throw ru(W())}W(),T="multiLineComment"},singleLineComment:function(){switch(R){case"\n":case"\r":case"\u2028":case"\u2029":return W(),void(T="default");case void 0:return W(),K("eof")}W()},value:function(){switch(R){case"{":case"[":return K("punctuator",W());case"n":return W(),Q("ull"),K("null",null);case"t":return W(),Q("rue"),K("boolean",!0);case"f":return W(),Q("alse"),K("boolean",!1);case"-":case"+":return"-"===W()&&($=-1),void(T="sign");case".":return z=W(),void(T="decimalPointLeading");case"0":return z=W(),void(T="zero");case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return z=W(),void(T="decimalInteger");case"I":return W(),Q("nfinity"),K("numeric",1/0);case"N":return W(),Q("aN"),K("numeric",NaN);case'"':case"'":return H='"'===W(),z="",void(T="string")}throw ru(W())},identifierNameStartEscape:function(){if("u"!==R)throw ru(W());W();var u=Y();switch(u){case"$":case"_":break;default:if(!U.isIdStartChar(u))throw nu()}z+=u,T="identifierName"},identifierName:function(){switch(R){case"$":case"_":case"‌":case"‍":return void(z+=W());case"\\":return W(),void(T="identifierNameEscape")}if(!U.isIdContinueChar(R))return K("identifier",z);z+=W()},identifierNameEscape:function(){if("u"!==R)throw ru(W());W();var u=Y();switch(u){case"$":case"_":case"‌":case"‍":break;default:if(!U.isIdContinueChar(u))throw nu()}z+=u,T="identifierName"},sign:function(){switch(R){case".":return z=W(),void(T="decimalPointLeading");case"0":return z=W(),void(T="zero");case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return z=W(),void(T="decimalInteger");case"I":return W(),Q("nfinity"),K("numeric",$*(1/0));case"N":return W(),Q("aN"),K("numeric",NaN)}throw ru(W())},zero:function(){switch(R){case".":return z+=W(),void(T="decimalPoint");case"e":case"E":return z+=W(),void(T="decimalExponent");case"x":case"X":return z+=W(),void(T="hexadecimal")}return K("numeric",0*$)},decimalInteger:function(){switch(R){case".":return z+=W(),void(T="decimalPoint");case"e":case"E":return z+=W(),void(T="decimalExponent")}if(!U.isDigit(R))return K("numeric",$*Number(z));z+=W()},decimalPointLeading:function(){if(U.isDigit(R))return z+=W(),void(T="decimalFraction");throw ru(W())},decimalPoint:function(){switch(R){case"e":case"E":return z+=W(),void(T="decimalExponent")}return U.isDigit(R)?(z+=W(),void(T="decimalFraction")):K("numeric",$*Number(z))},decimalFraction:function(){switch(R){case"e":case"E":return z+=W(),void(T="decimalExponent")}if(!U.isDigit(R))return K("numeric",$*Number(z));z+=W()},decimalExponent:function(){switch(R){case"+":case"-":return z+=W(),void(T="decimalExponentSign")}if(U.isDigit(R))return z+=W(),void(T="decimalExponentInteger");throw ru(W())},decimalExponentSign:function(){if(U.isDigit(R))return z+=W(),void(T="decimalExponentInteger");throw ru(W())},decimalExponentInteger:function(){if(!U.isDigit(R))return K("numeric",$*Number(z));z+=W()},hexadecimal:function(){if(U.isHexDigit(R))return z+=W(),void(T="hexadecimalInteger");throw ru(W())},hexadecimalInteger:function(){if(!U.isHexDigit(R))return K("numeric",$*Number(z));z+=W()},string:function(){switch(R){case"\\":return W(),void(z+=function(){switch(q()){case"b":return W(),"\b";case"f":return W(),"\f";case"n":return W(),"\n";case"r":return W(),"\r";case"t":return W(),"\t";case"v":return W(),"\v";case"0":if(W(),U.isDigit(q()))throw ru(W());return"\0";case"x":return W(),function(){var u="",D=q();if(!U.isHexDigit(D))throw ru(W());if(u+=W(),D=q(),!U.isHexDigit(D))throw ru(W());return u+=W(),String.fromCodePoint(parseInt(u,16))}();case"u":return W(),Y();case"\n":case"\u2028":case"\u2029":return W(),"";case"\r":return W(),"\n"===q()&&W(),"";case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case void 0:throw ru(W())}return W()}());case'"':return H?(W(),K("string",z)):void(z+=W());case"'":return H?void(z+=W()):(W(),K("string",z));case"\n":case"\r":throw ru(W());case"\u2028":case"\u2029":!function(u){console.warn("JSON5: '"+Fu(u)+"' in strings is not valid ECMAScript; consider escaping")}(R);break;case void 0:throw ru(W())}z+=W()},start:function(){switch(R){case"{":case"[":return K("punctuator",W())}T="value"},beforePropertyName:function(){switch(R){case"$":case"_":return z=W(),void(T="identifierName");case"\\":return W(),void(T="identifierNameStartEscape");case"}":return K("punctuator",W());case'"':case"'":return H='"'===W(),void(T="string")}if(U.isIdStartChar(R))return z+=W(),void(T="identifierName");throw ru(W())},afterPropertyName:function(){if(":"===R)return K("punctuator",W());throw ru(W())},beforePropertyValue:function(){T="value"},afterPropertyValue:function(){switch(R){case",":case"}":return K("punctuator",W())}throw ru(W())},beforeArrayValue:function(){if("]"===R)return K("punctuator",W());T="value"},afterArrayValue:function(){switch(R){case",":case"]":return K("punctuator",W())}throw ru(W())},end:function(){throw ru(W())}};function K(u,D){return{type:u,value:D,line:V,column:J}}function Q(u){for(var D=0,e=u;D0;){var e=q();if(!U.isHexDigit(e))throw ru(W());u+=W()}return String.fromCodePoint(parseInt(u,16))}var uu={start:function(){if("eof"===M.type)throw tu();Du()},beforePropertyName:function(){switch(M.type){case"identifier":case"string":return k=M.value,void(O="afterPropertyName");case"punctuator":return void eu();case"eof":throw tu()}},afterPropertyName:function(){if("eof"===M.type)throw tu();O="beforePropertyValue"},beforePropertyValue:function(){if("eof"===M.type)throw tu();Du()},beforeArrayValue:function(){if("eof"===M.type)throw tu();"punctuator"!==M.type||"]"!==M.value?Du():eu()},afterPropertyValue:function(){if("eof"===M.type)throw tu();switch(M.value){case",":return void(O="beforePropertyName");case"}":eu()}},afterArrayValue:function(){if("eof"===M.type)throw tu();switch(M.value){case",":return void(O="beforeArrayValue");case"]":eu()}},end:function(){}};function Du(){var u;switch(M.type){case"punctuator":switch(M.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=M.value}if(void 0===L)L=u;else{var D=j[j.length-1];Array.isArray(D)?D.push(u):Object.defineProperty(D,k,{value:u,writable:!0,enumerable:!0,configurable:!0})}if(null!==u&&"object"==typeof u)j.push(u),O=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{var e=j[j.length-1];O=null==e?"end":Array.isArray(e)?"afterArrayValue":"afterPropertyValue"}}function eu(){j.pop();var u=j[j.length-1];O=null==u?"end":Array.isArray(u)?"afterArrayValue":"afterPropertyValue"}function ru(u){return Cu(void 0===u?"JSON5: invalid end of input at "+V+":"+J:"JSON5: invalid character '"+Fu(u)+"' at "+V+":"+J)}function tu(){return Cu("JSON5: invalid end of input at "+V+":"+J)}function nu(){return Cu("JSON5: invalid identifier character at "+V+":"+(J-=5))}function Fu(u){var D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){var e=u.charCodeAt(0).toString(16);return"\\x"+("00"+e).substring(e.length)}return u}function Cu(u){var D=new SyntaxError(u);return D.lineNumber=V,D.columnNumber=J,D}return{parse:function(u,D){_=String(u),O="start",j=[],I=0,V=1,J=0,M=void 0,k=void 0,L=void 0;do{M=Z(),uu[O]()}while("eof"!==M.type);return"function"==typeof D?function u(D,e,r){var t=D[e];if(null!=t&&"object"==typeof t)if(Array.isArray(t))for(var n=0;n0&&(e=Math.min(10,Math.floor(e)),A=" ".substr(0,e)):"string"==typeof e&&(A=e.substr(0,10)),c("",{"":u});function c(u,D){var e=D[u];switch(null!=e&&("function"==typeof e.toJSON5?e=e.toJSON5(u):"function"==typeof e.toJSON&&(e=e.toJSON(u))),t&&(e=t.call(D,u,e)),e instanceof Number?e=Number(e):e instanceof String?e=String(e):e instanceof Boolean&&(e=e.valueOf()),e){case null:return"null";case!0:return"true";case!1:return"false"}return"string"==typeof e?B(e):"number"==typeof e?String(e):"object"==typeof e?Array.isArray(e)?function(u){if(F.indexOf(u)>=0)throw TypeError("Converting circular structure to JSON5");F.push(u);var D=C;C+=A;for(var e,r=[],t=0;t=0)throw TypeError("Converting circular structure to JSON5");F.push(u);var D=C;C+=A;for(var e,t,n=r||Object.keys(u),i=[],E=0,o=n;E"string"==typeof u&&unicode.Space_Separator.test(u),isIdStartChar:u=>"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||unicode.ID_Start.test(u)),isIdContinueChar:u=>"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||unicode.ID_Continue.test(u)),isDigit:u=>"string"==typeof u&&/[0-9]/.test(u),isHexDigit:u=>"string"==typeof u&&/[0-9A-Fa-f]/.test(u)};let source,parseState,stack,pos,line,column,token,key,root;var parse=function(u,D){source=String(u),parseState="start",stack=[],pos=0,line=1,column=0,token=void 0,key=void 0,root=void 0;do{token=lex(),parseStates[parseState]()}while("eof"!==token.type);return"function"==typeof D?internalize({"":root},"",D):root};function internalize(u,D,e){const r=u[D];if(null!=r&&"object"==typeof r)if(Array.isArray(r))for(let u=0;u0;){const D=peek();if(!util.isHexDigit(D))throw invalidChar(read());u+=read()}return String.fromCodePoint(parseInt(u,16))}const parseStates={start(){if("eof"===token.type)throw invalidEOF();push()},beforePropertyName(){switch(token.type){case"identifier":case"string":return key=token.value,void(parseState="afterPropertyName");case"punctuator":return void pop();case"eof":throw invalidEOF()}},afterPropertyName(){if("eof"===token.type)throw invalidEOF();parseState="beforePropertyValue"},beforePropertyValue(){if("eof"===token.type)throw invalidEOF();push()},beforeArrayValue(){if("eof"===token.type)throw invalidEOF();"punctuator"!==token.type||"]"!==token.value?push():pop()},afterPropertyValue(){if("eof"===token.type)throw invalidEOF();switch(token.value){case",":return void(parseState="beforePropertyName");case"}":pop()}},afterArrayValue(){if("eof"===token.type)throw invalidEOF();switch(token.value){case",":return void(parseState="beforeArrayValue");case"]":pop()}},end(){}};function push(){let u;switch(token.type){case"punctuator":switch(token.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=token.value}if(void 0===root)root=u;else{const D=stack[stack.length-1];Array.isArray(D)?D.push(u):Object.defineProperty(D,key,{value:u,writable:!0,enumerable:!0,configurable:!0})}if(null!==u&&"object"==typeof u)stack.push(u),parseState=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{const u=stack[stack.length-1];parseState=null==u?"end":Array.isArray(u)?"afterArrayValue":"afterPropertyValue"}}function pop(){stack.pop();const u=stack[stack.length-1];parseState=null==u?"end":Array.isArray(u)?"afterArrayValue":"afterPropertyValue"}function invalidChar(u){return syntaxError(void 0===u?`JSON5: invalid end of input at ${line}:${column}`:`JSON5: invalid character '${formatChar(u)}' at ${line}:${column}`)}function invalidEOF(){return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)}function invalidIdentifier(){return syntaxError(`JSON5: invalid identifier character at ${line}:${column-=5}`)}function separatorChar(u){console.warn(`JSON5: '${formatChar(u)}' in strings is not valid ECMAScript; consider escaping`)}function formatChar(u){const D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){const D=u.charCodeAt(0).toString(16);return"\\x"+("00"+D).substring(D.length)}return u}function syntaxError(u){const D=new SyntaxError(u);return D.lineNumber=line,D.columnNumber=column,D}var stringify=function(u,D,e){const r=[];let t,F,C,a="",A="";if(null==D||"object"!=typeof D||Array.isArray(D)||(e=D.space,C=D.quote,D=D.replacer),"function"==typeof D)F=D;else if(Array.isArray(D)){t=[];for(const u of D){let D;"string"==typeof u?D=u:("number"==typeof u||u instanceof String||u instanceof Number)&&(D=String(u)),void 0!==D&&t.indexOf(D)<0&&t.push(D)}}return e instanceof Number?e=Number(e):e instanceof String&&(e=String(e)),"number"==typeof e?e>0&&(e=Math.min(10,Math.floor(e)),A=" ".substr(0,e)):"string"==typeof e&&(A=e.substr(0,10)),n("",{"":u});function n(u,D){let e=D[u];switch(null!=e&&("function"==typeof e.toJSON5?e=e.toJSON5(u):"function"==typeof e.toJSON&&(e=e.toJSON(u))),F&&(e=F.call(D,u,e)),e instanceof Number?e=Number(e):e instanceof String?e=String(e):e instanceof Boolean&&(e=e.valueOf()),e){case null:return"null";case!0:return"true";case!1:return"false"}return"string"==typeof e?E(e):"number"==typeof e?String(e):"object"==typeof e?Array.isArray(e)?function(u){if(r.indexOf(u)>=0)throw TypeError("Converting circular structure to JSON5");r.push(u);let D=a;a+=A;let e,t=[];for(let D=0;D=0)throw TypeError("Converting circular structure to JSON5");r.push(u);let D=a;a+=A;let e,F=t||Object.keys(u),C=[];for(const D of F){const e=n(D,u);if(void 0!==e){let u=i(D)+":";""!==A&&(u+=" "),u+=e,C.push(u)}}if(0===C.length)e="{}";else{let u;if(""===A)u=C.join(","),e="{"+u+"}";else{let r=",\n"+a;u=C.join(r),e="{\n"+a+u+",\n"+D+"}"}}return r.pop(),a=D,e}(e):void 0}function E(u){const D={"'":.1,'"':.2},e={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};let r="";for(let t=0;tD[u]= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === '$') || (c === '_') || + unicode.ID_Start.test(c) + ) + }, + + isIdContinueChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c === '$') || (c === '_') || + (c === '\u200C') || (c === '\u200D') || + unicode.ID_Continue.test(c) + ) + }, + + isDigit (c) { + return typeof c === 'string' && /[0-9]/.test(c) + }, + + isHexDigit (c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) + }, +}; + +let source; +let parseState; +let stack; +let pos; +let line; +let column; +let token; +let key; +let root; + +var parse = function parse (text, reviver) { + source = String(text); + parseState = 'start'; + stack = []; + pos = 0; + line = 1; + column = 0; + token = undefined; + key = undefined; + root = undefined; + + do { + token = lex(); + + // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } + + parseStates[parseState](); + } while (token.type !== 'eof') + + if (typeof reviver === 'function') { + return internalize({'': root}, '', reviver) + } + + return root +}; + +function internalize (holder, name, reviver) { + const value = holder[name]; + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const key = String(i); + const replacement = internalize(value, key, reviver); + if (replacement === undefined) { + delete value[key]; + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } else { + for (const key in value) { + const replacement = internalize(value, key, reviver); + if (replacement === undefined) { + delete value[key]; + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + } + } + + return reviver.call(holder, name, value) +} + +let lexState; +let buffer; +let doubleQuote; +let sign; +let c; + +function lex () { + lexState = 'default'; + buffer = ''; + doubleQuote = false; + sign = 1; + + for (;;) { + c = peek(); + + // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } + + const token = lexStates[lexState](); + if (token) { + return token + } + } +} + +function peek () { + if (source[pos]) { + return String.fromCodePoint(source.codePointAt(pos)) + } +} + +function read () { + const c = peek(); + + if (c === '\n') { + line++; + column = 0; + } else if (c) { + column += c.length; + } else { + column++; + } + + if (c) { + pos += c.length; + } + + return c +} + +const lexStates = { + default () { + switch (c) { + case '\t': + case '\v': + case '\f': + case ' ': + case '\u00A0': + case '\uFEFF': + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + return + + case '/': + read(); + lexState = 'comment'; + return + + case undefined: + read(); + return newToken('eof') + } + + if (util.isSpaceSeparator(c)) { + read(); + return + } + + // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } + + return lexStates[parseState]() + }, + + comment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineComment'; + return + + case '/': + read(); + lexState = 'singleLineComment'; + return + } + + throw invalidChar(read()) + }, + + multiLineComment () { + switch (c) { + case '*': + read(); + lexState = 'multiLineCommentAsterisk'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + }, + + multiLineCommentAsterisk () { + switch (c) { + case '*': + read(); + return + + case '/': + read(); + lexState = 'default'; + return + + case undefined: + throw invalidChar(read()) + } + + read(); + lexState = 'multiLineComment'; + }, + + singleLineComment () { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + lexState = 'default'; + return + + case undefined: + read(); + return newToken('eof') + } + + read(); + }, + + value () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + case 'n': + read(); + literal('ull'); + return newToken('null', null) + + case 't': + read(); + literal('rue'); + return newToken('boolean', true) + + case 'f': + read(); + literal('alse'); + return newToken('boolean', false) + + case '-': + case '+': + if (read() === '-') { + sign = -1; + } + + lexState = 'sign'; + return + + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + + case '"': + case "'": + doubleQuote = (read() === '"'); + buffer = ''; + lexState = 'string'; + return + } + + throw invalidChar(read()) + }, + + identifierNameStartEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + const u = unicodeEscape(); + switch (u) { + case '$': + case '_': + break + + default: + if (!util.isIdStartChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + identifierName () { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read(); + return + + case '\\': + read(); + lexState = 'identifierNameEscape'; + return + } + + if (util.isIdContinueChar(c)) { + buffer += read(); + return + } + + return newToken('identifier', buffer) + }, + + identifierNameEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read(); + const u = unicodeEscape(); + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break + + default: + if (!util.isIdContinueChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u; + lexState = 'identifierName'; + }, + + sign () { + switch (c) { + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return + + case '0': + buffer = read(); + lexState = 'zero'; + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return + + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', sign * Infinity) + + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN) + } + + throw invalidChar(read()) + }, + + zero () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + + case 'x': + case 'X': + buffer += read(); + lexState = 'hexadecimal'; + return + } + + return newToken('numeric', sign * 0) + }, + + decimalInteger () { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return + + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalPointLeading () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + throw invalidChar(read()) + }, + + decimalPoint () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalFraction () { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalExponent () { + switch (c) { + case '+': + case '-': + buffer += read(); + lexState = 'decimalExponentSign'; + return + } + + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentSign () { + if (util.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return + } + + throw invalidChar(read()) + }, + + decimalExponentInteger () { + if (util.isDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + hexadecimal () { + if (util.isHexDigit(c)) { + buffer += read(); + lexState = 'hexadecimalInteger'; + return + } + + throw invalidChar(read()) + }, + + hexadecimalInteger () { + if (util.isHexDigit(c)) { + buffer += read(); + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + string () { + switch (c) { + case '\\': + read(); + buffer += escape(); + return + + case '"': + if (doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case "'": + if (!doubleQuote) { + read(); + return newToken('string', buffer) + } + + buffer += read(); + return + + case '\n': + case '\r': + throw invalidChar(read()) + + case '\u2028': + case '\u2029': + separatorChar(c); + break + + case undefined: + throw invalidChar(read()) + } + + buffer += read(); + }, + + start () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } + + lexState = 'value'; + }, + + beforePropertyName () { + switch (c) { + case '$': + case '_': + buffer = read(); + lexState = 'identifierName'; + return + + case '\\': + read(); + lexState = 'identifierNameStartEscape'; + return + + case '}': + return newToken('punctuator', read()) + + case '"': + case "'": + doubleQuote = (read() === '"'); + lexState = 'string'; + return + } + + if (util.isIdStartChar(c)) { + buffer += read(); + lexState = 'identifierName'; + return + } + + throw invalidChar(read()) + }, + + afterPropertyName () { + if (c === ':') { + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforePropertyValue () { + lexState = 'value'; + }, + + afterPropertyValue () { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforeArrayValue () { + if (c === ']') { + return newToken('punctuator', read()) + } + + lexState = 'value'; + }, + + afterArrayValue () { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + end () { + // This code is unreachable since it's handled by the default lexState. + // if (c === undefined) { + // read() + // return newToken('eof') + // } + + throw invalidChar(read()) + }, +}; + +function newToken (type, value) { + return { + type, + value, + line, + column, + } +} + +function literal (s) { + for (const c of s) { + const p = peek(); + + if (p !== c) { + throw invalidChar(read()) + } + + read(); + } +} + +function escape () { + const c = peek(); + switch (c) { + case 'b': + read(); + return '\b' + + case 'f': + read(); + return '\f' + + case 'n': + read(); + return '\n' + + case 'r': + read(); + return '\r' + + case 't': + read(); + return '\t' + + case 'v': + read(); + return '\v' + + case '0': + read(); + if (util.isDigit(peek())) { + throw invalidChar(read()) + } + + return '\0' + + case 'x': + read(); + return hexEscape() + + case 'u': + read(); + return unicodeEscape() + + case '\n': + case '\u2028': + case '\u2029': + read(); + return '' + + case '\r': + read(); + if (peek() === '\n') { + read(); + } + + return '' + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()) + + case undefined: + throw invalidChar(read()) + } + + return read() +} + +function hexEscape () { + let buffer = ''; + let c = peek(); + + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +function unicodeEscape () { + let buffer = ''; + let count = 4; + + while (count-- > 0) { + const c = peek(); + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read(); + } + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +const parseStates = { + start () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforePropertyName () { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value; + parseState = 'afterPropertyName'; + return + + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + + pop(); + return + + case 'eof': + throw invalidEOF() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterPropertyName () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator' || token.value !== ':') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + parseState = 'beforePropertyValue'; + }, + + beforePropertyValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push(); + }, + + beforeArrayValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + if (token.type === 'punctuator' && token.value === ']') { + pop(); + return + } + + push(); + }, + + afterPropertyValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforePropertyName'; + return + + case '}': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterArrayValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforeArrayValue'; + return + + case ']': + pop(); + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + end () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } + }, +}; + +function push () { + let value; + + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {}; + break + + case '[': + value = []; + break + } + + break + + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value; + break + + // This code is unreachable. + // default: + // throw invalidToken() + } + + if (root === undefined) { + root = value; + } else { + const parent = stack[stack.length - 1]; + if (Array.isArray(parent)) { + parent.push(value); + } else { + Object.defineProperty(parent, key, { + value, + writable: true, + enumerable: true, + configurable: true, + }); + } + } + + if (value !== null && typeof value === 'object') { + stack.push(value); + + if (Array.isArray(value)) { + parseState = 'beforeArrayValue'; + } else { + parseState = 'beforePropertyName'; + } + } else { + const current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } +} + +function pop () { + stack.pop(); + + const current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } +} + +// This code is unreachable. +// function invalidParseState () { +// return new Error(`JSON5: invalid parse state '${parseState}'`) +// } + +// This code is unreachable. +// function invalidLexState (state) { +// return new Error(`JSON5: invalid lex state '${state}'`) +// } + +function invalidChar (c) { + if (c === undefined) { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) + } + + return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +} + +function invalidEOF () { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +} + +// This code is unreachable. +// function invalidToken () { +// if (token.type === 'eof') { +// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +// } + +// const c = String.fromCodePoint(token.value.codePointAt(0)) +// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +// } + +function invalidIdentifier () { + column -= 5; + return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`) +} + +function separatorChar (c) { + console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`); +} + +function formatChar (c) { + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + if (replacements[c]) { + return replacements[c] + } + + if (c < ' ') { + const hexString = c.charCodeAt(0).toString(16); + return '\\x' + ('00' + hexString).substring(hexString.length) + } + + return c +} + +function syntaxError (message) { + const err = new SyntaxError(message); + err.lineNumber = line; + err.columnNumber = column; + return err +} + +var stringify = function stringify (value, replacer, space) { + const stack = []; + let indent = ''; + let propertyList; + let replacerFunc; + let gap = ''; + let quote; + + if ( + replacer != null && + typeof replacer === 'object' && + !Array.isArray(replacer) + ) { + space = replacer.space; + quote = replacer.quote; + replacer = replacer.replacer; + } + + if (typeof replacer === 'function') { + replacerFunc = replacer; + } else if (Array.isArray(replacer)) { + propertyList = []; + for (const v of replacer) { + let item; + + if (typeof v === 'string') { + item = v; + } else if ( + typeof v === 'number' || + v instanceof String || + v instanceof Number + ) { + item = String(v); + } + + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item); + } + } + } + + if (space instanceof Number) { + space = Number(space); + } else if (space instanceof String) { + space = String(space); + } + + if (typeof space === 'number') { + if (space > 0) { + space = Math.min(10, Math.floor(space)); + gap = ' '.substr(0, space); + } + } else if (typeof space === 'string') { + gap = space.substr(0, 10); + } + + return serializeProperty('', {'': value}) + + function serializeProperty (key, holder) { + let value = holder[key]; + if (value != null) { + if (typeof value.toJSON5 === 'function') { + value = value.toJSON5(key); + } else if (typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + } + + if (replacerFunc) { + value = replacerFunc.call(holder, key, value); + } + + if (value instanceof Number) { + value = Number(value); + } else if (value instanceof String) { + value = String(value); + } else if (value instanceof Boolean) { + value = value.valueOf(); + } + + switch (value) { + case null: return 'null' + case true: return 'true' + case false: return 'false' + } + + if (typeof value === 'string') { + return quoteString(value, false) + } + + if (typeof value === 'number') { + return String(value) + } + + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value) + } + + return undefined + } + + function quoteString (value) { + const quotes = { + "'": 0.1, + '"': 0.2, + }; + + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + }; + + let product = ''; + + for (let i = 0; i < value.length; i++) { + const c = value[i]; + switch (c) { + case "'": + case '"': + quotes[c]++; + product += c; + continue + + case '\0': + if (util.isDigit(value[i + 1])) { + product += '\\x00'; + continue + } + } + + if (replacements[c]) { + product += replacements[c]; + continue + } + + if (c < ' ') { + let hexString = c.charCodeAt(0).toString(16); + product += '\\x' + ('00' + hexString).substring(hexString.length); + continue + } + + product += c; + } + + const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b); + + product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]); + + return quoteChar + product + quoteChar + } + + function serializeObject (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + let stepback = indent; + indent = indent + gap; + + let keys = propertyList || Object.keys(value); + let partial = []; + for (const key of keys) { + const propertyString = serializeProperty(key, value); + if (propertyString !== undefined) { + let member = serializeKey(key) + ':'; + if (gap !== '') { + member += ' '; + } + member += propertyString; + partial.push(member); + } + } + + let final; + if (partial.length === 0) { + final = '{}'; + } else { + let properties; + if (gap === '') { + properties = partial.join(','); + final = '{' + properties + '}'; + } else { + let separator = ',\n' + indent; + properties = partial.join(separator); + final = '{\n' + indent + properties + ',\n' + stepback + '}'; + } + } + + stack.pop(); + indent = stepback; + return final + } + + function serializeKey (key) { + if (key.length === 0) { + return quoteString(key, true) + } + + const firstChar = String.fromCodePoint(key.codePointAt(0)); + if (!util.isIdStartChar(firstChar)) { + return quoteString(key, true) + } + + for (let i = firstChar.length; i < key.length; i++) { + if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key, true) + } + } + + return key + } + + function serializeArray (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value); + + let stepback = indent; + indent = indent + gap; + + let partial = []; + for (let i = 0; i < value.length; i++) { + const propertyString = serializeProperty(String(i), value); + partial.push((propertyString !== undefined) ? propertyString : 'null'); + } + + let final; + if (partial.length === 0) { + final = '[]'; + } else { + if (gap === '') { + let properties = partial.join(','); + final = '[' + properties + ']'; + } else { + let separator = ',\n' + indent; + let properties = partial.join(separator); + final = '[\n' + indent + properties + ',\n' + stepback + ']'; + } + } + + stack.pop(); + indent = stepback; + return final + } +}; + +const JSON5 = { + parse, + stringify, +}; + +var lib = JSON5; + +export default lib; diff --git a/node_modules/json5/lib/cli.js b/node_modules/json5/lib/cli.js new file mode 100644 index 0000000..93cb809 --- /dev/null +++ b/node_modules/json5/lib/cli.js @@ -0,0 +1,152 @@ +#!/usr/bin/env node + +const fs = require('fs') +const path = require('path') +const pkg = require('../package.json') +const JSON5 = require('./') + +const argv = parseArgs() + +if (argv.version) { + version() +} else if (argv.help) { + usage() +} else { + const inFilename = argv.defaults[0] + + let readStream + if (inFilename) { + readStream = fs.createReadStream(inFilename) + } else { + readStream = process.stdin + } + + let json5 = '' + readStream.on('data', data => { + json5 += data + }) + + readStream.on('end', () => { + let space + if (argv.space === 't' || argv.space === 'tab') { + space = '\t' + } else { + space = Number(argv.space) + } + + let value + try { + value = JSON5.parse(json5) + if (!argv.validate) { + const json = JSON.stringify(value, null, space) + + let writeStream + + // --convert is for backward compatibility with v0.5.1. If + // specified with and not --out-file, then a file with + // the same name but with a .json extension will be written. + if (argv.convert && inFilename && !argv.outFile) { + const parsedFilename = path.parse(inFilename) + const outFilename = path.format( + Object.assign( + parsedFilename, + {base: path.basename(parsedFilename.base, parsedFilename.ext) + '.json'} + ) + ) + + writeStream = fs.createWriteStream(outFilename) + } else if (argv.outFile) { + writeStream = fs.createWriteStream(argv.outFile) + } else { + writeStream = process.stdout + } + + writeStream.write(json) + } + } catch (err) { + console.error(err.message) + process.exit(1) + } + }) +} + +function parseArgs () { + let convert + let space + let validate + let outFile + let version + let help + const defaults = [] + + const args = process.argv.slice(2) + for (let i = 0; i < args.length; i++) { + const arg = args[i] + switch (arg) { + case '--convert': + case '-c': + convert = true + break + + case '--space': + case '-s': + space = args[++i] + break + + case '--validate': + case '-v': + validate = true + break + + case '--out-file': + case '-o': + outFile = args[++i] + break + + case '--version': + case '-V': + version = true + break + + case '--help': + case '-h': + help = true + break + + default: + defaults.push(arg) + break + } + } + + return { + convert, + space, + validate, + outFile, + version, + help, + defaults, + } +} + +function version () { + console.log(pkg.version) +} + +function usage () { + console.log( + ` + Usage: json5 [options] + + If is not provided, then STDIN is used. + + Options: + + -s, --space The number of spaces to indent or 't' for tabs + -o, --out-file [file] Output to the specified file, otherwise STDOUT + -v, --validate Validate JSON5 but do not output JSON + -V, --version Output the version number + -h, --help Output usage information` + ) +} diff --git a/node_modules/json5/lib/index.d.ts b/node_modules/json5/lib/index.d.ts new file mode 100644 index 0000000..1c45bca --- /dev/null +++ b/node_modules/json5/lib/index.d.ts @@ -0,0 +1,4 @@ +import parse = require('./parse') +import stringify = require('./stringify') + +export {parse, stringify} diff --git a/node_modules/json5/lib/index.js b/node_modules/json5/lib/index.js new file mode 100644 index 0000000..3679638 --- /dev/null +++ b/node_modules/json5/lib/index.js @@ -0,0 +1,9 @@ +const parse = require('./parse') +const stringify = require('./stringify') + +const JSON5 = { + parse, + stringify, +} + +module.exports = JSON5 diff --git a/node_modules/json5/lib/parse.d.ts b/node_modules/json5/lib/parse.d.ts new file mode 100644 index 0000000..8c8d883 --- /dev/null +++ b/node_modules/json5/lib/parse.d.ts @@ -0,0 +1,15 @@ +/** + * Parses a JSON5 string, constructing the JavaScript value or object described + * by the string. + * @template T The type of the return value. + * @param text The string to parse as JSON5. + * @param reviver A function that prescribes how the value originally produced + * by parsing is transformed before being returned. + * @returns The JavaScript value converted from the JSON5 string. + */ +declare function parse( + text: string, + reviver?: ((this: any, key: string, value: any) => any) | null, +): T + +export = parse diff --git a/node_modules/json5/lib/parse.js b/node_modules/json5/lib/parse.js new file mode 100644 index 0000000..da2078a --- /dev/null +++ b/node_modules/json5/lib/parse.js @@ -0,0 +1,1114 @@ +const util = require('./util') + +let source +let parseState +let stack +let pos +let line +let column +let token +let key +let root + +module.exports = function parse (text, reviver) { + source = String(text) + parseState = 'start' + stack = [] + pos = 0 + line = 1 + column = 0 + token = undefined + key = undefined + root = undefined + + do { + token = lex() + + // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } + + parseStates[parseState]() + } while (token.type !== 'eof') + + if (typeof reviver === 'function') { + return internalize({'': root}, '', reviver) + } + + return root +} + +function internalize (holder, name, reviver) { + const value = holder[name] + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const key = String(i) + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + } else { + for (const key in value) { + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + } + } + + return reviver.call(holder, name, value) +} + +let lexState +let buffer +let doubleQuote +let sign +let c + +function lex () { + lexState = 'default' + buffer = '' + doubleQuote = false + sign = 1 + + for (;;) { + c = peek() + + // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } + + const token = lexStates[lexState]() + if (token) { + return token + } + } +} + +function peek () { + if (source[pos]) { + return String.fromCodePoint(source.codePointAt(pos)) + } +} + +function read () { + const c = peek() + + if (c === '\n') { + line++ + column = 0 + } else if (c) { + column += c.length + } else { + column++ + } + + if (c) { + pos += c.length + } + + return c +} + +const lexStates = { + default () { + switch (c) { + case '\t': + case '\v': + case '\f': + case ' ': + case '\u00A0': + case '\uFEFF': + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read() + return + + case '/': + read() + lexState = 'comment' + return + + case undefined: + read() + return newToken('eof') + } + + if (util.isSpaceSeparator(c)) { + read() + return + } + + // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } + + return lexStates[parseState]() + }, + + comment () { + switch (c) { + case '*': + read() + lexState = 'multiLineComment' + return + + case '/': + read() + lexState = 'singleLineComment' + return + } + + throw invalidChar(read()) + }, + + multiLineComment () { + switch (c) { + case '*': + read() + lexState = 'multiLineCommentAsterisk' + return + + case undefined: + throw invalidChar(read()) + } + + read() + }, + + multiLineCommentAsterisk () { + switch (c) { + case '*': + read() + return + + case '/': + read() + lexState = 'default' + return + + case undefined: + throw invalidChar(read()) + } + + read() + lexState = 'multiLineComment' + }, + + singleLineComment () { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read() + lexState = 'default' + return + + case undefined: + read() + return newToken('eof') + } + + read() + }, + + value () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + case 'n': + read() + literal('ull') + return newToken('null', null) + + case 't': + read() + literal('rue') + return newToken('boolean', true) + + case 'f': + read() + literal('alse') + return newToken('boolean', false) + + case '-': + case '+': + if (read() === '-') { + sign = -1 + } + + lexState = 'sign' + return + + case '.': + buffer = read() + lexState = 'decimalPointLeading' + return + + case '0': + buffer = read() + lexState = 'zero' + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read() + lexState = 'decimalInteger' + return + + case 'I': + read() + literal('nfinity') + return newToken('numeric', Infinity) + + case 'N': + read() + literal('aN') + return newToken('numeric', NaN) + + case '"': + case "'": + doubleQuote = (read() === '"') + buffer = '' + lexState = 'string' + return + } + + throw invalidChar(read()) + }, + + identifierNameStartEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read() + const u = unicodeEscape() + switch (u) { + case '$': + case '_': + break + + default: + if (!util.isIdStartChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u + lexState = 'identifierName' + }, + + identifierName () { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read() + return + + case '\\': + read() + lexState = 'identifierNameEscape' + return + } + + if (util.isIdContinueChar(c)) { + buffer += read() + return + } + + return newToken('identifier', buffer) + }, + + identifierNameEscape () { + if (c !== 'u') { + throw invalidChar(read()) + } + + read() + const u = unicodeEscape() + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break + + default: + if (!util.isIdContinueChar(u)) { + throw invalidIdentifier() + } + + break + } + + buffer += u + lexState = 'identifierName' + }, + + sign () { + switch (c) { + case '.': + buffer = read() + lexState = 'decimalPointLeading' + return + + case '0': + buffer = read() + lexState = 'zero' + return + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read() + lexState = 'decimalInteger' + return + + case 'I': + read() + literal('nfinity') + return newToken('numeric', sign * Infinity) + + case 'N': + read() + literal('aN') + return newToken('numeric', NaN) + } + + throw invalidChar(read()) + }, + + zero () { + switch (c) { + case '.': + buffer += read() + lexState = 'decimalPoint' + return + + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + + case 'x': + case 'X': + buffer += read() + lexState = 'hexadecimal' + return + } + + return newToken('numeric', sign * 0) + }, + + decimalInteger () { + switch (c) { + case '.': + buffer += read() + lexState = 'decimalPoint' + return + + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + } + + if (util.isDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalPointLeading () { + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalFraction' + return + } + + throw invalidChar(read()) + }, + + decimalPoint () { + switch (c) { + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + } + + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalFraction' + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalFraction () { + switch (c) { + case 'e': + case 'E': + buffer += read() + lexState = 'decimalExponent' + return + } + + if (util.isDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + decimalExponent () { + switch (c) { + case '+': + case '-': + buffer += read() + lexState = 'decimalExponentSign' + return + } + + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalExponentInteger' + return + } + + throw invalidChar(read()) + }, + + decimalExponentSign () { + if (util.isDigit(c)) { + buffer += read() + lexState = 'decimalExponentInteger' + return + } + + throw invalidChar(read()) + }, + + decimalExponentInteger () { + if (util.isDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + hexadecimal () { + if (util.isHexDigit(c)) { + buffer += read() + lexState = 'hexadecimalInteger' + return + } + + throw invalidChar(read()) + }, + + hexadecimalInteger () { + if (util.isHexDigit(c)) { + buffer += read() + return + } + + return newToken('numeric', sign * Number(buffer)) + }, + + string () { + switch (c) { + case '\\': + read() + buffer += escape() + return + + case '"': + if (doubleQuote) { + read() + return newToken('string', buffer) + } + + buffer += read() + return + + case "'": + if (!doubleQuote) { + read() + return newToken('string', buffer) + } + + buffer += read() + return + + case '\n': + case '\r': + throw invalidChar(read()) + + case '\u2028': + case '\u2029': + separatorChar(c) + break + + case undefined: + throw invalidChar(read()) + } + + buffer += read() + }, + + start () { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()) + + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } + + lexState = 'value' + }, + + beforePropertyName () { + switch (c) { + case '$': + case '_': + buffer = read() + lexState = 'identifierName' + return + + case '\\': + read() + lexState = 'identifierNameStartEscape' + return + + case '}': + return newToken('punctuator', read()) + + case '"': + case "'": + doubleQuote = (read() === '"') + lexState = 'string' + return + } + + if (util.isIdStartChar(c)) { + buffer += read() + lexState = 'identifierName' + return + } + + throw invalidChar(read()) + }, + + afterPropertyName () { + if (c === ':') { + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforePropertyValue () { + lexState = 'value' + }, + + afterPropertyValue () { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + beforeArrayValue () { + if (c === ']') { + return newToken('punctuator', read()) + } + + lexState = 'value' + }, + + afterArrayValue () { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()) + } + + throw invalidChar(read()) + }, + + end () { + // This code is unreachable since it's handled by the default lexState. + // if (c === undefined) { + // read() + // return newToken('eof') + // } + + throw invalidChar(read()) + }, +} + +function newToken (type, value) { + return { + type, + value, + line, + column, + } +} + +function literal (s) { + for (const c of s) { + const p = peek() + + if (p !== c) { + throw invalidChar(read()) + } + + read() + } +} + +function escape () { + const c = peek() + switch (c) { + case 'b': + read() + return '\b' + + case 'f': + read() + return '\f' + + case 'n': + read() + return '\n' + + case 'r': + read() + return '\r' + + case 't': + read() + return '\t' + + case 'v': + read() + return '\v' + + case '0': + read() + if (util.isDigit(peek())) { + throw invalidChar(read()) + } + + return '\0' + + case 'x': + read() + return hexEscape() + + case 'u': + read() + return unicodeEscape() + + case '\n': + case '\u2028': + case '\u2029': + read() + return '' + + case '\r': + read() + if (peek() === '\n') { + read() + } + + return '' + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()) + + case undefined: + throw invalidChar(read()) + } + + return read() +} + +function hexEscape () { + let buffer = '' + let c = peek() + + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read() + + c = peek() + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read() + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +function unicodeEscape () { + let buffer = '' + let count = 4 + + while (count-- > 0) { + const c = peek() + if (!util.isHexDigit(c)) { + throw invalidChar(read()) + } + + buffer += read() + } + + return String.fromCodePoint(parseInt(buffer, 16)) +} + +const parseStates = { + start () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push() + }, + + beforePropertyName () { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value + parseState = 'afterPropertyName' + return + + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + + pop() + return + + case 'eof': + throw invalidEOF() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterPropertyName () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator' || token.value !== ':') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + parseState = 'beforePropertyValue' + }, + + beforePropertyValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + push() + }, + + beforeArrayValue () { + if (token.type === 'eof') { + throw invalidEOF() + } + + if (token.type === 'punctuator' && token.value === ']') { + pop() + return + } + + push() + }, + + afterPropertyValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforePropertyName' + return + + case '}': + pop() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + afterArrayValue () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + + if (token.type === 'eof') { + throw invalidEOF() + } + + switch (token.value) { + case ',': + parseState = 'beforeArrayValue' + return + + case ']': + pop() + } + + // This code is unreachable since it's handled by the lexState. + // throw invalidToken() + }, + + end () { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } + }, +} + +function push () { + let value + + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {} + break + + case '[': + value = [] + break + } + + break + + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value + break + + // This code is unreachable. + // default: + // throw invalidToken() + } + + if (root === undefined) { + root = value + } else { + const parent = stack[stack.length - 1] + if (Array.isArray(parent)) { + parent.push(value) + } else { + Object.defineProperty(parent, key, { + value, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + + if (value !== null && typeof value === 'object') { + stack.push(value) + + if (Array.isArray(value)) { + parseState = 'beforeArrayValue' + } else { + parseState = 'beforePropertyName' + } + } else { + const current = stack[stack.length - 1] + if (current == null) { + parseState = 'end' + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue' + } else { + parseState = 'afterPropertyValue' + } + } +} + +function pop () { + stack.pop() + + const current = stack[stack.length - 1] + if (current == null) { + parseState = 'end' + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue' + } else { + parseState = 'afterPropertyValue' + } +} + +// This code is unreachable. +// function invalidParseState () { +// return new Error(`JSON5: invalid parse state '${parseState}'`) +// } + +// This code is unreachable. +// function invalidLexState (state) { +// return new Error(`JSON5: invalid lex state '${state}'`) +// } + +function invalidChar (c) { + if (c === undefined) { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) + } + + return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +} + +function invalidEOF () { + return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +} + +// This code is unreachable. +// function invalidToken () { +// if (token.type === 'eof') { +// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) +// } + +// const c = String.fromCodePoint(token.value.codePointAt(0)) +// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) +// } + +function invalidIdentifier () { + column -= 5 + return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`) +} + +function separatorChar (c) { + console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`) +} + +function formatChar (c) { + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + } + + if (replacements[c]) { + return replacements[c] + } + + if (c < ' ') { + const hexString = c.charCodeAt(0).toString(16) + return '\\x' + ('00' + hexString).substring(hexString.length) + } + + return c +} + +function syntaxError (message) { + const err = new SyntaxError(message) + err.lineNumber = line + err.columnNumber = column + return err +} diff --git a/node_modules/json5/lib/register.js b/node_modules/json5/lib/register.js new file mode 100644 index 0000000..935cdba --- /dev/null +++ b/node_modules/json5/lib/register.js @@ -0,0 +1,13 @@ +const fs = require('fs') +const JSON5 = require('./') + +// eslint-disable-next-line node/no-deprecated-api +require.extensions['.json5'] = function (module, filename) { + const content = fs.readFileSync(filename, 'utf8') + try { + module.exports = JSON5.parse(content) + } catch (err) { + err.message = filename + ': ' + err.message + throw err + } +} diff --git a/node_modules/json5/lib/require.js b/node_modules/json5/lib/require.js new file mode 100644 index 0000000..3aa29be --- /dev/null +++ b/node_modules/json5/lib/require.js @@ -0,0 +1,4 @@ +// This file is for backward compatibility with v0.5.1. +require('./register') + +console.warn("'json5/require' is deprecated. Please use 'json5/register' instead.") diff --git a/node_modules/json5/lib/stringify.d.ts b/node_modules/json5/lib/stringify.d.ts new file mode 100644 index 0000000..3c34838 --- /dev/null +++ b/node_modules/json5/lib/stringify.d.ts @@ -0,0 +1,89 @@ +declare type StringifyOptions = { + /** + * A function that alters the behavior of the stringification process, or an + * array of String and Number objects that serve as a allowlist for + * selecting/filtering the properties of the value object to be included in + * the JSON5 string. If this value is null or not provided, all properties + * of the object are included in the resulting JSON5 string. + */ + replacer?: + | ((this: any, key: string, value: any) => any) + | (string | number)[] + | null + + /** + * A String or Number object that's used to insert white space into the + * output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this + * number is capped at 10 (if it is greater, the value is just 10). Values + * less than 1 indicate that no space should be used. If this is a String, + * the string (or the first 10 characters of the string, if it's longer than + * that) is used as white space. If this parameter is not provided (or is + * null), no white space is used. If white space is used, trailing commas + * will be used in objects and arrays. + */ + space?: string | number | null + + /** + * A String representing the quote character to use when serializing + * strings. + */ + quote?: string | null +} + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param replacer A function that alters the behavior of the stringification + * process. If this value is null or not provided, all properties of the object + * are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space into + * the output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this number + * is capped at 10 (if it is greater, the value is just 10). Values less than 1 + * indicate that no space should be used. If this is a String, the string (or + * the first 10 characters of the string, if it's longer than that) is used as + * white space. If this parameter is not provided (or is null), no white space + * is used. If white space is used, trailing commas will be used in objects and + * arrays. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify( + value: any, + replacer?: ((this: any, key: string, value: any) => any) | null, + space?: string | number | null, +): string + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param replacer An array of String and Number objects that serve as a + * allowlist for selecting/filtering the properties of the value object to be + * included in the JSON5 string. If this value is null or not provided, all + * properties of the object are included in the resulting JSON5 string. + * @param space A String or Number object that's used to insert white space into + * the output JSON5 string for readability purposes. If this is a Number, it + * indicates the number of space characters to use as white space; this number + * is capped at 10 (if it is greater, the value is just 10). Values less than 1 + * indicate that no space should be used. If this is a String, the string (or + * the first 10 characters of the string, if it's longer than that) is used as + * white space. If this parameter is not provided (or is null), no white space + * is used. If white space is used, trailing commas will be used in objects and + * arrays. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify( + value: any, + replacer: (string | number)[], + space?: string | number | null, +): string + +/** + * Converts a JavaScript value to a JSON5 string. + * @param value The value to convert to a JSON5 string. + * @param options An object specifying options. + * @returns The JSON5 string converted from the JavaScript value. + */ +declare function stringify(value: any, options: StringifyOptions): string + +export = stringify diff --git a/node_modules/json5/lib/stringify.js b/node_modules/json5/lib/stringify.js new file mode 100644 index 0000000..7cb3b0e --- /dev/null +++ b/node_modules/json5/lib/stringify.js @@ -0,0 +1,261 @@ +const util = require('./util') + +module.exports = function stringify (value, replacer, space) { + const stack = [] + let indent = '' + let propertyList + let replacerFunc + let gap = '' + let quote + + if ( + replacer != null && + typeof replacer === 'object' && + !Array.isArray(replacer) + ) { + space = replacer.space + quote = replacer.quote + replacer = replacer.replacer + } + + if (typeof replacer === 'function') { + replacerFunc = replacer + } else if (Array.isArray(replacer)) { + propertyList = [] + for (const v of replacer) { + let item + + if (typeof v === 'string') { + item = v + } else if ( + typeof v === 'number' || + v instanceof String || + v instanceof Number + ) { + item = String(v) + } + + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item) + } + } + } + + if (space instanceof Number) { + space = Number(space) + } else if (space instanceof String) { + space = String(space) + } + + if (typeof space === 'number') { + if (space > 0) { + space = Math.min(10, Math.floor(space)) + gap = ' '.substr(0, space) + } + } else if (typeof space === 'string') { + gap = space.substr(0, 10) + } + + return serializeProperty('', {'': value}) + + function serializeProperty (key, holder) { + let value = holder[key] + if (value != null) { + if (typeof value.toJSON5 === 'function') { + value = value.toJSON5(key) + } else if (typeof value.toJSON === 'function') { + value = value.toJSON(key) + } + } + + if (replacerFunc) { + value = replacerFunc.call(holder, key, value) + } + + if (value instanceof Number) { + value = Number(value) + } else if (value instanceof String) { + value = String(value) + } else if (value instanceof Boolean) { + value = value.valueOf() + } + + switch (value) { + case null: return 'null' + case true: return 'true' + case false: return 'false' + } + + if (typeof value === 'string') { + return quoteString(value, false) + } + + if (typeof value === 'number') { + return String(value) + } + + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value) + } + + return undefined + } + + function quoteString (value) { + const quotes = { + "'": 0.1, + '"': 0.2, + } + + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029', + } + + let product = '' + + for (let i = 0; i < value.length; i++) { + const c = value[i] + switch (c) { + case "'": + case '"': + quotes[c]++ + product += c + continue + + case '\0': + if (util.isDigit(value[i + 1])) { + product += '\\x00' + continue + } + } + + if (replacements[c]) { + product += replacements[c] + continue + } + + if (c < ' ') { + let hexString = c.charCodeAt(0).toString(16) + product += '\\x' + ('00' + hexString).substring(hexString.length) + continue + } + + product += c + } + + const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b) + + product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]) + + return quoteChar + product + quoteChar + } + + function serializeObject (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value) + + let stepback = indent + indent = indent + gap + + let keys = propertyList || Object.keys(value) + let partial = [] + for (const key of keys) { + const propertyString = serializeProperty(key, value) + if (propertyString !== undefined) { + let member = serializeKey(key) + ':' + if (gap !== '') { + member += ' ' + } + member += propertyString + partial.push(member) + } + } + + let final + if (partial.length === 0) { + final = '{}' + } else { + let properties + if (gap === '') { + properties = partial.join(',') + final = '{' + properties + '}' + } else { + let separator = ',\n' + indent + properties = partial.join(separator) + final = '{\n' + indent + properties + ',\n' + stepback + '}' + } + } + + stack.pop() + indent = stepback + return final + } + + function serializeKey (key) { + if (key.length === 0) { + return quoteString(key, true) + } + + const firstChar = String.fromCodePoint(key.codePointAt(0)) + if (!util.isIdStartChar(firstChar)) { + return quoteString(key, true) + } + + for (let i = firstChar.length; i < key.length; i++) { + if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key, true) + } + } + + return key + } + + function serializeArray (value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5') + } + + stack.push(value) + + let stepback = indent + indent = indent + gap + + let partial = [] + for (let i = 0; i < value.length; i++) { + const propertyString = serializeProperty(String(i), value) + partial.push((propertyString !== undefined) ? propertyString : 'null') + } + + let final + if (partial.length === 0) { + final = '[]' + } else { + if (gap === '') { + let properties = partial.join(',') + final = '[' + properties + ']' + } else { + let separator = ',\n' + indent + let properties = partial.join(separator) + final = '[\n' + indent + properties + ',\n' + stepback + ']' + } + } + + stack.pop() + indent = stepback + return final + } +} diff --git a/node_modules/json5/lib/unicode.d.ts b/node_modules/json5/lib/unicode.d.ts new file mode 100644 index 0000000..610f805 --- /dev/null +++ b/node_modules/json5/lib/unicode.d.ts @@ -0,0 +1,3 @@ +export declare const Space_Separator: RegExp +export declare const ID_Start: RegExp +export declare const ID_Continue: RegExp diff --git a/node_modules/json5/lib/unicode.js b/node_modules/json5/lib/unicode.js new file mode 100644 index 0000000..215ccd8 --- /dev/null +++ b/node_modules/json5/lib/unicode.js @@ -0,0 +1,4 @@ +// This is a generated file. Do not edit. +module.exports.Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/ +module.exports.ID_Start = /[\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\u0860-\u086A\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\u09FC\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-\u1884\u1887-\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\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\uDCE0-\uDCF2\uDCF4\uDCF5\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\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\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\uDD00-\uDD43]|\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\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/ +module.exports.ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\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\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\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\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\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\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\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\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\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\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\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\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ diff --git a/node_modules/json5/lib/util.d.ts b/node_modules/json5/lib/util.d.ts new file mode 100644 index 0000000..a940cea --- /dev/null +++ b/node_modules/json5/lib/util.d.ts @@ -0,0 +1,5 @@ +export declare function isSpaceSeparator(c?: string): boolean +export declare function isIdStartChar(c?: string): boolean +export declare function isIdContinueChar(c?: string): boolean +export declare function isDigit(c?: string): boolean +export declare function isHexDigit(c?: string): boolean diff --git a/node_modules/json5/lib/util.js b/node_modules/json5/lib/util.js new file mode 100644 index 0000000..40bfe2f --- /dev/null +++ b/node_modules/json5/lib/util.js @@ -0,0 +1,35 @@ +const unicode = require('../lib/unicode') + +module.exports = { + isSpaceSeparator (c) { + return typeof c === 'string' && unicode.Space_Separator.test(c) + }, + + isIdStartChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === '$') || (c === '_') || + unicode.ID_Start.test(c) + ) + }, + + isIdContinueChar (c) { + return typeof c === 'string' && ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c === '$') || (c === '_') || + (c === '\u200C') || (c === '\u200D') || + unicode.ID_Continue.test(c) + ) + }, + + isDigit (c) { + return typeof c === 'string' && /[0-9]/.test(c) + }, + + isHexDigit (c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) + }, +} diff --git a/node_modules/json5/package.json b/node_modules/json5/package.json new file mode 100644 index 0000000..60c51d9 --- /dev/null +++ b/node_modules/json5/package.json @@ -0,0 +1,72 @@ +{ + "name": "json5", + "version": "2.2.3", + "description": "JSON for Humans", + "main": "lib/index.js", + "module": "dist/index.mjs", + "bin": "lib/cli.js", + "browser": "dist/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/", + "dist/" + ], + "engines": { + "node": ">=6" + }, + "scripts": { + "build": "rollup -c", + "build-package": "node build/package.js", + "build-unicode": "node build/unicode.js", + "coverage": "tap --coverage-report html test", + "lint": "eslint --fix .", + "lint-report": "eslint .", + "prepublishOnly": "npm run production", + "preversion": "npm run production", + "production": "run-s test build", + "tap": "tap -Rspec --100 test", + "test": "run-s lint-report tap", + "version": "npm run build-package && git add package.json5" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/json5/json5.git" + }, + "keywords": [ + "json", + "json5", + "es5", + "es2015", + "ecmascript" + ], + "author": "Aseem Kishore ", + "contributors": [ + "Max Nanasy ", + "Andrew Eisenberg ", + "Jordan Tucker " + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/json5/json5/issues" + }, + "homepage": "http://json5.org/", + "devDependencies": { + "core-js": "^2.6.5", + "eslint": "^5.15.3", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-node": "^8.0.1", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-standard": "^4.0.0", + "npm-run-all": "^4.1.5", + "regenerate": "^1.4.0", + "rollup": "^0.64.1", + "rollup-plugin-buble": "^0.19.6", + "rollup-plugin-commonjs": "^9.2.1", + "rollup-plugin-node-resolve": "^3.4.0", + "rollup-plugin-terser": "^1.0.1", + "sinon": "^6.3.5", + "tap": "^12.6.0", + "unicode-10.0.0": "^0.7.5" + } +} diff --git a/node_modules/mgrs/.npmignore b/node_modules/mgrs/.npmignore new file mode 100644 index 0000000..8226f2b --- /dev/null +++ b/node_modules/mgrs/.npmignore @@ -0,0 +1,4 @@ +*~ +node_modules +.DS_STORE +coverage diff --git a/node_modules/mgrs/PUBLISHING.md b/node_modules/mgrs/PUBLISHING.md new file mode 100644 index 0000000..2a74804 --- /dev/null +++ b/node_modules/mgrs/PUBLISHING.md @@ -0,0 +1,17 @@ +Publishing +=== + +Use `tin` to update the version number in `package.json`. + + tin -v x.y.z + +Then run the publish script + + ./publish.sh + +afterwards don't forget to update the versions to be a prerelease of the next version, so if you just published 1.1.1 then: + + tin -v 1.1.2-alpha + git add package.json + git commit -m 'update version to 1.1.2-alpha' + git push origin master diff --git a/node_modules/mgrs/dist/mgrs.js b/node_modules/mgrs/dist/mgrs.js new file mode 100644 index 0000000..a272923 --- /dev/null +++ b/node_modules/mgrs/dist/mgrs.js @@ -0,0 +1,758 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.mgrs = global.mgrs || {}))); +}(this, (function (exports) { 'use strict'; + +/** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ +var NUM_100K_SETS = 6; + +/** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + +/** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + +var A = 65; // A +var I = 73; // I +var O = 79; // O +var V = 86; // V +var Z = 90; // Z +var mgrs = { + forward: forward, + inverse: inverse, + toPoint: toPoint +}; +/** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ +function forward(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({ + lat: ll[1], + lon: ll[0] + }), accuracy); +} + +/** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ +function inverse(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat, bbox.lon, bbox.lat]; + } + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; +} + +function toPoint(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat]; + } + return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2]; +} +/** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ +function degToRad(deg) { + return (deg * (Math.PI / 180.0)); +} + +/** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ +function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); +} + +/** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ +function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var k0 = 0.9996; + var LongOrigin; + var eccPrimeSquared; + var N, T, C, A, M; + var LatRad = degToRad(Lat); + var LongRad = degToRad(Long); + var LongOriginRad; + var ZoneNumber; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long === 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) { + ZoneNumber = 31; + } + else if (Long >= 9.0 && Long < 21.0) { + ZoneNumber = 33; + } + else if (Long >= 21.0 && Long < 33.0) { + ZoneNumber = 35; + } + else if (Long >= 33.0 && Long < 42.0) { + ZoneNumber = 37; + } + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + LongOriginRad = degToRad(LongOrigin); + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad)); + T = Math.tan(LatRad) * Math.tan(LatRad); + C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad); + A = Math.cos(LatRad) * (LongRad - LongOriginRad); + + M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.sin(6 * LatRad)); + + var UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; +} + +/** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ +function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var eccPrimeSquared; + var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared)); + var N1, T1, C1, R1, D, M; + var LongOrigin; + var mu, phi1Rad; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter < 'N') { + y -= 10000000.0; // remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + M = y / k0; + mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256)); + + phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad)); + T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad); + C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad); + R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5); + D = x / (N1 * k0); + + var lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720); + lat = radToDeg(lat); + + var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad); + lon = LongOrigin + radToDeg(lon); + + var result; + if (utm.accuracy) { + var topRight = UTMtoLL({ + northing: utm.northing + utm.accuracy, + easting: utm.easting + utm.accuracy, + zoneLetter: utm.zoneLetter, + zoneNumber: utm.zoneNumber + }); + result = { + top: topRight.lat, + right: topRight.lon, + bottom: lat, + left: lon + }; + } + else { + result = { + lat: lat, + lon: lon + }; + } + return result; +} + +/** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ +function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + var LetterDesignator = 'Z'; + + if ((84 >= lat) && (lat >= 72)) { + LetterDesignator = 'X'; + } + else if ((72 > lat) && (lat >= 64)) { + LetterDesignator = 'W'; + } + else if ((64 > lat) && (lat >= 56)) { + LetterDesignator = 'V'; + } + else if ((56 > lat) && (lat >= 48)) { + LetterDesignator = 'U'; + } + else if ((48 > lat) && (lat >= 40)) { + LetterDesignator = 'T'; + } + else if ((40 > lat) && (lat >= 32)) { + LetterDesignator = 'S'; + } + else if ((32 > lat) && (lat >= 24)) { + LetterDesignator = 'R'; + } + else if ((24 > lat) && (lat >= 16)) { + LetterDesignator = 'Q'; + } + else if ((16 > lat) && (lat >= 8)) { + LetterDesignator = 'P'; + } + else if ((8 > lat) && (lat >= 0)) { + LetterDesignator = 'N'; + } + else if ((0 > lat) && (lat >= -8)) { + LetterDesignator = 'M'; + } + else if ((-8 > lat) && (lat >= -16)) { + LetterDesignator = 'L'; + } + else if ((-16 > lat) && (lat >= -24)) { + LetterDesignator = 'K'; + } + else if ((-24 > lat) && (lat >= -32)) { + LetterDesignator = 'J'; + } + else if ((-32 > lat) && (lat >= -40)) { + LetterDesignator = 'H'; + } + else if ((-40 > lat) && (lat >= -48)) { + LetterDesignator = 'G'; + } + else if ((-48 > lat) && (lat >= -56)) { + LetterDesignator = 'F'; + } + else if ((-56 > lat) && (lat >= -64)) { + LetterDesignator = 'E'; + } + else if ((-64 > lat) && (lat >= -72)) { + LetterDesignator = 'D'; + } + else if ((-72 > lat) && (lat >= -80)) { + LetterDesignator = 'C'; + } + return LetterDesignator; +} + +/** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ +function encode(utm, accuracy) { + // prepend with leading zeroes + var seasting = "00000" + utm.easting, + snorthing = "00000" + utm.northing; + + return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy); +} + +/** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ +function get100kID(easting, northing, zoneNumber) { + var setParm = get100kSetForZone(zoneNumber); + var setColumn = Math.floor(easting / 100000); + var setRow = Math.floor(northing / 100000) % 20; + return getLetter100kID(setColumn, setRow, setParm); +} + +/** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ +function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm === 0) { + setParm = NUM_100K_SETS; + } + + return setParm; +} + +/** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ +function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm - 1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + var colInt = colOrigin + column - 1; + var rowInt = rowOrigin + row; + var rollover = false; + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + rollover = true; + } + + if (colInt === I || (colOrigin < I && colInt > I) || ((colInt > I || colOrigin < I) && rollover)) { + colInt++; + } + + if (colInt === O || (colOrigin < O && colInt > O) || ((colInt > O || colOrigin < O) && rollover)) { + colInt++; + + if (colInt === I) { + colInt++; + } + } + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + rollover = true; + } + else { + rollover = false; + } + + if (((rowInt === I) || ((rowOrigin < I) && (rowInt > I))) || (((rowInt > I) || (rowOrigin < I)) && rollover)) { + rowInt++; + } + + if (((rowInt === O) || ((rowOrigin < O) && (rowInt > O))) || (((rowInt > O) || (rowOrigin < O)) && rollover)) { + rowInt++; + + if (rowInt === I) { + rowInt++; + } + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + } + + var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt); + return twoLetter; +} + +/** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ +function decode(mgrsString) { + + if (mgrsString && mgrsString.length === 0) { + throw ("MGRSPoint coverting from nothing"); + } + + var length = mgrsString.length; + + var hunK = null; + var sb = ""; + var testChar; + var i = 0; + + // get Zone number + while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) { + if (i >= 2) { + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + sb += testChar; + i++; + } + + var zoneNumber = parseInt(sb, 10); + + if (i === 0 || i + 3 > length) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') { + throw ("MGRSPoint zone letter " + zoneLetter + " not handled: " + mgrsString); + } + + hunK = mgrsString.substring(i, i += 2); + + var set = get100kSetForZone(zoneNumber); + + var east100k = getEastingFromChar(hunK.charAt(0), set); + var north100k = getNorthingFromChar(hunK.charAt(1), set); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + var remainder = length - i; + + if (remainder % 2 !== 0) { + throw ("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters" + mgrsString); + } + + var sep = remainder / 2; + + var sepEasting = 0.0; + var sepNorthing = 0.0; + var accuracyBonus, sepEastingString, sepNorthingString, easting, northing; + if (sep > 0) { + accuracyBonus = 100000.0 / Math.pow(10, sep); + sepEastingString = mgrsString.substring(i, i + sep); + sepEasting = parseFloat(sepEastingString) * accuracyBonus; + sepNorthingString = mgrsString.substring(i + sep); + sepNorthing = parseFloat(sepNorthingString) * accuracyBonus; + } + + easting = sepEasting + east100k; + northing = sepNorthing + north100k; + + return { + easting: easting, + northing: northing, + zoneLetter: zoneLetter, + zoneNumber: zoneNumber, + accuracy: accuracyBonus + }; +} + +/** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ +function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + var rewindMarker = false; + + while (curCol !== e.charCodeAt(0)) { + curCol++; + if (curCol === I) { + curCol++; + } + if (curCol === O) { + curCol++; + } + if (curCol > Z) { + if (rewindMarker) { + throw ("Bad character: " + e); + } + curCol = A; + rewindMarker = true; + } + eastingValue += 100000.0; + } + + return eastingValue; +} + +/** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ +function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw ("MGRSPoint given invalid Northing " + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow !== n.charCodeAt(0)) { + curRow++; + if (curRow === I) { + curRow++; + } + if (curRow === O) { + curRow++; + } + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw ("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; +} + +/** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ +function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } + else { + throw ("Invalid zone letter: " + zoneLetter); + } + +} + +exports['default'] = mgrs; +exports.forward = forward; +exports.inverse = inverse; +exports.toPoint = toPoint; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/node_modules/mgrs/license.md b/node_modules/mgrs/license.md new file mode 100644 index 0000000..f999ce2 --- /dev/null +++ b/node_modules/mgrs/license.md @@ -0,0 +1,19 @@ +Copyright (c) 2012, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral, Calvin Metcalf + + 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._ \ No newline at end of file diff --git a/node_modules/mgrs/mgrs.js b/node_modules/mgrs/mgrs.js new file mode 100644 index 0000000..bb08a56 --- /dev/null +++ b/node_modules/mgrs/mgrs.js @@ -0,0 +1,746 @@ + + + +/** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ +var NUM_100K_SETS = 6; + +/** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + +/** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + +var A = 65; // A +var I = 73; // I +var O = 79; // O +var V = 86; // V +var Z = 90; // Z +export default { + forward: forward, + inverse: inverse, + toPoint: toPoint +}; +/** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ +export function forward(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({ + lat: ll[1], + lon: ll[0] + }), accuracy); +}; + +/** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ +export function inverse(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat, bbox.lon, bbox.lat]; + } + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; +}; + +export function toPoint(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat]; + } + return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2]; +}; +/** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ +function degToRad(deg) { + return (deg * (Math.PI / 180.0)); +} + +/** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ +function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); +} + +/** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ +function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var k0 = 0.9996; + var LongOrigin; + var eccPrimeSquared; + var N, T, C, A, M; + var LatRad = degToRad(Lat); + var LongRad = degToRad(Long); + var LongOriginRad; + var ZoneNumber; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long === 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) { + ZoneNumber = 31; + } + else if (Long >= 9.0 && Long < 21.0) { + ZoneNumber = 33; + } + else if (Long >= 21.0 && Long < 33.0) { + ZoneNumber = 35; + } + else if (Long >= 33.0 && Long < 42.0) { + ZoneNumber = 37; + } + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + LongOriginRad = degToRad(LongOrigin); + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad)); + T = Math.tan(LatRad) * Math.tan(LatRad); + C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad); + A = Math.cos(LatRad) * (LongRad - LongOriginRad); + + M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.sin(6 * LatRad)); + + var UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; +} + +/** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ +function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var eccPrimeSquared; + var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared)); + var N1, T1, C1, R1, D, M; + var LongOrigin; + var mu, phi1Rad; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter < 'N') { + y -= 10000000.0; // remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + M = y / k0; + mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256)); + + phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad)); + T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad); + C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad); + R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5); + D = x / (N1 * k0); + + var lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720); + lat = radToDeg(lat); + + var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad); + lon = LongOrigin + radToDeg(lon); + + var result; + if (utm.accuracy) { + var topRight = UTMtoLL({ + northing: utm.northing + utm.accuracy, + easting: utm.easting + utm.accuracy, + zoneLetter: utm.zoneLetter, + zoneNumber: utm.zoneNumber + }); + result = { + top: topRight.lat, + right: topRight.lon, + bottom: lat, + left: lon + }; + } + else { + result = { + lat: lat, + lon: lon + }; + } + return result; +} + +/** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ +function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + var LetterDesignator = 'Z'; + + if ((84 >= lat) && (lat >= 72)) { + LetterDesignator = 'X'; + } + else if ((72 > lat) && (lat >= 64)) { + LetterDesignator = 'W'; + } + else if ((64 > lat) && (lat >= 56)) { + LetterDesignator = 'V'; + } + else if ((56 > lat) && (lat >= 48)) { + LetterDesignator = 'U'; + } + else if ((48 > lat) && (lat >= 40)) { + LetterDesignator = 'T'; + } + else if ((40 > lat) && (lat >= 32)) { + LetterDesignator = 'S'; + } + else if ((32 > lat) && (lat >= 24)) { + LetterDesignator = 'R'; + } + else if ((24 > lat) && (lat >= 16)) { + LetterDesignator = 'Q'; + } + else if ((16 > lat) && (lat >= 8)) { + LetterDesignator = 'P'; + } + else if ((8 > lat) && (lat >= 0)) { + LetterDesignator = 'N'; + } + else if ((0 > lat) && (lat >= -8)) { + LetterDesignator = 'M'; + } + else if ((-8 > lat) && (lat >= -16)) { + LetterDesignator = 'L'; + } + else if ((-16 > lat) && (lat >= -24)) { + LetterDesignator = 'K'; + } + else if ((-24 > lat) && (lat >= -32)) { + LetterDesignator = 'J'; + } + else if ((-32 > lat) && (lat >= -40)) { + LetterDesignator = 'H'; + } + else if ((-40 > lat) && (lat >= -48)) { + LetterDesignator = 'G'; + } + else if ((-48 > lat) && (lat >= -56)) { + LetterDesignator = 'F'; + } + else if ((-56 > lat) && (lat >= -64)) { + LetterDesignator = 'E'; + } + else if ((-64 > lat) && (lat >= -72)) { + LetterDesignator = 'D'; + } + else if ((-72 > lat) && (lat >= -80)) { + LetterDesignator = 'C'; + } + return LetterDesignator; +} + +/** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ +function encode(utm, accuracy) { + // prepend with leading zeroes + var seasting = "00000" + utm.easting, + snorthing = "00000" + utm.northing; + + return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy); +} + +/** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ +function get100kID(easting, northing, zoneNumber) { + var setParm = get100kSetForZone(zoneNumber); + var setColumn = Math.floor(easting / 100000); + var setRow = Math.floor(northing / 100000) % 20; + return getLetter100kID(setColumn, setRow, setParm); +} + +/** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ +function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm === 0) { + setParm = NUM_100K_SETS; + } + + return setParm; +} + +/** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ +function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm - 1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + var colInt = colOrigin + column - 1; + var rowInt = rowOrigin + row; + var rollover = false; + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + rollover = true; + } + + if (colInt === I || (colOrigin < I && colInt > I) || ((colInt > I || colOrigin < I) && rollover)) { + colInt++; + } + + if (colInt === O || (colOrigin < O && colInt > O) || ((colInt > O || colOrigin < O) && rollover)) { + colInt++; + + if (colInt === I) { + colInt++; + } + } + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + rollover = true; + } + else { + rollover = false; + } + + if (((rowInt === I) || ((rowOrigin < I) && (rowInt > I))) || (((rowInt > I) || (rowOrigin < I)) && rollover)) { + rowInt++; + } + + if (((rowInt === O) || ((rowOrigin < O) && (rowInt > O))) || (((rowInt > O) || (rowOrigin < O)) && rollover)) { + rowInt++; + + if (rowInt === I) { + rowInt++; + } + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + } + + var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt); + return twoLetter; +} + +/** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ +function decode(mgrsString) { + + if (mgrsString && mgrsString.length === 0) { + throw ("MGRSPoint coverting from nothing"); + } + + var length = mgrsString.length; + + var hunK = null; + var sb = ""; + var testChar; + var i = 0; + + // get Zone number + while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) { + if (i >= 2) { + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + sb += testChar; + i++; + } + + var zoneNumber = parseInt(sb, 10); + + if (i === 0 || i + 3 > length) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') { + throw ("MGRSPoint zone letter " + zoneLetter + " not handled: " + mgrsString); + } + + hunK = mgrsString.substring(i, i += 2); + + var set = get100kSetForZone(zoneNumber); + + var east100k = getEastingFromChar(hunK.charAt(0), set); + var north100k = getNorthingFromChar(hunK.charAt(1), set); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + var remainder = length - i; + + if (remainder % 2 !== 0) { + throw ("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters" + mgrsString); + } + + var sep = remainder / 2; + + var sepEasting = 0.0; + var sepNorthing = 0.0; + var accuracyBonus, sepEastingString, sepNorthingString, easting, northing; + if (sep > 0) { + accuracyBonus = 100000.0 / Math.pow(10, sep); + sepEastingString = mgrsString.substring(i, i + sep); + sepEasting = parseFloat(sepEastingString) * accuracyBonus; + sepNorthingString = mgrsString.substring(i + sep); + sepNorthing = parseFloat(sepNorthingString) * accuracyBonus; + } + + easting = sepEasting + east100k; + northing = sepNorthing + north100k; + + return { + easting: easting, + northing: northing, + zoneLetter: zoneLetter, + zoneNumber: zoneNumber, + accuracy: accuracyBonus + }; +} + +/** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ +function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + var rewindMarker = false; + + while (curCol !== e.charCodeAt(0)) { + curCol++; + if (curCol === I) { + curCol++; + } + if (curCol === O) { + curCol++; + } + if (curCol > Z) { + if (rewindMarker) { + throw ("Bad character: " + e); + } + curCol = A; + rewindMarker = true; + } + eastingValue += 100000.0; + } + + return eastingValue; +} + +/** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ +function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw ("MGRSPoint given invalid Northing " + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow !== n.charCodeAt(0)) { + curRow++; + if (curRow === I) { + curRow++; + } + if (curRow === O) { + curRow++; + } + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw ("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; +} + +/** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ +function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } + else { + throw ("Invalid zone letter: " + zoneLetter); + } + +} diff --git a/node_modules/mgrs/openmap.md b/node_modules/mgrs/openmap.md new file mode 100644 index 0000000..cba0d76 --- /dev/null +++ b/node_modules/mgrs/openmap.md @@ -0,0 +1,145 @@ +OpenMap Software License Agreement +====== + +This Agreement sets forth the terms and conditions under which +the software known as OpenMap(tm) will be licensed by BBN +Technologies ("BBN") to you ("Licensee"), and by which Derivative +Works (as hereafter defined) of OpenMap will be licensed by you to BBN. + +Definitions: + +- "Derivative Work(s)" shall mean any revision, enhancement, + modification, translation, abridgement, condensation or + expansion created by Licensee or BBN that is based upon the + Software or a portion thereof that would be a copyright + infringement if prepared without the authorization of the + copyright owners of the Software or portion thereof. + +- "OpenMap" shall mean a programmer's toolkit for building map + based applications as originally created by BBN, and any + Derivative Works thereof as created by either BBN or Licensee, + but shall include only those Derivative Works BBN has approved + for inclusion into, and BBN has integrated into OpenMap. + +- "Standard Version" shall mean OpenMap, as originally created by + BBN. + +- "Software" shall mean OpenMap and the Derivative Works created + by Licensee and the collection of files distributed by the + Licensee with OpenMap, and the collection of files created + through textual modifications. + +- "Copyright Holder" is whoever is named in the copyright or + copyrights for the Derivative Works. + +- "Licensee" is you, only if you agree to be bound by the terms + and conditions set forth in this Agreement. + +- "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people + involved. + +- "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions that they received it. + +1. BBN maintains all rights, title and interest in and to +OpenMap, including all applicable copyrights, trade secrets, +patents and other intellectual rights therein. Licensee hereby +grants to BBN all right, title and interest into the compilation +of OpenMap. Licensee shall own all rights, title and interest +into the Derivative Works created by Licensee (subject to the +compilation ownership by BBN). + +2. BBN hereby grants to Licensee a royalty free, worldwide right +and license to use, copy, distribute and make Derivative Works of +OpenMap, and sublicensing rights of any of the foregoing in +accordance with the terms and conditions of this Agreement, +provided that you duplicate all of the original copyright notices +and associated disclaimers. + +3. Licensee hereby grants to BBN a royalty free, worldwide right +and license to use, copy, distribute and make Derivative Works of +Derivative Works created by Licensee and sublicensing rights of +any of the foregoing. + +4. Licensee's right to create Derivative Works in the Software is +subject to Licensee agreement to insert a prominent notice in +each changed file stating how and when you changed that file, and +provided that you do at least ONE of the following: + + - a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or + placing the modifications on a major archive site and by + providing your modifications to the Copyright Holder. + + - b) use the modified Package only within your corporation or + organization. + + - c) rename any non-standard executables so the names do not + conflict with standard executables, which must also be + provided, and provide a separate manual page for each + non-standard executable that clearly documents how it + differs from OpenMap. + + - d) make other distribution arrangements with the Copyright + Holder. +5. Licensee may distribute the programs of this Software in +object code or executable form, provided that you do at least ONE +of the following: + + - a) distribute an OpenMap version of the executables and + library files, together with instructions (in the manual + page or equivalent) on where to get OpenMap. + + - b) accompany the distribution with the machine-readable + source code with your modifications. + + - c) accompany any non-standard executables with their + corresponding OpenMap executables, giving the non-standard + executables non-standard names, and clearly documenting + the differences in manual pages (or equivalent), together + with instructions on where to get OpenMap. + + - d) make other distribution arrangements with the Copyright + Holder. +6. You may charge a reasonable copying fee for any distribution +of this Software. You may charge any fee you choose for support +of this Software. You may not charge a fee for this Software +itself. However, you may distribute this Software in aggregate +with other (possibly commercial) programs as part of a larger +(possibly commercial) software distribution provided that you do +not advertise this Software as a product of your own. + +7. The data and images supplied as input to or produced as output +from the Software do not automatically fall under the copyright +of this Software, but belong to whomever generated them, and may +be sold commercially, and may be aggregated with this Software. + +8. BBN makes no representation about the suitability of OpenMap +for any purposes. BBN shall have no duty or requirement to +include any Derivative Works into OpenMap. + +9. Each party hereto represents and warrants that they have the +full unrestricted right to grant all rights and licenses granted +to the other party herein. + +10. THIS PACKAGE IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY +KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT LIMITED TO) +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND +WITHOUT ANY WARRANTIES AS TO NONINFRINGEMENT. + +11. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE OF DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS CONDUCT, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PACKAGE. + +12. Without limitation of the foregoing, You agree to commit no +act which, directly or indirectly, would violate any U.S. law, +regulation, or treaty, or any other international treaty or +agreement to which the United States adheres or with which the +United States complies, relating to the export or re-export of +any commodities, software, or technical data. \ No newline at end of file diff --git a/node_modules/mgrs/package.json b/node_modules/mgrs/package.json new file mode 100644 index 0000000..eb89248 --- /dev/null +++ b/node_modules/mgrs/package.json @@ -0,0 +1,31 @@ +{ + "name": "mgrs", + "version": "1.0.0", + "description": "Utility for converting between WGS84 lat/lng and MGRS coordinates", + "main": "dist/mgrs.js", + "module": "mgrs.js", + "scripts": { + "test": "npm run build && istanbul test _mocha test/test.js", + "build": "mkdir -p dist && rollup -c" + }, + "repository": { + "type": "git", + "url": "git://github.com/proj4js/mgrs.git" + }, + "keywords": [ + "mgrs", + "proj4", + "gis" + ], + "author": "proj4 team", + "license": "MIT", + "bugs": { + "url": "https://github.com/proj4js/mgrs/issues" + }, + "devDependencies": { + "rollup": "^0.41.4", + "chai": "~1.8.1", + "istanbul": "~0.1.46", + "mocha": "~1.15.1" + } +} diff --git a/node_modules/mgrs/publish.sh b/node_modules/mgrs/publish.sh new file mode 100644 index 0000000..b96e6d0 --- /dev/null +++ b/node_modules/mgrs/publish.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# get current version +VERSION=$(npm ls --json=true mgrs | grep version | awk '{ print $2}'| sed -e 's/^"//' -e 's/"$//') + +# Build +git checkout -b build +npm run build +git add dist -f +git commit -m "build $VERSION" + +# Tag and push +git tag $VERSION +git push --tags git@github.com:proj4js/mgrs.git $VERSION + +# Publish +npm publish + +# Cleanup +git checkout master +git branch -D build diff --git a/node_modules/mgrs/readme.md b/node_modules/mgrs/readme.md new file mode 100644 index 0000000..1106c1f --- /dev/null +++ b/node_modules/mgrs/readme.md @@ -0,0 +1,44 @@ +mgrs +==== + +Utility for converting between WGS84 lat/lng and MGRS coordinates, spunoff from [proj4js](https://github.com/proj4js/proj4js) + +has 3 methods + +- forward, takes an array of `[lon,lat]` and optional accuracy and returns an mgrs string +- inverse, takes an mgrs string and returns a bbox. +- toPoint, takes an mgrs string, returns an array of '[lon,lat]' + +install dev dependencies with + +```bash +npm install +``` + +test with + +```bash +npm test +``` + +test coverage with + +```bash +npm test --coverage +``` + +build with + +```bash +npm run build +``` + + +Licensed under the MIT license except: + +Portions of this software are based on a port of components from the OpenMap +com.bbn.openmap.proj.coords Java package. An initial port was initially created +by Patrice G. Cappelaere and included in Community Mapbuilder +(http://svn.codehaus.org/mapbuilder/), which is licensed under the LGPL license +as per http://www.gnu.org/copyleft/lesser.html. OpenMap is licensed under the +[following license agreement](openmap.md): diff --git a/node_modules/mgrs/rollup.config.js b/node_modules/mgrs/rollup.config.js new file mode 100644 index 0000000..e60eab9 --- /dev/null +++ b/node_modules/mgrs/rollup.config.js @@ -0,0 +1,8 @@ + +export default { + entry: 'mgrs.js', + dest: 'dist/mgrs.js', + format: 'umd', + moduleName: 'mgrs', + exports: 'named' +}; diff --git a/node_modules/mgrs/test/test.js b/node_modules/mgrs/test/test.js new file mode 100644 index 0000000..3bc5b5f --- /dev/null +++ b/node_modules/mgrs/test/test.js @@ -0,0 +1,37 @@ +var should = require('chai').should(); +var mgrs = require('../dist/mgrs'); +describe('First MGRS set', function() { + var mgrsStr = "33UXP04"; + var point = mgrs.toPoint(mgrsStr); + it('Longitude of point from MGRS correct.', function() { + point[0].should.be.closeTo(16.41450, 0.000001); + }); + it('Latitude of point from MGRS correct.', function() { + point[1].should.be.closeTo(48.24949, 0.000001); + }); + it('MGRS reference with highest accuracy correct.', function() { + mgrs.forward(point).should.equal("33UXP0500444998"); + }); + it('MGRS reference with 1-digit accuracy correct.', function() { + mgrs.forward(point,1).should.equal(mgrsStr); + }); +}); +describe('Second MGRS set', function() { + var mgrsStr = "24XWT783908"; // near UTM zone border, so there are two ways to reference this + var point = mgrs.toPoint(mgrsStr); + it('Longitude of point from MGRS correct.', function() { + point[0].should.be.closeTo(-32.66433, 0.00001); + }); + it('Latitude of point from MGRS correct.', function() { + point[1].should.be.closeTo(83.62778, 0.00001); + }); + it('MGRS reference with 1-digit accuracy correct.', function() { + mgrs.forward(point,3).should.equal('25XEN041865'); + }); + it('MGRS reference with 5-digit accuracy, northing all zeros', function(){ + mgrs.forward([0,0],5).should.equal('31NAA6602100000'); + }); + it('MGRS reference with 5-digit accuracy, northing one digit', function(){ + mgrs.forward([0,0.00001],5).should.equal('31NAA6602100001'); + }); +}) \ No newline at end of file diff --git a/node_modules/node-fetch/LICENSE.md b/node_modules/node-fetch/LICENSE.md new file mode 100644 index 0000000..660ffec --- /dev/null +++ b/node_modules/node-fetch/LICENSE.md @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 David Frank + +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/node_modules/node-fetch/README.md b/node_modules/node-fetch/README.md new file mode 100644 index 0000000..4f87a59 --- /dev/null +++ b/node_modules/node-fetch/README.md @@ -0,0 +1,633 @@ +node-fetch +========== + +[![npm version][npm-image]][npm-url] +[![build status][travis-image]][travis-url] +[![coverage status][codecov-image]][codecov-url] +[![install size][install-size-image]][install-size-url] +[![Discord][discord-image]][discord-url] + +A light-weight module that brings `window.fetch` to Node.js + +(We are looking for [v2 maintainers and collaborators](https://github.com/bitinn/node-fetch/issues/567)) + +[![Backers][opencollective-image]][opencollective-url] + + + +- [Motivation](#motivation) +- [Features](#features) +- [Difference from client-side fetch](#difference-from-client-side-fetch) +- [Installation](#installation) +- [Loading and configuring the module](#loading-and-configuring-the-module) +- [Common Usage](#common-usage) + - [Plain text or HTML](#plain-text-or-html) + - [JSON](#json) + - [Simple Post](#simple-post) + - [Post with JSON](#post-with-json) + - [Post with form parameters](#post-with-form-parameters) + - [Handling exceptions](#handling-exceptions) + - [Handling client and server errors](#handling-client-and-server-errors) +- [Advanced Usage](#advanced-usage) + - [Streams](#streams) + - [Buffer](#buffer) + - [Accessing Headers and other Meta data](#accessing-headers-and-other-meta-data) + - [Extract Set-Cookie Header](#extract-set-cookie-header) + - [Post data using a file stream](#post-data-using-a-file-stream) + - [Post with form-data (detect multipart)](#post-with-form-data-detect-multipart) + - [Request cancellation with AbortSignal](#request-cancellation-with-abortsignal) +- [API](#api) + - [fetch(url[, options])](#fetchurl-options) + - [Options](#options) + - [Class: Request](#class-request) + - [Class: Response](#class-response) + - [Class: Headers](#class-headers) + - [Interface: Body](#interface-body) + - [Class: FetchError](#class-fetcherror) +- [License](#license) +- [Acknowledgement](#acknowledgement) + + + +## Motivation + +Instead of implementing `XMLHttpRequest` in Node.js to run browser-specific [Fetch polyfill](https://github.com/github/fetch), why not go from native `http` to `fetch` API directly? Hence, `node-fetch`, minimal code for a `window.fetch` compatible API on Node.js runtime. + +See Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) or Leonardo Quixada's [cross-fetch](https://github.com/lquixada/cross-fetch) for isomorphic usage (exports `node-fetch` for server-side, `whatwg-fetch` for client-side). + +## Features + +- Stay consistent with `window.fetch` API. +- Make conscious trade-off when following [WHATWG fetch spec][whatwg-fetch] and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known differences. +- Use native promise but allow substituting it with [insert your favorite promise library]. +- Use native Node streams for body on both request and response. +- Decode content encoding (gzip/deflate) properly and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically. +- Useful extensions such as timeout, redirect limit, response size limit, [explicit errors](ERROR-HANDLING.md) for troubleshooting. + +## Difference from client-side fetch + +- See [Known Differences](LIMITS.md) for details. +- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue. +- Pull requests are welcomed too! + +## Installation + +Current stable release (`2.x`) + +```sh +$ npm install node-fetch +``` + +## Loading and configuring the module +We suggest you load the module via `require` until the stabilization of ES modules in node: +```js +const fetch = require('node-fetch'); +``` + +If you are using a Promise library other than native, set it through `fetch.Promise`: +```js +const Bluebird = require('bluebird'); + +fetch.Promise = Bluebird; +``` + +## Common Usage + +NOTE: The documentation below is up-to-date with `2.x` releases; see the [`1.x` readme](https://github.com/bitinn/node-fetch/blob/1.x/README.md), [changelog](https://github.com/bitinn/node-fetch/blob/1.x/CHANGELOG.md) and [2.x upgrade guide](UPGRADE-GUIDE.md) for the differences. + +#### Plain text or HTML +```js +fetch('https://github.com/') + .then(res => res.text()) + .then(body => console.log(body)); +``` + +#### JSON + +```js + +fetch('https://api.github.com/users/github') + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Simple Post +```js +fetch('https://httpbin.org/post', { method: 'POST', body: 'a=1' }) + .then(res => res.json()) // expecting a json response + .then(json => console.log(json)); +``` + +#### Post with JSON + +```js +const body = { a: 1 }; + +fetch('https://httpbin.org/post', { + method: 'post', + body: JSON.stringify(body), + headers: { 'Content-Type': 'application/json' }, + }) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Post with form parameters +`URLSearchParams` is available in Node.js as of v7.5.0. See [official documentation](https://nodejs.org/api/url.html#url_class_urlsearchparams) for more usage methods. + +NOTE: The `Content-Type` header is only set automatically to `x-www-form-urlencoded` when an instance of `URLSearchParams` is given as such: + +```js +const { URLSearchParams } = require('url'); + +const params = new URLSearchParams(); +params.append('a', 1); + +fetch('https://httpbin.org/post', { method: 'POST', body: params }) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Handling exceptions +NOTE: 3xx-5xx responses are *NOT* exceptions and should be handled in `then()`; see the next section for more information. + +Adding a catch to the fetch promise chain will catch *all* exceptions, such as errors originating from node core libraries, network errors and operational errors, which are instances of FetchError. See the [error handling document](ERROR-HANDLING.md) for more details. + +```js +fetch('https://domain.invalid/') + .catch(err => console.error(err)); +``` + +#### Handling client and server errors +It is common to create a helper function to check that the response contains no client (4xx) or server (5xx) error responses: + +```js +function checkStatus(res) { + if (res.ok) { // res.status >= 200 && res.status < 300 + return res; + } else { + throw MyCustomError(res.statusText); + } +} + +fetch('https://httpbin.org/status/400') + .then(checkStatus) + .then(res => console.log('will not get here...')) +``` + +## Advanced Usage + +#### Streams +The "Node.js way" is to use streams when possible: + +```js +fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png') + .then(res => { + const dest = fs.createWriteStream('./octocat.png'); + res.body.pipe(dest); + }); +``` + +In Node.js 14 you can also use async iterators to read `body`; however, be careful to catch +errors -- the longer a response runs, the more likely it is to encounter an error. + +```js +const fetch = require('node-fetch'); +const response = await fetch('https://httpbin.org/stream/3'); +try { + for await (const chunk of response.body) { + console.dir(JSON.parse(chunk.toString())); + } +} catch (err) { + console.error(err.stack); +} +``` + +In Node.js 12 you can also use async iterators to read `body`; however, async iterators with streams +did not mature until Node.js 14, so you need to do some extra work to ensure you handle errors +directly from the stream and wait on it response to fully close. + +```js +const fetch = require('node-fetch'); +const read = async body => { + let error; + body.on('error', err => { + error = err; + }); + for await (const chunk of body) { + console.dir(JSON.parse(chunk.toString())); + } + return new Promise((resolve, reject) => { + body.on('close', () => { + error ? reject(error) : resolve(); + }); + }); +}; +try { + const response = await fetch('https://httpbin.org/stream/3'); + await read(response.body); +} catch (err) { + console.error(err.stack); +} +``` + +#### Buffer +If you prefer to cache binary data in full, use buffer(). (NOTE: `buffer()` is a `node-fetch`-only API) + +```js +const fileType = require('file-type'); + +fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png') + .then(res => res.buffer()) + .then(buffer => fileType(buffer)) + .then(type => { /* ... */ }); +``` + +#### Accessing Headers and other Meta data +```js +fetch('https://github.com/') + .then(res => { + console.log(res.ok); + console.log(res.status); + console.log(res.statusText); + console.log(res.headers.raw()); + console.log(res.headers.get('content-type')); + }); +``` + +#### Extract Set-Cookie Header + +Unlike browsers, you can access raw `Set-Cookie` headers manually using `Headers.raw()`. This is a `node-fetch` only API. + +```js +fetch(url).then(res => { + // returns an array of values, instead of a string of comma-separated values + console.log(res.headers.raw()['set-cookie']); +}); +``` + +#### Post data using a file stream + +```js +const { createReadStream } = require('fs'); + +const stream = createReadStream('input.txt'); + +fetch('https://httpbin.org/post', { method: 'POST', body: stream }) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Post with form-data (detect multipart) + +```js +const FormData = require('form-data'); + +const form = new FormData(); +form.append('a', 1); + +fetch('https://httpbin.org/post', { method: 'POST', body: form }) + .then(res => res.json()) + .then(json => console.log(json)); + +// OR, using custom headers +// NOTE: getHeaders() is non-standard API + +const form = new FormData(); +form.append('a', 1); + +const options = { + method: 'POST', + body: form, + headers: form.getHeaders() +} + +fetch('https://httpbin.org/post', options) + .then(res => res.json()) + .then(json => console.log(json)); +``` + +#### Request cancellation with AbortSignal + +> NOTE: You may cancel streamed requests only on Node >= v8.0.0 + +You may cancel requests with `AbortController`. A suggested implementation is [`abort-controller`](https://www.npmjs.com/package/abort-controller). + +An example of timing out a request after 150ms could be achieved as the following: + +```js +import AbortController from 'abort-controller'; + +const controller = new AbortController(); +const timeout = setTimeout( + () => { controller.abort(); }, + 150, +); + +fetch(url, { signal: controller.signal }) + .then(res => res.json()) + .then( + data => { + useData(data) + }, + err => { + if (err.name === 'AbortError') { + // request was aborted + } + }, + ) + .finally(() => { + clearTimeout(timeout); + }); +``` + +See [test cases](https://github.com/bitinn/node-fetch/blob/master/test/test.js) for more examples. + + +## API + +### fetch(url[, options]) + +- `url` A string representing the URL for fetching +- `options` [Options](#fetch-options) for the HTTP(S) request +- Returns: Promise<[Response](#class-response)> + +Perform an HTTP(S) fetch. + +`url` should be an absolute url, such as `https://example.com/`. A path-relative URL (`/file/under/root`) or protocol-relative URL (`//can-be-http-or-https.com/`) will result in a rejected `Promise`. + + +### Options + +The default values are shown after each option key. + +```js +{ + // These properties are part of the Fetch Standard + method: 'GET', + headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below) + body: null, // request body. can be null, a string, a Buffer, a Blob, or a Node.js Readable stream + redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect + signal: null, // pass an instance of AbortSignal to optionally abort requests + + // The following properties are node-fetch extensions + follow: 20, // maximum redirect count. 0 to not follow redirect + timeout: 0, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead. + compress: true, // support gzip/deflate content encoding. false to disable + size: 0, // maximum response body size in bytes. 0 to disable + agent: null // http(s).Agent instance or function that returns an instance (see below) +} +``` + +##### Default Headers + +If no values are set, the following request headers will be sent automatically: + +Header | Value +------------------- | -------------------------------------------------------- +`Accept-Encoding` | `gzip,deflate` _(when `options.compress === true`)_ +`Accept` | `*/*` +`Connection` | `close` _(when no `options.agent` is present)_ +`Content-Length` | _(automatically calculated, if possible)_ +`Transfer-Encoding` | `chunked` _(when `req.body` is a stream)_ +`User-Agent` | `node-fetch/1.0 (+https://github.com/bitinn/node-fetch)` + +Note: when `body` is a `Stream`, `Content-Length` is not set automatically. + +##### Custom Agent + +The `agent` option allows you to specify networking related options which are out of the scope of Fetch, including and not limited to the following: + +- Support self-signed certificate +- Use only IPv4 or IPv6 +- Custom DNS Lookup + +See [`http.Agent`](https://nodejs.org/api/http.html#http_new_agent_options) for more information. + +In addition, the `agent` option accepts a function that returns `http`(s)`.Agent` instance given current [URL](https://nodejs.org/api/url.html), this is useful during a redirection chain across HTTP and HTTPS protocol. + +```js +const httpAgent = new http.Agent({ + keepAlive: true +}); +const httpsAgent = new https.Agent({ + keepAlive: true +}); + +const options = { + agent: function (_parsedURL) { + if (_parsedURL.protocol == 'http:') { + return httpAgent; + } else { + return httpsAgent; + } + } +} +``` + + +### Class: Request + +An HTTP(S) request containing information about URL, method, headers, and the body. This class implements the [Body](#iface-body) interface. + +Due to the nature of Node.js, the following properties are not implemented at this moment: + +- `type` +- `destination` +- `referrer` +- `referrerPolicy` +- `mode` +- `credentials` +- `cache` +- `integrity` +- `keepalive` + +The following node-fetch extension properties are provided: + +- `follow` +- `compress` +- `counter` +- `agent` + +See [options](#fetch-options) for exact meaning of these extensions. + +#### new Request(input[, options]) + +*(spec-compliant)* + +- `input` A string representing a URL, or another `Request` (which will be cloned) +- `options` [Options][#fetch-options] for the HTTP(S) request + +Constructs a new `Request` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request). + +In most cases, directly `fetch(url, options)` is simpler than creating a `Request` object. + + +### Class: Response + +An HTTP(S) response. This class implements the [Body](#iface-body) interface. + +The following properties are not implemented in node-fetch at this moment: + +- `Response.error()` +- `Response.redirect()` +- `type` +- `trailer` + +#### new Response([body[, options]]) + +*(spec-compliant)* + +- `body` A `String` or [`Readable` stream][node-readable] +- `options` A [`ResponseInit`][response-init] options dictionary + +Constructs a new `Response` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response). + +Because Node.js does not implement service workers (for which this class was designed), one rarely has to construct a `Response` directly. + +#### response.ok + +*(spec-compliant)* + +Convenience property representing if the request ended normally. Will evaluate to true if the response status was greater than or equal to 200 but smaller than 300. + +#### response.redirected + +*(spec-compliant)* + +Convenience property representing if the request has been redirected at least once. Will evaluate to true if the internal redirect counter is greater than 0. + + +### Class: Headers + +This class allows manipulating and iterating over a set of HTTP headers. All methods specified in the [Fetch Standard][whatwg-fetch] are implemented. + +#### new Headers([init]) + +*(spec-compliant)* + +- `init` Optional argument to pre-fill the `Headers` object + +Construct a new `Headers` object. `init` can be either `null`, a `Headers` object, an key-value map object or any iterable object. + +```js +// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class + +const meta = { + 'Content-Type': 'text/xml', + 'Breaking-Bad': '<3' +}; +const headers = new Headers(meta); + +// The above is equivalent to +const meta = [ + [ 'Content-Type', 'text/xml' ], + [ 'Breaking-Bad', '<3' ] +]; +const headers = new Headers(meta); + +// You can in fact use any iterable objects, like a Map or even another Headers +const meta = new Map(); +meta.set('Content-Type', 'text/xml'); +meta.set('Breaking-Bad', '<3'); +const headers = new Headers(meta); +const copyOfHeaders = new Headers(headers); +``` + + +### Interface: Body + +`Body` is an abstract interface with methods that are applicable to both `Request` and `Response` classes. + +The following methods are not yet implemented in node-fetch at this moment: + +- `formData()` + +#### body.body + +*(deviation from spec)* + +* Node.js [`Readable` stream][node-readable] + +Data are encapsulated in the `Body` object. Note that while the [Fetch Standard][whatwg-fetch] requires the property to always be a WHATWG `ReadableStream`, in node-fetch it is a Node.js [`Readable` stream][node-readable]. + +#### body.bodyUsed + +*(spec-compliant)* + +* `Boolean` + +A boolean property for if this body has been consumed. Per the specs, a consumed body cannot be used again. + +#### body.arrayBuffer() +#### body.blob() +#### body.json() +#### body.text() + +*(spec-compliant)* + +* Returns: Promise + +Consume the body and return a promise that will resolve to one of these formats. + +#### body.buffer() + +*(node-fetch extension)* + +* Returns: Promise<Buffer> + +Consume the body and return a promise that will resolve to a Buffer. + +#### body.textConverted() + +*(node-fetch extension)* + +* Returns: Promise<String> + +Identical to `body.text()`, except instead of always converting to UTF-8, encoding sniffing will be performed and text converted to UTF-8 if possible. + +(This API requires an optional dependency of the npm package [encoding](https://www.npmjs.com/package/encoding), which you need to install manually. `webpack` users may see [a warning message](https://github.com/bitinn/node-fetch/issues/412#issuecomment-379007792) due to this optional dependency.) + + +### Class: FetchError + +*(node-fetch extension)* + +An operational error in the fetching process. See [ERROR-HANDLING.md][] for more info. + + +### Class: AbortError + +*(node-fetch extension)* + +An Error thrown when the request is aborted in response to an `AbortSignal`'s `abort` event. It has a `name` property of `AbortError`. See [ERROR-HANDLING.MD][] for more info. + +## Acknowledgement + +Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference. + +`node-fetch` v1 was maintained by [@bitinn](https://github.com/bitinn); v2 was maintained by [@TimothyGu](https://github.com/timothygu), [@bitinn](https://github.com/bitinn) and [@jimmywarting](https://github.com/jimmywarting); v2 readme is written by [@jkantr](https://github.com/jkantr). + +## License + +MIT + +[npm-image]: https://flat.badgen.net/npm/v/node-fetch +[npm-url]: https://www.npmjs.com/package/node-fetch +[travis-image]: https://flat.badgen.net/travis/bitinn/node-fetch +[travis-url]: https://travis-ci.org/bitinn/node-fetch +[codecov-image]: https://flat.badgen.net/codecov/c/github/bitinn/node-fetch/master +[codecov-url]: https://codecov.io/gh/bitinn/node-fetch +[install-size-image]: https://flat.badgen.net/packagephobia/install/node-fetch +[install-size-url]: https://packagephobia.now.sh/result?p=node-fetch +[discord-image]: https://img.shields.io/discord/619915844268326952?color=%237289DA&label=Discord&style=flat-square +[discord-url]: https://discord.gg/Zxbndcm +[opencollective-image]: https://opencollective.com/node-fetch/backers.svg +[opencollective-url]: https://opencollective.com/node-fetch +[whatwg-fetch]: https://fetch.spec.whatwg.org/ +[response-init]: https://fetch.spec.whatwg.org/#responseinit +[node-readable]: https://nodejs.org/api/stream.html#stream_readable_streams +[mdn-headers]: https://developer.mozilla.org/en-US/docs/Web/API/Headers +[LIMITS.md]: https://github.com/bitinn/node-fetch/blob/master/LIMITS.md +[ERROR-HANDLING.md]: https://github.com/bitinn/node-fetch/blob/master/ERROR-HANDLING.md +[UPGRADE-GUIDE.md]: https://github.com/bitinn/node-fetch/blob/master/UPGRADE-GUIDE.md diff --git a/node_modules/node-fetch/browser.js b/node_modules/node-fetch/browser.js new file mode 100644 index 0000000..ee86265 --- /dev/null +++ b/node_modules/node-fetch/browser.js @@ -0,0 +1,25 @@ +"use strict"; + +// ref: https://github.com/tc39/proposal-global +var getGlobal = function () { + // the only reliable means to get the global object is + // `Function('return this')()` + // However, this causes CSP violations in Chrome apps. + if (typeof self !== 'undefined') { return self; } + if (typeof window !== 'undefined') { return window; } + if (typeof global !== 'undefined') { return global; } + throw new Error('unable to locate global object'); +} + +var globalObject = getGlobal(); + +module.exports = exports = globalObject.fetch; + +// Needed for TypeScript and Webpack. +if (globalObject.fetch) { + exports.default = globalObject.fetch.bind(globalObject); +} + +exports.Headers = globalObject.Headers; +exports.Request = globalObject.Request; +exports.Response = globalObject.Response; diff --git a/node_modules/node-fetch/lib/index.es.js b/node_modules/node-fetch/lib/index.es.js new file mode 100644 index 0000000..ed27a46 --- /dev/null +++ b/node_modules/node-fetch/lib/index.es.js @@ -0,0 +1,1781 @@ +process.emitWarning("The .es.js file is deprecated. Use .mjs instead."); + +import Stream from 'stream'; +import http from 'http'; +import Url from 'url'; +import whatwgUrl from 'whatwg-url'; +import https from 'https'; +import zlib from 'zlib'; + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = / 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // tests for socket presence, as in some situations the + // the 'socket' event is not triggered for the request + // (happens in deno), avoids `TypeError` + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket && socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +export default fetch; +export { Headers, Request, Response, FetchError }; diff --git a/node_modules/node-fetch/lib/index.js b/node_modules/node-fetch/lib/index.js new file mode 100644 index 0000000..087f2a0 --- /dev/null +++ b/node_modules/node-fetch/lib/index.js @@ -0,0 +1,1790 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var Stream = _interopDefault(require('stream')); +var http = _interopDefault(require('http')); +var Url = _interopDefault(require('url')); +var whatwgUrl = _interopDefault(require('whatwg-url')); +var https = _interopDefault(require('https')); +var zlib = _interopDefault(require('zlib')); + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = / 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // tests for socket presence, as in some situations the + // the 'socket' event is not triggered for the request + // (happens in deno), avoids `TypeError` + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket && socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; diff --git a/node_modules/node-fetch/lib/index.mjs b/node_modules/node-fetch/lib/index.mjs new file mode 100644 index 0000000..4ed7fa5 --- /dev/null +++ b/node_modules/node-fetch/lib/index.mjs @@ -0,0 +1,1779 @@ +import Stream from 'stream'; +import http from 'http'; +import Url from 'url'; +import whatwgUrl from 'whatwg-url'; +import https from 'https'; +import zlib from 'zlib'; + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = / 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // tests for socket presence, as in some situations the + // the 'socket' event is not triggered for the request + // (happens in deno), avoids `TypeError` + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket && socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +export default fetch; +export { Headers, Request, Response, FetchError }; diff --git a/node_modules/node-fetch/package.json b/node_modules/node-fetch/package.json new file mode 100644 index 0000000..0ba36fd --- /dev/null +++ b/node_modules/node-fetch/package.json @@ -0,0 +1,89 @@ +{ + "name": "node-fetch", + "version": "2.6.12", + "description": "A light-weight module that brings window.fetch to node.js", + "main": "lib/index.js", + "browser": "./browser.js", + "module": "lib/index.mjs", + "files": [ + "lib/index.js", + "lib/index.mjs", + "lib/index.es.js", + "browser.js" + ], + "engines": { + "node": "4.x || >=6.0.0" + }, + "scripts": { + "build": "cross-env BABEL_ENV=rollup rollup -c", + "prepare": "npm run build", + "test": "cross-env BABEL_ENV=test mocha --require babel-register --throw-deprecation test/test.js", + "report": "cross-env BABEL_ENV=coverage nyc --reporter lcov --reporter text mocha -R spec test/test.js", + "coverage": "cross-env BABEL_ENV=coverage nyc --reporter json --reporter text mocha -R spec test/test.js && codecov -f coverage/coverage-final.json" + }, + "repository": { + "type": "git", + "url": "https://github.com/bitinn/node-fetch.git" + }, + "keywords": [ + "fetch", + "http", + "promise" + ], + "author": "David Frank", + "license": "MIT", + "bugs": { + "url": "https://github.com/bitinn/node-fetch/issues" + }, + "homepage": "https://github.com/bitinn/node-fetch", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + }, + "devDependencies": { + "@ungap/url-search-params": "^0.1.2", + "abort-controller": "^1.1.0", + "abortcontroller-polyfill": "^1.3.0", + "babel-core": "^6.26.3", + "babel-plugin-istanbul": "^4.1.6", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-polyfill": "^6.26.0", + "babel-preset-env": "1.4.0", + "babel-register": "^6.16.3", + "chai": "^3.5.0", + "chai-as-promised": "^7.1.1", + "chai-iterator": "^1.1.1", + "chai-string": "~1.3.0", + "codecov": "3.3.0", + "cross-env": "^5.2.0", + "form-data": "^2.3.3", + "is-builtin-module": "^1.0.0", + "mocha": "^5.0.0", + "nyc": "11.9.0", + "parted": "^0.1.1", + "promise": "^8.0.3", + "resumer": "0.0.0", + "rollup": "^0.63.4", + "rollup-plugin-babel": "^3.0.7", + "string-to-arraybuffer": "^1.0.2", + "teeny-request": "3.7.0" + }, + "release": { + "branches": [ + "+([0-9]).x", + "main", + "next", + { + "name": "beta", + "prerelease": true + } + ] + } +} diff --git a/node_modules/proj4/.github/workflows/build-and-test.yml b/node_modules/proj4/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..b1ce32d --- /dev/null +++ b/node_modules/proj4/.github/workflows/build-and-test.yml @@ -0,0 +1,31 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: Node.js CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [14.x, 16.x, 18.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm run build --if-present + - run: npm test diff --git a/node_modules/proj4/.jshintrc b/node_modules/proj4/.jshintrc new file mode 100644 index 0000000..aa02ed7 --- /dev/null +++ b/node_modules/proj4/.jshintrc @@ -0,0 +1,12 @@ +{ + "esversion": 6, + "curly": true, + "eqeqeq": true, + "latedef": "nofunc", + "undef": true, + "unused": true, + "trailing": true, + "indent": 2, + "browser": true, + "node": true +} \ No newline at end of file diff --git a/node_modules/proj4/AUTHORS b/node_modules/proj4/AUTHORS new file mode 100644 index 0000000..1d39107 --- /dev/null +++ b/node_modules/proj4/AUTHORS @@ -0,0 +1,25 @@ +Mike Adair +Richard Greenwood +Calvin Metcalf +Richard Marsden (http://www.winwaed.com) +#credit for +#src/projCode/gnom.js +#src/projCode/cea.js +T. Mittan +#credit for +#src/projCode/eqdc.js +#src/projCode/equi.js +#src/projCode/merc.js +#src/projCode/mill.js +#src/projCode/omerc.js +#src/projCode/ortho.js +#src/projCode/poly.js +#src/projCode/poly.js +D. Steinwand +#credit for +#src/projCode/merc.js +#src/projCode/laea.js +#src/projCode/moll.js +S. Nelson +#credit for +#src/projCode/moll.js \ No newline at end of file diff --git a/node_modules/proj4/Gruntfile.js b/node_modules/proj4/Gruntfile.js new file mode 100644 index 0000000..777ae3b --- /dev/null +++ b/node_modules/proj4/Gruntfile.js @@ -0,0 +1,126 @@ +var json = require('rollup-plugin-json'); +var nodeResolve = require('rollup-plugin-node-resolve'); +var replace = require('rollup-plugin-replace'); +var pkg = require('./package.json'); + +var projs = [ + 'tmerc', + 'etmerc', + 'utm', + 'sterea', + 'stere', + 'somerc', + 'omerc', + 'lcc', + 'krovak', + 'cass', + 'laea', + 'aea', + 'gnom', + 'cea', + 'eqc', + 'poly', + 'nzmg', + 'mill', + 'sinu', + 'moll', + 'eqdc', + 'vandg', + 'aeqd', + 'ortho', + 'qsc', + 'robin', + 'geocent', + 'tpers', + 'geos' +]; +module.exports = function (grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + connect: { + server: { + options: { + port: process.env.PORT || 8080, + base: '.' + } + } + }, + mocha_phantomjs: { + all: { + options: { + reporter: "dot", + urls: [ //my ide requries process.env.IP and PORT + "http://" + (process.env.IP || "127.0.0.1") + ":" + (process.env.PORT || "8080") + "/test/amd.html", + "http://" + (process.env.IP || "127.0.0.1") + ":" + (process.env.PORT || "8080") + "/test/opt.html" + ] + } + } + }, + jshint: { + options: { + jshintrc: "./.jshintrc" + }, + all: ['./lib/*.js', './lib/*/*.js'] + }, + rollup: { + options: { + format: "umd", + moduleName: "proj4", + plugins: [ + replace({ + __VERSION__: pkg.version + }), + json(), + nodeResolve() + ] + }, + files: { + dest: './dist/proj4-src.js', + src: './lib/index.js', + }, + }, + uglify: { + options: { + report: 'gzip', + mangle:{ + reserved: ['proj4','Projection','Point'] + }, + }, + all: { + src: 'dist/proj4-src.js', + dest: 'dist/proj4.js' + } + } + }); + grunt.loadNpmTasks('grunt-rollup'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-mocha-phantomjs'); + grunt.registerTask('custom',function(){ + grunt.task.run('rollup', 'uglify'); + var projections = this.args; + if(projections[0]==='default'){ + grunt.file.write('./projs.js','export default function(){}'); + return; + } + if(projections[0]==='all'){ + projections = projs; + } + grunt.file.write('./projs.js',[ + projections.map(function(proj) { + return "import " + proj + " from './lib/projections/" + proj + "';"; + }).join("\n"), + "export default function(proj4){", + projections.map(function(proj) { + return " proj4.Proj.projections.add(" + proj + ");" + }).join("\n"), + "}" + ].join("\n")); + }); + grunt.registerTask('build',function(){ + var args = this.args.length?this.args[0].split(','):['default']; + grunt.task.run('jshint', 'custom:'+args.join(':')); + }); + grunt.registerTask('default', ['build:all', 'connect','mocha_phantomjs']); +}; diff --git a/node_modules/proj4/LICENSE.md b/node_modules/proj4/LICENSE.md new file mode 100644 index 0000000..d1d9107 --- /dev/null +++ b/node_modules/proj4/LICENSE.md @@ -0,0 +1,29 @@ +## Proj4js -- Javascript reprojection library. + +Authors: +- Mike Adair madairATdmsolutions.ca +- Richard Greenwood richATgreenwoodmap.com +- Didier Richard didier.richardATign.fr +- Stephen Irons stephen.ironsATclear.net.nz +- Olivier Terral oterralATgmail.com +- Calvin Metcalf cmetcalfATappgeo.com + +Copyright (c) 2014, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf + + 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/node_modules/proj4/PUBLISHING.md b/node_modules/proj4/PUBLISHING.md new file mode 100644 index 0000000..250c84f --- /dev/null +++ b/node_modules/proj4/PUBLISHING.md @@ -0,0 +1,21 @@ +Publishing +=== + +Make sure you have the latest from the main branch: + + git pull origin master + +Use `tin` to update the version number in the `package.json`, `component.json` & `bower.json`. + + tin -v x.y.z + +Then run the publish script + + ./publish.sh + +afterwards don't forget to update the versions to be a prerelease of the next version, so if you just published 1.1.1 then: + + tin -v 1.1.2-alpha + git add package.json component.json bower.json + git commit -m 'update version to 1.1.2-alpha' + git push origin master \ No newline at end of file diff --git a/node_modules/proj4/README.md b/node_modules/proj4/README.md new file mode 100644 index 0000000..3eec694 --- /dev/null +++ b/node_modules/proj4/README.md @@ -0,0 +1,194 @@ +# PROJ4JS [![Build Status](https://api.travis-ci.org/proj4js/proj4js.svg?branch=master)](https://travis-ci.org/proj4js/proj4js) + +Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations. +Originally a port of [PROJ](https://proj.org/) ([then known as PROJ.4](https://proj.org/faq.html#what-happened-to-proj-4)) and GCTCP C ([Archive](https://web.archive.org/web/20130523091752/http://edcftp.cr.usgs.gov/pub/software/gctpc/)) it is +a part of the [MetaCRS](https://trac.osgeo.org/metacrs/wiki) group of projects. + +## Installing + +Depending on your preferences + +```bash +npm install proj4 +bower install proj4 +component install proj4js/proj4js +``` + +or just manually grab the file `proj4.js` from the [latest release](https://github.com/proj4js/proj4js/releases)'s `dist/` folder. + +If you do not want to download anything, Proj4js is also hosted on [cdnjs](https://www.cdnjs.com/libraries/proj4js) for direct use in your browser applications. + +## Using + +The basic signature is: + +```javascript +proj4([fromProjection, ]toProjection[, coordinates]) +``` + +Projections can be proj or wkt strings. + +Coordinates may be an object of the form `{x:x,y:y}` or an array of the form `[x,y]`. + +When all 3 arguments are given, the result is that the coordinates are transformed from projection1 to projection 2. And returned in the same format that they were given in. + +```javascript +var firstProjection = 'PROJCS["NAD83 / Massachusetts Mainland",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",42.68333333333333],PARAMETER["standard_parallel_2",41.71666666666667],PARAMETER["latitude_of_origin",41],PARAMETER["central_meridian",-71.5],PARAMETER["false_easting",200000],PARAMETER["false_northing",750000],AUTHORITY["EPSG","26986"],AXIS["X",EAST],AXIS["Y",NORTH]]'; +var secondProjection = "+proj=gnom +lat_0=90 +lon_0=0 +x_0=6300000 +y_0=6300000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"; +//I'm not going to redefine those two in latter examples. +proj4(firstProjection,secondProjection,[-122.305887, 58.9465872]); +// [-2690575.447893817, 36622916.8071244564] +``` + +The library can also parse coordinates provided with an elevation and measure, again as an object of the form `{x:x,y:y,z:z,m:m}` or an array of the form `[x,y,z,m]`. + +```javascript +proj4(firstProjection,secondProjection,[-122.305887, 58.9465872,10]); +// [-2690575.447893817, 36622916.8071244564, 10] +``` + +If only 1 projection is given then it is assumed that it is being projected *from* WGS84 (fromProjection is WGS84). + +```javascript +proj4(firstProjection,[-71,41]); +// [242075.00535055372, 750123.32090043] +``` + +If no coordinates are given an object with two methods is returned, its methods are `forward` which projects from the first projection to the second and `inverse` which projects from the second to the first. + +```javascript +proj4(firstProjection,secondProjection).forward([-122.305887, 58.9465872]); +// [-2690575.447893817, 36622916.8071244564] +proj4(secondProjection,firstProjection).inverse([-122.305887, 58.9465872]); +// [-2690575.447893817, 36622916.8071244564] +``` + +And as above if only one projection is given, it's assumed to be coming from wgs84: + +```javascript +proj4(firstProjection).forward([-71,41]); +// [242075.00535055372, 750123.32090043] +proj4(firstProjection).inverse([242075.00535055372, 750123.32090043]); +// [-71, 40.99999999999986] +``` +Note: The generation of the floating point value `40.99999999999986` in this example represents the fact that some variance in precision is involved in any conversion between one coordinate reference system and another. + +## Named Projections + +If you prefer to define a projection as a string and reference it that way, you may use the proj4.defs method which can be called 2 ways, with a name and projection: + +```js +proj4.defs('WGS84', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"); +``` + +or with an array + +```js +proj4.defs([ + [ + 'EPSG:4326', + '+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees'], + [ + 'EPSG:4269', + '+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees' + ] +]); +``` + +you can then do + +```js +proj4('EPSG:4326'); +``` + +instead of writing out the whole proj definition, by default proj4 has the following projections predefined: + +- 'EPSG:4326', which has the following alias + - 'WGS84' +- 'EPSG:4269' +- 'EPSG:3857', which has the following aliases + - 'EPSG:3785' + - 'GOOGLE' + - 'EPSG:900913' + - 'EPSG:102113' + +Defined projections can also be accessed through the proj4.defs function (`proj4.defs('EPSG:4326')`). + +proj4.defs can also be used to define a named alias: + +```javascript +proj4.defs('urn:x-ogc:def:crs:EPSG:4326', proj4.defs('EPSG:4326')); +``` + +## Axis order + +By default, proj4 uses `[x,y]` axis order for projected (cartesian) coordinate systems and `[x=longitude,y=latitude]` for geographic coordinates. To enforce the axis order of the provided proj or wkt string, use the +```javascript +proj4(fromProjection, toProjection).forward(coordinate, enforceAxis); +proj4(fromProjection, toProjection).inverse(coordinate, enforceAxis); +``` +signatures with `enforceAxis` set to `true`: +```javascript +proj4('+proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees +axis=neu', firstProjection).forward([41, -71], true); +// [242075.00535055372, 750123.32090043] +proj4('+proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees +axis=neu', firstProjection).inverse([242075.00535055372, 750123.32090043], true); +//[40.99999999999986, -71] +//the floating points to answer your question +``` + +## Grid Based Datum Adjustments + +To use `+nadgrids=` in a proj definition, first read your NTv2 `.gsb` file (e.g. from https://github.com/OSGeo/proj-datumgrid) into an ArrayBuffer, then pass it to `proj4.nadgrid`. E.g: + +```javascript +const buffer = fs.readFileSync('ntv2.gsb').buffer +proj4.nadgrid('key', buffer); +``` + +then use the given key in your definition, e.g. `+nadgrids=@key,null`. See [Grid Based Datum Adjustments](https://proj.org/usage/transformation.html?highlight=nadgrids#grid-based-datum-adjustments). + +## TypeScript + +TypeScript implementation was added to the [DefinitelyTyped repository](https://github.com/DefinitelyTyped/DefinitelyTyped). + +```bash +$ npm install --save @types/proj4 +``` + +## Developing +To set up build tools make sure you have node and grunt-cli installed and then run `npm install`. + +To do the complete build and browser tests run + +```bash +node_modules/.bin/grunt +``` + +To run node tests run + +```bash +npm test +``` + +To run node tests with coverage run + +```bash +npm test --coverage +``` + +To create a build with only default projections (latlon and Mercator) run + +```bash +node_modules/.bin/grunt build +``` + +To create a build with only custom projections include a comma separated list of projections codes (the file name in 'lib/projections' without the '.js') after a colon, e.g. + +```bash +node_modules/.bin/grunt build:tmerc +#includes transverse Mercator +node_modules/.bin/grunt build:lcc +#includes lambert conformal conic +node_modules/.bin/grunt build:omerc,moll +#includes oblique Mercator and Mollweide +``` diff --git a/node_modules/proj4/REFERENCES.md b/node_modules/proj4/REFERENCES.md new file mode 100644 index 0000000..d84798f --- /dev/null +++ b/node_modules/proj4/REFERENCES.md @@ -0,0 +1,33 @@ +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological Survey + Professional Paper 1395 (Supersedes USGS Bulletin 1532), + United States Government Printing Office, Washington D.C., 1987. + Accessed: 2016-05-09. https://pubs.er.usgs.gov/publication/pp1395 +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , + United State Government Printing Office, Washington D.C., 1989. + Accessed: 2016-05-09. https://pubs.er.usgs.gov/publication/pp1453 +3. "Cartographic Projection Procedures for the UNIX Environment- + A User's Manual" by Gerald I. Evenden, + USGS Open File Report 90-284 and Release 4 Interim Reports (2003). + Accessed: 2016-06-09. http://www2.bren.ucsb.edu/~frew/ESM264/private/proj_manual.pdf +4. Snyder, John P., "Flattening the Earth - + Two Thousand Years of Map Projections", Univ. Chicago Press, 1993 +5. Wolfram Mathworld "Gnomonic Projection" + http://mathworld.wolfram.com/GnomonicProjection.html + Accessed: 12th November 2009 +6. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. +7. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + Access date 2016-05-09. https://pubs.er.usgs.gov/publication/pp1395 +8. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +9. Department of Land and Survey Technical Circular 1973/32 + http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf +10. OSG Technical Report 4.1 + http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf +11. Formules et constantes pour le Calcul pour la + projection cylindrique conforme à axe oblique et pour la transformation entre + des systèmes de référence. + http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf diff --git a/node_modules/proj4/bower.json b/node_modules/proj4/bower.json new file mode 100644 index 0000000..e9694ad --- /dev/null +++ b/node_modules/proj4/bower.json @@ -0,0 +1,24 @@ +{ + "name": "proj4", + "version": "2.9.0", + "description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.", + "homepage": "https://github.com/proj4js/proj4js", + "main": "dist/proj4.js", + "keywords": [ + "gis", + "projections", + "geospatial", + "transform", + "datum" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "almond", + "src" + ] +} diff --git a/node_modules/proj4/changelog.md b/node_modules/proj4/changelog.md new file mode 100644 index 0000000..7901d49 --- /dev/null +++ b/node_modules/proj4/changelog.md @@ -0,0 +1,21 @@ +Change log +=== +- 2.2.1: Documentation fixes and added proj4.defs('name') as an alias for proj4.defs['name']; + +- 2.1.4: dist folder is added back in after accidentally omitting it in 2.1.1 + +- 2.1.3: skipped as issues with the dist folder are ironed out. + +- 2.1.2: added sensible defaults for false eastings/northings + +- 2.1.1: tweaks to how we publish it, fixes related to errors with the OSGB36 and Reseau National Belge 1972 datums, we took the first steps towards depreciating the proj4.Point class. + +- 2.1.0: targeted builds for projections are now supported, and internally projection creation is more modular. + +- 2.0.3: mgrs is broken out into it's own module loaded via npm. + +- 2.0.2: module common is broken up into a collection of smaller modules. + +- 2.0.1: fix typo in eqc projection. + +- 2.0.0: we start the change log. \ No newline at end of file diff --git a/node_modules/proj4/component.json b/node_modules/proj4/component.json new file mode 100644 index 0000000..f5af9a6 --- /dev/null +++ b/node_modules/proj4/component.json @@ -0,0 +1,17 @@ +{ + "name": "proj4", + "version": "2.9.0", + "description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.", + "repo": "proj4js/proj4js", + "keywords": [ + "projections", + "proj4", + "transform", + "crs" + ], + "license": "MIT", + "main": "dist/proj4.js", + "scripts": [ + "dist/proj4.js" + ] +} diff --git a/node_modules/proj4/dist/proj4-src.js b/node_modules/proj4/dist/proj4-src.js new file mode 100644 index 0000000..d3cc483 --- /dev/null +++ b/node_modules/proj4/dist/proj4-src.js @@ -0,0 +1,7355 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.proj4 = factory()); +}(this, (function () { 'use strict'; + + var globals = function(defs) { + defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"); + defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees"); + defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"); + + defs.WGS84 = defs['EPSG:4326']; + defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857 + defs.GOOGLE = defs['EPSG:3857']; + defs['EPSG:900913'] = defs['EPSG:3857']; + defs['EPSG:102113'] = defs['EPSG:3857']; + }; + + var PJD_3PARAM = 1; + var PJD_7PARAM = 2; + var PJD_GRIDSHIFT = 3; + var PJD_WGS84 = 4; // WGS84 or equivalent + var PJD_NODATUM = 5; // WGS84 or equivalent + var SRS_WGS84_SEMIMAJOR = 6378137.0; // only used in grid shift transforms + var SRS_WGS84_SEMIMINOR = 6356752.314; // only used in grid shift transforms + var SRS_WGS84_ESQUARED = 0.0066943799901413165; // only used in grid shift transforms + var SEC_TO_RAD = 4.84813681109535993589914102357e-6; + var HALF_PI = Math.PI/2; + // ellipoid pj_set_ell.c + var SIXTH = 0.1666666666666666667; + /* 1/6 */ + var RA4 = 0.04722222222222222222; + /* 17/360 */ + var RA6 = 0.02215608465608465608; + var EPSLN = 1.0e-10; + // you'd think you could use Number.EPSILON above but that makes + // Mollweide get into an infinate loop. + + var D2R = 0.01745329251994329577; + var R2D = 57.29577951308232088; + var FORTPI = Math.PI/4; + var TWO_PI = Math.PI * 2; + // SPI is slightly greater than Math.PI, so values that exceed the -180..180 + // degree range by a tiny amount don't get wrapped. This prevents points that + // have drifted from their original location along the 180th meridian (due to + // floating point error) from changing their sign. + var SPI = 3.14159265359; + + var exports$1 = {}; + exports$1.greenwich = 0.0; //"0dE", + exports$1.lisbon = -9.131906111111; //"9d07'54.862\"W", + exports$1.paris = 2.337229166667; //"2d20'14.025\"E", + exports$1.bogota = -74.080916666667; //"74d04'51.3\"W", + exports$1.madrid = -3.687938888889; //"3d41'16.58\"W", + exports$1.rome = 12.452333333333; //"12d27'8.4\"E", + exports$1.bern = 7.439583333333; //"7d26'22.5\"E", + exports$1.jakarta = 106.807719444444; //"106d48'27.79\"E", + exports$1.ferro = -17.666666666667; //"17d40'W", + exports$1.brussels = 4.367975; //"4d22'4.71\"E", + exports$1.stockholm = 18.058277777778; //"18d3'29.8\"E", + exports$1.athens = 23.7163375; //"23d42'58.815\"E", + exports$1.oslo = 10.722916666667; //"10d43'22.5\"E" + + var units = { + ft: {to_meter: 0.3048}, + 'us-ft': {to_meter: 1200 / 3937} + }; + + var ignoredChar = /[\s_\-\/\(\)]/g; + function match(obj, key) { + if (obj[key]) { + return obj[key]; + } + var keys = Object.keys(obj); + var lkey = key.toLowerCase().replace(ignoredChar, ''); + var i = -1; + var testkey, processedKey; + while (++i < keys.length) { + testkey = keys[i]; + processedKey = testkey.toLowerCase().replace(ignoredChar, ''); + if (processedKey === lkey) { + return obj[testkey]; + } + } + } + + var parseProj = function(defData) { + var self = {}; + var paramObj = defData.split('+').map(function(v) { + return v.trim(); + }).filter(function(a) { + return a; + }).reduce(function(p, a) { + var split = a.split('='); + split.push(true); + p[split[0].toLowerCase()] = split[1]; + return p; + }, {}); + var paramName, paramVal, paramOutname; + var params = { + proj: 'projName', + datum: 'datumCode', + rf: function(v) { + self.rf = parseFloat(v); + }, + lat_0: function(v) { + self.lat0 = v * D2R; + }, + lat_1: function(v) { + self.lat1 = v * D2R; + }, + lat_2: function(v) { + self.lat2 = v * D2R; + }, + lat_ts: function(v) { + self.lat_ts = v * D2R; + }, + lon_0: function(v) { + self.long0 = v * D2R; + }, + lon_1: function(v) { + self.long1 = v * D2R; + }, + lon_2: function(v) { + self.long2 = v * D2R; + }, + alpha: function(v) { + self.alpha = parseFloat(v) * D2R; + }, + gamma: function(v) { + self.rectified_grid_angle = parseFloat(v); + }, + lonc: function(v) { + self.longc = v * D2R; + }, + x_0: function(v) { + self.x0 = parseFloat(v); + }, + y_0: function(v) { + self.y0 = parseFloat(v); + }, + k_0: function(v) { + self.k0 = parseFloat(v); + }, + k: function(v) { + self.k0 = parseFloat(v); + }, + a: function(v) { + self.a = parseFloat(v); + }, + b: function(v) { + self.b = parseFloat(v); + }, + r_a: function() { + self.R_A = true; + }, + zone: function(v) { + self.zone = parseInt(v, 10); + }, + south: function() { + self.utmSouth = true; + }, + towgs84: function(v) { + self.datum_params = v.split(",").map(function(a) { + return parseFloat(a); + }); + }, + to_meter: function(v) { + self.to_meter = parseFloat(v); + }, + units: function(v) { + self.units = v; + var unit = match(units, v); + if (unit) { + self.to_meter = unit.to_meter; + } + }, + from_greenwich: function(v) { + self.from_greenwich = v * D2R; + }, + pm: function(v) { + var pm = match(exports$1, v); + self.from_greenwich = (pm ? pm : parseFloat(v)) * D2R; + }, + nadgrids: function(v) { + if (v === '@null') { + self.datumCode = 'none'; + } + else { + self.nadgrids = v; + } + }, + axis: function(v) { + var legalAxis = "ewnsud"; + if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) { + self.axis = v; + } + }, + approx: function() { + self.approx = true; + } + }; + for (paramName in paramObj) { + paramVal = paramObj[paramName]; + if (paramName in params) { + paramOutname = params[paramName]; + if (typeof paramOutname === 'function') { + paramOutname(paramVal); + } + else { + self[paramOutname] = paramVal; + } + } + else { + self[paramName] = paramVal; + } + } + if(typeof self.datumCode === 'string' && self.datumCode !== "WGS84"){ + self.datumCode = self.datumCode.toLowerCase(); + } + return self; + }; + + var NEUTRAL = 1; + var KEYWORD = 2; + var NUMBER = 3; + var QUOTED = 4; + var AFTERQUOTE = 5; + var ENDED = -1; + var whitespace = /\s/; + var latin = /[A-Za-z]/; + var keyword = /[A-Za-z84_]/; + var endThings = /[,\]]/; + var digets = /[\d\.E\-\+]/; + // const ignoredChar = /[\s_\-\/\(\)]/g; + function Parser(text) { + if (typeof text !== 'string') { + throw new Error('not a string'); + } + this.text = text.trim(); + this.level = 0; + this.place = 0; + this.root = null; + this.stack = []; + this.currentObject = null; + this.state = NEUTRAL; + } + Parser.prototype.readCharicter = function() { + var char = this.text[this.place++]; + if (this.state !== QUOTED) { + while (whitespace.test(char)) { + if (this.place >= this.text.length) { + return; + } + char = this.text[this.place++]; + } + } + switch (this.state) { + case NEUTRAL: + return this.neutral(char); + case KEYWORD: + return this.keyword(char) + case QUOTED: + return this.quoted(char); + case AFTERQUOTE: + return this.afterquote(char); + case NUMBER: + return this.number(char); + case ENDED: + return; + } + }; + Parser.prototype.afterquote = function(char) { + if (char === '"') { + this.word += '"'; + this.state = QUOTED; + return; + } + if (endThings.test(char)) { + this.word = this.word.trim(); + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in afterquote yet, index ' + this.place); + }; + Parser.prototype.afterItem = function(char) { + if (char === ',') { + if (this.word !== null) { + this.currentObject.push(this.word); + } + this.word = null; + this.state = NEUTRAL; + return; + } + if (char === ']') { + this.level--; + if (this.word !== null) { + this.currentObject.push(this.word); + this.word = null; + } + this.state = NEUTRAL; + this.currentObject = this.stack.pop(); + if (!this.currentObject) { + this.state = ENDED; + } + + return; + } + }; + Parser.prototype.number = function(char) { + if (digets.test(char)) { + this.word += char; + return; + } + if (endThings.test(char)) { + this.word = parseFloat(this.word); + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in number yet, index ' + this.place); + }; + Parser.prototype.quoted = function(char) { + if (char === '"') { + this.state = AFTERQUOTE; + return; + } + this.word += char; + return; + }; + Parser.prototype.keyword = function(char) { + if (keyword.test(char)) { + this.word += char; + return; + } + if (char === '[') { + var newObjects = []; + newObjects.push(this.word); + this.level++; + if (this.root === null) { + this.root = newObjects; + } else { + this.currentObject.push(newObjects); + } + this.stack.push(this.currentObject); + this.currentObject = newObjects; + this.state = NEUTRAL; + return; + } + if (endThings.test(char)) { + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in keyword yet, index ' + this.place); + }; + Parser.prototype.neutral = function(char) { + if (latin.test(char)) { + this.word = char; + this.state = KEYWORD; + return; + } + if (char === '"') { + this.word = ''; + this.state = QUOTED; + return; + } + if (digets.test(char)) { + this.word = char; + this.state = NUMBER; + return; + } + if (endThings.test(char)) { + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in neutral yet, index ' + this.place); + }; + Parser.prototype.output = function() { + while (this.place < this.text.length) { + this.readCharicter(); + } + if (this.state === ENDED) { + return this.root; + } + throw new Error('unable to parse string "' +this.text + '". State is ' + this.state); + }; + + function parseString(txt) { + var parser = new Parser(txt); + return parser.output(); + } + + function mapit(obj, key, value) { + if (Array.isArray(key)) { + value.unshift(key); + key = null; + } + var thing = key ? {} : obj; + + var out = value.reduce(function(newObj, item) { + sExpr(item, newObj); + return newObj + }, thing); + if (key) { + obj[key] = out; + } + } + + function sExpr(v, obj) { + if (!Array.isArray(v)) { + obj[v] = true; + return; + } + var key = v.shift(); + if (key === 'PARAMETER') { + key = v.shift(); + } + if (v.length === 1) { + if (Array.isArray(v[0])) { + obj[key] = {}; + sExpr(v[0], obj[key]); + return; + } + obj[key] = v[0]; + return; + } + if (!v.length) { + obj[key] = true; + return; + } + if (key === 'TOWGS84') { + obj[key] = v; + return; + } + if (key === 'AXIS') { + if (!(key in obj)) { + obj[key] = []; + } + obj[key].push(v); + return; + } + if (!Array.isArray(key)) { + obj[key] = {}; + } + + var i; + switch (key) { + case 'UNIT': + case 'PRIMEM': + case 'VERT_DATUM': + obj[key] = { + name: v[0].toLowerCase(), + convert: v[1] + }; + if (v.length === 3) { + sExpr(v[2], obj[key]); + } + return; + case 'SPHEROID': + case 'ELLIPSOID': + obj[key] = { + name: v[0], + a: v[1], + rf: v[2] + }; + if (v.length === 4) { + sExpr(v[3], obj[key]); + } + return; + case 'PROJECTEDCRS': + case 'PROJCRS': + case 'GEOGCS': + case 'GEOCCS': + case 'PROJCS': + case 'LOCAL_CS': + case 'GEODCRS': + case 'GEODETICCRS': + case 'GEODETICDATUM': + case 'EDATUM': + case 'ENGINEERINGDATUM': + case 'VERT_CS': + case 'VERTCRS': + case 'VERTICALCRS': + case 'COMPD_CS': + case 'COMPOUNDCRS': + case 'ENGINEERINGCRS': + case 'ENGCRS': + case 'FITTED_CS': + case 'LOCAL_DATUM': + case 'DATUM': + v[0] = ['name', v[0]]; + mapit(obj, key, v); + return; + default: + i = -1; + while (++i < v.length) { + if (!Array.isArray(v[i])) { + return sExpr(v, obj[key]); + } + } + return mapit(obj, key, v); + } + } + + var D2R$1 = 0.01745329251994329577; + function rename(obj, params) { + var outName = params[0]; + var inName = params[1]; + if (!(outName in obj) && (inName in obj)) { + obj[outName] = obj[inName]; + if (params.length === 3) { + obj[outName] = params[2](obj[outName]); + } + } + } + + function d2r(input) { + return input * D2R$1; + } + + function cleanWKT(wkt) { + if (wkt.type === 'GEOGCS') { + wkt.projName = 'longlat'; + } else if (wkt.type === 'LOCAL_CS') { + wkt.projName = 'identity'; + wkt.local = true; + } else { + if (typeof wkt.PROJECTION === 'object') { + wkt.projName = Object.keys(wkt.PROJECTION)[0]; + } else { + wkt.projName = wkt.PROJECTION; + } + } + if (wkt.AXIS) { + var axisOrder = ''; + for (var i = 0, ii = wkt.AXIS.length; i < ii; ++i) { + var axis = [wkt.AXIS[i][0].toLowerCase(), wkt.AXIS[i][1].toLowerCase()]; + if (axis[0].indexOf('north') !== -1 || ((axis[0] === 'y' || axis[0] === 'lat') && axis[1] === 'north')) { + axisOrder += 'n'; + } else if (axis[0].indexOf('south') !== -1 || ((axis[0] === 'y' || axis[0] === 'lat') && axis[1] === 'south')) { + axisOrder += 's'; + } else if (axis[0].indexOf('east') !== -1 || ((axis[0] === 'x' || axis[0] === 'lon') && axis[1] === 'east')) { + axisOrder += 'e'; + } else if (axis[0].indexOf('west') !== -1 || ((axis[0] === 'x' || axis[0] === 'lon') && axis[1] === 'west')) { + axisOrder += 'w'; + } + } + if (axisOrder.length === 2) { + axisOrder += 'u'; + } + if (axisOrder.length === 3) { + wkt.axis = axisOrder; + } + } + if (wkt.UNIT) { + wkt.units = wkt.UNIT.name.toLowerCase(); + if (wkt.units === 'metre') { + wkt.units = 'meter'; + } + if (wkt.UNIT.convert) { + if (wkt.type === 'GEOGCS') { + if (wkt.DATUM && wkt.DATUM.SPHEROID) { + wkt.to_meter = wkt.UNIT.convert*wkt.DATUM.SPHEROID.a; + } + } else { + wkt.to_meter = wkt.UNIT.convert; + } + } + } + var geogcs = wkt.GEOGCS; + if (wkt.type === 'GEOGCS') { + geogcs = wkt; + } + if (geogcs) { + //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){ + // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R; + //} + if (geogcs.DATUM) { + wkt.datumCode = geogcs.DATUM.name.toLowerCase(); + } else { + wkt.datumCode = geogcs.name.toLowerCase(); + } + if (wkt.datumCode.slice(0, 2) === 'd_') { + wkt.datumCode = wkt.datumCode.slice(2); + } + if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') { + wkt.datumCode = 'nzgd49'; + } + if (wkt.datumCode === 'wgs_1984' || wkt.datumCode === 'world_geodetic_system_1984') { + if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') { + wkt.sphere = true; + } + wkt.datumCode = 'wgs84'; + } + if (wkt.datumCode.slice(-6) === '_ferro') { + wkt.datumCode = wkt.datumCode.slice(0, - 6); + } + if (wkt.datumCode.slice(-8) === '_jakarta') { + wkt.datumCode = wkt.datumCode.slice(0, - 8); + } + if (~wkt.datumCode.indexOf('belge')) { + wkt.datumCode = 'rnb72'; + } + if (geogcs.DATUM && geogcs.DATUM.SPHEROID) { + wkt.ellps = geogcs.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk'); + if (wkt.ellps.toLowerCase().slice(0, 13) === 'international') { + wkt.ellps = 'intl'; + } + + wkt.a = geogcs.DATUM.SPHEROID.a; + wkt.rf = parseFloat(geogcs.DATUM.SPHEROID.rf, 10); + } + + if (geogcs.DATUM && geogcs.DATUM.TOWGS84) { + wkt.datum_params = geogcs.DATUM.TOWGS84; + } + if (~wkt.datumCode.indexOf('osgb_1936')) { + wkt.datumCode = 'osgb36'; + } + if (~wkt.datumCode.indexOf('osni_1952')) { + wkt.datumCode = 'osni52'; + } + if (~wkt.datumCode.indexOf('tm65') + || ~wkt.datumCode.indexOf('geodetic_datum_of_1965')) { + wkt.datumCode = 'ire65'; + } + if (wkt.datumCode === 'ch1903+') { + wkt.datumCode = 'ch1903'; + } + if (~wkt.datumCode.indexOf('israel')) { + wkt.datumCode = 'isr93'; + } + } + if (wkt.b && !isFinite(wkt.b)) { + wkt.b = wkt.a; + } + + function toMeter(input) { + var ratio = wkt.to_meter || 1; + return input * ratio; + } + var renamer = function(a) { + return rename(wkt, a); + }; + var list = [ + ['standard_parallel_1', 'Standard_Parallel_1'], + ['standard_parallel_1', 'Latitude of 1st standard parallel'], + ['standard_parallel_2', 'Standard_Parallel_2'], + ['standard_parallel_2', 'Latitude of 2nd standard parallel'], + ['false_easting', 'False_Easting'], + ['false_easting', 'False easting'], + ['false-easting', 'Easting at false origin'], + ['false_northing', 'False_Northing'], + ['false_northing', 'False northing'], + ['false_northing', 'Northing at false origin'], + ['central_meridian', 'Central_Meridian'], + ['central_meridian', 'Longitude of natural origin'], + ['central_meridian', 'Longitude of false origin'], + ['latitude_of_origin', 'Latitude_Of_Origin'], + ['latitude_of_origin', 'Central_Parallel'], + ['latitude_of_origin', 'Latitude of natural origin'], + ['latitude_of_origin', 'Latitude of false origin'], + ['scale_factor', 'Scale_Factor'], + ['k0', 'scale_factor'], + ['latitude_of_center', 'Latitude_Of_Center'], + ['latitude_of_center', 'Latitude_of_center'], + ['lat0', 'latitude_of_center', d2r], + ['longitude_of_center', 'Longitude_Of_Center'], + ['longitude_of_center', 'Longitude_of_center'], + ['longc', 'longitude_of_center', d2r], + ['x0', 'false_easting', toMeter], + ['y0', 'false_northing', toMeter], + ['long0', 'central_meridian', d2r], + ['lat0', 'latitude_of_origin', d2r], + ['lat0', 'standard_parallel_1', d2r], + ['lat1', 'standard_parallel_1', d2r], + ['lat2', 'standard_parallel_2', d2r], + ['azimuth', 'Azimuth'], + ['alpha', 'azimuth', d2r], + ['srsCode', 'name'] + ]; + list.forEach(renamer); + if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === 'Lambert_Azimuthal_Equal_Area')) { + wkt.long0 = wkt.longc; + } + if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) { + wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90); + wkt.lat_ts = wkt.lat1; + } + } + var wkt = function(wkt) { + var lisp = parseString(wkt); + var type = lisp.shift(); + var name = lisp.shift(); + lisp.unshift(['name', name]); + lisp.unshift(['type', type]); + var obj = {}; + sExpr(lisp, obj); + cleanWKT(obj); + return obj; + }; + + function defs(name) { + /*global console*/ + var that = this; + if (arguments.length === 2) { + var def = arguments[1]; + if (typeof def === 'string') { + if (def.charAt(0) === '+') { + defs[name] = parseProj(arguments[1]); + } + else { + defs[name] = wkt(arguments[1]); + } + } else { + defs[name] = def; + } + } + else if (arguments.length === 1) { + if (Array.isArray(name)) { + return name.map(function(v) { + if (Array.isArray(v)) { + defs.apply(that, v); + } + else { + defs(v); + } + }); + } + else if (typeof name === 'string') { + if (name in defs) { + return defs[name]; + } + } + else if ('EPSG' in name) { + defs['EPSG:' + name.EPSG] = name; + } + else if ('ESRI' in name) { + defs['ESRI:' + name.ESRI] = name; + } + else if ('IAU2000' in name) { + defs['IAU2000:' + name.IAU2000] = name; + } + else { + console.log(name); + } + return; + } + + + } + globals(defs); + + function testObj(code){ + return typeof code === 'string'; + } + function testDef(code){ + return code in defs; + } + var codeWords = ['PROJECTEDCRS', 'PROJCRS', 'GEOGCS','GEOCCS','PROJCS','LOCAL_CS', 'GEODCRS', 'GEODETICCRS', 'GEODETICDATUM', 'ENGCRS', 'ENGINEERINGCRS']; + function testWKT(code){ + return codeWords.some(function (word) { + return code.indexOf(word) > -1; + }); + } + var codes = ['3857', '900913', '3785', '102113']; + function checkMercator(item) { + var auth = match(item, 'authority'); + if (!auth) { + return; + } + var code = match(auth, 'epsg'); + return code && codes.indexOf(code) > -1; + } + function checkProjStr(item) { + var ext = match(item, 'extension'); + if (!ext) { + return; + } + return match(ext, 'proj4'); + } + function testProj(code){ + return code[0] === '+'; + } + function parse(code){ + if (testObj(code)) { + //check to see if this is a WKT string + if (testDef(code)) { + return defs[code]; + } + if (testWKT(code)) { + var out = wkt(code); + // test of spetial case, due to this being a very common and often malformed + if (checkMercator(out)) { + return defs['EPSG:3857']; + } + var maybeProjStr = checkProjStr(out); + if (maybeProjStr) { + return parseProj(maybeProjStr); + } + return out; + } + if (testProj(code)) { + return parseProj(code); + } + }else{ + return code; + } + } + + var extend = function(destination, source) { + destination = destination || {}; + var value, property; + if (!source) { + return destination; + } + for (property in source) { + value = source[property]; + if (value !== undefined) { + destination[property] = value; + } + } + return destination; + }; + + var msfnz = function(eccent, sinphi, cosphi) { + var con = eccent * sinphi; + return cosphi / (Math.sqrt(1 - con * con)); + }; + + var sign = function(x) { + return x<0 ? -1 : 1; + }; + + var adjust_lon = function(x) { + return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI)); + }; + + var tsfnz = function(eccent, phi, sinphi) { + var con = eccent * sinphi; + var com = 0.5 * eccent; + con = Math.pow(((1 - con) / (1 + con)), com); + return (Math.tan(0.5 * (HALF_PI - phi)) / con); + }; + + var phi2z = function(eccent, ts) { + var eccnth = 0.5 * eccent; + var con, dphi; + var phi = HALF_PI - 2 * Math.atan(ts); + for (var i = 0; i <= 15; i++) { + con = eccent * Math.sin(phi); + dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi; + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + //console.log("phi2z has NoConvergence"); + return -9999; + }; + + function init() { + var con = this.b / this.a; + this.es = 1 - con * con; + if(!('x0' in this)){ + this.x0 = 0; + } + if(!('y0' in this)){ + this.y0 = 0; + } + this.e = Math.sqrt(this.es); + if (this.lat_ts) { + if (this.sphere) { + this.k0 = Math.cos(this.lat_ts); + } + else { + this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } + } + else { + if (!this.k0) { + if (this.k) { + this.k0 = this.k; + } + else { + this.k0 = 1; + } + } + } + } + + /* Mercator forward equations--mapping lat,long to x,y + --------------------------------------------------*/ + + function forward(p) { + var lon = p.x; + var lat = p.y; + // convert to radians + if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) { + return null; + } + + var x, y; + if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) { + return null; + } + else { + if (this.sphere) { + x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0); + y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat)); + } + else { + var sinphi = Math.sin(lat); + var ts = tsfnz(this.e, lat, sinphi); + x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0); + y = this.y0 - this.a * this.k0 * Math.log(ts); + } + p.x = x; + p.y = y; + return p; + } + } + + /* Mercator inverse equations--mapping x,y to lat/long + --------------------------------------------------*/ + function inverse(p) { + + var x = p.x - this.x0; + var y = p.y - this.y0; + var lon, lat; + + if (this.sphere) { + lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0))); + } + else { + var ts = Math.exp(-y / (this.a * this.k0)); + lat = phi2z(this.e, ts); + if (lat === -9999) { + return null; + } + } + lon = adjust_lon(this.long0 + x / (this.a * this.k0)); + + p.x = lon; + p.y = lat; + return p; + } + + var names$1 = ["Mercator", "Popular Visualisation Pseudo Mercator", "Mercator_1SP", "Mercator_Auxiliary_Sphere", "merc"]; + var merc = { + init: init, + forward: forward, + inverse: inverse, + names: names$1 + }; + + function init$1() { + //no-op for longlat + } + + function identity(pt) { + return pt; + } + var names$2 = ["longlat", "identity"]; + var longlat = { + init: init$1, + forward: identity, + inverse: identity, + names: names$2 + }; + + var projs = [merc, longlat]; + var names = {}; + var projStore = []; + + function add(proj, i) { + var len = projStore.length; + if (!proj.names) { + console.log(i); + return true; + } + projStore[len] = proj; + proj.names.forEach(function(n) { + names[n.toLowerCase()] = len; + }); + return this; + } + + function get(name) { + if (!name) { + return false; + } + var n = name.toLowerCase(); + if (typeof names[n] !== 'undefined' && projStore[names[n]]) { + return projStore[names[n]]; + } + } + + function start() { + projs.forEach(add); + } + var projections = { + start: start, + add: add, + get: get + }; + + var exports$2 = {}; + exports$2.MERIT = { + a: 6378137.0, + rf: 298.257, + ellipseName: "MERIT 1983" + }; + + exports$2.SGS85 = { + a: 6378136.0, + rf: 298.257, + ellipseName: "Soviet Geodetic System 85" + }; + + exports$2.GRS80 = { + a: 6378137.0, + rf: 298.257222101, + ellipseName: "GRS 1980(IUGG, 1980)" + }; + + exports$2.IAU76 = { + a: 6378140.0, + rf: 298.257, + ellipseName: "IAU 1976" + }; + + exports$2.airy = { + a: 6377563.396, + b: 6356256.910, + ellipseName: "Airy 1830" + }; + + exports$2.APL4 = { + a: 6378137, + rf: 298.25, + ellipseName: "Appl. Physics. 1965" + }; + + exports$2.NWL9D = { + a: 6378145.0, + rf: 298.25, + ellipseName: "Naval Weapons Lab., 1965" + }; + + exports$2.mod_airy = { + a: 6377340.189, + b: 6356034.446, + ellipseName: "Modified Airy" + }; + + exports$2.andrae = { + a: 6377104.43, + rf: 300.0, + ellipseName: "Andrae 1876 (Den., Iclnd.)" + }; + + exports$2.aust_SA = { + a: 6378160.0, + rf: 298.25, + ellipseName: "Australian Natl & S. Amer. 1969" + }; + + exports$2.GRS67 = { + a: 6378160.0, + rf: 298.2471674270, + ellipseName: "GRS 67(IUGG 1967)" + }; + + exports$2.bessel = { + a: 6377397.155, + rf: 299.1528128, + ellipseName: "Bessel 1841" + }; + + exports$2.bess_nam = { + a: 6377483.865, + rf: 299.1528128, + ellipseName: "Bessel 1841 (Namibia)" + }; + + exports$2.clrk66 = { + a: 6378206.4, + b: 6356583.8, + ellipseName: "Clarke 1866" + }; + + exports$2.clrk80 = { + a: 6378249.145, + rf: 293.4663, + ellipseName: "Clarke 1880 mod." + }; + + exports$2.clrk80ign = { + a: 6378249.2, + b: 6356515, + rf: 293.4660213, + ellipseName: "Clarke 1880 (IGN)" + }; + + exports$2.clrk58 = { + a: 6378293.645208759, + rf: 294.2606763692654, + ellipseName: "Clarke 1858" + }; + + exports$2.CPM = { + a: 6375738.7, + rf: 334.29, + ellipseName: "Comm. des Poids et Mesures 1799" + }; + + exports$2.delmbr = { + a: 6376428.0, + rf: 311.5, + ellipseName: "Delambre 1810 (Belgium)" + }; + + exports$2.engelis = { + a: 6378136.05, + rf: 298.2566, + ellipseName: "Engelis 1985" + }; + + exports$2.evrst30 = { + a: 6377276.345, + rf: 300.8017, + ellipseName: "Everest 1830" + }; + + exports$2.evrst48 = { + a: 6377304.063, + rf: 300.8017, + ellipseName: "Everest 1948" + }; + + exports$2.evrst56 = { + a: 6377301.243, + rf: 300.8017, + ellipseName: "Everest 1956" + }; + + exports$2.evrst69 = { + a: 6377295.664, + rf: 300.8017, + ellipseName: "Everest 1969" + }; + + exports$2.evrstSS = { + a: 6377298.556, + rf: 300.8017, + ellipseName: "Everest (Sabah & Sarawak)" + }; + + exports$2.fschr60 = { + a: 6378166.0, + rf: 298.3, + ellipseName: "Fischer (Mercury Datum) 1960" + }; + + exports$2.fschr60m = { + a: 6378155.0, + rf: 298.3, + ellipseName: "Fischer 1960" + }; + + exports$2.fschr68 = { + a: 6378150.0, + rf: 298.3, + ellipseName: "Fischer 1968" + }; + + exports$2.helmert = { + a: 6378200.0, + rf: 298.3, + ellipseName: "Helmert 1906" + }; + + exports$2.hough = { + a: 6378270.0, + rf: 297.0, + ellipseName: "Hough" + }; + + exports$2.intl = { + a: 6378388.0, + rf: 297.0, + ellipseName: "International 1909 (Hayford)" + }; + + exports$2.kaula = { + a: 6378163.0, + rf: 298.24, + ellipseName: "Kaula 1961" + }; + + exports$2.lerch = { + a: 6378139.0, + rf: 298.257, + ellipseName: "Lerch 1979" + }; + + exports$2.mprts = { + a: 6397300.0, + rf: 191.0, + ellipseName: "Maupertius 1738" + }; + + exports$2.new_intl = { + a: 6378157.5, + b: 6356772.2, + ellipseName: "New International 1967" + }; + + exports$2.plessis = { + a: 6376523.0, + rf: 6355863.0, + ellipseName: "Plessis 1817 (France)" + }; + + exports$2.krass = { + a: 6378245.0, + rf: 298.3, + ellipseName: "Krassovsky, 1942" + }; + + exports$2.SEasia = { + a: 6378155.0, + b: 6356773.3205, + ellipseName: "Southeast Asia" + }; + + exports$2.walbeck = { + a: 6376896.0, + b: 6355834.8467, + ellipseName: "Walbeck" + }; + + exports$2.WGS60 = { + a: 6378165.0, + rf: 298.3, + ellipseName: "WGS 60" + }; + + exports$2.WGS66 = { + a: 6378145.0, + rf: 298.25, + ellipseName: "WGS 66" + }; + + exports$2.WGS7 = { + a: 6378135.0, + rf: 298.26, + ellipseName: "WGS 72" + }; + + var WGS84 = exports$2.WGS84 = { + a: 6378137.0, + rf: 298.257223563, + ellipseName: "WGS 84" + }; + + exports$2.sphere = { + a: 6370997.0, + b: 6370997.0, + ellipseName: "Normal Sphere (r=6370997)" + }; + + function eccentricity(a, b, rf, R_A) { + var a2 = a * a; // used in geocentric + var b2 = b * b; // used in geocentric + var es = (a2 - b2) / a2; // e ^ 2 + var e = 0; + if (R_A) { + a *= 1 - es * (SIXTH + es * (RA4 + es * RA6)); + a2 = a * a; + es = 0; + } else { + e = Math.sqrt(es); // eccentricity + } + var ep2 = (a2 - b2) / b2; // used in geocentric + return { + es: es, + e: e, + ep2: ep2 + }; + } + function sphere(a, b, rf, ellps, sphere) { + if (!a) { // do we have an ellipsoid? + var ellipse = match(exports$2, ellps); + if (!ellipse) { + ellipse = WGS84; + } + a = ellipse.a; + b = ellipse.b; + rf = ellipse.rf; + } + + if (rf && !b) { + b = (1.0 - 1.0 / rf) * a; + } + if (rf === 0 || Math.abs(a - b) < EPSLN) { + sphere = true; + b = a; + } + return { + a: a, + b: b, + rf: rf, + sphere: sphere + }; + } + + var exports$3 = {}; + exports$3.wgs84 = { + towgs84: "0,0,0", + ellipse: "WGS84", + datumName: "WGS84" + }; + + exports$3.ch1903 = { + towgs84: "674.374,15.056,405.346", + ellipse: "bessel", + datumName: "swiss" + }; + + exports$3.ggrs87 = { + towgs84: "-199.87,74.79,246.62", + ellipse: "GRS80", + datumName: "Greek_Geodetic_Reference_System_1987" + }; + + exports$3.nad83 = { + towgs84: "0,0,0", + ellipse: "GRS80", + datumName: "North_American_Datum_1983" + }; + + exports$3.nad27 = { + nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", + ellipse: "clrk66", + datumName: "North_American_Datum_1927" + }; + + exports$3.potsdam = { + towgs84: "598.1,73.7,418.2,0.202,0.045,-2.455,6.7", + ellipse: "bessel", + datumName: "Potsdam Rauenberg 1950 DHDN" + }; + + exports$3.carthage = { + towgs84: "-263.0,6.0,431.0", + ellipse: "clark80", + datumName: "Carthage 1934 Tunisia" + }; + + exports$3.hermannskogel = { + towgs84: "577.326,90.129,463.919,5.137,1.474,5.297,2.4232", + ellipse: "bessel", + datumName: "Hermannskogel" + }; + + exports$3.osni52 = { + towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", + ellipse: "airy", + datumName: "Irish National" + }; + + exports$3.ire65 = { + towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", + ellipse: "mod_airy", + datumName: "Ireland 1965" + }; + + exports$3.rassadiran = { + towgs84: "-133.63,-157.5,-158.62", + ellipse: "intl", + datumName: "Rassadiran" + }; + + exports$3.nzgd49 = { + towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", + ellipse: "intl", + datumName: "New Zealand Geodetic Datum 1949" + }; + + exports$3.osgb36 = { + towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", + ellipse: "airy", + datumName: "Airy 1830" + }; + + exports$3.s_jtsk = { + towgs84: "589,76,480", + ellipse: 'bessel', + datumName: 'S-JTSK (Ferro)' + }; + + exports$3.beduaram = { + towgs84: '-106,-87,188', + ellipse: 'clrk80', + datumName: 'Beduaram' + }; + + exports$3.gunung_segara = { + towgs84: '-403,684,41', + ellipse: 'bessel', + datumName: 'Gunung Segara Jakarta' + }; + + exports$3.rnb72 = { + towgs84: "106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1", + ellipse: "intl", + datumName: "Reseau National Belge 1972" + }; + + function datum(datumCode, datum_params, a, b, es, ep2, nadgrids) { + var out = {}; + + if (datumCode === undefined || datumCode === 'none') { + out.datum_type = PJD_NODATUM; + } else { + out.datum_type = PJD_WGS84; + } + + if (datum_params) { + out.datum_params = datum_params.map(parseFloat); + if (out.datum_params[0] !== 0 || out.datum_params[1] !== 0 || out.datum_params[2] !== 0) { + out.datum_type = PJD_3PARAM; + } + if (out.datum_params.length > 3) { + if (out.datum_params[3] !== 0 || out.datum_params[4] !== 0 || out.datum_params[5] !== 0 || out.datum_params[6] !== 0) { + out.datum_type = PJD_7PARAM; + out.datum_params[3] *= SEC_TO_RAD; + out.datum_params[4] *= SEC_TO_RAD; + out.datum_params[5] *= SEC_TO_RAD; + out.datum_params[6] = (out.datum_params[6] / 1000000.0) + 1.0; + } + } + } + + if (nadgrids) { + out.datum_type = PJD_GRIDSHIFT; + out.grids = nadgrids; + } + out.a = a; //datum object also uses these values + out.b = b; + out.es = es; + out.ep2 = ep2; + return out; + } + + /** + * Resources for details of NTv2 file formats: + * - https://web.archive.org/web/20140127204822if_/http://www.mgs.gov.on.ca:80/stdprodconsume/groups/content/@mgs/@iandit/documents/resourcelist/stel02_047447.pdf + * - http://mimaka.com/help/gs/html/004_NTV2%20Data%20Format.htm + */ + + var loadedNadgrids = {}; + + /** + * Load a binary NTv2 file (.gsb) to a key that can be used in a proj string like +nadgrids=. Pass the NTv2 file + * as an ArrayBuffer. + */ + function nadgrid(key, data) { + var view = new DataView(data); + var isLittleEndian = detectLittleEndian(view); + var header = readHeader(view, isLittleEndian); + if (header.nSubgrids > 1) { + console.log('Only single NTv2 subgrids are currently supported, subsequent sub grids are ignored'); + } + var subgrids = readSubgrids(view, header, isLittleEndian); + var nadgrid = {header: header, subgrids: subgrids}; + loadedNadgrids[key] = nadgrid; + return nadgrid; + } + + /** + * Given a proj4 value for nadgrids, return an array of loaded grids + */ + function getNadgrids(nadgrids) { + // Format details: http://proj.maptools.org/gen_parms.html + if (nadgrids === undefined) { return null; } + var grids = nadgrids.split(','); + return grids.map(parseNadgridString); + } + + function parseNadgridString(value) { + if (value.length === 0) { + return null; + } + var optional = value[0] === '@'; + if (optional) { + value = value.slice(1); + } + if (value === 'null') { + return {name: 'null', mandatory: !optional, grid: null, isNull: true}; + } + return { + name: value, + mandatory: !optional, + grid: loadedNadgrids[value] || null, + isNull: false + }; + } + + function secondsToRadians(seconds) { + return (seconds / 3600) * Math.PI / 180; + } + + function detectLittleEndian(view) { + var nFields = view.getInt32(8, false); + if (nFields === 11) { + return false; + } + nFields = view.getInt32(8, true); + if (nFields !== 11) { + console.warn('Failed to detect nadgrid endian-ness, defaulting to little-endian'); + } + return true; + } + + function readHeader(view, isLittleEndian) { + return { + nFields: view.getInt32(8, isLittleEndian), + nSubgridFields: view.getInt32(24, isLittleEndian), + nSubgrids: view.getInt32(40, isLittleEndian), + shiftType: decodeString(view, 56, 56 + 8).trim(), + fromSemiMajorAxis: view.getFloat64(120, isLittleEndian), + fromSemiMinorAxis: view.getFloat64(136, isLittleEndian), + toSemiMajorAxis: view.getFloat64(152, isLittleEndian), + toSemiMinorAxis: view.getFloat64(168, isLittleEndian), + }; + } + + function decodeString(view, start, end) { + return String.fromCharCode.apply(null, new Uint8Array(view.buffer.slice(start, end))); + } + + function readSubgrids(view, header, isLittleEndian) { + var gridOffset = 176; + var grids = []; + for (var i = 0; i < header.nSubgrids; i++) { + var subHeader = readGridHeader(view, gridOffset, isLittleEndian); + var nodes = readGridNodes(view, gridOffset, subHeader, isLittleEndian); + var lngColumnCount = Math.round( + 1 + (subHeader.upperLongitude - subHeader.lowerLongitude) / subHeader.longitudeInterval); + var latColumnCount = Math.round( + 1 + (subHeader.upperLatitude - subHeader.lowerLatitude) / subHeader.latitudeInterval); + // Proj4 operates on radians whereas the coordinates are in seconds in the grid + grids.push({ + ll: [secondsToRadians(subHeader.lowerLongitude), secondsToRadians(subHeader.lowerLatitude)], + del: [secondsToRadians(subHeader.longitudeInterval), secondsToRadians(subHeader.latitudeInterval)], + lim: [lngColumnCount, latColumnCount], + count: subHeader.gridNodeCount, + cvs: mapNodes(nodes) + }); + } + return grids; + } + + function mapNodes(nodes) { + return nodes.map(function (r) {return [secondsToRadians(r.longitudeShift), secondsToRadians(r.latitudeShift)];}); + } + + function readGridHeader(view, offset, isLittleEndian) { + return { + name: decodeString(view, offset + 8, offset + 16).trim(), + parent: decodeString(view, offset + 24, offset + 24 + 8).trim(), + lowerLatitude: view.getFloat64(offset + 72, isLittleEndian), + upperLatitude: view.getFloat64(offset + 88, isLittleEndian), + lowerLongitude: view.getFloat64(offset + 104, isLittleEndian), + upperLongitude: view.getFloat64(offset + 120, isLittleEndian), + latitudeInterval: view.getFloat64(offset + 136, isLittleEndian), + longitudeInterval: view.getFloat64(offset + 152, isLittleEndian), + gridNodeCount: view.getInt32(offset + 168, isLittleEndian) + }; + } + + function readGridNodes(view, offset, gridHeader, isLittleEndian) { + var nodesOffset = offset + 176; + var gridRecordLength = 16; + var gridShiftRecords = []; + for (var i = 0; i < gridHeader.gridNodeCount; i++) { + var record = { + latitudeShift: view.getFloat32(nodesOffset + i * gridRecordLength, isLittleEndian), + longitudeShift: view.getFloat32(nodesOffset + i * gridRecordLength + 4, isLittleEndian), + latitudeAccuracy: view.getFloat32(nodesOffset + i * gridRecordLength + 8, isLittleEndian), + longitudeAccuracy: view.getFloat32(nodesOffset + i * gridRecordLength + 12, isLittleEndian), + }; + gridShiftRecords.push(record); + } + return gridShiftRecords; + } + + function Projection(srsCode,callback) { + if (!(this instanceof Projection)) { + return new Projection(srsCode); + } + callback = callback || function(error){ + if(error){ + throw error; + } + }; + var json = parse(srsCode); + if(typeof json !== 'object'){ + callback(srsCode); + return; + } + var ourProj = Projection.projections.get(json.projName); + if(!ourProj){ + callback(srsCode); + return; + } + if (json.datumCode && json.datumCode !== 'none') { + var datumDef = match(exports$3, json.datumCode); + if (datumDef) { + json.datum_params = json.datum_params || (datumDef.towgs84 ? datumDef.towgs84.split(',') : null); + json.ellps = datumDef.ellipse; + json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode; + } + } + json.k0 = json.k0 || 1.0; + json.axis = json.axis || 'enu'; + json.ellps = json.ellps || 'wgs84'; + json.lat1 = json.lat1 || json.lat0; // Lambert_Conformal_Conic_1SP, for example, needs this + + var sphere_ = sphere(json.a, json.b, json.rf, json.ellps, json.sphere); + var ecc = eccentricity(sphere_.a, sphere_.b, sphere_.rf, json.R_A); + var nadgrids = getNadgrids(json.nadgrids); + var datumObj = json.datum || datum(json.datumCode, json.datum_params, sphere_.a, sphere_.b, ecc.es, ecc.ep2, + nadgrids); + + extend(this, json); // transfer everything over from the projection because we don't know what we'll need + extend(this, ourProj); // transfer all the methods from the projection + + // copy the 4 things over we calculated in deriveConstants.sphere + this.a = sphere_.a; + this.b = sphere_.b; + this.rf = sphere_.rf; + this.sphere = sphere_.sphere; + + // copy the 3 things we calculated in deriveConstants.eccentricity + this.es = ecc.es; + this.e = ecc.e; + this.ep2 = ecc.ep2; + + // add in the datum object + this.datum = datumObj; + + // init the projection + this.init(); + + // legecy callback from back in the day when it went to spatialreference.org + callback(null, this); + + } + Projection.projections = projections; + Projection.projections.start(); + + 'use strict'; + function compareDatums(source, dest) { + if (source.datum_type !== dest.datum_type) { + return false; // false, datums are not equal + } else if (source.a !== dest.a || Math.abs(source.es - dest.es) > 0.000000000050) { + // the tolerance for es is to ensure that GRS80 and WGS84 + // are considered identical + return false; + } else if (source.datum_type === PJD_3PARAM) { + return (source.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2]); + } else if (source.datum_type === PJD_7PARAM) { + return (source.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2] && source.datum_params[3] === dest.datum_params[3] && source.datum_params[4] === dest.datum_params[4] && source.datum_params[5] === dest.datum_params[5] && source.datum_params[6] === dest.datum_params[6]); + } else { + return true; // datums are equal + } + } // cs_compare_datums() + + /* + * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates + * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), + * according to the current ellipsoid parameters. + * + * Latitude : Geodetic latitude in radians (input) + * Longitude : Geodetic longitude in radians (input) + * Height : Geodetic height, in meters (input) + * X : Calculated Geocentric X coordinate, in meters (output) + * Y : Calculated Geocentric Y coordinate, in meters (output) + * Z : Calculated Geocentric Z coordinate, in meters (output) + * + */ + function geodeticToGeocentric(p, es, a) { + var Longitude = p.x; + var Latitude = p.y; + var Height = p.z ? p.z : 0; //Z value not always supplied + + var Rn; /* Earth radius at location */ + var Sin_Lat; /* Math.sin(Latitude) */ + var Sin2_Lat; /* Square of Math.sin(Latitude) */ + var Cos_Lat; /* Math.cos(Latitude) */ + + /* + ** Don't blow up if Latitude is just a little out of the value + ** range as it may just be a rounding issue. Also removed longitude + ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001. + */ + if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) { + Latitude = -HALF_PI; + } else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) { + Latitude = HALF_PI; + } else if (Latitude < -HALF_PI) { + /* Latitude out of range */ + //..reportError('geocent:lat out of range:' + Latitude); + return { x: -Infinity, y: -Infinity, z: p.z }; + } else if (Latitude > HALF_PI) { + /* Latitude out of range */ + return { x: Infinity, y: Infinity, z: p.z }; + } + + if (Longitude > Math.PI) { + Longitude -= (2 * Math.PI); + } + Sin_Lat = Math.sin(Latitude); + Cos_Lat = Math.cos(Latitude); + Sin2_Lat = Sin_Lat * Sin_Lat; + Rn = a / (Math.sqrt(1.0e0 - es * Sin2_Lat)); + return { + x: (Rn + Height) * Cos_Lat * Math.cos(Longitude), + y: (Rn + Height) * Cos_Lat * Math.sin(Longitude), + z: ((Rn * (1 - es)) + Height) * Sin_Lat + }; + } // cs_geodetic_to_geocentric() + + function geocentricToGeodetic(p, es, a, b) { + /* local defintions and variables */ + /* end-criterium of loop, accuracy of sin(Latitude) */ + var genau = 1e-12; + var genau2 = (genau * genau); + var maxiter = 30; + + var P; /* distance between semi-minor axis and location */ + var RR; /* distance between center and location */ + var CT; /* sin of geocentric latitude */ + var ST; /* cos of geocentric latitude */ + var RX; + var RK; + var RN; /* Earth radius at location */ + var CPHI0; /* cos of start or old geodetic latitude in iterations */ + var SPHI0; /* sin of start or old geodetic latitude in iterations */ + var CPHI; /* cos of searched geodetic latitude */ + var SPHI; /* sin of searched geodetic latitude */ + var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ + var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */ + + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0.0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + P = Math.sqrt(X * X + Y * Y); + RR = Math.sqrt(X * X + Y * Y + Z * Z); + + /* special cases for latitude and longitude */ + if (P / a < genau) { + + /* special case, if P=0. (X=0., Y=0.) */ + Longitude = 0.0; + + /* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis + * of ellipsoid (=center of mass), Latitude becomes PI/2 */ + if (RR / a < genau) { + Latitude = HALF_PI; + Height = -b; + return { + x: p.x, + y: p.y, + z: p.z + }; + } + } else { + /* ellipsoidal (geodetic) longitude + * interval: -PI < Longitude <= +PI */ + Longitude = Math.atan2(Y, X); + } + + /* -------------------------------------------------------------- + * Following iterative algorithm was developped by + * "Institut for Erdmessung", University of Hannover, July 1988. + * Internet: www.ife.uni-hannover.de + * Iterative computation of CPHI,SPHI and Height. + * Iteration of CPHI and SPHI to 10**-12 radian resp. + * 2*10**-7 arcsec. + * -------------------------------------------------------------- + */ + CT = Z / RR; + ST = P / RR; + RX = 1.0 / Math.sqrt(1.0 - es * (2.0 - es) * ST * ST); + CPHI0 = ST * (1.0 - es) * RX; + SPHI0 = CT * RX; + iter = 0; + + /* loop to find sin(Latitude) resp. Latitude + * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ + do { + iter++; + RN = a / Math.sqrt(1.0 - es * SPHI0 * SPHI0); + + /* ellipsoidal (geodetic) height */ + Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - es * SPHI0 * SPHI0); + + RK = es * RN / (RN + Height); + RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST); + CPHI = ST * (1.0 - RK) * RX; + SPHI = CT * RX; + SDPHI = SPHI * CPHI0 - CPHI * SPHI0; + CPHI0 = CPHI; + SPHI0 = SPHI; + } + while (SDPHI * SDPHI > genau2 && iter < maxiter); + + /* ellipsoidal (geodetic) latitude */ + Latitude = Math.atan(SPHI / Math.abs(CPHI)); + return { + x: Longitude, + y: Latitude, + z: Height + }; + } // cs_geocentric_to_geodetic() + + /****************************************************************/ + // pj_geocentic_to_wgs84( p ) + // p = point to transform in geocentric coordinates (x,y,z) + + + /** point object, nothing fancy, just allows values to be + passed back and forth by reference rather than by value. + Other point classes may be used as long as they have + x and y properties, which will get modified in the transform method. + */ + function geocentricToWgs84(p, datum_type, datum_params) { + + if (datum_type === PJD_3PARAM) { + // if( x[io] === HUGE_VAL ) + // continue; + return { + x: p.x + datum_params[0], + y: p.y + datum_params[1], + z: p.z + datum_params[2], + }; + } else if (datum_type === PJD_7PARAM) { + var Dx_BF = datum_params[0]; + var Dy_BF = datum_params[1]; + var Dz_BF = datum_params[2]; + var Rx_BF = datum_params[3]; + var Ry_BF = datum_params[4]; + var Rz_BF = datum_params[5]; + var M_BF = datum_params[6]; + // if( x[io] === HUGE_VAL ) + // continue; + return { + x: M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF, + y: M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF, + z: M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF + }; + } + } // cs_geocentric_to_wgs84 + + /****************************************************************/ + // pj_geocentic_from_wgs84() + // coordinate system definition, + // point to transform in geocentric coordinates (x,y,z) + function geocentricFromWgs84(p, datum_type, datum_params) { + + if (datum_type === PJD_3PARAM) { + //if( x[io] === HUGE_VAL ) + // continue; + return { + x: p.x - datum_params[0], + y: p.y - datum_params[1], + z: p.z - datum_params[2], + }; + + } else if (datum_type === PJD_7PARAM) { + var Dx_BF = datum_params[0]; + var Dy_BF = datum_params[1]; + var Dz_BF = datum_params[2]; + var Rx_BF = datum_params[3]; + var Ry_BF = datum_params[4]; + var Rz_BF = datum_params[5]; + var M_BF = datum_params[6]; + var x_tmp = (p.x - Dx_BF) / M_BF; + var y_tmp = (p.y - Dy_BF) / M_BF; + var z_tmp = (p.z - Dz_BF) / M_BF; + //if( x[io] === HUGE_VAL ) + // continue; + + return { + x: x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp, + y: -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp, + z: Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp + }; + } //cs_geocentric_from_wgs84() + } + + function checkParams(type) { + return (type === PJD_3PARAM || type === PJD_7PARAM); + } + + var datum_transform = function(source, dest, point) { + // Short cut if the datums are identical. + if (compareDatums(source, dest)) { + return point; // in this case, zero is sucess, + // whereas cs_compare_datums returns 1 to indicate TRUE + // confusing, should fix this + } + + // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest + if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) { + return point; + } + + // If this datum requires grid shifts, then apply it to geodetic coordinates. + var source_a = source.a; + var source_es = source.es; + if (source.datum_type === PJD_GRIDSHIFT) { + var gridShiftCode = applyGridShift(source, false, point); + if (gridShiftCode !== 0) { + return undefined; + } + source_a = SRS_WGS84_SEMIMAJOR; + source_es = SRS_WGS84_ESQUARED; + } + + var dest_a = dest.a; + var dest_b = dest.b; + var dest_es = dest.es; + if (dest.datum_type === PJD_GRIDSHIFT) { + dest_a = SRS_WGS84_SEMIMAJOR; + dest_b = SRS_WGS84_SEMIMINOR; + dest_es = SRS_WGS84_ESQUARED; + } + + // Do we need to go through geocentric coordinates? + if (source_es === dest_es && source_a === dest_a && !checkParams(source.datum_type) && !checkParams(dest.datum_type)) { + return point; + } + + // Convert to geocentric coordinates. + point = geodeticToGeocentric(point, source_es, source_a); + // Convert between datums + if (checkParams(source.datum_type)) { + point = geocentricToWgs84(point, source.datum_type, source.datum_params); + } + if (checkParams(dest.datum_type)) { + point = geocentricFromWgs84(point, dest.datum_type, dest.datum_params); + } + point = geocentricToGeodetic(point, dest_es, dest_a, dest_b); + + if (dest.datum_type === PJD_GRIDSHIFT) { + var destGridShiftResult = applyGridShift(dest, true, point); + if (destGridShiftResult !== 0) { + return undefined; + } + } + + return point; + }; + + function applyGridShift(source, inverse, point) { + if (source.grids === null || source.grids.length === 0) { + console.log('Grid shift grids not found'); + return -1; + } + var input = {x: -point.x, y: point.y}; + var output = {x: Number.NaN, y: Number.NaN}; + var attemptedGrids = []; + for (var i = 0; i < source.grids.length; i++) { + var grid = source.grids[i]; + attemptedGrids.push(grid.name); + if (grid.isNull) { + output = input; + break; + } + if (grid.grid === null) { + if (grid.mandatory) { + console.log("Unable to find mandatory grid '" + grid.name + "'"); + return -1; + } + continue; + } + var subgrid = grid.grid.subgrids[0]; + // skip tables that don't match our point at all + var epsilon = (Math.abs(subgrid.del[1]) + Math.abs(subgrid.del[0])) / 10000.0; + var minX = subgrid.ll[0] - epsilon; + var minY = subgrid.ll[1] - epsilon; + var maxX = subgrid.ll[0] + (subgrid.lim[0] - 1) * subgrid.del[0] + epsilon; + var maxY = subgrid.ll[1] + (subgrid.lim[1] - 1) * subgrid.del[1] + epsilon; + if (minY > input.y || minX > input.x || maxY < input.y || maxX < input.x ) { + continue; + } + output = applySubgridShift(input, inverse, subgrid); + if (!isNaN(output.x)) { + break; + } + } + if (isNaN(output.x)) { + console.log("Failed to find a grid shift table for location '"+ + -input.x * R2D + " " + input.y * R2D + " tried: '" + attemptedGrids + "'"); + return -1; + } + point.x = -output.x; + point.y = output.y; + return 0; + } + + function applySubgridShift(pin, inverse, ct) { + var val = {x: Number.NaN, y: Number.NaN}; + if (isNaN(pin.x)) { return val; } + var tb = {x: pin.x, y: pin.y}; + tb.x -= ct.ll[0]; + tb.y -= ct.ll[1]; + tb.x = adjust_lon(tb.x - Math.PI) + Math.PI; + var t = nadInterpolate(tb, ct); + if (inverse) { + if (isNaN(t.x)) { + return val; + } + t.x = tb.x - t.x; + t.y = tb.y - t.y; + var i = 9, tol = 1e-12; + var dif, del; + do { + del = nadInterpolate(t, ct); + if (isNaN(del.x)) { + console.log("Inverse grid shift iteration failed, presumably at grid edge. Using first approximation."); + break; + } + dif = {x: tb.x - (del.x + t.x), y: tb.y - (del.y + t.y)}; + t.x += dif.x; + t.y += dif.y; + } while (i-- && Math.abs(dif.x) > tol && Math.abs(dif.y) > tol); + if (i < 0) { + console.log("Inverse grid shift iterator failed to converge."); + return val; + } + val.x = adjust_lon(t.x + ct.ll[0]); + val.y = t.y + ct.ll[1]; + } else { + if (!isNaN(t.x)) { + val.x = pin.x + t.x; + val.y = pin.y + t.y; + } + } + return val; + } + + function nadInterpolate(pin, ct) { + var t = {x: pin.x / ct.del[0], y: pin.y / ct.del[1]}; + var indx = {x: Math.floor(t.x), y: Math.floor(t.y)}; + var frct = {x: t.x - 1.0 * indx.x, y: t.y - 1.0 * indx.y}; + var val= {x: Number.NaN, y: Number.NaN}; + var inx; + if (indx.x < 0 || indx.x >= ct.lim[0]) { + return val; + } + if (indx.y < 0 || indx.y >= ct.lim[1]) { + return val; + } + inx = (indx.y * ct.lim[0]) + indx.x; + var f00 = {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + inx++; + var f10= {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + inx += ct.lim[0]; + var f11 = {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + inx--; + var f01 = {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + var m11 = frct.x * frct.y, m10 = frct.x * (1.0 - frct.y), + m00 = (1.0 - frct.x) * (1.0 - frct.y), m01 = (1.0 - frct.x) * frct.y; + val.x = (m00 * f00.x + m10 * f10.x + m01 * f01.x + m11 * f11.x); + val.y = (m00 * f00.y + m10 * f10.y + m01 * f01.y + m11 * f11.y); + return val; + } + + var adjust_axis = function(crs, denorm, point) { + var xin = point.x, + yin = point.y, + zin = point.z || 0.0; + var v, t, i; + var out = {}; + for (i = 0; i < 3; i++) { + if (denorm && i === 2 && point.z === undefined) { + continue; + } + if (i === 0) { + v = xin; + if ("ew".indexOf(crs.axis[i]) !== -1) { + t = 'x'; + } else { + t = 'y'; + } + + } + else if (i === 1) { + v = yin; + if ("ns".indexOf(crs.axis[i]) !== -1) { + t = 'y'; + } else { + t = 'x'; + } + } + else { + v = zin; + t = 'z'; + } + switch (crs.axis[i]) { + case 'e': + out[t] = v; + break; + case 'w': + out[t] = -v; + break; + case 'n': + out[t] = v; + break; + case 's': + out[t] = -v; + break; + case 'u': + if (point[t] !== undefined) { + out.z = v; + } + break; + case 'd': + if (point[t] !== undefined) { + out.z = -v; + } + break; + default: + //console.log("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName); + return null; + } + } + return out; + }; + + var toPoint = function (array){ + var out = { + x: array[0], + y: array[1] + }; + if (array.length>2) { + out.z = array[2]; + } + if (array.length>3) { + out.m = array[3]; + } + return out; + }; + + var checkSanity = function (point) { + checkCoord(point.x); + checkCoord(point.y); + }; + function checkCoord(num) { + if (typeof Number.isFinite === 'function') { + if (Number.isFinite(num)) { + return; + } + throw new TypeError('coordinates must be finite numbers'); + } + if (typeof num !== 'number' || num !== num || !isFinite(num)) { + throw new TypeError('coordinates must be finite numbers'); + } + } + + function checkNotWGS(source, dest) { + return ( + (source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM || source.datum.datum_type === PJD_GRIDSHIFT) && dest.datumCode !== 'WGS84') || + ((dest.datum.datum_type === PJD_3PARAM || dest.datum.datum_type === PJD_7PARAM || dest.datum.datum_type === PJD_GRIDSHIFT) && source.datumCode !== 'WGS84'); + } + + function transform(source, dest, point, enforceAxis) { + var wgs84; + if (Array.isArray(point)) { + point = toPoint(point); + } else { + // Clone the point object so inputs don't get modified + point = { + x: point.x, + y: point.y, + z: point.z, + m: point.m + }; + } + var hasZ = point.z !== undefined; + checkSanity(point); + // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84 + if (source.datum && dest.datum && checkNotWGS(source, dest)) { + wgs84 = new Projection('WGS84'); + point = transform(source, wgs84, point, enforceAxis); + source = wgs84; + } + // DGR, 2010/11/12 + if (enforceAxis && source.axis !== 'enu') { + point = adjust_axis(source, false, point); + } + // Transform source points to long/lat, if they aren't already. + if (source.projName === 'longlat') { + point = { + x: point.x * D2R, + y: point.y * D2R, + z: point.z || 0 + }; + } else { + if (source.to_meter) { + point = { + x: point.x * source.to_meter, + y: point.y * source.to_meter, + z: point.z || 0 + }; + } + point = source.inverse(point); // Convert Cartesian to longlat + if (!point) { + return; + } + } + // Adjust for the prime meridian if necessary + if (source.from_greenwich) { + point.x += source.from_greenwich; + } + + // Convert datums if needed, and if possible. + point = datum_transform(source.datum, dest.datum, point); + if (!point) { + return; + } + + // Adjust for the prime meridian if necessary + if (dest.from_greenwich) { + point = { + x: point.x - dest.from_greenwich, + y: point.y, + z: point.z || 0 + }; + } + + if (dest.projName === 'longlat') { + // convert radians to decimal degrees + point = { + x: point.x * R2D, + y: point.y * R2D, + z: point.z || 0 + }; + } else { // else project + point = dest.forward(point); + if (dest.to_meter) { + point = { + x: point.x / dest.to_meter, + y: point.y / dest.to_meter, + z: point.z || 0 + }; + } + } + + // DGR, 2010/11/12 + if (enforceAxis && dest.axis !== 'enu') { + return adjust_axis(dest, true, point); + } + + if (!hasZ) { + delete point.z; + } + return point; + } + + var wgs84 = Projection('WGS84'); + + function transformer(from, to, coords, enforceAxis) { + var transformedArray, out, keys; + if (Array.isArray(coords)) { + transformedArray = transform(from, to, coords, enforceAxis) || {x: NaN, y: NaN}; + if (coords.length > 2) { + if ((typeof from.name !== 'undefined' && from.name === 'geocent') || (typeof to.name !== 'undefined' && to.name === 'geocent')) { + if (typeof transformedArray.z === 'number') { + return [transformedArray.x, transformedArray.y, transformedArray.z].concat(coords.splice(3)); + } else { + return [transformedArray.x, transformedArray.y, coords[2]].concat(coords.splice(3)); + } + } else { + return [transformedArray.x, transformedArray.y].concat(coords.splice(2)); + } + } else { + return [transformedArray.x, transformedArray.y]; + } + } else { + out = transform(from, to, coords, enforceAxis); + keys = Object.keys(coords); + if (keys.length === 2) { + return out; + } + keys.forEach(function (key) { + if ((typeof from.name !== 'undefined' && from.name === 'geocent') || (typeof to.name !== 'undefined' && to.name === 'geocent')) { + if (key === 'x' || key === 'y' || key === 'z') { + return; + } + } else { + if (key === 'x' || key === 'y') { + return; + } + } + out[key] = coords[key]; + }); + return out; + } + } + + function checkProj(item) { + if (item instanceof Projection) { + return item; + } + if (item.oProj) { + return item.oProj; + } + return Projection(item); + } + + function proj4$1(fromProj, toProj, coord) { + fromProj = checkProj(fromProj); + var single = false; + var obj; + if (typeof toProj === 'undefined') { + toProj = fromProj; + fromProj = wgs84; + single = true; + } else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) { + coord = toProj; + toProj = fromProj; + fromProj = wgs84; + single = true; + } + toProj = checkProj(toProj); + if (coord) { + return transformer(fromProj, toProj, coord); + } else { + obj = { + forward: function (coords, enforceAxis) { + return transformer(fromProj, toProj, coords, enforceAxis); + }, + inverse: function (coords, enforceAxis) { + return transformer(toProj, fromProj, coords, enforceAxis); + } + }; + if (single) { + obj.oProj = toProj; + } + return obj; + } + } + + /** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ + var NUM_100K_SETS = 6; + + /** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ + var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + + /** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ + var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + + var A = 65; // A + var I = 73; // I + var O = 79; // O + var V = 86; // V + var Z = 90; // Z + var mgrs = { + forward: forward$1, + inverse: inverse$1, + toPoint: toPoint$1 + }; + /** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ + function forward$1(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({ + lat: ll[1], + lon: ll[0] + }), accuracy); + } + + /** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ + function inverse$1(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat, bbox.lon, bbox.lat]; + } + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; + } + + function toPoint$1(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat]; + } + return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2]; + } + /** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ + function degToRad(deg) { + return (deg * (Math.PI / 180.0)); + } + + /** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ + function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); + } + + /** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ + function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var k0 = 0.9996; + var LongOrigin; + var eccPrimeSquared; + var N, T, C, A, M; + var LatRad = degToRad(Lat); + var LongRad = degToRad(Long); + var LongOriginRad; + var ZoneNumber; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long === 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) { + ZoneNumber = 31; + } + else if (Long >= 9.0 && Long < 21.0) { + ZoneNumber = 33; + } + else if (Long >= 21.0 && Long < 33.0) { + ZoneNumber = 35; + } + else if (Long >= 33.0 && Long < 42.0) { + ZoneNumber = 37; + } + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + LongOriginRad = degToRad(LongOrigin); + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad)); + T = Math.tan(LatRad) * Math.tan(LatRad); + C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad); + A = Math.cos(LatRad) * (LongRad - LongOriginRad); + + M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.sin(6 * LatRad)); + + var UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; + } + + /** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ + function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var eccPrimeSquared; + var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared)); + var N1, T1, C1, R1, D, M; + var LongOrigin; + var mu, phi1Rad; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter < 'N') { + y -= 10000000.0; // remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + M = y / k0; + mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256)); + + phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad)); + T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad); + C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad); + R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5); + D = x / (N1 * k0); + + var lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720); + lat = radToDeg(lat); + + var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad); + lon = LongOrigin + radToDeg(lon); + + var result; + if (utm.accuracy) { + var topRight = UTMtoLL({ + northing: utm.northing + utm.accuracy, + easting: utm.easting + utm.accuracy, + zoneLetter: utm.zoneLetter, + zoneNumber: utm.zoneNumber + }); + result = { + top: topRight.lat, + right: topRight.lon, + bottom: lat, + left: lon + }; + } + else { + result = { + lat: lat, + lon: lon + }; + } + return result; + } + + /** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ + function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + var LetterDesignator = 'Z'; + + if ((84 >= lat) && (lat >= 72)) { + LetterDesignator = 'X'; + } + else if ((72 > lat) && (lat >= 64)) { + LetterDesignator = 'W'; + } + else if ((64 > lat) && (lat >= 56)) { + LetterDesignator = 'V'; + } + else if ((56 > lat) && (lat >= 48)) { + LetterDesignator = 'U'; + } + else if ((48 > lat) && (lat >= 40)) { + LetterDesignator = 'T'; + } + else if ((40 > lat) && (lat >= 32)) { + LetterDesignator = 'S'; + } + else if ((32 > lat) && (lat >= 24)) { + LetterDesignator = 'R'; + } + else if ((24 > lat) && (lat >= 16)) { + LetterDesignator = 'Q'; + } + else if ((16 > lat) && (lat >= 8)) { + LetterDesignator = 'P'; + } + else if ((8 > lat) && (lat >= 0)) { + LetterDesignator = 'N'; + } + else if ((0 > lat) && (lat >= -8)) { + LetterDesignator = 'M'; + } + else if ((-8 > lat) && (lat >= -16)) { + LetterDesignator = 'L'; + } + else if ((-16 > lat) && (lat >= -24)) { + LetterDesignator = 'K'; + } + else if ((-24 > lat) && (lat >= -32)) { + LetterDesignator = 'J'; + } + else if ((-32 > lat) && (lat >= -40)) { + LetterDesignator = 'H'; + } + else if ((-40 > lat) && (lat >= -48)) { + LetterDesignator = 'G'; + } + else if ((-48 > lat) && (lat >= -56)) { + LetterDesignator = 'F'; + } + else if ((-56 > lat) && (lat >= -64)) { + LetterDesignator = 'E'; + } + else if ((-64 > lat) && (lat >= -72)) { + LetterDesignator = 'D'; + } + else if ((-72 > lat) && (lat >= -80)) { + LetterDesignator = 'C'; + } + return LetterDesignator; + } + + /** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ + function encode(utm, accuracy) { + // prepend with leading zeroes + var seasting = "00000" + utm.easting, + snorthing = "00000" + utm.northing; + + return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy); + } + + /** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ + function get100kID(easting, northing, zoneNumber) { + var setParm = get100kSetForZone(zoneNumber); + var setColumn = Math.floor(easting / 100000); + var setRow = Math.floor(northing / 100000) % 20; + return getLetter100kID(setColumn, setRow, setParm); + } + + /** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ + function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm === 0) { + setParm = NUM_100K_SETS; + } + + return setParm; + } + + /** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ + function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm - 1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + var colInt = colOrigin + column - 1; + var rowInt = rowOrigin + row; + var rollover = false; + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + rollover = true; + } + + if (colInt === I || (colOrigin < I && colInt > I) || ((colInt > I || colOrigin < I) && rollover)) { + colInt++; + } + + if (colInt === O || (colOrigin < O && colInt > O) || ((colInt > O || colOrigin < O) && rollover)) { + colInt++; + + if (colInt === I) { + colInt++; + } + } + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + rollover = true; + } + else { + rollover = false; + } + + if (((rowInt === I) || ((rowOrigin < I) && (rowInt > I))) || (((rowInt > I) || (rowOrigin < I)) && rollover)) { + rowInt++; + } + + if (((rowInt === O) || ((rowOrigin < O) && (rowInt > O))) || (((rowInt > O) || (rowOrigin < O)) && rollover)) { + rowInt++; + + if (rowInt === I) { + rowInt++; + } + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + } + + var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt); + return twoLetter; + } + + /** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ + function decode(mgrsString) { + + if (mgrsString && mgrsString.length === 0) { + throw ("MGRSPoint coverting from nothing"); + } + + var length = mgrsString.length; + + var hunK = null; + var sb = ""; + var testChar; + var i = 0; + + // get Zone number + while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) { + if (i >= 2) { + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + sb += testChar; + i++; + } + + var zoneNumber = parseInt(sb, 10); + + if (i === 0 || i + 3 > length) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') { + throw ("MGRSPoint zone letter " + zoneLetter + " not handled: " + mgrsString); + } + + hunK = mgrsString.substring(i, i += 2); + + var set = get100kSetForZone(zoneNumber); + + var east100k = getEastingFromChar(hunK.charAt(0), set); + var north100k = getNorthingFromChar(hunK.charAt(1), set); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + var remainder = length - i; + + if (remainder % 2 !== 0) { + throw ("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters" + mgrsString); + } + + var sep = remainder / 2; + + var sepEasting = 0.0; + var sepNorthing = 0.0; + var accuracyBonus, sepEastingString, sepNorthingString, easting, northing; + if (sep > 0) { + accuracyBonus = 100000.0 / Math.pow(10, sep); + sepEastingString = mgrsString.substring(i, i + sep); + sepEasting = parseFloat(sepEastingString) * accuracyBonus; + sepNorthingString = mgrsString.substring(i + sep); + sepNorthing = parseFloat(sepNorthingString) * accuracyBonus; + } + + easting = sepEasting + east100k; + northing = sepNorthing + north100k; + + return { + easting: easting, + northing: northing, + zoneLetter: zoneLetter, + zoneNumber: zoneNumber, + accuracy: accuracyBonus + }; + } + + /** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ + function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + var rewindMarker = false; + + while (curCol !== e.charCodeAt(0)) { + curCol++; + if (curCol === I) { + curCol++; + } + if (curCol === O) { + curCol++; + } + if (curCol > Z) { + if (rewindMarker) { + throw ("Bad character: " + e); + } + curCol = A; + rewindMarker = true; + } + eastingValue += 100000.0; + } + + return eastingValue; + } + + /** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ + function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw ("MGRSPoint given invalid Northing " + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow !== n.charCodeAt(0)) { + curRow++; + if (curRow === I) { + curRow++; + } + if (curRow === O) { + curRow++; + } + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw ("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; + } + + /** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ + function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } + else { + throw ("Invalid zone letter: " + zoneLetter); + } + + } + + function Point(x, y, z) { + if (!(this instanceof Point)) { + return new Point(x, y, z); + } + if (Array.isArray(x)) { + this.x = x[0]; + this.y = x[1]; + this.z = x[2] || 0.0; + } else if(typeof x === 'object') { + this.x = x.x; + this.y = x.y; + this.z = x.z || 0.0; + } else if (typeof x === 'string' && typeof y === 'undefined') { + var coords = x.split(','); + this.x = parseFloat(coords[0], 10); + this.y = parseFloat(coords[1], 10); + this.z = parseFloat(coords[2], 10) || 0.0; + } else { + this.x = x; + this.y = y; + this.z = z || 0.0; + } + console.warn('proj4.Point will be removed in version 3, use proj4.toPoint'); + } + + Point.fromMGRS = function(mgrsStr) { + return new Point(toPoint$1(mgrsStr)); + }; + Point.prototype.toMGRS = function(accuracy) { + return forward$1([this.x, this.y], accuracy); + }; + + var C00 = 1; + var C02 = 0.25; + var C04 = 0.046875; + var C06 = 0.01953125; + var C08 = 0.01068115234375; + var C22 = 0.75; + var C44 = 0.46875; + var C46 = 0.01302083333333333333; + var C48 = 0.00712076822916666666; + var C66 = 0.36458333333333333333; + var C68 = 0.00569661458333333333; + var C88 = 0.3076171875; + + var pj_enfn = function(es) { + var en = []; + en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08))); + en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08))); + var t = es * es; + en[2] = t * (C44 - es * (C46 + es * C48)); + t *= es; + en[3] = t * (C66 - es * C68); + en[4] = t * es * C88; + return en; + }; + + var pj_mlfn = function(phi, sphi, cphi, en) { + cphi *= sphi; + sphi *= sphi; + return (en[0] * phi - cphi * (en[1] + sphi * (en[2] + sphi * (en[3] + sphi * en[4])))); + }; + + var MAX_ITER = 20; + + var pj_inv_mlfn = function(arg, es, en) { + var k = 1 / (1 - es); + var phi = arg; + for (var i = MAX_ITER; i; --i) { /* rarely goes over 2 iterations */ + var s = Math.sin(phi); + var t = 1 - es * s * s; + //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg; + //phi -= t * (t * Math.sqrt(t)) * k; + t = (pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k; + phi -= t; + if (Math.abs(t) < EPSLN) { + return phi; + } + } + //..reportError("cass:pj_inv_mlfn: Convergence error"); + return phi; + }; + + // Heavily based on this tmerc projection implementation + // https://github.com/mbloch/mapshaper-proj/blob/master/src/projections/tmerc.js + + function init$2() { + this.x0 = this.x0 !== undefined ? this.x0 : 0; + this.y0 = this.y0 !== undefined ? this.y0 : 0; + this.long0 = this.long0 !== undefined ? this.long0 : 0; + this.lat0 = this.lat0 !== undefined ? this.lat0 : 0; + + if (this.es) { + this.en = pj_enfn(this.es); + this.ml0 = pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en); + } + } + + /** + Transverse Mercator Forward - long/lat to x/y + long/lat in radians + */ + function forward$2(p) { + var lon = p.x; + var lat = p.y; + + var delta_lon = adjust_lon(lon - this.long0); + var con; + var x, y; + var sin_phi = Math.sin(lat); + var cos_phi = Math.cos(lat); + + if (!this.es) { + var b = cos_phi * Math.sin(delta_lon); + + if ((Math.abs(Math.abs(b) - 1)) < EPSLN) { + return (93); + } + else { + x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b)) + this.x0; + y = cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - Math.pow(b, 2)); + b = Math.abs(y); + + if (b >= 1) { + if ((b - 1) > EPSLN) { + return (93); + } + else { + y = 0; + } + } + else { + y = Math.acos(y); + } + + if (lat < 0) { + y = -y; + } + + y = this.a * this.k0 * (y - this.lat0) + this.y0; + } + } + else { + var al = cos_phi * delta_lon; + var als = Math.pow(al, 2); + var c = this.ep2 * Math.pow(cos_phi, 2); + var cs = Math.pow(c, 2); + var tq = Math.abs(cos_phi) > EPSLN ? Math.tan(lat) : 0; + var t = Math.pow(tq, 2); + var ts = Math.pow(t, 2); + con = 1 - this.es * Math.pow(sin_phi, 2); + al = al / Math.sqrt(con); + var ml = pj_mlfn(lat, sin_phi, cos_phi, this.en); + + x = this.a * (this.k0 * al * (1 + + als / 6 * (1 - t + c + + als / 20 * (5 - 18 * t + ts + 14 * c - 58 * t * c + + als / 42 * (61 + 179 * ts - ts * t - 479 * t))))) + + this.x0; + + y = this.a * (this.k0 * (ml - this.ml0 + + sin_phi * delta_lon * al / 2 * (1 + + als / 12 * (5 - t + 9 * c + 4 * cs + + als / 30 * (61 + ts - 58 * t + 270 * c - 330 * t * c + + als / 56 * (1385 + 543 * ts - ts * t - 3111 * t)))))) + + this.y0; + } + + p.x = x; + p.y = y; + + return p; + } + + /** + Transverse Mercator Inverse - x/y to long/lat + */ + function inverse$2(p) { + var con, phi; + var lat, lon; + var x = (p.x - this.x0) * (1 / this.a); + var y = (p.y - this.y0) * (1 / this.a); + + if (!this.es) { + var f = Math.exp(x / this.k0); + var g = 0.5 * (f - 1 / f); + var temp = this.lat0 + y / this.k0; + var h = Math.cos(temp); + con = Math.sqrt((1 - Math.pow(h, 2)) / (1 + Math.pow(g, 2))); + lat = Math.asin(con); + + if (y < 0) { + lat = -lat; + } + + if ((g === 0) && (h === 0)) { + lon = 0; + } + else { + lon = adjust_lon(Math.atan2(g, h) + this.long0); + } + } + else { // ellipsoidal form + con = this.ml0 + y / this.k0; + phi = pj_inv_mlfn(con, this.es, this.en); + + if (Math.abs(phi) < HALF_PI) { + var sin_phi = Math.sin(phi); + var cos_phi = Math.cos(phi); + var tan_phi = Math.abs(cos_phi) > EPSLN ? Math.tan(phi) : 0; + var c = this.ep2 * Math.pow(cos_phi, 2); + var cs = Math.pow(c, 2); + var t = Math.pow(tan_phi, 2); + var ts = Math.pow(t, 2); + con = 1 - this.es * Math.pow(sin_phi, 2); + var d = x * Math.sqrt(con) / this.k0; + var ds = Math.pow(d, 2); + con = con * tan_phi; + + lat = phi - (con * ds / (1 - this.es)) * 0.5 * (1 - + ds / 12 * (5 + 3 * t - 9 * c * t + c - 4 * cs - + ds / 30 * (61 + 90 * t - 252 * c * t + 45 * ts + 46 * c - + ds / 56 * (1385 + 3633 * t + 4095 * ts + 1574 * ts * t)))); + + lon = adjust_lon(this.long0 + (d * (1 - + ds / 6 * (1 + 2 * t + c - + ds / 20 * (5 + 28 * t + 24 * ts + 8 * c * t + 6 * c - + ds / 42 * (61 + 662 * t + 1320 * ts + 720 * ts * t)))) / cos_phi)); + } + else { + lat = HALF_PI * sign(y); + lon = 0; + } + } + + p.x = lon; + p.y = lat; + + return p; + } + + var names$3 = ["Fast_Transverse_Mercator", "Fast Transverse Mercator"]; + var tmerc = { + init: init$2, + forward: forward$2, + inverse: inverse$2, + names: names$3 + }; + + var sinh = function(x) { + var r = Math.exp(x); + r = (r - 1 / r) / 2; + return r; + }; + + var hypot = function(x, y) { + x = Math.abs(x); + y = Math.abs(y); + var a = Math.max(x, y); + var b = Math.min(x, y) / (a ? a : 1); + + return a * Math.sqrt(1 + Math.pow(b, 2)); + }; + + var log1py = function(x) { + var y = 1 + x; + var z = y - 1; + + return z === 0 ? x : x * Math.log(y) / z; + }; + + var asinhy = function(x) { + var y = Math.abs(x); + y = log1py(y * (1 + y / (hypot(1, y) + 1))); + + return x < 0 ? -y : y; + }; + + var gatg = function(pp, B) { + var cos_2B = 2 * Math.cos(2 * B); + var i = pp.length - 1; + var h1 = pp[i]; + var h2 = 0; + var h; + + while (--i >= 0) { + h = -h2 + cos_2B * h1 + pp[i]; + h2 = h1; + h1 = h; + } + + return (B + h * Math.sin(2 * B)); + }; + + var clens = function(pp, arg_r) { + var r = 2 * Math.cos(arg_r); + var i = pp.length - 1; + var hr1 = pp[i]; + var hr2 = 0; + var hr; + + while (--i >= 0) { + hr = -hr2 + r * hr1 + pp[i]; + hr2 = hr1; + hr1 = hr; + } + + return Math.sin(arg_r) * hr; + }; + + var cosh = function(x) { + var r = Math.exp(x); + r = (r + 1 / r) / 2; + return r; + }; + + var clens_cmplx = function(pp, arg_r, arg_i) { + var sin_arg_r = Math.sin(arg_r); + var cos_arg_r = Math.cos(arg_r); + var sinh_arg_i = sinh(arg_i); + var cosh_arg_i = cosh(arg_i); + var r = 2 * cos_arg_r * cosh_arg_i; + var i = -2 * sin_arg_r * sinh_arg_i; + var j = pp.length - 1; + var hr = pp[j]; + var hi1 = 0; + var hr1 = 0; + var hi = 0; + var hr2; + var hi2; + + while (--j >= 0) { + hr2 = hr1; + hi2 = hi1; + hr1 = hr; + hi1 = hi; + hr = -hr2 + r * hr1 - i * hi1 + pp[j]; + hi = -hi2 + i * hr1 + r * hi1; + } + + r = sin_arg_r * cosh_arg_i; + i = cos_arg_r * sinh_arg_i; + + return [r * hr - i * hi, r * hi + i * hr]; + }; + + // Heavily based on this etmerc projection implementation + // https://github.com/mbloch/mapshaper-proj/blob/master/src/projections/etmerc.js + + function init$3() { + if (!this.approx && (isNaN(this.es) || this.es <= 0)) { + throw new Error('Incorrect elliptical usage. Try using the +approx option in the proj string, or PROJECTION["Fast_Transverse_Mercator"] in the WKT.'); + } + if (this.approx) { + // When '+approx' is set, use tmerc instead + tmerc.init.apply(this); + this.forward = tmerc.forward; + this.inverse = tmerc.inverse; + } + + this.x0 = this.x0 !== undefined ? this.x0 : 0; + this.y0 = this.y0 !== undefined ? this.y0 : 0; + this.long0 = this.long0 !== undefined ? this.long0 : 0; + this.lat0 = this.lat0 !== undefined ? this.lat0 : 0; + + this.cgb = []; + this.cbg = []; + this.utg = []; + this.gtu = []; + + var f = this.es / (1 + Math.sqrt(1 - this.es)); + var n = f / (2 - f); + var np = n; + + this.cgb[0] = n * (2 + n * (-2 / 3 + n * (-2 + n * (116 / 45 + n * (26 / 45 + n * (-2854 / 675 )))))); + this.cbg[0] = n * (-2 + n * ( 2 / 3 + n * ( 4 / 3 + n * (-82 / 45 + n * (32 / 45 + n * (4642 / 4725)))))); + + np = np * n; + this.cgb[1] = np * (7 / 3 + n * (-8 / 5 + n * (-227 / 45 + n * (2704 / 315 + n * (2323 / 945))))); + this.cbg[1] = np * (5 / 3 + n * (-16 / 15 + n * ( -13 / 9 + n * (904 / 315 + n * (-1522 / 945))))); + + np = np * n; + this.cgb[2] = np * (56 / 15 + n * (-136 / 35 + n * (-1262 / 105 + n * (73814 / 2835)))); + this.cbg[2] = np * (-26 / 15 + n * (34 / 21 + n * (8 / 5 + n * (-12686 / 2835)))); + + np = np * n; + this.cgb[3] = np * (4279 / 630 + n * (-332 / 35 + n * (-399572 / 14175))); + this.cbg[3] = np * (1237 / 630 + n * (-12 / 5 + n * ( -24832 / 14175))); + + np = np * n; + this.cgb[4] = np * (4174 / 315 + n * (-144838 / 6237)); + this.cbg[4] = np * (-734 / 315 + n * (109598 / 31185)); + + np = np * n; + this.cgb[5] = np * (601676 / 22275); + this.cbg[5] = np * (444337 / 155925); + + np = Math.pow(n, 2); + this.Qn = this.k0 / (1 + n) * (1 + np * (1 / 4 + np * (1 / 64 + np / 256))); + + this.utg[0] = n * (-0.5 + n * ( 2 / 3 + n * (-37 / 96 + n * ( 1 / 360 + n * (81 / 512 + n * (-96199 / 604800)))))); + this.gtu[0] = n * (0.5 + n * (-2 / 3 + n * (5 / 16 + n * (41 / 180 + n * (-127 / 288 + n * (7891 / 37800)))))); + + this.utg[1] = np * (-1 / 48 + n * (-1 / 15 + n * (437 / 1440 + n * (-46 / 105 + n * (1118711 / 3870720))))); + this.gtu[1] = np * (13 / 48 + n * (-3 / 5 + n * (557 / 1440 + n * (281 / 630 + n * (-1983433 / 1935360))))); + + np = np * n; + this.utg[2] = np * (-17 / 480 + n * (37 / 840 + n * (209 / 4480 + n * (-5569 / 90720 )))); + this.gtu[2] = np * (61 / 240 + n * (-103 / 140 + n * (15061 / 26880 + n * (167603 / 181440)))); + + np = np * n; + this.utg[3] = np * (-4397 / 161280 + n * (11 / 504 + n * (830251 / 7257600))); + this.gtu[3] = np * (49561 / 161280 + n * (-179 / 168 + n * (6601661 / 7257600))); + + np = np * n; + this.utg[4] = np * (-4583 / 161280 + n * (108847 / 3991680)); + this.gtu[4] = np * (34729 / 80640 + n * (-3418889 / 1995840)); + + np = np * n; + this.utg[5] = np * (-20648693 / 638668800); + this.gtu[5] = np * (212378941 / 319334400); + + var Z = gatg(this.cbg, this.lat0); + this.Zb = -this.Qn * (Z + clens(this.gtu, 2 * Z)); + } + + function forward$3(p) { + var Ce = adjust_lon(p.x - this.long0); + var Cn = p.y; + + Cn = gatg(this.cbg, Cn); + var sin_Cn = Math.sin(Cn); + var cos_Cn = Math.cos(Cn); + var sin_Ce = Math.sin(Ce); + var cos_Ce = Math.cos(Ce); + + Cn = Math.atan2(sin_Cn, cos_Ce * cos_Cn); + Ce = Math.atan2(sin_Ce * cos_Cn, hypot(sin_Cn, cos_Cn * cos_Ce)); + Ce = asinhy(Math.tan(Ce)); + + var tmp = clens_cmplx(this.gtu, 2 * Cn, 2 * Ce); + + Cn = Cn + tmp[0]; + Ce = Ce + tmp[1]; + + var x; + var y; + + if (Math.abs(Ce) <= 2.623395162778) { + x = this.a * (this.Qn * Ce) + this.x0; + y = this.a * (this.Qn * Cn + this.Zb) + this.y0; + } + else { + x = Infinity; + y = Infinity; + } + + p.x = x; + p.y = y; + + return p; + } + + function inverse$3(p) { + var Ce = (p.x - this.x0) * (1 / this.a); + var Cn = (p.y - this.y0) * (1 / this.a); + + Cn = (Cn - this.Zb) / this.Qn; + Ce = Ce / this.Qn; + + var lon; + var lat; + + if (Math.abs(Ce) <= 2.623395162778) { + var tmp = clens_cmplx(this.utg, 2 * Cn, 2 * Ce); + + Cn = Cn + tmp[0]; + Ce = Ce + tmp[1]; + Ce = Math.atan(sinh(Ce)); + + var sin_Cn = Math.sin(Cn); + var cos_Cn = Math.cos(Cn); + var sin_Ce = Math.sin(Ce); + var cos_Ce = Math.cos(Ce); + + Cn = Math.atan2(sin_Cn * cos_Ce, hypot(sin_Ce, cos_Ce * cos_Cn)); + Ce = Math.atan2(sin_Ce, cos_Ce * cos_Cn); + + lon = adjust_lon(Ce + this.long0); + lat = gatg(this.cgb, Cn); + } + else { + lon = Infinity; + lat = Infinity; + } + + p.x = lon; + p.y = lat; + + return p; + } + + var names$4 = ["Extended_Transverse_Mercator", "Extended Transverse Mercator", "etmerc", "Transverse_Mercator", "Transverse Mercator", "tmerc"]; + var etmerc = { + init: init$3, + forward: forward$3, + inverse: inverse$3, + names: names$4 + }; + + var adjust_zone = function(zone, lon) { + if (zone === undefined) { + zone = Math.floor((adjust_lon(lon) + Math.PI) * 30 / Math.PI) + 1; + + if (zone < 0) { + return 0; + } else if (zone > 60) { + return 60; + } + } + return zone; + }; + + var dependsOn = 'etmerc'; + function init$4() { + var zone = adjust_zone(this.zone, this.long0); + if (zone === undefined) { + throw new Error('unknown utm zone'); + } + this.lat0 = 0; + this.long0 = ((6 * Math.abs(zone)) - 183) * D2R; + this.x0 = 500000; + this.y0 = this.utmSouth ? 10000000 : 0; + this.k0 = 0.9996; + + etmerc.init.apply(this); + this.forward = etmerc.forward; + this.inverse = etmerc.inverse; + } + + var names$5 = ["Universal Transverse Mercator System", "utm"]; + var utm = { + init: init$4, + names: names$5, + dependsOn: dependsOn + }; + + var srat = function(esinp, exp) { + return (Math.pow((1 - esinp) / (1 + esinp), exp)); + }; + + var MAX_ITER$1 = 20; + function init$6() { + var sphi = Math.sin(this.lat0); + var cphi = Math.cos(this.lat0); + cphi *= cphi; + this.rc = Math.sqrt(1 - this.es) / (1 - this.es * sphi * sphi); + this.C = Math.sqrt(1 + this.es * cphi * cphi / (1 - this.es)); + this.phic0 = Math.asin(sphi / this.C); + this.ratexp = 0.5 * this.C * this.e; + this.K = Math.tan(0.5 * this.phic0 + FORTPI) / (Math.pow(Math.tan(0.5 * this.lat0 + FORTPI), this.C) * srat(this.e * sphi, this.ratexp)); + } + + function forward$5(p) { + var lon = p.x; + var lat = p.y; + + p.y = 2 * Math.atan(this.K * Math.pow(Math.tan(0.5 * lat + FORTPI), this.C) * srat(this.e * Math.sin(lat), this.ratexp)) - HALF_PI; + p.x = this.C * lon; + return p; + } + + function inverse$5(p) { + var DEL_TOL = 1e-14; + var lon = p.x / this.C; + var lat = p.y; + var num = Math.pow(Math.tan(0.5 * lat + FORTPI) / this.K, 1 / this.C); + for (var i = MAX_ITER$1; i > 0; --i) { + lat = 2 * Math.atan(num * srat(this.e * Math.sin(p.y), - 0.5 * this.e)) - HALF_PI; + if (Math.abs(lat - p.y) < DEL_TOL) { + break; + } + p.y = lat; + } + /* convergence failed */ + if (!i) { + return null; + } + p.x = lon; + p.y = lat; + return p; + } + + var names$7 = ["gauss"]; + var gauss = { + init: init$6, + forward: forward$5, + inverse: inverse$5, + names: names$7 + }; + + function init$5() { + gauss.init.apply(this); + if (!this.rc) { + return; + } + this.sinc0 = Math.sin(this.phic0); + this.cosc0 = Math.cos(this.phic0); + this.R2 = 2 * this.rc; + if (!this.title) { + this.title = "Oblique Stereographic Alternative"; + } + } + + function forward$4(p) { + var sinc, cosc, cosl, k; + p.x = adjust_lon(p.x - this.long0); + gauss.forward.apply(this, [p]); + sinc = Math.sin(p.y); + cosc = Math.cos(p.y); + cosl = Math.cos(p.x); + k = this.k0 * this.R2 / (1 + this.sinc0 * sinc + this.cosc0 * cosc * cosl); + p.x = k * cosc * Math.sin(p.x); + p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl); + p.x = this.a * p.x + this.x0; + p.y = this.a * p.y + this.y0; + return p; + } + + function inverse$4(p) { + var sinc, cosc, lon, lat, rho; + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + if ((rho = Math.sqrt(p.x * p.x + p.y * p.y))) { + var c = 2 * Math.atan2(rho, this.R2); + sinc = Math.sin(c); + cosc = Math.cos(c); + lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho); + lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc); + } + else { + lat = this.phic0; + lon = 0; + } + + p.x = lon; + p.y = lat; + gauss.inverse.apply(this, [p]); + p.x = adjust_lon(p.x + this.long0); + return p; + } + + var names$6 = ["Stereographic_North_Pole", "Oblique_Stereographic", "Polar_Stereographic", "sterea","Oblique Stereographic Alternative","Double_Stereographic"]; + var sterea = { + init: init$5, + forward: forward$4, + inverse: inverse$4, + names: names$6 + }; + + function ssfn_(phit, sinphi, eccen) { + sinphi *= eccen; + return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen)); + } + + function init$7() { + this.coslat0 = Math.cos(this.lat0); + this.sinlat0 = Math.sin(this.lat0); + if (this.sphere) { + if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) { + this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts)); + } + } + else { + if (Math.abs(this.coslat0) <= EPSLN) { + if (this.lat0 > 0) { + //North pole + //trace('stere:north pole'); + this.con = 1; + } + else { + //South pole + //trace('stere:south pole'); + this.con = -1; + } + } + this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e)); + if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) { + this.k0 = 0.5 * this.cons * msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)) / tsfnz(this.e, this.con * this.lat_ts, this.con * Math.sin(this.lat_ts)); + } + this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0); + this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI; + this.cosX0 = Math.cos(this.X0); + this.sinX0 = Math.sin(this.X0); + } + } + + // Stereographic forward equations--mapping lat,long to x,y + function forward$6(p) { + var lon = p.x; + var lat = p.y; + var sinlat = Math.sin(lat); + var coslat = Math.cos(lat); + var A, X, sinX, cosX, ts, rh; + var dlon = adjust_lon(lon - this.long0); + + if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) { + //case of the origine point + //trace('stere:this is the origin point'); + p.x = NaN; + p.y = NaN; + return p; + } + if (this.sphere) { + //trace('stere:sphere case'); + A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon)); + p.x = this.a * A * coslat * Math.sin(dlon) + this.x0; + p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0; + return p; + } + else { + X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI; + cosX = Math.cos(X); + sinX = Math.sin(X); + if (Math.abs(this.coslat0) <= EPSLN) { + ts = tsfnz(this.e, lat * this.con, this.con * sinlat); + rh = 2 * this.a * this.k0 * ts / this.cons; + p.x = this.x0 + rh * Math.sin(lon - this.long0); + p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0); + //trace(p.toString()); + return p; + } + else if (Math.abs(this.sinlat0) < EPSLN) { + //Eq + //trace('stere:equateur'); + A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon)); + p.y = A * sinX; + } + else { + //other case + //trace('stere:normal case'); + A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon))); + p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0; + } + p.x = A * cosX * Math.sin(dlon) + this.x0; + } + //trace(p.toString()); + return p; + } + + //* Stereographic inverse equations--mapping x,y to lat/long + function inverse$6(p) { + p.x -= this.x0; + p.y -= this.y0; + var lon, lat, ts, ce, Chi; + var rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (this.sphere) { + var c = 2 * Math.atan(rh / (2 * this.a * this.k0)); + lon = this.long0; + lat = this.lat0; + if (rh <= EPSLN) { + p.x = lon; + p.y = lat; + return p; + } + lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh); + if (Math.abs(this.coslat0) < EPSLN) { + if (this.lat0 > 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y)); + } + else { + lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y)); + } + } + else { + lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(c), rh * this.coslat0 * Math.cos(c) - p.y * this.sinlat0 * Math.sin(c))); + } + p.x = lon; + p.y = lat; + return p; + } + else { + if (Math.abs(this.coslat0) <= EPSLN) { + if (rh <= EPSLN) { + lat = this.lat0; + lon = this.long0; + p.x = lon; + p.y = lat; + //trace(p.toString()); + return p; + } + p.x *= this.con; + p.y *= this.con; + ts = rh * this.cons / (2 * this.a * this.k0); + lat = this.con * phi2z(this.e, ts); + lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y)); + } + else { + ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1)); + lon = this.long0; + if (rh <= EPSLN) { + Chi = this.X0; + } + else { + Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh); + lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(ce), rh * this.cosX0 * Math.cos(ce) - p.y * this.sinX0 * Math.sin(ce))); + } + lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi))); + } + } + p.x = lon; + p.y = lat; + + //trace(p.toString()); + return p; + + } + + var names$8 = ["stere", "Stereographic_South_Pole", "Polar Stereographic (variant B)"]; + var stere = { + init: init$7, + forward: forward$6, + inverse: inverse$6, + names: names$8, + ssfn_: ssfn_ + }; + + /* + references: + Formules et constantes pour le Calcul pour la + projection cylindrique conforme à axe oblique et pour la transformation entre + des systèmes de référence. + http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf + */ + + function init$8() { + var phy0 = this.lat0; + this.lambda0 = this.long0; + var sinPhy0 = Math.sin(phy0); + var semiMajorAxis = this.a; + var invF = this.rf; + var flattening = 1 / invF; + var e2 = 2 * flattening - Math.pow(flattening, 2); + var e = this.e = Math.sqrt(e2); + this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2)); + this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4)); + this.b0 = Math.asin(sinPhy0 / this.alpha); + var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2)); + var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2)); + var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0)); + this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3; + } + + function forward$7(p) { + var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2)); + var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y))); + var S = -this.alpha * (Sa1 + Sa2) + this.K; + + // spheric latitude + var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4); + + // spheric longitude + var I = this.alpha * (p.x - this.lambda0); + + // psoeudo equatorial rotation + var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I))); + + var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I)); + + p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0; + p.x = this.R * rotI + this.x0; + return p; + } + + function inverse$7(p) { + var Y = p.x - this.x0; + var X = p.y - this.y0; + + var rotI = Y / this.R; + var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4); + + var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI)); + var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB))); + + var lambda = this.lambda0 + I / this.alpha; + + var S = 0; + var phy = b; + var prevPhy = -1000; + var iteration = 0; + while (Math.abs(phy - prevPhy) > 0.0000001) { + if (++iteration > 20) { + //...reportError("omercFwdInfinity"); + return; + } + //S = Math.log(Math.tan(Math.PI / 4 + phy / 2)); + S = 1 / this.alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - this.K) + this.e * Math.log(Math.tan(Math.PI / 4 + Math.asin(this.e * Math.sin(phy)) / 2)); + prevPhy = phy; + phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2; + } + + p.x = lambda; + p.y = phy; + return p; + } + + var names$9 = ["somerc"]; + var somerc = { + init: init$8, + forward: forward$7, + inverse: inverse$7, + names: names$9 + }; + + var TOL = 1e-7; + + function isTypeA(P) { + var typeAProjections = ['Hotine_Oblique_Mercator','Hotine_Oblique_Mercator_Azimuth_Natural_Origin']; + var projectionName = typeof P.PROJECTION === "object" ? Object.keys(P.PROJECTION)[0] : P.PROJECTION; + + return 'no_uoff' in P || 'no_off' in P || typeAProjections.indexOf(projectionName) !== -1; + } + + + /* Initialize the Oblique Mercator projection + ------------------------------------------*/ + function init$9() { + var con, com, cosph0, D, F, H, L, sinph0, p, J, gamma = 0, + gamma0, lamc = 0, lam1 = 0, lam2 = 0, phi1 = 0, phi2 = 0, alpha_c = 0; + + // only Type A uses the no_off or no_uoff property + // https://github.com/OSGeo/proj.4/issues/104 + this.no_off = isTypeA(this); + this.no_rot = 'no_rot' in this; + + var alp = false; + if ("alpha" in this) { + alp = true; + } + + var gam = false; + if ("rectified_grid_angle" in this) { + gam = true; + } + + if (alp) { + alpha_c = this.alpha; + } + + if (gam) { + gamma = (this.rectified_grid_angle * D2R); + } + + if (alp || gam) { + lamc = this.longc; + } else { + lam1 = this.long1; + phi1 = this.lat1; + lam2 = this.long2; + phi2 = this.lat2; + + if (Math.abs(phi1 - phi2) <= TOL || (con = Math.abs(phi1)) <= TOL || + Math.abs(con - HALF_PI) <= TOL || Math.abs(Math.abs(this.lat0) - HALF_PI) <= TOL || + Math.abs(Math.abs(phi2) - HALF_PI) <= TOL) { + throw new Error(); + } + } + + var one_es = 1.0 - this.es; + com = Math.sqrt(one_es); + + if (Math.abs(this.lat0) > EPSLN) { + sinph0 = Math.sin(this.lat0); + cosph0 = Math.cos(this.lat0); + con = 1 - this.es * sinph0 * sinph0; + this.B = cosph0 * cosph0; + this.B = Math.sqrt(1 + this.es * this.B * this.B / one_es); + this.A = this.B * this.k0 * com / con; + D = this.B * com / (cosph0 * Math.sqrt(con)); + F = D * D -1; + + if (F <= 0) { + F = 0; + } else { + F = Math.sqrt(F); + if (this.lat0 < 0) { + F = -F; + } + } + + this.E = F += D; + this.E *= Math.pow(tsfnz(this.e, this.lat0, sinph0), this.B); + } else { + this.B = 1 / com; + this.A = this.k0; + this.E = D = F = 1; + } + + if (alp || gam) { + if (alp) { + gamma0 = Math.asin(Math.sin(alpha_c) / D); + if (!gam) { + gamma = alpha_c; + } + } else { + gamma0 = gamma; + alpha_c = Math.asin(D * Math.sin(gamma0)); + } + this.lam0 = lamc - Math.asin(0.5 * (F - 1 / F) * Math.tan(gamma0)) / this.B; + } else { + H = Math.pow(tsfnz(this.e, phi1, Math.sin(phi1)), this.B); + L = Math.pow(tsfnz(this.e, phi2, Math.sin(phi2)), this.B); + F = this.E / H; + p = (L - H) / (L + H); + J = this.E * this.E; + J = (J - L * H) / (J + L * H); + con = lam1 - lam2; + + if (con < -Math.pi) { + lam2 -=TWO_PI; + } else if (con > Math.pi) { + lam2 += TWO_PI; + } + + this.lam0 = adjust_lon(0.5 * (lam1 + lam2) - Math.atan(J * Math.tan(0.5 * this.B * (lam1 - lam2)) / p) / this.B); + gamma0 = Math.atan(2 * Math.sin(this.B * adjust_lon(lam1 - this.lam0)) / (F - 1 / F)); + gamma = alpha_c = Math.asin(D * Math.sin(gamma0)); + } + + this.singam = Math.sin(gamma0); + this.cosgam = Math.cos(gamma0); + this.sinrot = Math.sin(gamma); + this.cosrot = Math.cos(gamma); + + this.rB = 1 / this.B; + this.ArB = this.A * this.rB; + this.BrA = 1 / this.ArB; + if (this.no_off) { + this.u_0 = 0; + } else { + this.u_0 = Math.abs(this.ArB * Math.atan(Math.sqrt(D * D - 1) / Math.cos(alpha_c))); + + if (this.lat0 < 0) { + this.u_0 = - this.u_0; + } + } + + F = 0.5 * gamma0; + this.v_pole_n = this.ArB * Math.log(Math.tan(FORTPI - F)); + this.v_pole_s = this.ArB * Math.log(Math.tan(FORTPI + F)); + } + + + /* Oblique Mercator forward equations--mapping lat,long to x,y + ----------------------------------------------------------*/ + function forward$8(p) { + var coords = {}; + var S, T, U, V, W, temp, u, v; + p.x = p.x - this.lam0; + + if (Math.abs(Math.abs(p.y) - HALF_PI) > EPSLN) { + W = this.E / Math.pow(tsfnz(this.e, p.y, Math.sin(p.y)), this.B); + + temp = 1 / W; + S = 0.5 * (W - temp); + T = 0.5 * (W + temp); + V = Math.sin(this.B * p.x); + U = (S * this.singam - V * this.cosgam) / T; + + if (Math.abs(Math.abs(U) - 1.0) < EPSLN) { + throw new Error(); + } + + v = 0.5 * this.ArB * Math.log((1 - U)/(1 + U)); + temp = Math.cos(this.B * p.x); + + if (Math.abs(temp) < TOL) { + u = this.A * p.x; + } else { + u = this.ArB * Math.atan2((S * this.cosgam + V * this.singam), temp); + } + } else { + v = p.y > 0 ? this.v_pole_n : this.v_pole_s; + u = this.ArB * p.y; + } + + if (this.no_rot) { + coords.x = u; + coords.y = v; + } else { + u -= this.u_0; + coords.x = v * this.cosrot + u * this.sinrot; + coords.y = u * this.cosrot - v * this.sinrot; + } + + coords.x = (this.a * coords.x + this.x0); + coords.y = (this.a * coords.y + this.y0); + + return coords; + } + + function inverse$8(p) { + var u, v, Qp, Sp, Tp, Vp, Up; + var coords = {}; + + p.x = (p.x - this.x0) * (1.0 / this.a); + p.y = (p.y - this.y0) * (1.0 / this.a); + + if (this.no_rot) { + v = p.y; + u = p.x; + } else { + v = p.x * this.cosrot - p.y * this.sinrot; + u = p.y * this.cosrot + p.x * this.sinrot + this.u_0; + } + + Qp = Math.exp(-this.BrA * v); + Sp = 0.5 * (Qp - 1 / Qp); + Tp = 0.5 * (Qp + 1 / Qp); + Vp = Math.sin(this.BrA * u); + Up = (Vp * this.cosgam + Sp * this.singam) / Tp; + + if (Math.abs(Math.abs(Up) - 1) < EPSLN) { + coords.x = 0; + coords.y = Up < 0 ? -HALF_PI : HALF_PI; + } else { + coords.y = this.E / Math.sqrt((1 + Up) / (1 - Up)); + coords.y = phi2z(this.e, Math.pow(coords.y, 1 / this.B)); + + if (coords.y === Infinity) { + throw new Error(); + } + + coords.x = -this.rB * Math.atan2((Sp * this.cosgam - Vp * this.singam), Math.cos(this.BrA * u)); + } + + coords.x += this.lam0; + + return coords; + } + + var names$10 = ["Hotine_Oblique_Mercator", "Hotine Oblique Mercator", "Hotine_Oblique_Mercator_Azimuth_Natural_Origin", "Hotine_Oblique_Mercator_Two_Point_Natural_Origin", "Hotine_Oblique_Mercator_Azimuth_Center", "Oblique_Mercator", "omerc"]; + var omerc = { + init: init$9, + forward: forward$8, + inverse: inverse$8, + names: names$10 + }; + + function init$10() { + + //double lat0; /* the reference latitude */ + //double long0; /* the reference longitude */ + //double lat1; /* first standard parallel */ + //double lat2; /* second standard parallel */ + //double r_maj; /* major axis */ + //double r_min; /* minor axis */ + //double false_east; /* x offset in meters */ + //double false_north; /* y offset in meters */ + + //the above value can be set with proj4.defs + //example: proj4.defs("EPSG:2154","+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"); + + if (!this.lat2) { + this.lat2 = this.lat1; + } //if lat2 is not defined + if (!this.k0) { + this.k0 = 1; + } + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + + var temp = this.b / this.a; + this.e = Math.sqrt(1 - temp * temp); + + var sin1 = Math.sin(this.lat1); + var cos1 = Math.cos(this.lat1); + var ms1 = msfnz(this.e, sin1, cos1); + var ts1 = tsfnz(this.e, this.lat1, sin1); + + var sin2 = Math.sin(this.lat2); + var cos2 = Math.cos(this.lat2); + var ms2 = msfnz(this.e, sin2, cos2); + var ts2 = tsfnz(this.e, this.lat2, sin2); + + var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0)); + + if (Math.abs(this.lat1 - this.lat2) > EPSLN) { + this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2); + } + else { + this.ns = sin1; + } + if (isNaN(this.ns)) { + this.ns = sin1; + } + this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns)); + this.rh = this.a * this.f0 * Math.pow(ts0, this.ns); + if (!this.title) { + this.title = "Lambert Conformal Conic"; + } + } + + // Lambert Conformal conic forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + function forward$9(p) { + + var lon = p.x; + var lat = p.y; + + // singular cases : + if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) { + lat = sign(lat) * (HALF_PI - 2 * EPSLN); + } + + var con = Math.abs(Math.abs(lat) - HALF_PI); + var ts, rh1; + if (con > EPSLN) { + ts = tsfnz(this.e, lat, Math.sin(lat)); + rh1 = this.a * this.f0 * Math.pow(ts, this.ns); + } + else { + con = lat * this.ns; + if (con <= 0) { + return null; + } + rh1 = 0; + } + var theta = this.ns * adjust_lon(lon - this.long0); + p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0; + p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0; + + return p; + } + + // Lambert Conformal Conic inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + function inverse$9(p) { + + var rh1, con, ts; + var lat, lon; + var x = (p.x - this.x0) / this.k0; + var y = (this.rh - (p.y - this.y0) / this.k0); + if (this.ns > 0) { + rh1 = Math.sqrt(x * x + y * y); + con = 1; + } + else { + rh1 = -Math.sqrt(x * x + y * y); + con = -1; + } + var theta = 0; + if (rh1 !== 0) { + theta = Math.atan2((con * x), (con * y)); + } + if ((rh1 !== 0) || (this.ns > 0)) { + con = 1 / this.ns; + ts = Math.pow((rh1 / (this.a * this.f0)), con); + lat = phi2z(this.e, ts); + if (lat === -9999) { + return null; + } + } + else { + lat = -HALF_PI; + } + lon = adjust_lon(theta / this.ns + this.long0); + + p.x = lon; + p.y = lat; + return p; + } + + var names$11 = [ + "Lambert Tangential Conformal Conic Projection", + "Lambert_Conformal_Conic", + "Lambert_Conformal_Conic_1SP", + "Lambert_Conformal_Conic_2SP", + "lcc", + "Lambert Conic Conformal (1SP)", + "Lambert Conic Conformal (2SP)" + ]; + + var lcc = { + init: init$10, + forward: forward$9, + inverse: inverse$9, + names: names$11 + }; + + function init$11() { + this.a = 6377397.155; + this.es = 0.006674372230614; + this.e = Math.sqrt(this.es); + if (!this.lat0) { + this.lat0 = 0.863937979737193; + } + if (!this.long0) { + this.long0 = 0.7417649320975901 - 0.308341501185665; + } + /* if scale not set default to 0.9999 */ + if (!this.k0) { + this.k0 = 0.9999; + } + this.s45 = 0.785398163397448; /* 45 */ + this.s90 = 2 * this.s45; + this.fi0 = this.lat0; + this.e2 = this.es; + this.e = Math.sqrt(this.e2); + this.alfa = Math.sqrt(1 + (this.e2 * Math.pow(Math.cos(this.fi0), 4)) / (1 - this.e2)); + this.uq = 1.04216856380474; + this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa); + this.g = Math.pow((1 + this.e * Math.sin(this.fi0)) / (1 - this.e * Math.sin(this.fi0)), this.alfa * this.e / 2); + this.k = Math.tan(this.u0 / 2 + this.s45) / Math.pow(Math.tan(this.fi0 / 2 + this.s45), this.alfa) * this.g; + this.k1 = this.k0; + this.n0 = this.a * Math.sqrt(1 - this.e2) / (1 - this.e2 * Math.pow(Math.sin(this.fi0), 2)); + this.s0 = 1.37008346281555; + this.n = Math.sin(this.s0); + this.ro0 = this.k1 * this.n0 / Math.tan(this.s0); + this.ad = this.s90 - this.uq; + } + + /* ellipsoid */ + /* calculate xy from lat/lon */ + /* Constants, identical to inverse transform function */ + function forward$10(p) { + var gfi, u, deltav, s, d, eps, ro; + var lon = p.x; + var lat = p.y; + var delta_lon = adjust_lon(lon - this.long0); + /* Transformation */ + gfi = Math.pow(((1 + this.e * Math.sin(lat)) / (1 - this.e * Math.sin(lat))), (this.alfa * this.e / 2)); + u = 2 * (Math.atan(this.k * Math.pow(Math.tan(lat / 2 + this.s45), this.alfa) / gfi) - this.s45); + deltav = -delta_lon * this.alfa; + s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav)); + d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s)); + eps = this.n * d; + ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2 + this.s45), this.n) / Math.pow(Math.tan(s / 2 + this.s45), this.n); + p.y = ro * Math.cos(eps) / 1; + p.x = ro * Math.sin(eps) / 1; + + if (!this.czech) { + p.y *= -1; + p.x *= -1; + } + return (p); + } + + /* calculate lat/lon from xy */ + function inverse$10(p) { + var u, deltav, s, d, eps, ro, fi1; + var ok; + + /* Transformation */ + /* revert y, x*/ + var tmp = p.x; + p.x = p.y; + p.y = tmp; + if (!this.czech) { + p.y *= -1; + p.x *= -1; + } + ro = Math.sqrt(p.x * p.x + p.y * p.y); + eps = Math.atan2(p.y, p.x); + d = eps / Math.sin(this.s0); + s = 2 * (Math.atan(Math.pow(this.ro0 / ro, 1 / this.n) * Math.tan(this.s0 / 2 + this.s45)) - this.s45); + u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d)); + deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u)); + p.x = this.long0 - deltav / this.alfa; + fi1 = u; + ok = 0; + var iter = 0; + do { + p.y = 2 * (Math.atan(Math.pow(this.k, - 1 / this.alfa) * Math.pow(Math.tan(u / 2 + this.s45), 1 / this.alfa) * Math.pow((1 + this.e * Math.sin(fi1)) / (1 - this.e * Math.sin(fi1)), this.e / 2)) - this.s45); + if (Math.abs(fi1 - p.y) < 0.0000000001) { + ok = 1; + } + fi1 = p.y; + iter += 1; + } while (ok === 0 && iter < 15); + if (iter >= 15) { + return null; + } + + return (p); + } + + var names$12 = ["Krovak", "krovak"]; + var krovak = { + init: init$11, + forward: forward$10, + inverse: inverse$10, + names: names$12 + }; + + var mlfn = function(e0, e1, e2, e3, phi) { + return (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi)); + }; + + var e0fn = function(x) { + return (1 - 0.25 * x * (1 + x / 16 * (3 + 1.25 * x))); + }; + + var e1fn = function(x) { + return (0.375 * x * (1 + 0.25 * x * (1 + 0.46875 * x))); + }; + + var e2fn = function(x) { + return (0.05859375 * x * x * (1 + 0.75 * x)); + }; + + var e3fn = function(x) { + return (x * x * x * (35 / 3072)); + }; + + var gN = function(a, e, sinphi) { + var temp = e * sinphi; + return a / Math.sqrt(1 - temp * temp); + }; + + var adjust_lat = function(x) { + return (Math.abs(x) < HALF_PI) ? x : (x - (sign(x) * Math.PI)); + }; + + var imlfn = function(ml, e0, e1, e2, e3) { + var phi; + var dphi; + + phi = ml / e0; + for (var i = 0; i < 15; i++) { + dphi = (ml - (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi))) / (e0 - 2 * e1 * Math.cos(2 * phi) + 4 * e2 * Math.cos(4 * phi) - 6 * e3 * Math.cos(6 * phi)); + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + + //..reportError("IMLFN-CONV:Latitude failed to converge after 15 iterations"); + return NaN; + }; + + function init$12() { + if (!this.sphere) { + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); + } + } + + /* Cassini forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ + function forward$11(p) { + + /* Forward equations + -----------------*/ + var x, y; + var lam = p.x; + var phi = p.y; + lam = adjust_lon(lam - this.long0); + + if (this.sphere) { + x = this.a * Math.asin(Math.cos(phi) * Math.sin(lam)); + y = this.a * (Math.atan2(Math.tan(phi), Math.cos(lam)) - this.lat0); + } + else { + //ellipsoid + var sinphi = Math.sin(phi); + var cosphi = Math.cos(phi); + var nl = gN(this.a, this.e, sinphi); + var tl = Math.tan(phi) * Math.tan(phi); + var al = lam * Math.cos(phi); + var asq = al * al; + var cl = this.es * cosphi * cosphi / (1 - this.es); + var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi); + + x = nl * al * (1 - asq * tl * (1 / 6 - (8 - tl + 8 * cl) * asq / 120)); + y = ml - this.ml0 + nl * sinphi / cosphi * asq * (0.5 + (5 - tl + 6 * cl) * asq / 24); + + + } + + p.x = x + this.x0; + p.y = y + this.y0; + return p; + } + + /* Inverse equations + -----------------*/ + function inverse$11(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x / this.a; + var y = p.y / this.a; + var phi, lam; + + if (this.sphere) { + var dd = y + this.lat0; + phi = Math.asin(Math.sin(dd) * Math.cos(x)); + lam = Math.atan2(Math.tan(x), Math.cos(dd)); + } + else { + /* ellipsoid */ + var ml1 = this.ml0 / this.a + y; + var phi1 = imlfn(ml1, this.e0, this.e1, this.e2, this.e3); + if (Math.abs(Math.abs(phi1) - HALF_PI) <= EPSLN) { + p.x = this.long0; + p.y = HALF_PI; + if (y < 0) { + p.y *= -1; + } + return p; + } + var nl1 = gN(this.a, this.e, Math.sin(phi1)); + + var rl1 = nl1 * nl1 * nl1 / this.a / this.a * (1 - this.es); + var tl1 = Math.pow(Math.tan(phi1), 2); + var dl = x * this.a / nl1; + var dsq = dl * dl; + phi = phi1 - nl1 * Math.tan(phi1) / rl1 * dl * dl * (0.5 - (1 + 3 * tl1) * dl * dl / 24); + lam = dl * (1 - dsq * (tl1 / 3 + (1 + 3 * tl1) * tl1 * dsq / 15)) / Math.cos(phi1); + + } + + p.x = adjust_lon(lam + this.long0); + p.y = adjust_lat(phi); + return p; + + } + + var names$13 = ["Cassini", "Cassini_Soldner", "cass"]; + var cass = { + init: init$12, + forward: forward$11, + inverse: inverse$11, + names: names$13 + }; + + var qsfnz = function(eccent, sinphi) { + var con; + if (eccent > 1.0e-7) { + con = eccent * sinphi; + return ((1 - eccent * eccent) * (sinphi / (1 - con * con) - (0.5 / eccent) * Math.log((1 - con) / (1 + con)))); + } + else { + return (2 * sinphi); + } + }; + + /* + reference + "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + */ + + var S_POLE = 1; + + var N_POLE = 2; + var EQUIT = 3; + var OBLIQ = 4; + + /* Initialize the Lambert Azimuthal Equal Area projection + ------------------------------------------------------*/ + function init$13() { + var t = Math.abs(this.lat0); + if (Math.abs(t - HALF_PI) < EPSLN) { + this.mode = this.lat0 < 0 ? this.S_POLE : this.N_POLE; + } + else if (Math.abs(t) < EPSLN) { + this.mode = this.EQUIT; + } + else { + this.mode = this.OBLIQ; + } + if (this.es > 0) { + var sinphi; + + this.qp = qsfnz(this.e, 1); + this.mmf = 0.5 / (1 - this.es); + this.apa = authset(this.es); + switch (this.mode) { + case this.N_POLE: + this.dd = 1; + break; + case this.S_POLE: + this.dd = 1; + break; + case this.EQUIT: + this.rq = Math.sqrt(0.5 * this.qp); + this.dd = 1 / this.rq; + this.xmf = 1; + this.ymf = 0.5 * this.qp; + break; + case this.OBLIQ: + this.rq = Math.sqrt(0.5 * this.qp); + sinphi = Math.sin(this.lat0); + this.sinb1 = qsfnz(this.e, sinphi) / this.qp; + this.cosb1 = Math.sqrt(1 - this.sinb1 * this.sinb1); + this.dd = Math.cos(this.lat0) / (Math.sqrt(1 - this.es * sinphi * sinphi) * this.rq * this.cosb1); + this.ymf = (this.xmf = this.rq) / this.dd; + this.xmf *= this.dd; + break; + } + } + else { + if (this.mode === this.OBLIQ) { + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + } + } + + /* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ + function forward$12(p) { + + /* Forward equations + -----------------*/ + var x, y, coslam, sinlam, sinphi, q, sinb, cosb, b, cosphi; + var lam = p.x; + var phi = p.y; + + lam = adjust_lon(lam - this.long0); + if (this.sphere) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + coslam = Math.cos(lam); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + y = (this.mode === this.EQUIT) ? 1 + cosphi * coslam : 1 + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= EPSLN) { + return null; + } + y = Math.sqrt(2 / y); + x = y * cosphi * Math.sin(lam); + y *= (this.mode === this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + } + else if (this.mode === this.N_POLE || this.mode === this.S_POLE) { + if (this.mode === this.N_POLE) { + coslam = -coslam; + } + if (Math.abs(phi + this.lat0) < EPSLN) { + return null; + } + y = FORTPI - phi * 0.5; + y = 2 * ((this.mode === this.S_POLE) ? Math.cos(y) : Math.sin(y)); + x = y * Math.sin(lam); + y *= coslam; + } + } + else { + sinb = 0; + cosb = 0; + b = 0; + coslam = Math.cos(lam); + sinlam = Math.sin(lam); + sinphi = Math.sin(phi); + q = qsfnz(this.e, sinphi); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + sinb = q / this.qp; + cosb = Math.sqrt(1 - sinb * sinb); + } + switch (this.mode) { + case this.OBLIQ: + b = 1 + this.sinb1 * sinb + this.cosb1 * cosb * coslam; + break; + case this.EQUIT: + b = 1 + cosb * coslam; + break; + case this.N_POLE: + b = HALF_PI + phi; + q = this.qp - q; + break; + case this.S_POLE: + b = phi - HALF_PI; + q = this.qp + q; + break; + } + if (Math.abs(b) < EPSLN) { + return null; + } + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + b = Math.sqrt(2 / b); + if (this.mode === this.OBLIQ) { + y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam); + } + else { + y = (b = Math.sqrt(2 / (1 + cosb * coslam))) * sinb * this.ymf; + } + x = this.xmf * b * cosb * sinlam; + break; + case this.N_POLE: + case this.S_POLE: + if (q >= 0) { + x = (b = Math.sqrt(q)) * sinlam; + y = coslam * ((this.mode === this.S_POLE) ? b : -b); + } + else { + x = y = 0; + } + break; + } + } + + p.x = this.a * x + this.x0; + p.y = this.a * y + this.y0; + return p; + } + + /* Inverse equations + -----------------*/ + function inverse$12(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x / this.a; + var y = p.y / this.a; + var lam, phi, cCe, sCe, q, rho, ab; + if (this.sphere) { + var cosz = 0, + rh, sinz = 0; + + rh = Math.sqrt(x * x + y * y); + phi = rh * 0.5; + if (phi > 1) { + return null; + } + phi = 2 * Math.asin(phi); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + sinz = Math.sin(phi); + cosz = Math.cos(phi); + } + switch (this.mode) { + case this.EQUIT: + phi = (Math.abs(rh) <= EPSLN) ? 0 : Math.asin(y * sinz / rh); + x *= sinz; + y = cosz * rh; + break; + case this.OBLIQ: + phi = (Math.abs(rh) <= EPSLN) ? this.lat0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh); + x *= sinz * this.cosph0; + y = (cosz - Math.sin(phi) * this.sinph0) * rh; + break; + case this.N_POLE: + y = -y; + phi = HALF_PI - phi; + break; + case this.S_POLE: + phi -= HALF_PI; + break; + } + lam = (y === 0 && (this.mode === this.EQUIT || this.mode === this.OBLIQ)) ? 0 : Math.atan2(x, y); + } + else { + ab = 0; + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + x /= this.dd; + y *= this.dd; + rho = Math.sqrt(x * x + y * y); + if (rho < EPSLN) { + p.x = this.long0; + p.y = this.lat0; + return p; + } + sCe = 2 * Math.asin(0.5 * rho / this.rq); + cCe = Math.cos(sCe); + x *= (sCe = Math.sin(sCe)); + if (this.mode === this.OBLIQ) { + ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho; + q = this.qp * ab; + y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe; + } + else { + ab = y * sCe / rho; + q = this.qp * ab; + y = rho * cCe; + } + } + else if (this.mode === this.N_POLE || this.mode === this.S_POLE) { + if (this.mode === this.N_POLE) { + y = -y; + } + q = (x * x + y * y); + if (!q) { + p.x = this.long0; + p.y = this.lat0; + return p; + } + ab = 1 - q / this.qp; + if (this.mode === this.S_POLE) { + ab = -ab; + } + } + lam = Math.atan2(x, y); + phi = authlat(Math.asin(ab), this.apa); + } + + p.x = adjust_lon(this.long0 + lam); + p.y = phi; + return p; + } + + /* determine latitude from authalic latitude */ + var P00 = 0.33333333333333333333; + + var P01 = 0.17222222222222222222; + var P02 = 0.10257936507936507936; + var P10 = 0.06388888888888888888; + var P11 = 0.06640211640211640211; + var P20 = 0.01641501294219154443; + + function authset(es) { + var t; + var APA = []; + APA[0] = es * P00; + t = es * es; + APA[0] += t * P01; + APA[1] = t * P10; + t *= es; + APA[0] += t * P02; + APA[1] += t * P11; + APA[2] = t * P20; + return APA; + } + + function authlat(beta, APA) { + var t = beta + beta; + return (beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t + t) + APA[2] * Math.sin(t + t + t)); + } + + var names$14 = ["Lambert Azimuthal Equal Area", "Lambert_Azimuthal_Equal_Area", "laea"]; + var laea = { + init: init$13, + forward: forward$12, + inverse: inverse$12, + names: names$14, + S_POLE: S_POLE, + N_POLE: N_POLE, + EQUIT: EQUIT, + OBLIQ: OBLIQ + }; + + var asinz = function(x) { + if (Math.abs(x) > 1) { + x = (x > 1) ? 1 : -1; + } + return Math.asin(x); + }; + + function init$14() { + + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); + this.e3 = Math.sqrt(this.es); + + this.sin_po = Math.sin(this.lat1); + this.cos_po = Math.cos(this.lat1); + this.t1 = this.sin_po; + this.con = this.sin_po; + this.ms1 = msfnz(this.e3, this.sin_po, this.cos_po); + this.qs1 = qsfnz(this.e3, this.sin_po); + + this.sin_po = Math.sin(this.lat2); + this.cos_po = Math.cos(this.lat2); + this.t2 = this.sin_po; + this.ms2 = msfnz(this.e3, this.sin_po, this.cos_po); + this.qs2 = qsfnz(this.e3, this.sin_po); + + this.sin_po = Math.sin(this.lat0); + this.cos_po = Math.cos(this.lat0); + this.t3 = this.sin_po; + this.qs0 = qsfnz(this.e3, this.sin_po); + + if (Math.abs(this.lat1 - this.lat2) > EPSLN) { + this.ns0 = (this.ms1 * this.ms1 - this.ms2 * this.ms2) / (this.qs2 - this.qs1); + } + else { + this.ns0 = this.con; + } + this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1; + this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0) / this.ns0; + } + + /* Albers Conical Equal Area forward equations--mapping lat,long to x,y + -------------------------------------------------------------------*/ + function forward$13(p) { + + var lon = p.x; + var lat = p.y; + + this.sin_phi = Math.sin(lat); + this.cos_phi = Math.cos(lat); + + var qs = qsfnz(this.e3, this.sin_phi); + var rh1 = this.a * Math.sqrt(this.c - this.ns0 * qs) / this.ns0; + var theta = this.ns0 * adjust_lon(lon - this.long0); + var x = rh1 * Math.sin(theta) + this.x0; + var y = this.rh - rh1 * Math.cos(theta) + this.y0; + + p.x = x; + p.y = y; + return p; + } + + function inverse$13(p) { + var rh1, qs, con, theta, lon, lat; + + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + if (this.ns0 >= 0) { + rh1 = Math.sqrt(p.x * p.x + p.y * p.y); + con = 1; + } + else { + rh1 = -Math.sqrt(p.x * p.x + p.y * p.y); + con = -1; + } + theta = 0; + if (rh1 !== 0) { + theta = Math.atan2(con * p.x, con * p.y); + } + con = rh1 * this.ns0 / this.a; + if (this.sphere) { + lat = Math.asin((this.c - con * con) / (2 * this.ns0)); + } + else { + qs = (this.c - con * con) / this.ns0; + lat = this.phi1z(this.e3, qs); + } + + lon = adjust_lon(theta / this.ns0 + this.long0); + p.x = lon; + p.y = lat; + return p; + } + + /* Function to compute phi1, the latitude for the inverse of the + Albers Conical Equal-Area projection. + -------------------------------------------*/ + function phi1z(eccent, qs) { + var sinphi, cosphi, con, com, dphi; + var phi = asinz(0.5 * qs); + if (eccent < EPSLN) { + return phi; + } + + var eccnts = eccent * eccent; + for (var i = 1; i <= 25; i++) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + con = eccent * sinphi; + com = 1 - con * con; + dphi = 0.5 * com * com / cosphi * (qs / (1 - eccnts) - sinphi / com + 0.5 / eccent * Math.log((1 - con) / (1 + con))); + phi = phi + dphi; + if (Math.abs(dphi) <= 1e-7) { + return phi; + } + } + return null; + } + + var names$15 = ["Albers_Conic_Equal_Area", "Albers", "aea"]; + var aea = { + init: init$14, + forward: forward$13, + inverse: inverse$13, + names: names$15, + phi1z: phi1z + }; + + /* + reference: + Wolfram Mathworld "Gnomonic Projection" + http://mathworld.wolfram.com/GnomonicProjection.html + Accessed: 12th November 2009 + */ + function init$15() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14 = Math.sin(this.lat0); + this.cos_p14 = Math.cos(this.lat0); + // Approximation for projecting points to the horizon (infinity) + this.infinity_dist = 1000 * this.a; + this.rc = 1; + } + + /* Gnomonic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + function forward$14(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + dlon = adjust_lon(lon - this.long0); + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1; + if ((g > 0) || (Math.abs(g) <= EPSLN)) { + x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g; + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g; + } + else { + + // Point is in the opposing hemisphere and is unprojectable + // We still need to return a reasonable point, so we project + // to infinity, on a bearing + // equivalent to the northern hemisphere equivalent + // This is a reasonable approximation for short shapes and lines that + // straddle the horizon. + + x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon); + y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + + } + p.x = x; + p.y = y; + return p; + } + + function inverse$14(p) { + var rh; /* Rho */ + var sinc, cosc; + var c; + var lon, lat; + + /* Inverse equations + -----------------*/ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + + if ((rh = Math.sqrt(p.x * p.x + p.y * p.y))) { + c = Math.atan2(rh, this.rc); + sinc = Math.sin(c); + cosc = Math.cos(c); + + lat = asinz(cosc * this.sin_p14 + (p.y * sinc * this.cos_p14) / rh); + lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc); + lon = adjust_lon(this.long0 + lon); + } + else { + lat = this.phic0; + lon = 0; + } + + p.x = lon; + p.y = lat; + return p; + } + + var names$16 = ["gnom"]; + var gnom = { + init: init$15, + forward: forward$14, + inverse: inverse$14, + names: names$16 + }; + + var iqsfnz = function(eccent, q) { + var temp = 1 - (1 - eccent * eccent) / (2 * eccent) * Math.log((1 - eccent) / (1 + eccent)); + if (Math.abs(Math.abs(q) - temp) < 1.0E-6) { + if (q < 0) { + return (-1 * HALF_PI); + } + else { + return HALF_PI; + } + } + //var phi = 0.5* q/(1-eccent*eccent); + var phi = Math.asin(0.5 * q); + var dphi; + var sin_phi; + var cos_phi; + var con; + for (var i = 0; i < 30; i++) { + sin_phi = Math.sin(phi); + cos_phi = Math.cos(phi); + con = eccent * sin_phi; + dphi = Math.pow(1 - con * con, 2) / (2 * cos_phi) * (q / (1 - eccent * eccent) - sin_phi / (1 - con * con) + 0.5 / eccent * Math.log((1 - con) / (1 + con))); + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + + //console.log("IQSFN-CONV:Latitude failed to converge after 30 iterations"); + return NaN; + }; + + /* + reference: + "Cartographic Projection Procedures for the UNIX Environment- + A User's Manual" by Gerald I. Evenden, + USGS Open File Report 90-284and Release 4 Interim Reports (2003) + */ + function init$16() { + //no-op + if (!this.sphere) { + this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } + } + + /* Cylindrical Equal Area forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ + function forward$15(p) { + var lon = p.x; + var lat = p.y; + var x, y; + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + if (this.sphere) { + x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts); + } + else { + var qs = qsfnz(this.e, Math.sin(lat)); + x = this.x0 + this.a * this.k0 * dlon; + y = this.y0 + this.a * qs * 0.5 / this.k0; + } + + p.x = x; + p.y = y; + return p; + } + + /* Cylindrical Equal Area inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ + function inverse$15(p) { + p.x -= this.x0; + p.y -= this.y0; + var lon, lat; + + if (this.sphere) { + lon = adjust_lon(this.long0 + (p.x / this.a) / Math.cos(this.lat_ts)); + lat = Math.asin((p.y / this.a) * Math.cos(this.lat_ts)); + } + else { + lat = iqsfnz(this.e, 2 * p.y * this.k0 / this.a); + lon = adjust_lon(this.long0 + p.x / (this.a * this.k0)); + } + + p.x = lon; + p.y = lat; + return p; + } + + var names$17 = ["cea"]; + var cea = { + init: init$16, + forward: forward$15, + inverse: inverse$15, + names: names$17 + }; + + function init$17() { + + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.lat0 = this.lat0 || 0; + this.long0 = this.long0 || 0; + this.lat_ts = this.lat_ts || 0; + this.title = this.title || "Equidistant Cylindrical (Plate Carre)"; + + this.rc = Math.cos(this.lat_ts); + } + + // forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + function forward$16(p) { + + var lon = p.x; + var lat = p.y; + + var dlon = adjust_lon(lon - this.long0); + var dlat = adjust_lat(lat - this.lat0); + p.x = this.x0 + (this.a * dlon * this.rc); + p.y = this.y0 + (this.a * dlat); + return p; + } + + // inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + function inverse$16(p) { + + var x = p.x; + var y = p.y; + + p.x = adjust_lon(this.long0 + ((x - this.x0) / (this.a * this.rc))); + p.y = adjust_lat(this.lat0 + ((y - this.y0) / (this.a))); + return p; + } + + var names$18 = ["Equirectangular", "Equidistant_Cylindrical", "eqc"]; + var eqc = { + init: init$17, + forward: forward$16, + inverse: inverse$16, + names: names$18 + }; + + var MAX_ITER$2 = 20; + + function init$18() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); // devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles + this.e = Math.sqrt(this.es); + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); //si que des zeros le calcul ne se fait pas + } + + /* Polyconic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + function forward$17(p) { + var lon = p.x; + var lat = p.y; + var x, y, el; + var dlon = adjust_lon(lon - this.long0); + el = dlon * Math.sin(lat); + if (this.sphere) { + if (Math.abs(lat) <= EPSLN) { + x = this.a * dlon; + y = -1 * this.a * this.lat0; + } + else { + x = this.a * Math.sin(el) / Math.tan(lat); + y = this.a * (adjust_lat(lat - this.lat0) + (1 - Math.cos(el)) / Math.tan(lat)); + } + } + else { + if (Math.abs(lat) <= EPSLN) { + x = this.a * dlon; + y = -1 * this.ml0; + } + else { + var nl = gN(this.a, this.e, Math.sin(lat)) / Math.tan(lat); + x = nl * Math.sin(el); + y = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat) - this.ml0 + nl * (1 - Math.cos(el)); + } + + } + p.x = x + this.x0; + p.y = y + this.y0; + return p; + } + + /* Inverse equations + -----------------*/ + function inverse$17(p) { + var lon, lat, x, y, i; + var al, bl; + var phi, dphi; + x = p.x - this.x0; + y = p.y - this.y0; + + if (this.sphere) { + if (Math.abs(y + this.a * this.lat0) <= EPSLN) { + lon = adjust_lon(x / this.a + this.long0); + lat = 0; + } + else { + al = this.lat0 + y / this.a; + bl = x * x / this.a / this.a + al * al; + phi = al; + var tanphi; + for (i = MAX_ITER$2; i; --i) { + tanphi = Math.tan(phi); + dphi = -1 * (al * (phi * tanphi + 1) - phi - 0.5 * (phi * phi + bl) * tanphi) / ((phi - al) / tanphi - 1); + phi += dphi; + if (Math.abs(dphi) <= EPSLN) { + lat = phi; + break; + } + } + lon = adjust_lon(this.long0 + (Math.asin(x * Math.tan(phi) / this.a)) / Math.sin(lat)); + } + } + else { + if (Math.abs(y + this.ml0) <= EPSLN) { + lat = 0; + lon = adjust_lon(this.long0 + x / this.a); + } + else { + + al = (this.ml0 + y) / this.a; + bl = x * x / this.a / this.a + al * al; + phi = al; + var cl, mln, mlnp, ma; + var con; + for (i = MAX_ITER$2; i; --i) { + con = this.e * Math.sin(phi); + cl = Math.sqrt(1 - con * con) * Math.tan(phi); + mln = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi); + mlnp = this.e0 - 2 * this.e1 * Math.cos(2 * phi) + 4 * this.e2 * Math.cos(4 * phi) - 6 * this.e3 * Math.cos(6 * phi); + ma = mln / this.a; + dphi = (al * (cl * ma + 1) - ma - 0.5 * cl * (ma * ma + bl)) / (this.es * Math.sin(2 * phi) * (ma * ma + bl - 2 * al * ma) / (4 * cl) + (al - ma) * (cl * mlnp - 2 / Math.sin(2 * phi)) - mlnp); + phi -= dphi; + if (Math.abs(dphi) <= EPSLN) { + lat = phi; + break; + } + } + + //lat=phi4z(this.e,this.e0,this.e1,this.e2,this.e3,al,bl,0,0); + cl = Math.sqrt(1 - this.es * Math.pow(Math.sin(lat), 2)) * Math.tan(lat); + lon = adjust_lon(this.long0 + Math.asin(x * cl / this.a) / Math.sin(lat)); + } + } + + p.x = lon; + p.y = lat; + return p; + } + + var names$19 = ["Polyconic", "poly"]; + var poly = { + init: init$18, + forward: forward$17, + inverse: inverse$17, + names: names$19 + }; + + /* + reference + Department of Land and Survey Technical Circular 1973/32 + http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf + OSG Technical Report 4.1 + http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf + */ + + /** + * iterations: Number of iterations to refine inverse transform. + * 0 -> km accuracy + * 1 -> m accuracy -- suitable for most mapping applications + * 2 -> mm accuracy + */ + + + function init$19() { + this.A = []; + this.A[1] = 0.6399175073; + this.A[2] = -0.1358797613; + this.A[3] = 0.063294409; + this.A[4] = -0.02526853; + this.A[5] = 0.0117879; + this.A[6] = -0.0055161; + this.A[7] = 0.0026906; + this.A[8] = -0.001333; + this.A[9] = 0.00067; + this.A[10] = -0.00034; + + this.B_re = []; + this.B_im = []; + this.B_re[1] = 0.7557853228; + this.B_im[1] = 0; + this.B_re[2] = 0.249204646; + this.B_im[2] = 0.003371507; + this.B_re[3] = -0.001541739; + this.B_im[3] = 0.041058560; + this.B_re[4] = -0.10162907; + this.B_im[4] = 0.01727609; + this.B_re[5] = -0.26623489; + this.B_im[5] = -0.36249218; + this.B_re[6] = -0.6870983; + this.B_im[6] = -1.1651967; + + this.C_re = []; + this.C_im = []; + this.C_re[1] = 1.3231270439; + this.C_im[1] = 0; + this.C_re[2] = -0.577245789; + this.C_im[2] = -0.007809598; + this.C_re[3] = 0.508307513; + this.C_im[3] = -0.112208952; + this.C_re[4] = -0.15094762; + this.C_im[4] = 0.18200602; + this.C_re[5] = 1.01418179; + this.C_im[5] = 1.64497696; + this.C_re[6] = 1.9660549; + this.C_im[6] = 2.5127645; + + this.D = []; + this.D[1] = 1.5627014243; + this.D[2] = 0.5185406398; + this.D[3] = -0.03333098; + this.D[4] = -0.1052906; + this.D[5] = -0.0368594; + this.D[6] = 0.007317; + this.D[7] = 0.01220; + this.D[8] = 0.00394; + this.D[9] = -0.0013; + } + + /** + New Zealand Map Grid Forward - long/lat to x/y + long/lat in radians + */ + function forward$18(p) { + var n; + var lon = p.x; + var lat = p.y; + + var delta_lat = lat - this.lat0; + var delta_lon = lon - this.long0; + + // 1. Calculate d_phi and d_psi ... // and d_lambda + // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians. + var d_phi = delta_lat / SEC_TO_RAD * 1E-5; + var d_lambda = delta_lon; + var d_phi_n = 1; // d_phi^0 + + var d_psi = 0; + for (n = 1; n <= 10; n++) { + d_phi_n = d_phi_n * d_phi; + d_psi = d_psi + this.A[n] * d_phi_n; + } + + // 2. Calculate theta + var th_re = d_psi; + var th_im = d_lambda; + + // 3. Calculate z + var th_n_re = 1; + var th_n_im = 0; // theta^0 + var th_n_re1; + var th_n_im1; + + var z_re = 0; + var z_im = 0; + for (n = 1; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + z_re = z_re + this.B_re[n] * th_n_re - this.B_im[n] * th_n_im; + z_im = z_im + this.B_im[n] * th_n_re + this.B_re[n] * th_n_im; + } + + // 4. Calculate easting and northing + p.x = (z_im * this.a) + this.x0; + p.y = (z_re * this.a) + this.y0; + + return p; + } + + /** + New Zealand Map Grid Inverse - x/y to long/lat + */ + function inverse$18(p) { + var n; + var x = p.x; + var y = p.y; + + var delta_x = x - this.x0; + var delta_y = y - this.y0; + + // 1. Calculate z + var z_re = delta_y / this.a; + var z_im = delta_x / this.a; + + // 2a. Calculate theta - first approximation gives km accuracy + var z_n_re = 1; + var z_n_im = 0; // z^0 + var z_n_re1; + var z_n_im1; + + var th_re = 0; + var th_im = 0; + for (n = 1; n <= 6; n++) { + z_n_re1 = z_n_re * z_re - z_n_im * z_im; + z_n_im1 = z_n_im * z_re + z_n_re * z_im; + z_n_re = z_n_re1; + z_n_im = z_n_im1; + th_re = th_re + this.C_re[n] * z_n_re - this.C_im[n] * z_n_im; + th_im = th_im + this.C_im[n] * z_n_re + this.C_re[n] * z_n_im; + } + + // 2b. Iterate to refine the accuracy of the calculation + // 0 iterations gives km accuracy + // 1 iteration gives m accuracy -- good enough for most mapping applications + // 2 iterations bives mm accuracy + for (var i = 0; i < this.iterations; i++) { + var th_n_re = th_re; + var th_n_im = th_im; + var th_n_re1; + var th_n_im1; + + var num_re = z_re; + var num_im = z_im; + for (n = 2; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + num_re = num_re + (n - 1) * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im); + num_im = num_im + (n - 1) * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im); + } + + th_n_re = 1; + th_n_im = 0; + var den_re = this.B_re[1]; + var den_im = this.B_im[1]; + for (n = 2; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + den_re = den_re + n * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im); + den_im = den_im + n * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im); + } + + // Complex division + var den2 = den_re * den_re + den_im * den_im; + th_re = (num_re * den_re + num_im * den_im) / den2; + th_im = (num_im * den_re - num_re * den_im) / den2; + } + + // 3. Calculate d_phi ... // and d_lambda + var d_psi = th_re; + var d_lambda = th_im; + var d_psi_n = 1; // d_psi^0 + + var d_phi = 0; + for (n = 1; n <= 9; n++) { + d_psi_n = d_psi_n * d_psi; + d_phi = d_phi + this.D[n] * d_psi_n; + } + + // 4. Calculate latitude and longitude + // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians. + var lat = this.lat0 + (d_phi * SEC_TO_RAD * 1E5); + var lon = this.long0 + d_lambda; + + p.x = lon; + p.y = lat; + + return p; + } + + var names$20 = ["New_Zealand_Map_Grid", "nzmg"]; + var nzmg = { + init: init$19, + forward: forward$18, + inverse: inverse$18, + names: names$20 + }; + + /* + reference + "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + */ + + + /* Initialize the Miller Cylindrical projection + -------------------------------------------*/ + function init$20() { + //no-op + } + + /* Miller Cylindrical forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ + function forward$19(p) { + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + var x = this.x0 + this.a * dlon; + var y = this.y0 + this.a * Math.log(Math.tan((Math.PI / 4) + (lat / 2.5))) * 1.25; + + p.x = x; + p.y = y; + return p; + } + + /* Miller Cylindrical inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ + function inverse$19(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = adjust_lon(this.long0 + p.x / this.a); + var lat = 2.5 * (Math.atan(Math.exp(0.8 * p.y / this.a)) - Math.PI / 4); + + p.x = lon; + p.y = lat; + return p; + } + + var names$21 = ["Miller_Cylindrical", "mill"]; + var mill = { + init: init$20, + forward: forward$19, + inverse: inverse$19, + names: names$21 + }; + + var MAX_ITER$3 = 20; + function init$21() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + + if (!this.sphere) { + this.en = pj_enfn(this.es); + } + else { + this.n = 1; + this.m = 0; + this.es = 0; + this.C_y = Math.sqrt((this.m + 1) / this.n); + this.C_x = this.C_y / (this.m + 1); + } + + } + + /* Sinusoidal forward equations--mapping lat,long to x,y + -----------------------------------------------------*/ + function forward$20(p) { + var x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + lon = adjust_lon(lon - this.long0); + + if (this.sphere) { + if (!this.m) { + lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat; + } + else { + var k = this.n * Math.sin(lat); + for (var i = MAX_ITER$3; i; --i) { + var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat)); + lat -= V; + if (Math.abs(V) < EPSLN) { + break; + } + } + } + x = this.a * this.C_x * lon * (this.m + Math.cos(lat)); + y = this.a * this.C_y * lat; + + } + else { + + var s = Math.sin(lat); + var c = Math.cos(lat); + y = this.a * pj_mlfn(lat, s, c, this.en); + x = this.a * lon * c / Math.sqrt(1 - this.es * s * s); + } + + p.x = x; + p.y = y; + return p; + } + + function inverse$20(p) { + var lat, temp, lon, s; + + p.x -= this.x0; + lon = p.x / this.a; + p.y -= this.y0; + lat = p.y / this.a; + + if (this.sphere) { + lat /= this.C_y; + lon = lon / (this.C_x * (this.m + Math.cos(lat))); + if (this.m) { + lat = asinz((this.m * lat + Math.sin(lat)) / this.n); + } + else if (this.n !== 1) { + lat = asinz(Math.sin(lat) / this.n); + } + lon = adjust_lon(lon + this.long0); + lat = adjust_lat(lat); + } + else { + lat = pj_inv_mlfn(p.y / this.a, this.es, this.en); + s = Math.abs(lat); + if (s < HALF_PI) { + s = Math.sin(lat); + temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat)); + //temp = this.long0 + p.x / (this.a * Math.cos(lat)); + lon = adjust_lon(temp); + } + else if ((s - EPSLN) < HALF_PI) { + lon = this.long0; + } + } + p.x = lon; + p.y = lat; + return p; + } + + var names$22 = ["Sinusoidal", "sinu"]; + var sinu = { + init: init$21, + forward: forward$20, + inverse: inverse$20, + names: names$22 + }; + + function init$22() {} + /* Mollweide forward equations--mapping lat,long to x,y + ----------------------------------------------------*/ + function forward$21(p) { + + /* Forward equations + -----------------*/ + var lon = p.x; + var lat = p.y; + + var delta_lon = adjust_lon(lon - this.long0); + var theta = lat; + var con = Math.PI * Math.sin(lat); + + /* Iterate using the Newton-Raphson method to find theta + -----------------------------------------------------*/ + while (true) { + var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta)); + theta += delta_theta; + if (Math.abs(delta_theta) < EPSLN) { + break; + } + } + theta /= 2; + + /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting" + this is done here because of precision problems with "cos(theta)" + --------------------------------------------------------------------------*/ + if (Math.PI / 2 - Math.abs(lat) < EPSLN) { + delta_lon = 0; + } + var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0; + var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0; + + p.x = x; + p.y = y; + return p; + } + + function inverse$21(p) { + var theta; + var arg; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + arg = p.y / (1.4142135623731 * this.a); + + /* Because of division by zero problems, 'arg' can not be 1. Therefore + a number very close to one is used instead. + -------------------------------------------------------------------*/ + if (Math.abs(arg) > 0.999999999999) { + arg = 0.999999999999; + } + theta = Math.asin(arg); + var lon = adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta)))); + if (lon < (-Math.PI)) { + lon = -Math.PI; + } + if (lon > Math.PI) { + lon = Math.PI; + } + arg = (2 * theta + Math.sin(2 * theta)) / Math.PI; + if (Math.abs(arg) > 1) { + arg = 1; + } + var lat = Math.asin(arg); + + p.x = lon; + p.y = lat; + return p; + } + + var names$23 = ["Mollweide", "moll"]; + var moll = { + init: init$22, + forward: forward$21, + inverse: inverse$21, + names: names$23 + }; + + function init$23() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + this.lat2 = this.lat2 || this.lat1; + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); + this.e = Math.sqrt(this.es); + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + + this.sinphi = Math.sin(this.lat1); + this.cosphi = Math.cos(this.lat1); + + this.ms1 = msfnz(this.e, this.sinphi, this.cosphi); + this.ml1 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat1); + + if (Math.abs(this.lat1 - this.lat2) < EPSLN) { + this.ns = this.sinphi; + } + else { + this.sinphi = Math.sin(this.lat2); + this.cosphi = Math.cos(this.lat2); + this.ms2 = msfnz(this.e, this.sinphi, this.cosphi); + this.ml2 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2); + this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1); + } + this.g = this.ml1 + this.ms1 / this.ns; + this.ml0 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); + this.rh = this.a * (this.g - this.ml0); + } + + /* Equidistant Conic forward equations--mapping lat,long to x,y + -----------------------------------------------------------*/ + function forward$22(p) { + var lon = p.x; + var lat = p.y; + var rh1; + + /* Forward equations + -----------------*/ + if (this.sphere) { + rh1 = this.a * (this.g - lat); + } + else { + var ml = mlfn(this.e0, this.e1, this.e2, this.e3, lat); + rh1 = this.a * (this.g - ml); + } + var theta = this.ns * adjust_lon(lon - this.long0); + var x = this.x0 + rh1 * Math.sin(theta); + var y = this.y0 + this.rh - rh1 * Math.cos(theta); + p.x = x; + p.y = y; + return p; + } + + /* Inverse equations + -----------------*/ + function inverse$22(p) { + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + var con, rh1, lat, lon; + if (this.ns >= 0) { + rh1 = Math.sqrt(p.x * p.x + p.y * p.y); + con = 1; + } + else { + rh1 = -Math.sqrt(p.x * p.x + p.y * p.y); + con = -1; + } + var theta = 0; + if (rh1 !== 0) { + theta = Math.atan2(con * p.x, con * p.y); + } + + if (this.sphere) { + lon = adjust_lon(this.long0 + theta / this.ns); + lat = adjust_lat(this.g - rh1 / this.a); + p.x = lon; + p.y = lat; + return p; + } + else { + var ml = this.g - rh1 / this.a; + lat = imlfn(ml, this.e0, this.e1, this.e2, this.e3); + lon = adjust_lon(this.long0 + theta / this.ns); + p.x = lon; + p.y = lat; + return p; + } + + } + + var names$24 = ["Equidistant_Conic", "eqdc"]; + var eqdc = { + init: init$23, + forward: forward$22, + inverse: inverse$22, + names: names$24 + }; + + /* Initialize the Van Der Grinten projection + ----------------------------------------*/ + function init$24() { + //this.R = 6370997; //Radius of earth + this.R = this.a; + } + + function forward$23(p) { + + var lon = p.x; + var lat = p.y; + + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + var x, y; + + if (Math.abs(lat) <= EPSLN) { + x = this.x0 + this.R * dlon; + y = this.y0; + } + var theta = asinz(2 * Math.abs(lat / Math.PI)); + if ((Math.abs(dlon) <= EPSLN) || (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN)) { + x = this.x0; + if (lat >= 0) { + y = this.y0 + Math.PI * this.R * Math.tan(0.5 * theta); + } + else { + y = this.y0 + Math.PI * this.R * -Math.tan(0.5 * theta); + } + // return(OK); + } + var al = 0.5 * Math.abs((Math.PI / dlon) - (dlon / Math.PI)); + var asq = al * al; + var sinth = Math.sin(theta); + var costh = Math.cos(theta); + + var g = costh / (sinth + costh - 1); + var gsq = g * g; + var m = g * (2 / sinth - 1); + var msq = m * m; + var con = Math.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq); + if (dlon < 0) { + con = -con; + } + x = this.x0 + con; + //con = Math.abs(con / (Math.PI * this.R)); + var q = asq + g; + con = Math.PI * this.R * (m * q - al * Math.sqrt((msq + asq) * (asq + 1) - q * q)) / (msq + asq); + if (lat >= 0) { + //y = this.y0 + Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con); + y = this.y0 + con; + } + else { + //y = this.y0 - Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con); + y = this.y0 - con; + } + p.x = x; + p.y = y; + return p; + } + + /* Van Der Grinten inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ + function inverse$23(p) { + var lon, lat; + var xx, yy, xys, c1, c2, c3; + var a1; + var m1; + var con; + var th1; + var d; + + /* inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + con = Math.PI * this.R; + xx = p.x / con; + yy = p.y / con; + xys = xx * xx + yy * yy; + c1 = -Math.abs(yy) * (1 + xys); + c2 = c1 - 2 * yy * yy + xx * xx; + c3 = -2 * c1 + 1 + 2 * yy * yy + xys * xys; + d = yy * yy / c3 + (2 * c2 * c2 * c2 / c3 / c3 / c3 - 9 * c1 * c2 / c3 / c3) / 27; + a1 = (c1 - c2 * c2 / 3 / c3) / c3; + m1 = 2 * Math.sqrt(-a1 / 3); + con = ((3 * d) / a1) / m1; + if (Math.abs(con) > 1) { + if (con >= 0) { + con = 1; + } + else { + con = -1; + } + } + th1 = Math.acos(con) / 3; + if (p.y >= 0) { + lat = (-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI; + } + else { + lat = -(-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI; + } + + if (Math.abs(xx) < EPSLN) { + lon = this.long0; + } + else { + lon = adjust_lon(this.long0 + Math.PI * (xys - 1 + Math.sqrt(1 + 2 * (xx * xx - yy * yy) + xys * xys)) / 2 / xx); + } + + p.x = lon; + p.y = lat; + return p; + } + + var names$25 = ["Van_der_Grinten_I", "VanDerGrinten", "vandg"]; + var vandg = { + init: init$24, + forward: forward$23, + inverse: inverse$23, + names: names$25 + }; + + function init$25() { + this.sin_p12 = Math.sin(this.lat0); + this.cos_p12 = Math.cos(this.lat0); + } + + function forward$24(p) { + var lon = p.x; + var lat = p.y; + var sinphi = Math.sin(p.y); + var cosphi = Math.cos(p.y); + var dlon = adjust_lon(lon - this.long0); + var e0, e1, e2, e3, Mlp, Ml, tanphi, Nl1, Nl, psi, Az, G, H, GH, Hs, c, kp, cos_c, s, s2, s3, s4, s5; + if (this.sphere) { + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North Pole case + p.x = this.x0 + this.a * (HALF_PI - lat) * Math.sin(dlon); + p.y = this.y0 - this.a * (HALF_PI - lat) * Math.cos(dlon); + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South Pole case + p.x = this.x0 + this.a * (HALF_PI + lat) * Math.sin(dlon); + p.y = this.y0 + this.a * (HALF_PI + lat) * Math.cos(dlon); + return p; + } + else { + //default case + cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon); + c = Math.acos(cos_c); + kp = c ? c / Math.sin(c) : 1; + p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon); + p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon)); + return p; + } + } + else { + e0 = e0fn(this.es); + e1 = e1fn(this.es); + e2 = e2fn(this.es); + e3 = e3fn(this.es); + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North Pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + Ml = this.a * mlfn(e0, e1, e2, e3, lat); + p.x = this.x0 + (Mlp - Ml) * Math.sin(dlon); + p.y = this.y0 - (Mlp - Ml) * Math.cos(dlon); + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South Pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + Ml = this.a * mlfn(e0, e1, e2, e3, lat); + p.x = this.x0 + (Mlp + Ml) * Math.sin(dlon); + p.y = this.y0 + (Mlp + Ml) * Math.cos(dlon); + return p; + } + else { + //Default case + tanphi = sinphi / cosphi; + Nl1 = gN(this.a, this.e, this.sin_p12); + Nl = gN(this.a, this.e, sinphi); + psi = Math.atan((1 - this.es) * tanphi + this.es * Nl1 * this.sin_p12 / (Nl * cosphi)); + Az = Math.atan2(Math.sin(dlon), this.cos_p12 * Math.tan(psi) - this.sin_p12 * Math.cos(dlon)); + if (Az === 0) { + s = Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi)); + } + else if (Math.abs(Math.abs(Az) - Math.PI) <= EPSLN) { + s = -Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi)); + } + else { + s = Math.asin(Math.sin(dlon) * Math.cos(psi) / Math.sin(Az)); + } + G = this.e * this.sin_p12 / Math.sqrt(1 - this.es); + H = this.e * this.cos_p12 * Math.cos(Az) / Math.sqrt(1 - this.es); + GH = G * H; + Hs = H * H; + s2 = s * s; + s3 = s2 * s; + s4 = s3 * s; + s5 = s4 * s; + c = Nl1 * s * (1 - s2 * Hs * (1 - Hs) / 6 + s3 / 8 * GH * (1 - 2 * Hs) + s4 / 120 * (Hs * (4 - 7 * Hs) - 3 * G * G * (1 - 7 * Hs)) - s5 / 48 * GH); + p.x = this.x0 + c * Math.sin(Az); + p.y = this.y0 + c * Math.cos(Az); + return p; + } + } + + + } + + function inverse$24(p) { + p.x -= this.x0; + p.y -= this.y0; + var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F, sinpsi; + if (this.sphere) { + rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (rh > (2 * HALF_PI * this.a)) { + return; + } + z = rh / this.a; + + sinz = Math.sin(z); + cosz = Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= EPSLN) { + lat = this.lat0; + } + else { + lat = asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh); + con = Math.abs(this.lat0) - HALF_PI; + if (Math.abs(con) <= EPSLN) { + if (this.lat0 >= 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y)); + } + else { + lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y)); + } + } + else { + /*con = cosz - this.sin_p12 * Math.sin(lat); + if ((Math.abs(con) < EPSLN) && (Math.abs(p.x) < EPSLN)) { + //no-op, just keep the lon value as is + } else { + var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh)); + lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh))); + }*/ + lon = adjust_lon(this.long0 + Math.atan2(p.x * sinz, rh * this.cos_p12 * cosz - p.y * this.sin_p12 * sinz)); + } + } + + p.x = lon; + p.y = lat; + return p; + } + else { + e0 = e0fn(this.es); + e1 = e1fn(this.es); + e2 = e2fn(this.es); + e3 = e3fn(this.es); + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + rh = Math.sqrt(p.x * p.x + p.y * p.y); + M = Mlp - rh; + lat = imlfn(M / this.a, e0, e1, e2, e3); + lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y)); + p.x = lon; + p.y = lat; + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + rh = Math.sqrt(p.x * p.x + p.y * p.y); + M = rh - Mlp; + + lat = imlfn(M / this.a, e0, e1, e2, e3); + lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y)); + p.x = lon; + p.y = lat; + return p; + } + else { + //default case + rh = Math.sqrt(p.x * p.x + p.y * p.y); + Az = Math.atan2(p.x, p.y); + N1 = gN(this.a, this.e, this.sin_p12); + cosAz = Math.cos(Az); + tmp = this.e * this.cos_p12 * cosAz; + A = -tmp * tmp / (1 - this.es); + B = 3 * this.es * (1 - A) * this.sin_p12 * this.cos_p12 * cosAz / (1 - this.es); + D = rh / N1; + Ee = D - A * (1 + A) * Math.pow(D, 3) / 6 - B * (1 + 3 * A) * Math.pow(D, 4) / 24; + F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6; + psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz); + lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi))); + sinpsi = Math.sin(psi); + lat = Math.atan2((sinpsi - this.es * F * this.sin_p12) * Math.tan(psi), sinpsi * (1 - this.es)); + p.x = lon; + p.y = lat; + return p; + } + } + + } + + var names$26 = ["Azimuthal_Equidistant", "aeqd"]; + var aeqd = { + init: init$25, + forward: forward$24, + inverse: inverse$24, + names: names$26 + }; + + function init$26() { + //double temp; /* temporary variable */ + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14 = Math.sin(this.lat0); + this.cos_p14 = Math.cos(this.lat0); + } + + /* Orthographic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + function forward$25(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g, x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + dlon = adjust_lon(lon - this.long0); + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1; + if ((g > 0) || (Math.abs(g) <= EPSLN)) { + x = this.a * ksp * cosphi * Math.sin(dlon); + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + } + p.x = x; + p.y = y; + return p; + } + + function inverse$25(p) { + var rh; /* height above ellipsoid */ + var z; /* angle */ + var sinz, cosz; /* sin of z and cos of z */ + var con; + var lon, lat; + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + rh = Math.sqrt(p.x * p.x + p.y * p.y); + z = asinz(rh / this.a); + + sinz = Math.sin(z); + cosz = Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= EPSLN) { + lat = this.lat0; + p.x = lon; + p.y = lat; + return p; + } + lat = asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14) / rh); + con = Math.abs(this.lat0) - HALF_PI; + if (Math.abs(con) <= EPSLN) { + if (this.lat0 >= 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y)); + } + else { + lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y)); + } + p.x = lon; + p.y = lat; + return p; + } + lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz), rh * this.cos_p14 * cosz - p.y * this.sin_p14 * sinz)); + p.x = lon; + p.y = lat; + return p; + } + + var names$27 = ["ortho"]; + var ortho = { + init: init$26, + forward: forward$25, + inverse: inverse$25, + names: names$27 + }; + + // QSC projection rewritten from the original PROJ4 + // https://github.com/OSGeo/proj.4/blob/master/src/PJ_qsc.c + + /* constants */ + var FACE_ENUM = { + FRONT: 1, + RIGHT: 2, + BACK: 3, + LEFT: 4, + TOP: 5, + BOTTOM: 6 + }; + + var AREA_ENUM = { + AREA_0: 1, + AREA_1: 2, + AREA_2: 3, + AREA_3: 4 + }; + + function init$27() { + + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.lat0 = this.lat0 || 0; + this.long0 = this.long0 || 0; + this.lat_ts = this.lat_ts || 0; + this.title = this.title || "Quadrilateralized Spherical Cube"; + + /* Determine the cube face from the center of projection. */ + if (this.lat0 >= HALF_PI - FORTPI / 2.0) { + this.face = FACE_ENUM.TOP; + } else if (this.lat0 <= -(HALF_PI - FORTPI / 2.0)) { + this.face = FACE_ENUM.BOTTOM; + } else if (Math.abs(this.long0) <= FORTPI) { + this.face = FACE_ENUM.FRONT; + } else if (Math.abs(this.long0) <= HALF_PI + FORTPI) { + this.face = this.long0 > 0.0 ? FACE_ENUM.RIGHT : FACE_ENUM.LEFT; + } else { + this.face = FACE_ENUM.BACK; + } + + /* Fill in useful values for the ellipsoid <-> sphere shift + * described in [LK12]. */ + if (this.es !== 0) { + this.one_minus_f = 1 - (this.a - this.b) / this.a; + this.one_minus_f_squared = this.one_minus_f * this.one_minus_f; + } + } + + // QSC forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + function forward$26(p) { + var xy = {x: 0, y: 0}; + var lat, lon; + var theta, phi; + var t, mu; + /* nu; */ + var area = {value: 0}; + + // move lon according to projection's lon + p.x -= this.long0; + + /* Convert the geodetic latitude to a geocentric latitude. + * This corresponds to the shift from the ellipsoid to the sphere + * described in [LK12]. */ + if (this.es !== 0) {//if (P->es != 0) { + lat = Math.atan(this.one_minus_f_squared * Math.tan(p.y)); + } else { + lat = p.y; + } + + /* Convert the input lat, lon into theta, phi as used by QSC. + * This depends on the cube face and the area on it. + * For the top and bottom face, we can compute theta and phi + * directly from phi, lam. For the other faces, we must use + * unit sphere cartesian coordinates as an intermediate step. */ + lon = p.x; //lon = lp.lam; + if (this.face === FACE_ENUM.TOP) { + phi = HALF_PI - lat; + if (lon >= FORTPI && lon <= HALF_PI + FORTPI) { + area.value = AREA_ENUM.AREA_0; + theta = lon - HALF_PI; + } else if (lon > HALF_PI + FORTPI || lon <= -(HALF_PI + FORTPI)) { + area.value = AREA_ENUM.AREA_1; + theta = (lon > 0.0 ? lon - SPI : lon + SPI); + } else if (lon > -(HALF_PI + FORTPI) && lon <= -FORTPI) { + area.value = AREA_ENUM.AREA_2; + theta = lon + HALF_PI; + } else { + area.value = AREA_ENUM.AREA_3; + theta = lon; + } + } else if (this.face === FACE_ENUM.BOTTOM) { + phi = HALF_PI + lat; + if (lon >= FORTPI && lon <= HALF_PI + FORTPI) { + area.value = AREA_ENUM.AREA_0; + theta = -lon + HALF_PI; + } else if (lon < FORTPI && lon >= -FORTPI) { + area.value = AREA_ENUM.AREA_1; + theta = -lon; + } else if (lon < -FORTPI && lon >= -(HALF_PI + FORTPI)) { + area.value = AREA_ENUM.AREA_2; + theta = -lon - HALF_PI; + } else { + area.value = AREA_ENUM.AREA_3; + theta = (lon > 0.0 ? -lon + SPI : -lon - SPI); + } + } else { + var q, r, s; + var sinlat, coslat; + var sinlon, coslon; + + if (this.face === FACE_ENUM.RIGHT) { + lon = qsc_shift_lon_origin(lon, +HALF_PI); + } else if (this.face === FACE_ENUM.BACK) { + lon = qsc_shift_lon_origin(lon, +SPI); + } else if (this.face === FACE_ENUM.LEFT) { + lon = qsc_shift_lon_origin(lon, -HALF_PI); + } + sinlat = Math.sin(lat); + coslat = Math.cos(lat); + sinlon = Math.sin(lon); + coslon = Math.cos(lon); + q = coslat * coslon; + r = coslat * sinlon; + s = sinlat; + + if (this.face === FACE_ENUM.FRONT) { + phi = Math.acos(q); + theta = qsc_fwd_equat_face_theta(phi, s, r, area); + } else if (this.face === FACE_ENUM.RIGHT) { + phi = Math.acos(r); + theta = qsc_fwd_equat_face_theta(phi, s, -q, area); + } else if (this.face === FACE_ENUM.BACK) { + phi = Math.acos(-q); + theta = qsc_fwd_equat_face_theta(phi, s, -r, area); + } else if (this.face === FACE_ENUM.LEFT) { + phi = Math.acos(-r); + theta = qsc_fwd_equat_face_theta(phi, s, q, area); + } else { + /* Impossible */ + phi = theta = 0; + area.value = AREA_ENUM.AREA_0; + } + } + + /* Compute mu and nu for the area of definition. + * For mu, see Eq. (3-21) in [OL76], but note the typos: + * compare with Eq. (3-14). For nu, see Eq. (3-38). */ + mu = Math.atan((12 / SPI) * (theta + Math.acos(Math.sin(theta) * Math.cos(FORTPI)) - HALF_PI)); + t = Math.sqrt((1 - Math.cos(phi)) / (Math.cos(mu) * Math.cos(mu)) / (1 - Math.cos(Math.atan(1 / Math.cos(theta))))); + + /* Apply the result to the real area. */ + if (area.value === AREA_ENUM.AREA_1) { + mu += HALF_PI; + } else if (area.value === AREA_ENUM.AREA_2) { + mu += SPI; + } else if (area.value === AREA_ENUM.AREA_3) { + mu += 1.5 * SPI; + } + + /* Now compute x, y from mu and nu */ + xy.x = t * Math.cos(mu); + xy.y = t * Math.sin(mu); + xy.x = xy.x * this.a + this.x0; + xy.y = xy.y * this.a + this.y0; + + p.x = xy.x; + p.y = xy.y; + return p; + } + + // QSC inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + function inverse$26(p) { + var lp = {lam: 0, phi: 0}; + var mu, nu, cosmu, tannu; + var tantheta, theta, cosphi, phi; + var t; + var area = {value: 0}; + + /* de-offset */ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + /* Convert the input x, y to the mu and nu angles as used by QSC. + * This depends on the area of the cube face. */ + nu = Math.atan(Math.sqrt(p.x * p.x + p.y * p.y)); + mu = Math.atan2(p.y, p.x); + if (p.x >= 0.0 && p.x >= Math.abs(p.y)) { + area.value = AREA_ENUM.AREA_0; + } else if (p.y >= 0.0 && p.y >= Math.abs(p.x)) { + area.value = AREA_ENUM.AREA_1; + mu -= HALF_PI; + } else if (p.x < 0.0 && -p.x >= Math.abs(p.y)) { + area.value = AREA_ENUM.AREA_2; + mu = (mu < 0.0 ? mu + SPI : mu - SPI); + } else { + area.value = AREA_ENUM.AREA_3; + mu += HALF_PI; + } + + /* Compute phi and theta for the area of definition. + * The inverse projection is not described in the original paper, but some + * good hints can be found here (as of 2011-12-14): + * http://fits.gsfc.nasa.gov/fitsbits/saf.93/saf.9302 + * (search for "Message-Id: <9302181759.AA25477 at fits.cv.nrao.edu>") */ + t = (SPI / 12) * Math.tan(mu); + tantheta = Math.sin(t) / (Math.cos(t) - (1 / Math.sqrt(2))); + theta = Math.atan(tantheta); + cosmu = Math.cos(mu); + tannu = Math.tan(nu); + cosphi = 1 - cosmu * cosmu * tannu * tannu * (1 - Math.cos(Math.atan(1 / Math.cos(theta)))); + if (cosphi < -1) { + cosphi = -1; + } else if (cosphi > +1) { + cosphi = +1; + } + + /* Apply the result to the real area on the cube face. + * For the top and bottom face, we can compute phi and lam directly. + * For the other faces, we must use unit sphere cartesian coordinates + * as an intermediate step. */ + if (this.face === FACE_ENUM.TOP) { + phi = Math.acos(cosphi); + lp.phi = HALF_PI - phi; + if (area.value === AREA_ENUM.AREA_0) { + lp.lam = theta + HALF_PI; + } else if (area.value === AREA_ENUM.AREA_1) { + lp.lam = (theta < 0.0 ? theta + SPI : theta - SPI); + } else if (area.value === AREA_ENUM.AREA_2) { + lp.lam = theta - HALF_PI; + } else /* area.value == AREA_ENUM.AREA_3 */ { + lp.lam = theta; + } + } else if (this.face === FACE_ENUM.BOTTOM) { + phi = Math.acos(cosphi); + lp.phi = phi - HALF_PI; + if (area.value === AREA_ENUM.AREA_0) { + lp.lam = -theta + HALF_PI; + } else if (area.value === AREA_ENUM.AREA_1) { + lp.lam = -theta; + } else if (area.value === AREA_ENUM.AREA_2) { + lp.lam = -theta - HALF_PI; + } else /* area.value == AREA_ENUM.AREA_3 */ { + lp.lam = (theta < 0.0 ? -theta - SPI : -theta + SPI); + } + } else { + /* Compute phi and lam via cartesian unit sphere coordinates. */ + var q, r, s; + q = cosphi; + t = q * q; + if (t >= 1) { + s = 0; + } else { + s = Math.sqrt(1 - t) * Math.sin(theta); + } + t += s * s; + if (t >= 1) { + r = 0; + } else { + r = Math.sqrt(1 - t); + } + /* Rotate q,r,s into the correct area. */ + if (area.value === AREA_ENUM.AREA_1) { + t = r; + r = -s; + s = t; + } else if (area.value === AREA_ENUM.AREA_2) { + r = -r; + s = -s; + } else if (area.value === AREA_ENUM.AREA_3) { + t = r; + r = s; + s = -t; + } + /* Rotate q,r,s into the correct cube face. */ + if (this.face === FACE_ENUM.RIGHT) { + t = q; + q = -r; + r = t; + } else if (this.face === FACE_ENUM.BACK) { + q = -q; + r = -r; + } else if (this.face === FACE_ENUM.LEFT) { + t = q; + q = r; + r = -t; + } + /* Now compute phi and lam from the unit sphere coordinates. */ + lp.phi = Math.acos(-s) - HALF_PI; + lp.lam = Math.atan2(r, q); + if (this.face === FACE_ENUM.RIGHT) { + lp.lam = qsc_shift_lon_origin(lp.lam, -HALF_PI); + } else if (this.face === FACE_ENUM.BACK) { + lp.lam = qsc_shift_lon_origin(lp.lam, -SPI); + } else if (this.face === FACE_ENUM.LEFT) { + lp.lam = qsc_shift_lon_origin(lp.lam, +HALF_PI); + } + } + + /* Apply the shift from the sphere to the ellipsoid as described + * in [LK12]. */ + if (this.es !== 0) { + var invert_sign; + var tanphi, xa; + invert_sign = (lp.phi < 0 ? 1 : 0); + tanphi = Math.tan(lp.phi); + xa = this.b / Math.sqrt(tanphi * tanphi + this.one_minus_f_squared); + lp.phi = Math.atan(Math.sqrt(this.a * this.a - xa * xa) / (this.one_minus_f * xa)); + if (invert_sign) { + lp.phi = -lp.phi; + } + } + + lp.lam += this.long0; + p.x = lp.lam; + p.y = lp.phi; + return p; + } + + /* Helper function for forward projection: compute the theta angle + * and determine the area number. */ + function qsc_fwd_equat_face_theta(phi, y, x, area) { + var theta; + if (phi < EPSLN) { + area.value = AREA_ENUM.AREA_0; + theta = 0.0; + } else { + theta = Math.atan2(y, x); + if (Math.abs(theta) <= FORTPI) { + area.value = AREA_ENUM.AREA_0; + } else if (theta > FORTPI && theta <= HALF_PI + FORTPI) { + area.value = AREA_ENUM.AREA_1; + theta -= HALF_PI; + } else if (theta > HALF_PI + FORTPI || theta <= -(HALF_PI + FORTPI)) { + area.value = AREA_ENUM.AREA_2; + theta = (theta >= 0.0 ? theta - SPI : theta + SPI); + } else { + area.value = AREA_ENUM.AREA_3; + theta += HALF_PI; + } + } + return theta; + } + + /* Helper function: shift the longitude. */ + function qsc_shift_lon_origin(lon, offset) { + var slon = lon + offset; + if (slon < -SPI) { + slon += TWO_PI; + } else if (slon > +SPI) { + slon -= TWO_PI; + } + return slon; + } + + var names$28 = ["Quadrilateralized Spherical Cube", "Quadrilateralized_Spherical_Cube", "qsc"]; + var qsc = { + init: init$27, + forward: forward$26, + inverse: inverse$26, + names: names$28 + }; + + // Robinson projection + // Based on https://github.com/OSGeo/proj.4/blob/master/src/PJ_robin.c + // Polynomial coeficients from http://article.gmane.org/gmane.comp.gis.proj-4.devel/6039 + + var COEFS_X = [ + [1.0000, 2.2199e-17, -7.15515e-05, 3.1103e-06], + [0.9986, -0.000482243, -2.4897e-05, -1.3309e-06], + [0.9954, -0.00083103, -4.48605e-05, -9.86701e-07], + [0.9900, -0.00135364, -5.9661e-05, 3.6777e-06], + [0.9822, -0.00167442, -4.49547e-06, -5.72411e-06], + [0.9730, -0.00214868, -9.03571e-05, 1.8736e-08], + [0.9600, -0.00305085, -9.00761e-05, 1.64917e-06], + [0.9427, -0.00382792, -6.53386e-05, -2.6154e-06], + [0.9216, -0.00467746, -0.00010457, 4.81243e-06], + [0.8962, -0.00536223, -3.23831e-05, -5.43432e-06], + [0.8679, -0.00609363, -0.000113898, 3.32484e-06], + [0.8350, -0.00698325, -6.40253e-05, 9.34959e-07], + [0.7986, -0.00755338, -5.00009e-05, 9.35324e-07], + [0.7597, -0.00798324, -3.5971e-05, -2.27626e-06], + [0.7186, -0.00851367, -7.01149e-05, -8.6303e-06], + [0.6732, -0.00986209, -0.000199569, 1.91974e-05], + [0.6213, -0.010418, 8.83923e-05, 6.24051e-06], + [0.5722, -0.00906601, 0.000182, 6.24051e-06], + [0.5322, -0.00677797, 0.000275608, 6.24051e-06] + ]; + + var COEFS_Y = [ + [-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11], + [0.0620, 0.0124, -1.26793e-09, 4.22642e-10], + [0.1240, 0.0124, 5.07171e-09, -1.60604e-09], + [0.1860, 0.0123999, -1.90189e-08, 6.00152e-09], + [0.2480, 0.0124002, 7.10039e-08, -2.24e-08], + [0.3100, 0.0123992, -2.64997e-07, 8.35986e-08], + [0.3720, 0.0124029, 9.88983e-07, -3.11994e-07], + [0.4340, 0.0123893, -3.69093e-06, -4.35621e-07], + [0.4958, 0.0123198, -1.02252e-05, -3.45523e-07], + [0.5571, 0.0121916, -1.54081e-05, -5.82288e-07], + [0.6176, 0.0119938, -2.41424e-05, -5.25327e-07], + [0.6769, 0.011713, -3.20223e-05, -5.16405e-07], + [0.7346, 0.0113541, -3.97684e-05, -6.09052e-07], + [0.7903, 0.0109107, -4.89042e-05, -1.04739e-06], + [0.8435, 0.0103431, -6.4615e-05, -1.40374e-09], + [0.8936, 0.00969686, -6.4636e-05, -8.547e-06], + [0.9394, 0.00840947, -0.000192841, -4.2106e-06], + [0.9761, 0.00616527, -0.000256, -4.2106e-06], + [1.0000, 0.00328947, -0.000319159, -4.2106e-06] + ]; + + var FXC = 0.8487; + var FYC = 1.3523; + var C1 = R2D/5; // rad to 5-degree interval + var RC1 = 1/C1; + var NODES = 18; + + var poly3_val = function(coefs, x) { + return coefs[0] + x * (coefs[1] + x * (coefs[2] + x * coefs[3])); + }; + + var poly3_der = function(coefs, x) { + return coefs[1] + x * (2 * coefs[2] + x * 3 * coefs[3]); + }; + + function newton_rapshon(f_df, start, max_err, iters) { + var x = start; + for (; iters; --iters) { + var upd = f_df(x); + x -= upd; + if (Math.abs(upd) < max_err) { + break; + } + } + return x; + } + + function init$28() { + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.long0 = this.long0 || 0; + this.es = 0; + this.title = this.title || "Robinson"; + } + + function forward$27(ll) { + var lon = adjust_lon(ll.x - this.long0); + + var dphi = Math.abs(ll.y); + var i = Math.floor(dphi * C1); + if (i < 0) { + i = 0; + } else if (i >= NODES) { + i = NODES - 1; + } + dphi = R2D * (dphi - RC1 * i); + var xy = { + x: poly3_val(COEFS_X[i], dphi) * lon, + y: poly3_val(COEFS_Y[i], dphi) + }; + if (ll.y < 0) { + xy.y = -xy.y; + } + + xy.x = xy.x * this.a * FXC + this.x0; + xy.y = xy.y * this.a * FYC + this.y0; + return xy; + } + + function inverse$27(xy) { + var ll = { + x: (xy.x - this.x0) / (this.a * FXC), + y: Math.abs(xy.y - this.y0) / (this.a * FYC) + }; + + if (ll.y >= 1) { // pathologic case + ll.x /= COEFS_X[NODES][0]; + ll.y = xy.y < 0 ? -HALF_PI : HALF_PI; + } else { + // find table interval + var i = Math.floor(ll.y * NODES); + if (i < 0) { + i = 0; + } else if (i >= NODES) { + i = NODES - 1; + } + for (;;) { + if (COEFS_Y[i][0] > ll.y) { + --i; + } else if (COEFS_Y[i+1][0] <= ll.y) { + ++i; + } else { + break; + } + } + // linear interpolation in 5 degree interval + var coefs = COEFS_Y[i]; + var t = 5 * (ll.y - coefs[0]) / (COEFS_Y[i+1][0] - coefs[0]); + // find t so that poly3_val(coefs, t) = ll.y + t = newton_rapshon(function(x) { + return (poly3_val(coefs, x) - ll.y) / poly3_der(coefs, x); + }, t, EPSLN, 100); + + ll.x /= poly3_val(COEFS_X[i], t); + ll.y = (5 * i + t) * D2R; + if (xy.y < 0) { + ll.y = -ll.y; + } + } + + ll.x = adjust_lon(ll.x + this.long0); + return ll; + } + + var names$29 = ["Robinson", "robin"]; + var robin = { + init: init$28, + forward: forward$27, + inverse: inverse$27, + names: names$29 + }; + + function init$29() { + this.name = 'geocent'; + + } + + function forward$28(p) { + var point = geodeticToGeocentric(p, this.es, this.a); + return point; + } + + function inverse$28(p) { + var point = geocentricToGeodetic(p, this.es, this.a, this.b); + return point; + } + + var names$30 = ["Geocentric", 'geocentric', "geocent", "Geocent"]; + var geocent = { + init: init$29, + forward: forward$28, + inverse: inverse$28, + names: names$30 + }; + + var mode = { + N_POLE: 0, + S_POLE: 1, + EQUIT: 2, + OBLIQ: 3 + }; + + var params = { + h: { def: 100000, num: true }, // default is Karman line, no default in PROJ.7 + azi: { def: 0, num: true, degrees: true }, // default is North + tilt: { def: 0, num: true, degrees: true }, // default is Nadir + long0: { def: 0, num: true }, // default is Greenwich, conversion to rad is automatic + lat0: { def: 0, num: true } // default is Equator, conversion to rad is automatic + }; + + function init$30() { + Object.keys(params).forEach(function (p) { + if (typeof this[p] === "undefined") { + this[p] = params[p].def; + } else if (params[p].num && isNaN(this[p])) { + throw new Error("Invalid parameter value, must be numeric " + p + " = " + this[p]); + } else if (params[p].num) { + this[p] = parseFloat(this[p]); + } + if (params[p].degrees) { + this[p] = this[p] * D2R; + } + }.bind(this)); + + if (Math.abs((Math.abs(this.lat0) - HALF_PI)) < EPSLN) { + this.mode = this.lat0 < 0 ? mode.S_POLE : mode.N_POLE; + } else if (Math.abs(this.lat0) < EPSLN) { + this.mode = mode.EQUIT; + } else { + this.mode = mode.OBLIQ; + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + + this.pn1 = this.h / this.a; // Normalize relative to the Earth's radius + + if (this.pn1 <= 0 || this.pn1 > 1e10) { + throw new Error("Invalid height"); + } + + this.p = 1 + this.pn1; + this.rp = 1 / this.p; + this.h1 = 1 / this.pn1; + this.pfact = (this.p + 1) * this.h1; + this.es = 0; + + var omega = this.tilt; + var gamma = this.azi; + this.cg = Math.cos(gamma); + this.sg = Math.sin(gamma); + this.cw = Math.cos(omega); + this.sw = Math.sin(omega); + } + + function forward$29(p) { + p.x -= this.long0; + var sinphi = Math.sin(p.y); + var cosphi = Math.cos(p.y); + var coslam = Math.cos(p.x); + var x, y; + switch (this.mode) { + case mode.OBLIQ: + y = this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + break; + case mode.EQUIT: + y = cosphi * coslam; + break; + case mode.S_POLE: + y = -sinphi; + break; + case mode.N_POLE: + y = sinphi; + break; + } + y = this.pn1 / (this.p - y); + x = y * cosphi * Math.sin(p.x); + + switch (this.mode) { + case mode.OBLIQ: + y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + break; + case mode.EQUIT: + y *= sinphi; + break; + case mode.N_POLE: + y *= -(cosphi * coslam); + break; + case mode.S_POLE: + y *= cosphi * coslam; + break; + } + + // Tilt + var yt, ba; + yt = y * this.cg + x * this.sg; + ba = 1 / (yt * this.sw * this.h1 + this.cw); + x = (x * this.cg - y * this.sg) * this.cw * ba; + y = yt * ba; + + p.x = x * this.a; + p.y = y * this.a; + return p; + } + + function inverse$29(p) { + p.x /= this.a; + p.y /= this.a; + var r = { x: p.x, y: p.y }; + + // Un-Tilt + var bm, bq, yt; + yt = 1 / (this.pn1 - p.y * this.sw); + bm = this.pn1 * p.x * yt; + bq = this.pn1 * p.y * this.cw * yt; + p.x = bm * this.cg + bq * this.sg; + p.y = bq * this.cg - bm * this.sg; + + var rh = hypot(p.x, p.y); + if (Math.abs(rh) < EPSLN) { + r.x = 0; + r.y = p.y; + } else { + var cosz, sinz; + sinz = 1 - rh * rh * this.pfact; + sinz = (this.p - Math.sqrt(sinz)) / (this.pn1 / rh + rh / this.pn1); + cosz = Math.sqrt(1 - sinz * sinz); + switch (this.mode) { + case mode.OBLIQ: + r.y = Math.asin(cosz * this.sinph0 + p.y * sinz * this.cosph0 / rh); + p.y = (cosz - this.sinph0 * Math.sin(r.y)) * rh; + p.x *= sinz * this.cosph0; + break; + case mode.EQUIT: + r.y = Math.asin(p.y * sinz / rh); + p.y = cosz * rh; + p.x *= sinz; + break; + case mode.N_POLE: + r.y = Math.asin(cosz); + p.y = -p.y; + break; + case mode.S_POLE: + r.y = -Math.asin(cosz); + break; + } + r.x = Math.atan2(p.x, p.y); + } + + p.x = r.x + this.long0; + p.y = r.y; + return p; + } + + var names$31 = ["Tilted_Perspective", "tpers"]; + var tpers = { + init: init$30, + forward: forward$29, + inverse: inverse$29, + names: names$31 + }; + + function init$31() { + this.flip_axis = (this.sweep === 'x' ? 1 : 0); + this.h = Number(this.h); + this.radius_g_1 = this.h / this.a; + + if (this.radius_g_1 <= 0 || this.radius_g_1 > 1e10) { + throw new Error(); + } + + this.radius_g = 1.0 + this.radius_g_1; + this.C = this.radius_g * this.radius_g - 1.0; + + if (this.es !== 0.0) { + var one_es = 1.0 - this.es; + var rone_es = 1 / one_es; + + this.radius_p = Math.sqrt(one_es); + this.radius_p2 = one_es; + this.radius_p_inv2 = rone_es; + + this.shape = 'ellipse'; // Use as a condition in the forward and inverse functions. + } else { + this.radius_p = 1.0; + this.radius_p2 = 1.0; + this.radius_p_inv2 = 1.0; + + this.shape = 'sphere'; // Use as a condition in the forward and inverse functions. + } + + if (!this.title) { + this.title = "Geostationary Satellite View"; + } + } + + function forward$30(p) { + var lon = p.x; + var lat = p.y; + var tmp, v_x, v_y, v_z; + lon = lon - this.long0; + + if (this.shape === 'ellipse') { + lat = Math.atan(this.radius_p2 * Math.tan(lat)); + var r = this.radius_p / hypot(this.radius_p * Math.cos(lat), Math.sin(lat)); + + v_x = r * Math.cos(lon) * Math.cos(lat); + v_y = r * Math.sin(lon) * Math.cos(lat); + v_z = r * Math.sin(lat); + + if (((this.radius_g - v_x) * v_x - v_y * v_y - v_z * v_z * this.radius_p_inv2) < 0.0) { + p.x = Number.NaN; + p.y = Number.NaN; + return p; + } + + tmp = this.radius_g - v_x; + if (this.flip_axis) { + p.x = this.radius_g_1 * Math.atan(v_y / hypot(v_z, tmp)); + p.y = this.radius_g_1 * Math.atan(v_z / tmp); + } else { + p.x = this.radius_g_1 * Math.atan(v_y / tmp); + p.y = this.radius_g_1 * Math.atan(v_z / hypot(v_y, tmp)); + } + } else if (this.shape === 'sphere') { + tmp = Math.cos(lat); + v_x = Math.cos(lon) * tmp; + v_y = Math.sin(lon) * tmp; + v_z = Math.sin(lat); + tmp = this.radius_g - v_x; + + if (this.flip_axis) { + p.x = this.radius_g_1 * Math.atan(v_y / hypot(v_z, tmp)); + p.y = this.radius_g_1 * Math.atan(v_z / tmp); + } else { + p.x = this.radius_g_1 * Math.atan(v_y / tmp); + p.y = this.radius_g_1 * Math.atan(v_z / hypot(v_y, tmp)); + } + } + p.x = p.x * this.a; + p.y = p.y * this.a; + return p; + } + + function inverse$30(p) { + var v_x = -1.0; + var v_y = 0.0; + var v_z = 0.0; + var a, b, det, k; + + p.x = p.x / this.a; + p.y = p.y / this.a; + + if (this.shape === 'ellipse') { + if (this.flip_axis) { + v_z = Math.tan(p.y / this.radius_g_1); + v_y = Math.tan(p.x / this.radius_g_1) * hypot(1.0, v_z); + } else { + v_y = Math.tan(p.x / this.radius_g_1); + v_z = Math.tan(p.y / this.radius_g_1) * hypot(1.0, v_y); + } + + var v_zp = v_z / this.radius_p; + a = v_y * v_y + v_zp * v_zp + v_x * v_x; + b = 2 * this.radius_g * v_x; + det = (b * b) - 4 * a * this.C; + + if (det < 0.0) { + p.x = Number.NaN; + p.y = Number.NaN; + return p; + } + + k = (-b - Math.sqrt(det)) / (2.0 * a); + v_x = this.radius_g + k * v_x; + v_y *= k; + v_z *= k; + + p.x = Math.atan2(v_y, v_x); + p.y = Math.atan(v_z * Math.cos(p.x) / v_x); + p.y = Math.atan(this.radius_p_inv2 * Math.tan(p.y)); + } else if (this.shape === 'sphere') { + if (this.flip_axis) { + v_z = Math.tan(p.y / this.radius_g_1); + v_y = Math.tan(p.x / this.radius_g_1) * Math.sqrt(1.0 + v_z * v_z); + } else { + v_y = Math.tan(p.x / this.radius_g_1); + v_z = Math.tan(p.y / this.radius_g_1) * Math.sqrt(1.0 + v_y * v_y); + } + + a = v_y * v_y + v_z * v_z + v_x * v_x; + b = 2 * this.radius_g * v_x; + det = (b * b) - 4 * a * this.C; + if (det < 0.0) { + p.x = Number.NaN; + p.y = Number.NaN; + return p; + } + + k = (-b - Math.sqrt(det)) / (2.0 * a); + v_x = this.radius_g + k * v_x; + v_y *= k; + v_z *= k; + + p.x = Math.atan2(v_y, v_x); + p.y = Math.atan(v_z * Math.cos(p.x) / v_x); + } + p.x = p.x + this.long0; + return p; + } + + var names$32 = ["Geostationary Satellite View", "Geostationary_Satellite", "geos"]; + var geos = { + init: init$31, + forward: forward$30, + inverse: inverse$30, + names: names$32, + }; + + var includedProjections = function(proj4){ + proj4.Proj.projections.add(tmerc); + proj4.Proj.projections.add(etmerc); + proj4.Proj.projections.add(utm); + proj4.Proj.projections.add(sterea); + proj4.Proj.projections.add(stere); + proj4.Proj.projections.add(somerc); + proj4.Proj.projections.add(omerc); + proj4.Proj.projections.add(lcc); + proj4.Proj.projections.add(krovak); + proj4.Proj.projections.add(cass); + proj4.Proj.projections.add(laea); + proj4.Proj.projections.add(aea); + proj4.Proj.projections.add(gnom); + proj4.Proj.projections.add(cea); + proj4.Proj.projections.add(eqc); + proj4.Proj.projections.add(poly); + proj4.Proj.projections.add(nzmg); + proj4.Proj.projections.add(mill); + proj4.Proj.projections.add(sinu); + proj4.Proj.projections.add(moll); + proj4.Proj.projections.add(eqdc); + proj4.Proj.projections.add(vandg); + proj4.Proj.projections.add(aeqd); + proj4.Proj.projections.add(ortho); + proj4.Proj.projections.add(qsc); + proj4.Proj.projections.add(robin); + proj4.Proj.projections.add(geocent); + proj4.Proj.projections.add(tpers); + proj4.Proj.projections.add(geos); + }; + + proj4$1.defaultDatum = 'WGS84'; //default datum + proj4$1.Proj = Projection; + proj4$1.WGS84 = new proj4$1.Proj('WGS84'); + proj4$1.Point = Point; + proj4$1.toPoint = toPoint; + proj4$1.defs = defs; + proj4$1.nadgrid = nadgrid; + proj4$1.transform = transform; + proj4$1.mgrs = mgrs; + proj4$1.version = '2.9.0'; + includedProjections(proj4$1); + + return proj4$1; + +}))); diff --git a/node_modules/proj4/dist/proj4.js b/node_modules/proj4/dist/proj4.js new file mode 100644 index 0000000..4d4a5b5 --- /dev/null +++ b/node_modules/proj4/dist/proj4.js @@ -0,0 +1 @@ +!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?module.exports=s():"function"==typeof define&&define.amd?define(s):t.proj4=s()}(this,function(){"use strict";function t(t,s){if(t[s])return t[s];for(var i,a=Object.keys(t),h=s.toLowerCase().replace(Ot,""),e=-1;++e0?90:-90),t.lat_ts=t.lat1)}function o(t){var s=this;if(2===arguments.length){var i=arguments[1];"string"==typeof i?"+"===i.charAt(0)?o[t]=kt(arguments[1]):o[t]=zt(arguments[1]):o[t]=i}else if(1===arguments.length){if(Array.isArray(t))return t.map(function(t){Array.isArray(t)?o.apply(s,t):o(t)});if("string"==typeof t){if(t in o)return o[t]}else"EPSG"in t?o["EPSG:"+t.EPSG]=t:"ESRI"in t?o["ESRI:"+t.ESRI]=t:"IAU2000"in t?o["IAU2000:"+t.IAU2000]=t:console.log(t);return}}function l(t){return"string"==typeof t}function u(t){return t in o}function c(t){return Ft.some(function(s){return t.indexOf(s)>-1})}function M(s){var i=t(s,"authority");if(i){var a=t(i,"epsg");return a&&Dt.indexOf(a)>-1}}function f(s){var i=t(s,"extension");if(i)return t(i,"proj4")}function d(t){return"+"===t[0]}function p(t){if(!l(t))return t;if(u(t))return o[t];if(c(t)){var s=zt(t);if(M(s))return o["EPSG:3857"];var i=f(s);return i?kt(i):s}return d(t)?kt(t):void 0}function m(t){return t}function y(t,s){var i=Zt.length;return t.names?(Zt[i]=t,t.names.forEach(function(t){Vt[t.toLowerCase()]=i}),this):(console.log(s),!0)}function _(t,s,i,a){var h=t*t,e=s*s,n=(h-e)/h,r=0;return a?(h=(t*=1-n*(gt+n*(vt+n*bt)))*t,n=0):r=Math.sqrt(n),{es:n,e:r,ep2:(h-e)/e}}function x(s,i,a,h,e){if(!s){var n=t($t,h);n||(n=ts),s=n.a,i=n.b,a=n.rf}return a&&!i&&(i=(1-1/a)*s),(0===a||Math.abs(s-i)3&&(0===r.datum_params[3]&&0===r.datum_params[4]&&0===r.datum_params[5]&&0===r.datum_params[6]||(r.datum_type=dt,r.datum_params[3]*=_t,r.datum_params[4]*=_t,r.datum_params[5]*=_t,r.datum_params[6]=r.datum_params[6]/1e6+1))),n&&(r.datum_type=pt,r.grids=n),r.a=i,r.b=a,r.es=h,r.ep2=e,r}function v(t){return void 0===t?null:t.split(",").map(b)}function b(t){if(0===t.length)return null;var s="@"===t[0];return s&&(t=t.slice(1)),"null"===t?{name:"null",mandatory:!s,grid:null,isNull:!0}:{name:t,mandatory:!s,grid:is[t]||null,isNull:!1}}function w(t){return t/3600*Math.PI/180}function N(t){var s=t.getInt32(8,!1);return 11!==s&&(11!==(s=t.getInt32(8,!0))&&console.warn("Failed to detect nadgrid endian-ness, defaulting to little-endian"),!0)}function A(t,s){return{nFields:t.getInt32(8,s),nSubgridFields:t.getInt32(24,s),nSubgrids:t.getInt32(40,s),shiftType:E(t,56,64).trim(),fromSemiMajorAxis:t.getFloat64(120,s),fromSemiMinorAxis:t.getFloat64(136,s),toSemiMajorAxis:t.getFloat64(152,s),toSemiMinorAxis:t.getFloat64(168,s)}}function E(t,s,i){return String.fromCharCode.apply(null,new Uint8Array(t.buffer.slice(s,i)))}function C(t,s,i){for(var a=[],h=0;h5e-11)&&(t.datum_type===ft?t.datum_params[0]===s.datum_params[0]&&t.datum_params[1]===s.datum_params[1]&&t.datum_params[2]===s.datum_params[2]:t.datum_type!==dt||t.datum_params[0]===s.datum_params[0]&&t.datum_params[1]===s.datum_params[1]&&t.datum_params[2]===s.datum_params[2]&&t.datum_params[3]===s.datum_params[3]&&t.datum_params[4]===s.datum_params[4]&&t.datum_params[5]===s.datum_params[5]&&t.datum_params[6]===s.datum_params[6]))}function k(t,s,i){var a,h,e,n,r=t.x,o=t.y,l=t.z?t.z:0;if(o<-xt&&o>-1.001*xt)o=-xt;else if(o>xt&&o<1.001*xt)o=xt;else{if(o<-xt)return{x:-1/0,y:-1/0,z:t.z};if(o>xt)return{x:1/0,y:1/0,z:t.z}}return r>Math.PI&&(r-=2*Math.PI),h=Math.sin(o),n=Math.cos(o),e=h*h,a=i/Math.sqrt(1-s*e),{x:(a+l)*n*Math.cos(r),y:(a+l)*n*Math.sin(r),z:(a*(1-s)+l)*h}}function q(t,s,i,a){var h,e,n,r,o,l,u,c,M,f,d,p,m,y,_,x,g=t.x,v=t.y,b=t.z?t.z:0;if(h=Math.sqrt(g*g+v*v),e=Math.sqrt(g*g+v*v+b*b),h/i<1e-12){if(y=0,e/i<1e-12)return _=xt,x=-a,{x:t.x,y:t.y,z:t.z}}else y=Math.atan2(v,g);n=b/e,c=(r=h/e)*(1-s)*(o=1/Math.sqrt(1-s*(2-s)*r*r)),M=n*o,m=0;do{m++,l=s*(u=i/Math.sqrt(1-s*M*M))/(u+(x=h*c+b*M-u*(1-s*M*M))),p=(d=n*(o=1/Math.sqrt(1-l*(2-l)*r*r)))*c-(f=r*(1-l)*o)*M,c=f,M=d}while(p*p>1e-24&&m<30);return _=Math.atan(d/Math.abs(f)),{x:y,y:_,z:x}}function R(t,s,i){if(s===ft)return{x:t.x+i[0],y:t.y+i[1],z:t.z+i[2]};if(s===dt){var a=i[0],h=i[1],e=i[2],n=i[3],r=i[4],o=i[5],l=i[6];return{x:l*(t.x-o*t.y+r*t.z)+a,y:l*(o*t.x+t.y-n*t.z)+h,z:l*(-r*t.x+n*t.y+t.z)+e}}}function L(t,s,i){if(s===ft)return{x:t.x-i[0],y:t.y-i[1],z:t.z-i[2]};if(s===dt){var a=i[0],h=i[1],e=i[2],n=i[3],r=i[4],o=i[5],l=i[6],u=(t.x-a)/l,c=(t.y-h)/l,M=(t.z-e)/l;return{x:u+o*c-r*M,y:-o*u+c+n*M,z:r*u-n*c+M}}}function T(t){return t===ft||t===dt}function G(t,s,i){if(null===t.grids||0===t.grids.length)return console.log("Grid shift grids not found"),-1;for(var a={x:-i.x,y:i.y},h={x:Number.NaN,y:Number.NaN},e=[],n=0;na.y||u>a.x||f1e-12&&Math.abs(n.y)>1e-12);if(o<0)return console.log("Inverse grid shift iterator failed to converge."),a;a.x=Ht(e.x+i.ll[0]),a.y=e.y+i.ll[1]}else isNaN(e.x)||(a.x=t.x+e.x,a.y=t.y+e.y);return a}function B(t,s){var i,a={x:t.x/s.del[0],y:t.y/s.del[1]},h={x:Math.floor(a.x),y:Math.floor(a.y)},e={x:a.x-1*h.x,y:a.y-1*h.y},n={x:Number.NaN,y:Number.NaN};if(h.x<0||h.x>=s.lim[0])return n;if(h.y<0||h.y>=s.lim[1])return n;i=h.y*s.lim[0]+h.x;var r={x:s.cvs[i][0],y:s.cvs[i][1]};i++;var o={x:s.cvs[i][0],y:s.cvs[i][1]};i+=s.lim[0];var l={x:s.cvs[i][0],y:s.cvs[i][1]};i--;var u={x:s.cvs[i][0],y:s.cvs[i][1]},c=e.x*e.y,M=e.x*(1-e.y),f=(1-e.x)*(1-e.y),d=(1-e.x)*e.y;return n.x=f*r.x+M*o.x+d*u.x+c*l.x,n.y=f*r.y+M*o.y+d*u.y+c*l.y,n}function z(t){if("function"==typeof Number.isFinite){if(Number.isFinite(t))return;throw new TypeError("coordinates must be finite numbers")}if("number"!=typeof t||t!==t||!isFinite(t))throw new TypeError("coordinates must be finite numbers")}function F(t,s){return(t.datum.datum_type===ft||t.datum.datum_type===dt||t.datum.datum_type===pt)&&"WGS84"!==s.datumCode||(s.datum.datum_type===ft||s.datum.datum_type===dt||s.datum.datum_type===pt)&&"WGS84"!==t.datumCode}function D(t,s,i,a){var h,e=void 0!==(i=Array.isArray(i)?es(i):{x:i.x,y:i.y,z:i.z,m:i.m}).z;if(ns(i),t.datum&&s.datum&&F(t,s)&&(i=D(t,h=new Projection("WGS84"),i,a),t=h),a&&"enu"!==t.axis&&(i=hs(t,!1,i)),"longlat"===t.projName)i={x:i.x*Nt,y:i.y*Nt,z:i.z||0};else if(t.to_meter&&(i={x:i.x*t.to_meter,y:i.y*t.to_meter,z:i.z||0}),!(i=t.inverse(i)))return;if(t.from_greenwich&&(i.x+=t.from_greenwich),i=as(t.datum,s.datum,i))return s.from_greenwich&&(i={x:i.x-s.from_greenwich,y:i.y,z:i.z||0}),"longlat"===s.projName?i={x:i.x*At,y:i.y*At,z:i.z||0}:(i=s.forward(i),s.to_meter&&(i={x:i.x/s.to_meter,y:i.y/s.to_meter,z:i.z||0})),a&&"enu"!==s.axis?hs(s,!0,i):(e||delete i.z,i)}function U(t,s,i,a){var h,e,n;return Array.isArray(i)?(h=D(t,s,i,a)||{x:NaN,y:NaN},i.length>2?void 0!==t.name&&"geocent"===t.name||void 0!==s.name&&"geocent"===s.name?"number"==typeof h.z?[h.x,h.y,h.z].concat(i.splice(3)):[h.x,h.y,i[2]].concat(i.splice(3)):[h.x,h.y].concat(i.splice(2)):[h.x,h.y]):(e=D(t,s,i,a),2===(n=Object.keys(i)).length?e:(n.forEach(function(a){if(void 0!==t.name&&"geocent"===t.name||void 0!==s.name&&"geocent"===s.name){if("x"===a||"y"===a||"z"===a)return}else if("x"===a||"y"===a)return;e[a]=i[a]}),e))}function Q(t){return t instanceof Projection?t:t.oProj?t.oProj:Projection(t)}function W(t,s,i){t=Q(t);var a,h=!1;return void 0===s?(s=t,t=rs,h=!0):(void 0!==s.x||Array.isArray(s))&&(i=s,s=t,t=rs,h=!0),s=Q(s),i?U(t,s,i):(a={forward:function(i,a){return U(t,s,i,a)},inverse:function(i,a){return U(s,t,i,a)}},h&&(a.oProj=s),a)}function H(t,s){return s=s||5,$(V({lat:t[1],lon:t[0]}),s)}function X(t){var s=Z(at(t.toUpperCase()));return s.lat&&s.lon?[s.lon,s.lat]:[(s.left+s.right)/2,(s.top+s.bottom)/2]}function J(t){return t*(Math.PI/180)}function K(t){return t/Math.PI*180}function V(t){var s,i,a,h,e,n,r,o=t.lat,l=t.lon,u=6378137,c=J(o),M=J(l);r=Math.floor((l+180)/6)+1,180===l&&(r=60),o>=56&&o<64&&l>=3&&l<12&&(r=32),o>=72&&o<84&&(l>=0&&l<9?r=31:l>=9&&l<21?r=33:l>=21&&l<33?r=35:l>=33&&l<42&&(r=37)),n=J(6*(r-1)-180+3),s=u/Math.sqrt(1-.00669438*Math.sin(c)*Math.sin(c)),i=Math.tan(c)*Math.tan(c),a=.006739496752268451*Math.cos(c)*Math.cos(c);var f=.9996*s*((h=Math.cos(c)*(M-n))+(1-i+a)*h*h*h/6+(5-18*i+i*i+72*a-.39089081163157013)*h*h*h*h*h/120)+5e5,d=.9996*((e=u*(.9983242984503243*c-.002514607064228144*Math.sin(2*c)+2639046602129982e-21*Math.sin(4*c)-3.418046101696858e-9*Math.sin(6*c)))+s*Math.tan(c)*(h*h/2+(5-i+9*a+4*a*a)*h*h*h*h/24+(61-58*i+i*i+600*a-2.2240339282485886)*h*h*h*h*h*h/720));return o<0&&(d+=1e7),{northing:Math.round(d),easting:Math.round(f),zoneNumber:r,zoneLetter:Y(o)}}function Z(t){var s=t.northing,i=t.easting,a=t.zoneLetter,h=t.zoneNumber;if(h<0||h>60)return null;var e,n,r,o,l,u,c,M,f=6378137,d=(1-Math.sqrt(.99330562))/(1+Math.sqrt(.99330562)),p=i-5e5,m=s;a<"N"&&(m-=1e7),u=6*(h-1)-180+3,M=(c=m/.9996/6367449.145945056)+(3*d/2-27*d*d*d/32)*Math.sin(2*c)+(21*d*d/16-55*d*d*d*d/32)*Math.sin(4*c)+151*d*d*d/96*Math.sin(6*c),e=f/Math.sqrt(1-.00669438*Math.sin(M)*Math.sin(M)),n=Math.tan(M)*Math.tan(M),r=.006739496752268451*Math.cos(M)*Math.cos(M),o=.99330562*f/Math.pow(1-.00669438*Math.sin(M)*Math.sin(M),1.5),l=p/(.9996*e);var y=M-e*Math.tan(M)/o*(l*l/2-(5+3*n+10*r-4*r*r-.06065547077041606)*l*l*l*l/24+(61+90*n+298*r+45*n*n-1.6983531815716497-3*r*r)*l*l*l*l*l*l/720);y=K(y);var _=(l-(1+2*n+r)*l*l*l/6+(5-2*r+28*n-3*r*r+.05391597401814761+24*n*n)*l*l*l*l*l/120)/Math.cos(M);_=u+K(_);var x;if(t.accuracy){var g=Z({northing:t.northing+t.accuracy,easting:t.easting+t.accuracy,zoneLetter:t.zoneLetter,zoneNumber:t.zoneNumber});x={top:g.lat,right:g.lon,bottom:y,left:_}}else x={lat:y,lon:_};return x}function Y(t){var s="Z";return 84>=t&&t>=72?s="X":72>t&&t>=64?s="W":64>t&&t>=56?s="V":56>t&&t>=48?s="U":48>t&&t>=40?s="T":40>t&&t>=32?s="S":32>t&&t>=24?s="R":24>t&&t>=16?s="Q":16>t&&t>=8?s="P":8>t&&t>=0?s="N":0>t&&t>=-8?s="M":-8>t&&t>=-16?s="L":-16>t&&t>=-24?s="K":-24>t&&t>=-32?s="J":-32>t&&t>=-40?s="H":-40>t&&t>=-48?s="G":-48>t&&t>=-56?s="F":-56>t&&t>=-64?s="E":-64>t&&t>=-72?s="D":-72>t&&t>=-80&&(s="C"),s}function $(t,s){var i="00000"+t.easting,a="00000"+t.northing;return t.zoneNumber+t.zoneLetter+tt(t.easting,t.northing,t.zoneNumber)+i.substr(i.length-5,s)+a.substr(a.length-5,s)}function tt(t,s,i){var a=st(i);return it(Math.floor(t/1e5),Math.floor(s/1e5)%20,a)}function st(t){var s=t%os;return 0===s&&(s=os),s}function it(t,s,i){var a=i-1,h=ls.charCodeAt(a),e=us.charCodeAt(a),n=h+t-1,r=e+s,o=!1;return n>ps&&(n=n-ps+cs-1,o=!0),(n===Ms||hMs||(n>Ms||hfs||(n>fs||hps&&(n=n-ps+cs-1),r>ds?(r=r-ds+cs-1,o=!0):o=!1,(r===Ms||eMs||(r>Ms||efs||(r>fs||eds&&(r=r-ds+cs-1),String.fromCharCode(n)+String.fromCharCode(r)}function at(t){if(t&&0===t.length)throw"MGRSPoint coverting from nothing";for(var s,i=t.length,a=null,h="",e=0;!/[A-Z]/.test(s=t.charAt(e));){if(e>=2)throw"MGRSPoint bad conversion from: "+t;h+=s,e++}var n=parseInt(h,10);if(0===e||e+3>i)throw"MGRSPoint bad conversion from: "+t;var r=t.charAt(e++);if(r<="A"||"B"===r||"Y"===r||r>="Z"||"I"===r||"O"===r)throw"MGRSPoint zone letter "+r+" not handled: "+t;a=t.substring(e,e+=2);for(var o=st(n),l=ht(a.charAt(0),o),u=et(a.charAt(1),o);u0&&(M=1e5/Math.pow(10,y),f=t.substring(e,e+y),_=parseFloat(f)*M,d=t.substring(e+y),x=parseFloat(d)*M),p=_+l,m=x+u,{easting:p,northing:m,zoneLetter:r,zoneNumber:n,accuracy:M}}function ht(t,s){for(var i=ls.charCodeAt(s-1),a=1e5,h=!1;i!==t.charCodeAt(0);){if(++i===Ms&&i++,i===fs&&i++,i>ps){if(h)throw"Bad character: "+t;i=cs,h=!0}a+=1e5}return a}function et(t,s){if(t>"V")throw"MGRSPoint given invalid Northing "+t;for(var i=us.charCodeAt(s-1),a=0,h=!1;i!==t.charCodeAt(0);){if(++i===Ms&&i++,i===fs&&i++,i>ds){if(h)throw"Bad character: "+t;i=cs,h=!0}a+=1e5}return a}function nt(t){var s;switch(t){case"C":s=11e5;break;case"D":s=2e6;break;case"E":s=28e5;break;case"F":s=37e5;break;case"G":s=46e5;break;case"H":s=55e5;break;case"J":s=64e5;break;case"K":s=73e5;break;case"L":s=82e5;break;case"M":s=91e5;break;case"N":s=0;break;case"P":s=8e5;break;case"Q":s=17e5;break;case"R":s=26e5;break;case"S":s=35e5;break;case"T":s=44e5;break;case"U":s=53e5;break;case"V":s=62e5;break;case"W":s=7e6;break;case"X":s=79e5;break;default:s=-1}if(s>=0)return s;throw"Invalid zone letter: "+t}function Point(t,s,i){if(!(this instanceof Point))return new Point(t,s,i);if(Array.isArray(t))this.x=t[0],this.y=t[1],this.z=t[2]||0;else if("object"==typeof t)this.x=t.x,this.y=t.y,this.z=t.z||0;else if("string"==typeof t&&void 0===s){var a=t.split(",");this.x=parseFloat(a[0],10),this.y=parseFloat(a[1],10),this.z=parseFloat(a[2],10)||0}else this.x=t,this.y=s,this.z=i||0;console.warn("proj4.Point will be removed in version 3, use proj4.toPoint")}function rt(t){var s=["Hotine_Oblique_Mercator","Hotine_Oblique_Mercator_Azimuth_Natural_Origin"],i="object"==typeof t.PROJECTION?Object.keys(t.PROJECTION)[0]:t.PROJECTION;return"no_uoff"in t||"no_off"in t||-1!==s.indexOf(i)}function ot(t){var s,i=[];return i[0]=t*$s,s=t*t,i[0]+=s*ti,i[1]=s*ii,s*=t,i[0]+=s*si,i[1]+=s*ai,i[2]=s*hi,i}function lt(t,s){var i=t+t;return t+s[0]*Math.sin(i)+s[1]*Math.sin(i+i)+s[2]*Math.sin(i+i+i)}function ut(t,s,i,a){var h;return tEt&&h<=xt+Et?(a.value=Ni.AREA_1,h-=xt):h>xt+Et||h<=-(xt+Et)?(a.value=Ni.AREA_2,h=h>=0?h-Pt:h+Pt):(a.value=Ni.AREA_3,h+=xt)),h}function ct(t,s){var i=t+s;return i<-Pt?i+=Ct:i>+Pt&&(i-=Ct),i}function Mt(t,s,i,a){for(var h=s;a;--a){var e=t(h);if(h-=e,Math.abs(e)=this.text.length)return;t=this.text[this.place++]}switch(this.state){case qt:return this.neutral(t);case 2:return this.keyword(t);case 4:return this.quoted(t);case 5:return this.afterquote(t);case 3:return this.number(t);case-1:return}},s.prototype.afterquote=function(t){if('"'===t)return this.word+='"',void(this.state=4);if(Gt.test(t))return this.word=this.word.trim(),void this.afterItem(t);throw new Error("havn't handled \""+t+'" in afterquote yet, index '+this.place)},s.prototype.afterItem=function(t){return","===t?(null!==this.word&&this.currentObject.push(this.word),this.word=null,void(this.state=qt)):"]"===t?(this.level--,null!==this.word&&(this.currentObject.push(this.word),this.word=null),this.state=qt,this.currentObject=this.stack.pop(),void(this.currentObject||(this.state=-1))):void 0},s.prototype.number=function(t){if(!jt.test(t)){if(Gt.test(t))return this.word=parseFloat(this.word),void this.afterItem(t);throw new Error("havn't handled \""+t+'" in number yet, index '+this.place)}this.word+=t},s.prototype.quoted=function(t){'"'!==t?this.word+=t:this.state=5},s.prototype.keyword=function(t){if(Tt.test(t))this.word+=t;else{if("["===t){var s=[];return s.push(this.word),this.level++,null===this.root?this.root=s:this.currentObject.push(s),this.stack.push(this.currentObject),this.currentObject=s,void(this.state=qt)}if(!Gt.test(t))throw new Error("havn't handled \""+t+'" in keyword yet, index '+this.place);this.afterItem(t)}},s.prototype.neutral=function(t){if(Lt.test(t))return this.word=t,void(this.state=2);if('"'===t)return this.word="",void(this.state=4);if(jt.test(t))return this.word=t,void(this.state=3);{if(!Gt.test(t))throw new Error("havn't handled \""+t+'" in neutral yet, index '+this.place);this.afterItem(t)}},s.prototype.output=function(){for(;this.place90&&i*At<-90&&s*At>180&&s*At<-180)return null;var a,h;if(Math.abs(Math.abs(i)-xt)<=wt)return null;if(this.sphere)a=this.x0+this.a*this.k0*Ht(s-this.long0),h=this.y0+this.a*this.k0*Math.log(Math.tan(Et+.5*i));else{var e=Math.sin(i),n=Xt(this.e,i,e);a=this.x0+this.a*this.k0*Ht(s-this.long0),h=this.y0-this.a*this.k0*Math.log(n)}return t.x=a,t.y=h,t},inverse:function(t){var s,i,a=t.x-this.x0,h=t.y-this.y0;if(this.sphere)i=xt-2*Math.atan(Math.exp(-h/(this.a*this.k0)));else{var e=Math.exp(-h/(this.a*this.k0));if(-9999===(i=Jt(this.e,e)))return null}return s=Ht(this.long0+a/(this.a*this.k0)),t.x=s,t.y=i,t},names:["Mercator","Popular Visualisation Pseudo Mercator","Mercator_1SP","Mercator_Auxiliary_Sphere","merc"]},{init:function(){},forward:m,inverse:m,names:["longlat","identity"]}],Vt={},Zt=[],Yt={start:function(){Kt.forEach(y)},add:y,get:function(t){if(!t)return!1;var s=t.toLowerCase();return void 0!==Vt[s]&&Zt[Vt[s]]?Zt[Vt[s]]:void 0}},$t={};$t.MERIT={a:6378137,rf:298.257,ellipseName:"MERIT 1983"},$t.SGS85={a:6378136,rf:298.257,ellipseName:"Soviet Geodetic System 85"},$t.GRS80={a:6378137,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},$t.IAU76={a:6378140,rf:298.257,ellipseName:"IAU 1976"},$t.airy={a:6377563.396,b:6356256.91,ellipseName:"Airy 1830"},$t.APL4={a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},$t.NWL9D={a:6378145,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},$t.mod_airy={a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},$t.andrae={a:6377104.43,rf:300,ellipseName:"Andrae 1876 (Den., Iclnd.)"},$t.aust_SA={a:6378160,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},$t.GRS67={a:6378160,rf:298.247167427,ellipseName:"GRS 67(IUGG 1967)"},$t.bessel={a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},$t.bess_nam={a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},$t.clrk66={a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},$t.clrk80={a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},$t.clrk80ign={a:6378249.2,b:6356515,rf:293.4660213,ellipseName:"Clarke 1880 (IGN)"},$t.clrk58={a:6378293.645208759,rf:294.2606763692654,ellipseName:"Clarke 1858"},$t.CPM={a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},$t.delmbr={a:6376428,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},$t.engelis={a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},$t.evrst30={a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},$t.evrst48={a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},$t.evrst56={a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},$t.evrst69={a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},$t.evrstSS={a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},$t.fschr60={a:6378166,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},$t.fschr60m={a:6378155,rf:298.3,ellipseName:"Fischer 1960"},$t.fschr68={a:6378150,rf:298.3,ellipseName:"Fischer 1968"},$t.helmert={a:6378200,rf:298.3,ellipseName:"Helmert 1906"},$t.hough={a:6378270,rf:297,ellipseName:"Hough"},$t.intl={a:6378388,rf:297,ellipseName:"International 1909 (Hayford)"},$t.kaula={a:6378163,rf:298.24,ellipseName:"Kaula 1961"},$t.lerch={a:6378139,rf:298.257,ellipseName:"Lerch 1979"},$t.mprts={a:6397300,rf:191,ellipseName:"Maupertius 1738"},$t.new_intl={a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},$t.plessis={a:6376523,rf:6355863,ellipseName:"Plessis 1817 (France)"},$t.krass={a:6378245,rf:298.3,ellipseName:"Krassovsky, 1942"},$t.SEasia={a:6378155,b:6356773.3205,ellipseName:"Southeast Asia"},$t.walbeck={a:6376896,b:6355834.8467,ellipseName:"Walbeck"},$t.WGS60={a:6378165,rf:298.3,ellipseName:"WGS 60"},$t.WGS66={a:6378145,rf:298.25,ellipseName:"WGS 66"},$t.WGS7={a:6378135,rf:298.26,ellipseName:"WGS 72"};var ts=$t.WGS84={a:6378137,rf:298.257223563,ellipseName:"WGS 84"};$t.sphere={a:6370997,b:6370997,ellipseName:"Normal Sphere (r=6370997)"};var ss={};ss.wgs84={towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},ss.ch1903={towgs84:"674.374,15.056,405.346",ellipse:"bessel",datumName:"swiss"},ss.ggrs87={towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},ss.nad83={towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},ss.nad27={nadgrids:"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},ss.potsdam={towgs84:"598.1,73.7,418.2,0.202,0.045,-2.455,6.7",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},ss.carthage={towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},ss.hermannskogel={towgs84:"577.326,90.129,463.919,5.137,1.474,5.297,2.4232",ellipse:"bessel",datumName:"Hermannskogel"},ss.osni52={towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"airy",datumName:"Irish National"},ss.ire65={towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},ss.rassadiran={towgs84:"-133.63,-157.5,-158.62",ellipse:"intl",datumName:"Rassadiran"},ss.nzgd49={towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},ss.osgb36={towgs84:"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"},ss.s_jtsk={towgs84:"589,76,480",ellipse:"bessel",datumName:"S-JTSK (Ferro)"},ss.beduaram={towgs84:"-106,-87,188",ellipse:"clrk80",datumName:"Beduaram"},ss.gunung_segara={towgs84:"-403,684,41",ellipse:"bessel",datumName:"Gunung Segara Jakarta"},ss.rnb72={towgs84:"106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",ellipse:"intl",datumName:"Reseau National Belge 1972"};var is={};Projection.projections=Yt,Projection.projections.start();var as=function(t,s,i){if(O(t,s))return i;if(t.datum_type===yt||s.datum_type===yt)return i;var a=t.a,h=t.es;if(t.datum_type===pt){if(0!==G(t,!1,i))return;a=6378137,h=.0066943799901413165}var e=s.a,n=s.b,r=s.es;return s.datum_type===pt&&(e=6378137,n=6356752.314,r=.0066943799901413165),h!==r||a!==e||T(t.datum_type)||T(s.datum_type)?(i=k(i,h,a),T(t.datum_type)&&(i=R(i,t.datum_type,t.datum_params)),T(s.datum_type)&&(i=L(i,s.datum_type,s.datum_params)),i=q(i,r,e,n),s.datum_type!==pt||0===G(s,!0,i)?i:void 0):i},hs=function(t,s,i){var a,h,e,n=i.x,r=i.y,o=i.z||0,l={};for(e=0;e<3;e++)if(!s||2!==e||void 0!==i.z)switch(0===e?(a=n,h=-1!=="ew".indexOf(t.axis[e])?"x":"y"):1===e?(a=r,h=-1!=="ns".indexOf(t.axis[e])?"y":"x"):(a=o,h="z"),t.axis[e]){case"e":l[h]=a;break;case"w":l[h]=-a;break;case"n":l[h]=a;break;case"s":l[h]=-a;break;case"u":void 0!==i[h]&&(l.z=a);break;case"d":void 0!==i[h]&&(l.z=-a);break;default:return null}return l},es=function(t){var s={x:t[0],y:t[1]};return t.length>2&&(s.z=t[2]),t.length>3&&(s.m=t[3]),s},ns=function(t){z(t.x),z(t.y)},rs=Projection("WGS84"),os=6,ls="AJSAJS",us="AFAFAF",cs=65,Ms=73,fs=79,ds=86,ps=90,ms={forward:H,inverse:function(t){var s=Z(at(t.toUpperCase()));return s.lat&&s.lon?[s.lon,s.lat,s.lon,s.lat]:[s.left,s.bottom,s.right,s.top]},toPoint:X};Point.fromMGRS=function(t){return new Point(X(t))},Point.prototype.toMGRS=function(t){return H([this.x,this.y],t)};var ys=.01068115234375,_s=function(t){var s=[];s[0]=1-t*(.25+t*(.046875+t*(.01953125+t*ys))),s[1]=t*(.75-t*(.046875+t*(.01953125+t*ys)));var i=t*t;return s[2]=i*(.46875-t*(.013020833333333334+.007120768229166667*t)),i*=t,s[3]=i*(.3645833333333333-.005696614583333333*t),s[4]=i*t*.3076171875,s},xs=function(t,s,i,a){return i*=s,s*=s,a[0]*t-i*(a[1]+s*(a[2]+s*(a[3]+s*a[4])))},gs=function(t,s,i){for(var a=1/(1-s),h=t,e=20;e;--e){var n=Math.sin(h),r=1-s*n*n;if(r=(xs(h,n,Math.cos(h),i)-t)*(r*Math.sqrt(r))*a,h-=r,Math.abs(r)wt?Math.tan(e):0,d=Math.pow(f,2),p=Math.pow(d,2);s=1-this.es*Math.pow(r,2),l/=Math.sqrt(s);var m=xs(e,r,o,this.en);i=this.a*(this.k0*l*(1+u/6*(1-d+c+u/20*(5-18*d+p+14*c-58*d*c+u/42*(61+179*p-p*d-479*d)))))+this.x0,a=this.a*(this.k0*(m-this.ml0+r*n*l/2*(1+u/12*(5-d+9*c+4*M+u/30*(61+p-58*d+270*c-330*d*c+u/56*(1385+543*p-p*d-3111*d))))))+this.y0}else{var y=o*Math.sin(n);if(Math.abs(Math.abs(y)-1)=1){if(y-1>wt)return 93;a=0}else a=Math.acos(a);e<0&&(a=-a),a=this.a*this.k0*(a-this.lat0)+this.y0}return t.x=i,t.y=a,t},inverse:function(t){var s,i,a,h,e=(t.x-this.x0)*(1/this.a),n=(t.y-this.y0)*(1/this.a);if(this.es)if(s=this.ml0+n/this.k0,i=gs(s,this.es,this.en),Math.abs(i)wt?Math.tan(i):0,u=this.ep2*Math.pow(o,2),c=Math.pow(u,2),M=Math.pow(l,2),f=Math.pow(M,2);s=1-this.es*Math.pow(r,2);var d=e*Math.sqrt(s)/this.k0,p=Math.pow(d,2);a=i-(s*=l)*p/(1-this.es)*.5*(1-p/12*(5+3*M-9*u*M+u-4*c-p/30*(61+90*M-252*u*M+45*f+46*u-p/56*(1385+3633*M+4095*f+1574*f*M)))),h=Ht(this.long0+d*(1-p/6*(1+2*M+u-p/20*(5+28*M+24*f+8*u*M+6*u-p/42*(61+662*M+1320*f+720*f*M))))/o)}else a=xt*Wt(n),h=0;else{var m=Math.exp(e/this.k0),y=.5*(m-1/m),_=this.lat0+n/this.k0,x=Math.cos(_);s=Math.sqrt((1-Math.pow(x,2))/(1+Math.pow(y,2))),a=Math.asin(s),n<0&&(a=-a),h=0===y&&0===x?0:Ht(Math.atan2(y,x)+this.long0)}return t.x=h,t.y=a,t},names:["Fast_Transverse_Mercator","Fast Transverse Mercator"]},bs=function(t){var s=Math.exp(t);return s=(s-1/s)/2},ws=function(t,s){t=Math.abs(t),s=Math.abs(s);var i=Math.max(t,s),a=Math.min(t,s)/(i||1);return i*Math.sqrt(1+Math.pow(a,2))},Ns=function(t){var s=1+t,i=s-1;return 0===i?t:t*Math.log(s)/i},As=function(t){var s=Math.abs(t);return s=Ns(s*(1+s/(ws(1,s)+1))),t<0?-s:s},Es=function(t,s){for(var i,a=2*Math.cos(2*s),h=t.length-1,e=t[h],n=0;--h>=0;)i=a*e-n+t[h],n=e,e=i;return s+i*Math.sin(2*s)},Cs=function(t,s){for(var i,a=2*Math.cos(s),h=t.length-1,e=t[h],n=0;--h>=0;)i=a*e-n+t[h],n=e,e=i;return Math.sin(s)*i},Ps=function(t){var s=Math.exp(t);return s=(s+1/s)/2},Ss=function(t,s,i){for(var a,h,e=Math.sin(s),n=Math.cos(s),r=bs(i),o=Ps(i),l=2*n*o,u=-2*e*r,c=t.length-1,M=t[c],f=0,d=0,p=0;--c>=0;)a=d,h=f,M=l*(d=M)-a-u*(f=p)+t[c],p=u*d-h+l*f;return l=e*o,u=n*r,[l*M-u*p,l*p+u*M]},Is={init:function(){if(!this.approx&&(isNaN(this.es)||this.es<=0))throw new Error('Incorrect elliptical usage. Try using the +approx option in the proj string, or PROJECTION["Fast_Transverse_Mercator"] in the WKT.');this.approx&&(vs.init.apply(this),this.forward=vs.forward,this.inverse=vs.inverse),this.x0=void 0!==this.x0?this.x0:0,this.y0=void 0!==this.y0?this.y0:0,this.long0=void 0!==this.long0?this.long0:0,this.lat0=void 0!==this.lat0?this.lat0:0,this.cgb=[],this.cbg=[],this.utg=[],this.gtu=[];var t=this.es/(1+Math.sqrt(1-this.es)),s=t/(2-t),i=s;this.cgb[0]=s*(2+s*(-2/3+s*(s*(116/45+s*(26/45+s*(-2854/675)))-2))),this.cbg[0]=s*(s*(2/3+s*(4/3+s*(-82/45+s*(32/45+s*(4642/4725)))))-2),i*=s,this.cgb[1]=i*(7/3+s*(s*(-227/45+s*(2704/315+s*(2323/945)))-1.6)),this.cbg[1]=i*(5/3+s*(-16/15+s*(-13/9+s*(904/315+s*(-1522/945))))),i*=s,this.cgb[2]=i*(56/15+s*(-136/35+s*(-1262/105+s*(73814/2835)))),this.cbg[2]=i*(-26/15+s*(34/21+s*(1.6+s*(-12686/2835)))),i*=s,this.cgb[3]=i*(4279/630+s*(-332/35+s*(-399572/14175))),this.cbg[3]=i*(1237/630+s*(s*(-24832/14175)-2.4)),i*=s,this.cgb[4]=i*(4174/315+s*(-144838/6237)),this.cbg[4]=i*(-734/315+s*(109598/31185)),i*=s,this.cgb[5]=i*(601676/22275),this.cbg[5]=i*(444337/155925),i=Math.pow(s,2),this.Qn=this.k0/(1+s)*(1+i*(.25+i*(1/64+i/256))),this.utg[0]=s*(s*(2/3+s*(-37/96+s*(1/360+s*(81/512+s*(-96199/604800)))))-.5),this.gtu[0]=s*(.5+s*(-2/3+s*(5/16+s*(41/180+s*(-127/288+s*(7891/37800)))))),this.utg[1]=i*(-1/48+s*(-1/15+s*(437/1440+s*(-46/105+s*(1118711/3870720))))),this.gtu[1]=i*(13/48+s*(s*(557/1440+s*(281/630+s*(-1983433/1935360)))-.6)),i*=s,this.utg[2]=i*(-17/480+s*(37/840+s*(209/4480+s*(-5569/90720)))),this.gtu[2]=i*(61/240+s*(-103/140+s*(15061/26880+s*(167603/181440)))),i*=s,this.utg[3]=i*(-4397/161280+s*(11/504+s*(830251/7257600))),this.gtu[3]=i*(49561/161280+s*(-179/168+s*(6601661/7257600))),i*=s,this.utg[4]=i*(-4583/161280+s*(108847/3991680)),this.gtu[4]=i*(34729/80640+s*(-3418889/1995840)),i*=s,this.utg[5]=-.03233083094085698*i,this.gtu[5]=.6650675310896665*i;var a=Es(this.cbg,this.lat0);this.Zb=-this.Qn*(a+Cs(this.gtu,2*a))},forward:function(t){var s=Ht(t.x-this.long0),i=t.y;i=Es(this.cbg,i);var a=Math.sin(i),h=Math.cos(i),e=Math.sin(s),n=Math.cos(s);i=Math.atan2(a,n*h),s=Math.atan2(e*h,ws(a,h*n)),s=As(Math.tan(s));var r=Ss(this.gtu,2*i,2*s);i+=r[0],s+=r[1];var o,l;return Math.abs(s)<=2.623395162778?(o=this.a*(this.Qn*s)+this.x0,l=this.a*(this.Qn*i+this.Zb)+this.y0):(o=1/0,l=1/0),t.x=o,t.y=l,t},inverse:function(t){var s=(t.x-this.x0)*(1/this.a),i=(t.y-this.y0)*(1/this.a);i=(i-this.Zb)/this.Qn,s/=this.Qn;var a,h;if(Math.abs(s)<=2.623395162778){var e=Ss(this.utg,2*i,2*s);i+=e[0],s+=e[1],s=Math.atan(bs(s));var n=Math.sin(i),r=Math.cos(i),o=Math.sin(s),l=Math.cos(s);i=Math.atan2(n*l,ws(o,l*r)),s=Math.atan2(o,l*r),a=Ht(s+this.long0),h=Es(this.cgb,i)}else a=1/0,h=1/0;return t.x=a,t.y=h,t},names:["Extended_Transverse_Mercator","Extended Transverse Mercator","etmerc","Transverse_Mercator","Transverse Mercator","tmerc"]},Os=function(t,s){if(void 0===t){if((t=Math.floor(30*(Ht(s)+Math.PI)/Math.PI)+1)<0)return 0;if(t>60)return 60}return t},ks={init:function(){var t=Os(this.zone,this.long0);if(void 0===t)throw new Error("unknown utm zone");this.lat0=0,this.long0=(6*Math.abs(t)-183)*Nt,this.x0=5e5,this.y0=this.utmSouth?1e7:0,this.k0=.9996,Is.init.apply(this),this.forward=Is.forward,this.inverse=Is.inverse},names:["Universal Transverse Mercator System","utm"],dependsOn:"etmerc"},qs=function(t,s){return Math.pow((1-t)/(1+t),s)},Rs=20,Ls={init:function(){var t=Math.sin(this.lat0),s=Math.cos(this.lat0);s*=s,this.rc=Math.sqrt(1-this.es)/(1-this.es*t*t),this.C=Math.sqrt(1+this.es*s*s/(1-this.es)),this.phic0=Math.asin(t/this.C),this.ratexp=.5*this.C*this.e,this.K=Math.tan(.5*this.phic0+Et)/(Math.pow(Math.tan(.5*this.lat0+Et),this.C)*qs(this.e*t,this.ratexp))},forward:function(t){var s=t.x,i=t.y;return t.y=2*Math.atan(this.K*Math.pow(Math.tan(.5*i+Et),this.C)*qs(this.e*Math.sin(i),this.ratexp))-xt,t.x=this.C*s,t},inverse:function(t){for(var s=t.x/this.C,i=t.y,a=Math.pow(Math.tan(.5*i+Et)/this.K,1/this.C),h=Rs;h>0&&(i=2*Math.atan(a*qs(this.e*Math.sin(t.y),-.5*this.e))-xt,!(Math.abs(i-t.y)<1e-14));--h)t.y=i;return h?(t.x=s,t.y=i,t):null},names:["gauss"]},Ts={init:function(){Ls.init.apply(this),this.rc&&(this.sinc0=Math.sin(this.phic0),this.cosc0=Math.cos(this.phic0),this.R2=2*this.rc,this.title||(this.title="Oblique Stereographic Alternative"))},forward:function(t){var s,i,a,h;return t.x=Ht(t.x-this.long0),Ls.forward.apply(this,[t]),s=Math.sin(t.y),i=Math.cos(t.y),a=Math.cos(t.x),h=this.k0*this.R2/(1+this.sinc0*s+this.cosc0*i*a),t.x=h*i*Math.sin(t.x),t.y=h*(this.cosc0*s-this.sinc0*i*a),t.x=this.a*t.x+this.x0,t.y=this.a*t.y+this.y0,t},inverse:function(t){var s,i,a,h,e;if(t.x=(t.x-this.x0)/this.a,t.y=(t.y-this.y0)/this.a,t.x/=this.k0,t.y/=this.k0,e=Math.sqrt(t.x*t.x+t.y*t.y)){var n=2*Math.atan2(e,this.R2);s=Math.sin(n),i=Math.cos(n),h=Math.asin(i*this.sinc0+t.y*s*this.cosc0/e),a=Math.atan2(t.x*s,e*this.cosc0*i-t.y*this.sinc0*s)}else h=this.phic0,a=0;return t.x=a,t.y=h,Ls.inverse.apply(this,[t]),t.x=Ht(t.x+this.long0),t},names:["Stereographic_North_Pole","Oblique_Stereographic","Polar_Stereographic","sterea","Oblique Stereographic Alternative","Double_Stereographic"]},Gs={init:function(){this.coslat0=Math.cos(this.lat0),this.sinlat0=Math.sin(this.lat0),this.sphere?1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=wt&&(this.k0=.5*(1+Wt(this.lat0)*Math.sin(this.lat_ts))):(Math.abs(this.coslat0)<=wt&&(this.lat0>0?this.con=1:this.con=-1),this.cons=Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e)),1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=wt&&(this.k0=.5*this.cons*Qt(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts))/Xt(this.e,this.con*this.lat_ts,this.con*Math.sin(this.lat_ts))),this.ms1=Qt(this.e,this.sinlat0,this.coslat0),this.X0=2*Math.atan(this.ssfn_(this.lat0,this.sinlat0,this.e))-xt,this.cosX0=Math.cos(this.X0),this.sinX0=Math.sin(this.X0))},forward:function(t){var s,i,a,h,e,n,r=t.x,o=t.y,l=Math.sin(o),u=Math.cos(o),c=Ht(r-this.long0);return Math.abs(Math.abs(r-this.long0)-Math.PI)<=wt&&Math.abs(o+this.lat0)<=wt?(t.x=NaN,t.y=NaN,t):this.sphere?(s=2*this.k0/(1+this.sinlat0*l+this.coslat0*u*Math.cos(c)),t.x=this.a*s*u*Math.sin(c)+this.x0,t.y=this.a*s*(this.coslat0*l-this.sinlat0*u*Math.cos(c))+this.y0,t):(i=2*Math.atan(this.ssfn_(o,l,this.e))-xt,h=Math.cos(i),a=Math.sin(i),Math.abs(this.coslat0)<=wt?(e=Xt(this.e,o*this.con,this.con*l),n=2*this.a*this.k0*e/this.cons,t.x=this.x0+n*Math.sin(r-this.long0),t.y=this.y0-this.con*n*Math.cos(r-this.long0),t):(Math.abs(this.sinlat0)0?this.long0+Math.atan2(t.x,-1*t.y):this.long0+Math.atan2(t.x,t.y):this.long0+Math.atan2(t.x*Math.sin(r),n*this.coslat0*Math.cos(r)-t.y*this.sinlat0*Math.sin(r))),t.x=s,t.y=i,t)}if(Math.abs(this.coslat0)<=wt){if(n<=wt)return i=this.lat0,s=this.long0,t.x=s,t.y=i,t;t.x*=this.con,t.y*=this.con,a=n*this.cons/(2*this.a*this.k0),i=this.con*Jt(this.e,a),s=this.con*Ht(this.con*this.long0+Math.atan2(t.x,-1*t.y))}else h=2*Math.atan(n*this.cosX0/(2*this.a*this.k0*this.ms1)),s=this.long0,n<=wt?e=this.X0:(e=Math.asin(Math.cos(h)*this.sinX0+t.y*Math.sin(h)*this.cosX0/n),s=Ht(this.long0+Math.atan2(t.x*Math.sin(h),n*this.cosX0*Math.cos(h)-t.y*this.sinX0*Math.sin(h)))),i=-1*Jt(this.e,Math.tan(.5*(xt+e)));return t.x=s,t.y=i,t},names:["stere","Stereographic_South_Pole","Polar Stereographic (variant B)"],ssfn_:function(t,s,i){return s*=i,Math.tan(.5*(xt+t))*Math.pow((1-s)/(1+s),.5*i)}},js={init:function(){var t=this.lat0;this.lambda0=this.long0;var s=Math.sin(t),i=this.a,a=1/this.rf,h=2*a-Math.pow(a,2),e=this.e=Math.sqrt(h);this.R=this.k0*i*Math.sqrt(1-h)/(1-h*Math.pow(s,2)),this.alpha=Math.sqrt(1+h/(1-h)*Math.pow(Math.cos(t),4)),this.b0=Math.asin(s/this.alpha);var n=Math.log(Math.tan(Math.PI/4+this.b0/2)),r=Math.log(Math.tan(Math.PI/4+t/2)),o=Math.log((1+e*s)/(1-e*s));this.K=n-this.alpha*r+this.alpha*e/2*o},forward:function(t){var s=Math.log(Math.tan(Math.PI/4-t.y/2)),i=this.e/2*Math.log((1+this.e*Math.sin(t.y))/(1-this.e*Math.sin(t.y))),a=-this.alpha*(s+i)+this.K,h=2*(Math.atan(Math.exp(a))-Math.PI/4),e=this.alpha*(t.x-this.lambda0),n=Math.atan(Math.sin(e)/(Math.sin(this.b0)*Math.tan(h)+Math.cos(this.b0)*Math.cos(e))),r=Math.asin(Math.cos(this.b0)*Math.sin(h)-Math.sin(this.b0)*Math.cos(h)*Math.cos(e));return t.y=this.R/2*Math.log((1+Math.sin(r))/(1-Math.sin(r)))+this.y0,t.x=this.R*n+this.x0,t},inverse:function(t){for(var s=t.x-this.x0,i=t.y-this.y0,a=s/this.R,h=2*(Math.atan(Math.exp(i/this.R))-Math.PI/4),e=Math.asin(Math.cos(this.b0)*Math.sin(h)+Math.sin(this.b0)*Math.cos(h)*Math.cos(a)),n=Math.atan(Math.sin(a)/(Math.cos(this.b0)*Math.cos(a)-Math.sin(this.b0)*Math.tan(h))),r=this.lambda0+n/this.alpha,o=0,l=e,u=-1e3,c=0;Math.abs(l-u)>1e-7;){if(++c>20)return;o=1/this.alpha*(Math.log(Math.tan(Math.PI/4+e/2))-this.K)+this.e*Math.log(Math.tan(Math.PI/4+Math.asin(this.e*Math.sin(l))/2)),u=l,l=2*Math.atan(Math.exp(o))-Math.PI/2}return t.x=r,t.y=l,t},names:["somerc"]},Bs=1e-7,zs={init:function(){var t,s,i,a,h,e,n,r,o,l,u,c=0,M=0,f=0,d=0,p=0,m=0,y=0;this.no_off=rt(this),this.no_rot="no_rot"in this;var _=!1;"alpha"in this&&(_=!0);var x=!1;if("rectified_grid_angle"in this&&(x=!0),_&&(y=this.alpha),x&&(c=this.rectified_grid_angle*Nt),_||x)M=this.longc;else if(f=this.long1,p=this.lat1,d=this.long2,m=this.lat2,Math.abs(p-m)<=Bs||(t=Math.abs(p))<=Bs||Math.abs(t-xt)<=Bs||Math.abs(Math.abs(this.lat0)-xt)<=Bs||Math.abs(Math.abs(m)-xt)<=Bs)throw new Error;var g=1-this.es;s=Math.sqrt(g),Math.abs(this.lat0)>wt?(r=Math.sin(this.lat0),i=Math.cos(this.lat0),t=1-this.es*r*r,this.B=i*i,this.B=Math.sqrt(1+this.es*this.B*this.B/g),this.A=this.B*this.k0*s/t,(h=(a=this.B*s/(i*Math.sqrt(t)))*a-1)<=0?h=0:(h=Math.sqrt(h),this.lat0<0&&(h=-h)),this.E=h+=a,this.E*=Math.pow(Xt(this.e,this.lat0,r),this.B)):(this.B=1/s,this.A=this.k0,this.E=a=h=1),_||x?(_?(u=Math.asin(Math.sin(y)/a),x||(c=y)):(u=c,y=Math.asin(a*Math.sin(u))),this.lam0=M-Math.asin(.5*(h-1/h)*Math.tan(u))/this.B):(e=Math.pow(Xt(this.e,p,Math.sin(p)),this.B),n=Math.pow(Xt(this.e,m,Math.sin(m)),this.B),h=this.E/e,o=(n-e)/(n+e),l=((l=this.E*this.E)-n*e)/(l+n*e),(t=f-d)<-Math.pi?d-=Ct:t>Math.pi&&(d+=Ct),this.lam0=Ht(.5*(f+d)-Math.atan(l*Math.tan(.5*this.B*(f-d))/o)/this.B),u=Math.atan(2*Math.sin(this.B*Ht(f-this.lam0))/(h-1/h)),c=y=Math.asin(a*Math.sin(u))),this.singam=Math.sin(u),this.cosgam=Math.cos(u),this.sinrot=Math.sin(c),this.cosrot=Math.cos(c),this.rB=1/this.B,this.ArB=this.A*this.rB,this.BrA=1/this.ArB,this.no_off?this.u_0=0:(this.u_0=Math.abs(this.ArB*Math.atan(Math.sqrt(a*a-1)/Math.cos(y))),this.lat0<0&&(this.u_0=-this.u_0)),h=.5*u,this.v_pole_n=this.ArB*Math.log(Math.tan(Et-h)),this.v_pole_s=this.ArB*Math.log(Math.tan(Et+h))},forward:function(t){var s,i,a,h,e,n,r,o,l={};if(t.x=t.x-this.lam0,Math.abs(Math.abs(t.y)-xt)>wt){if(e=this.E/Math.pow(Xt(this.e,t.y,Math.sin(t.y)),this.B),n=1/e,s=.5*(e-n),i=.5*(e+n),h=Math.sin(this.B*t.x),a=(s*this.singam-h*this.cosgam)/i,Math.abs(Math.abs(a)-1)0?this.v_pole_n:this.v_pole_s,r=this.ArB*t.y;return this.no_rot?(l.x=r,l.y=o):(r-=this.u_0,l.x=o*this.cosrot+r*this.sinrot,l.y=r*this.cosrot-o*this.sinrot),l.x=this.a*l.x+this.x0,l.y=this.a*l.y+this.y0,l},inverse:function(t){var s,i,a,h,e,n,r,o={};if(t.x=(t.x-this.x0)*(1/this.a),t.y=(t.y-this.y0)*(1/this.a),this.no_rot?(i=t.y,s=t.x):(i=t.x*this.cosrot-t.y*this.sinrot,s=t.y*this.cosrot+t.x*this.sinrot+this.u_0),a=Math.exp(-this.BrA*i),h=.5*(a-1/a),e=.5*(a+1/a),n=Math.sin(this.BrA*s),r=(n*this.cosgam+h*this.singam)/e,Math.abs(Math.abs(r)-1)wt?this.ns=Math.log(a/r)/Math.log(h/o):this.ns=s,isNaN(this.ns)&&(this.ns=s),this.f0=a/(this.ns*Math.pow(h,this.ns)),this.rh=this.a*this.f0*Math.pow(l,this.ns),this.title||(this.title="Lambert Conformal Conic")}},forward:function(t){var s=t.x,i=t.y;Math.abs(2*Math.abs(i)-Math.PI)<=wt&&(i=Wt(i)*(xt-2*wt));var a,h,e=Math.abs(Math.abs(i)-xt);if(e>wt)a=Xt(this.e,i,Math.sin(i)),h=this.a*this.f0*Math.pow(a,this.ns);else{if((e=i*this.ns)<=0)return null;h=0}var n=this.ns*Ht(s-this.long0);return t.x=this.k0*(h*Math.sin(n))+this.x0,t.y=this.k0*(this.rh-h*Math.cos(n))+this.y0,t},inverse:function(t){var s,i,a,h,e,n=(t.x-this.x0)/this.k0,r=this.rh-(t.y-this.y0)/this.k0;this.ns>0?(s=Math.sqrt(n*n+r*r),i=1):(s=-Math.sqrt(n*n+r*r),i=-1);var o=0;if(0!==s&&(o=Math.atan2(i*n,i*r)),0!==s||this.ns>0){if(i=1/this.ns,a=Math.pow(s/(this.a*this.f0),i),-9999===(h=Jt(this.e,a)))return null}else h=-xt;return e=Ht(o/this.ns+this.long0),t.x=e,t.y=h,t},names:["Lambert Tangential Conformal Conic Projection","Lambert_Conformal_Conic","Lambert_Conformal_Conic_1SP","Lambert_Conformal_Conic_2SP","lcc","Lambert Conic Conformal (1SP)","Lambert Conic Conformal (2SP)"]},Ds={init:function(){this.a=6377397.155,this.es=.006674372230614,this.e=Math.sqrt(this.es),this.lat0||(this.lat0=.863937979737193),this.long0||(this.long0=.4334234309119251),this.k0||(this.k0=.9999),this.s45=.785398163397448,this.s90=2*this.s45,this.fi0=this.lat0,this.e2=this.es,this.e=Math.sqrt(this.e2),this.alfa=Math.sqrt(1+this.e2*Math.pow(Math.cos(this.fi0),4)/(1-this.e2)),this.uq=1.04216856380474,this.u0=Math.asin(Math.sin(this.fi0)/this.alfa),this.g=Math.pow((1+this.e*Math.sin(this.fi0))/(1-this.e*Math.sin(this.fi0)),this.alfa*this.e/2),this.k=Math.tan(this.u0/2+this.s45)/Math.pow(Math.tan(this.fi0/2+this.s45),this.alfa)*this.g,this.k1=this.k0,this.n0=this.a*Math.sqrt(1-this.e2)/(1-this.e2*Math.pow(Math.sin(this.fi0),2)),this.s0=1.37008346281555,this.n=Math.sin(this.s0),this.ro0=this.k1*this.n0/Math.tan(this.s0),this.ad=this.s90-this.uq},forward:function(t){var s,i,a,h,e,n,r,o=t.x,l=t.y,u=Ht(o-this.long0);return s=Math.pow((1+this.e*Math.sin(l))/(1-this.e*Math.sin(l)),this.alfa*this.e/2),i=2*(Math.atan(this.k*Math.pow(Math.tan(l/2+this.s45),this.alfa)/s)-this.s45),a=-u*this.alfa,h=Math.asin(Math.cos(this.ad)*Math.sin(i)+Math.sin(this.ad)*Math.cos(i)*Math.cos(a)),e=Math.asin(Math.cos(i)*Math.sin(a)/Math.cos(h)),n=this.n*e,r=this.ro0*Math.pow(Math.tan(this.s0/2+this.s45),this.n)/Math.pow(Math.tan(h/2+this.s45),this.n),t.y=r*Math.cos(n)/1,t.x=r*Math.sin(n)/1,this.czech||(t.y*=-1,t.x*=-1),t},inverse:function(t){var s,i,a,h,e,n,r,o=t.x;t.x=t.y,t.y=o,this.czech||(t.y*=-1,t.x*=-1),e=Math.sqrt(t.x*t.x+t.y*t.y),h=Math.atan2(t.y,t.x)/Math.sin(this.s0),a=2*(Math.atan(Math.pow(this.ro0/e,1/this.n)*Math.tan(this.s0/2+this.s45))-this.s45),s=Math.asin(Math.cos(this.ad)*Math.sin(a)-Math.sin(this.ad)*Math.cos(a)*Math.cos(h)),i=Math.asin(Math.cos(a)*Math.sin(h)/Math.cos(s)),t.x=this.long0-i/this.alfa,n=s,r=0;var l=0;do{t.y=2*(Math.atan(Math.pow(this.k,-1/this.alfa)*Math.pow(Math.tan(s/2+this.s45),1/this.alfa)*Math.pow((1+this.e*Math.sin(n))/(1-this.e*Math.sin(n)),this.e/2))-this.s45),Math.abs(n-t.y)<1e-10&&(r=1),n=t.y,l+=1}while(0===r&&l<15);return l>=15?null:t},names:["Krovak","krovak"]},Us=function(t,s,i,a,h){return t*h-s*Math.sin(2*h)+i*Math.sin(4*h)-a*Math.sin(6*h)},Qs=function(t){return 1-.25*t*(1+t/16*(3+1.25*t))},Ws=function(t){return.375*t*(1+.25*t*(1+.46875*t))},Hs=function(t){return.05859375*t*t*(1+.75*t)},Xs=function(t){return t*t*t*(35/3072)},Js=function(t,s,i){var a=s*i;return t/Math.sqrt(1-a*a)},Ks=function(t){return Math.abs(t)1e-7?(i=t*s,(1-t*t)*(s/(1-i*i)-.5/t*Math.log((1-i)/(1+i)))):2*s},$s=.3333333333333333,ti=.17222222222222222,si=.10257936507936508,ii=.06388888888888888,ai=.0664021164021164,hi=.016415012942191543,ei={init:function(){var t=Math.abs(this.lat0);if(Math.abs(t-xt)0){var s;switch(this.qp=Ys(this.e,1),this.mmf=.5/(1-this.es),this.apa=ot(this.es),this.mode){case this.N_POLE:case this.S_POLE:this.dd=1;break;case this.EQUIT:this.rq=Math.sqrt(.5*this.qp),this.dd=1/this.rq,this.xmf=1,this.ymf=.5*this.qp;break;case this.OBLIQ:this.rq=Math.sqrt(.5*this.qp),s=Math.sin(this.lat0),this.sinb1=Ys(this.e,s)/this.qp,this.cosb1=Math.sqrt(1-this.sinb1*this.sinb1),this.dd=Math.cos(this.lat0)/(Math.sqrt(1-this.es*s*s)*this.rq*this.cosb1),this.ymf=(this.xmf=this.rq)/this.dd,this.xmf*=this.dd}}else this.mode===this.OBLIQ&&(this.sinph0=Math.sin(this.lat0),this.cosph0=Math.cos(this.lat0))},forward:function(t){var s,i,a,h,e,n,r,o,l,u,c=t.x,M=t.y;if(c=Ht(c-this.long0),this.sphere){if(e=Math.sin(M),u=Math.cos(M),a=Math.cos(c),this.mode===this.OBLIQ||this.mode===this.EQUIT){if((i=this.mode===this.EQUIT?1+u*a:1+this.sinph0*e+this.cosph0*u*a)<=wt)return null;s=(i=Math.sqrt(2/i))*u*Math.sin(c),i*=this.mode===this.EQUIT?e:this.cosph0*e-this.sinph0*u*a}else if(this.mode===this.N_POLE||this.mode===this.S_POLE){if(this.mode===this.N_POLE&&(a=-a),Math.abs(M+this.lat0)=0?(s=(l=Math.sqrt(n))*h,i=a*(this.mode===this.S_POLE?l:-l)):s=i=0}}return t.x=this.a*s+this.x0,t.y=this.a*i+this.y0,t},inverse:function(t){t.x-=this.x0,t.y-=this.y0;var s,i,a,h,e,n,r,o=t.x/this.a,l=t.y/this.a;if(this.sphere){var u,c=0,M=0;if(u=Math.sqrt(o*o+l*l),(i=.5*u)>1)return null;switch(i=2*Math.asin(i),this.mode!==this.OBLIQ&&this.mode!==this.EQUIT||(M=Math.sin(i),c=Math.cos(i)),this.mode){case this.EQUIT:i=Math.abs(u)<=wt?0:Math.asin(l*M/u),o*=M,l=c*u;break;case this.OBLIQ:i=Math.abs(u)<=wt?this.lat0:Math.asin(c*this.sinph0+l*M*this.cosph0/u),o*=M*this.cosph0,l=(c-Math.sin(i)*this.sinph0)*u;break;case this.N_POLE:l=-l,i=xt-i;break;case this.S_POLE:i-=xt}s=0!==l||this.mode!==this.EQUIT&&this.mode!==this.OBLIQ?Math.atan2(o,l):0}else{if(r=0,this.mode===this.OBLIQ||this.mode===this.EQUIT){if(o/=this.dd,l*=this.dd,(n=Math.sqrt(o*o+l*l))1&&(t=t>1?1:-1),Math.asin(t)},ri={init:function(){Math.abs(this.lat1+this.lat2)wt?this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1):this.ns0=this.con,this.c=this.ms1*this.ms1+this.ns0*this.qs1,this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0)},forward:function(t){var s=t.x,i=t.y;this.sin_phi=Math.sin(i),this.cos_phi=Math.cos(i);var a=Ys(this.e3,this.sin_phi),h=this.a*Math.sqrt(this.c-this.ns0*a)/this.ns0,e=this.ns0*Ht(s-this.long0),n=h*Math.sin(e)+this.x0,r=this.rh-h*Math.cos(e)+this.y0;return t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n;return t.x-=this.x0,t.y=this.rh-t.y+this.y0,this.ns0>=0?(s=Math.sqrt(t.x*t.x+t.y*t.y),a=1):(s=-Math.sqrt(t.x*t.x+t.y*t.y),a=-1),h=0,0!==s&&(h=Math.atan2(a*t.x,a*t.y)),a=s*this.ns0/this.a,this.sphere?n=Math.asin((this.c-a*a)/(2*this.ns0)):(i=(this.c-a*a)/this.ns0,n=this.phi1z(this.e3,i)),e=Ht(h/this.ns0+this.long0),t.x=e,t.y=n,t},names:["Albers_Conic_Equal_Area","Albers","aea"],phi1z:function(t,s){var i,a,h,e,n,r=ni(.5*s);if(t0||Math.abs(e)<=wt?(n=this.x0+1*this.a*i*Math.sin(a)/e,r=this.y0+1*this.a*(this.cos_p14*s-this.sin_p14*i*h)/e):(n=this.x0+this.infinity_dist*i*Math.sin(a),r=this.y0+this.infinity_dist*(this.cos_p14*s-this.sin_p14*i*h)),t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n;return t.x=(t.x-this.x0)/this.a,t.y=(t.y-this.y0)/this.a,t.x/=this.k0,t.y/=this.k0,(s=Math.sqrt(t.x*t.x+t.y*t.y))?(h=Math.atan2(s,this.rc),i=Math.sin(h),a=Math.cos(h),n=ni(a*this.sin_p14+t.y*i*this.cos_p14/s),e=Math.atan2(t.x*i,s*this.cos_p14*a-t.y*this.sin_p14*i),e=Ht(this.long0+e)):(n=this.phic0,e=0),t.x=e,t.y=n,t},names:["gnom"]},li=function(t,s){var i=1-(1-t*t)/(2*t)*Math.log((1-t)/(1+t));if(Math.abs(Math.abs(s)-i)<1e-6)return s<0?-1*xt:xt;for(var a,h,e,n,r=Math.asin(.5*s),o=0;o<30;o++)if(h=Math.sin(r),e=Math.cos(r),n=t*h,a=Math.pow(1-n*n,2)/(2*e)*(s/(1-t*t)-h/(1-n*n)+.5/t*Math.log((1-n)/(1+n))),r+=a,Math.abs(a)<=1e-10)return r;return NaN},ui={init:function(){this.sphere||(this.k0=Qt(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts)))},forward:function(t){var s,i,a=t.x,h=t.y,e=Ht(a-this.long0);if(this.sphere)s=this.x0+this.a*e*Math.cos(this.lat_ts),i=this.y0+this.a*Math.sin(h)/Math.cos(this.lat_ts);else{var n=Ys(this.e,Math.sin(h));s=this.x0+this.a*this.k0*e,i=this.y0+this.a*n*.5/this.k0}return t.x=s,t.y=i,t},inverse:function(t){t.x-=this.x0,t.y-=this.y0;var s,i;return this.sphere?(s=Ht(this.long0+t.x/this.a/Math.cos(this.lat_ts)),i=Math.asin(t.y/this.a*Math.cos(this.lat_ts))):(i=li(this.e,2*t.y*this.k0/this.a),s=Ht(this.long0+t.x/(this.a*this.k0))),t.x=s,t.y=i,t},names:["cea"]},ci={init:function(){this.x0=this.x0||0,this.y0=this.y0||0,this.lat0=this.lat0||0,this.long0=this.long0||0,this.lat_ts=this.lat_ts||0,this.title=this.title||"Equidistant Cylindrical (Plate Carre)",this.rc=Math.cos(this.lat_ts)},forward:function(t){var s=t.x,i=t.y,a=Ht(s-this.long0),h=Ks(i-this.lat0);return t.x=this.x0+this.a*a*this.rc,t.y=this.y0+this.a*h,t},inverse:function(t){var s=t.x,i=t.y;return t.x=Ht(this.long0+(s-this.x0)/(this.a*this.rc)),t.y=Ks(this.lat0+(i-this.y0)/this.a),t},names:["Equirectangular","Equidistant_Cylindrical","eqc"]},Mi=20,fi={init:function(){this.temp=this.b/this.a,this.es=1-Math.pow(this.temp,2),this.e=Math.sqrt(this.es),this.e0=Qs(this.es),this.e1=Ws(this.es),this.e2=Hs(this.es),this.e3=Xs(this.es),this.ml0=this.a*Us(this.e0,this.e1,this.e2,this.e3,this.lat0)},forward:function(t){var s,i,a,h=t.x,e=t.y,n=Ht(h-this.long0);if(a=n*Math.sin(e),this.sphere)Math.abs(e)<=wt?(s=this.a*n,i=-1*this.a*this.lat0):(s=this.a*Math.sin(a)/Math.tan(e),i=this.a*(Ks(e-this.lat0)+(1-Math.cos(a))/Math.tan(e)));else if(Math.abs(e)<=wt)s=this.a*n,i=-1*this.ml0;else{var r=Js(this.a,this.e,Math.sin(e))/Math.tan(e);s=r*Math.sin(a),i=this.a*Us(this.e0,this.e1,this.e2,this.e3,e)-this.ml0+r*(1-Math.cos(a))}return t.x=s+this.x0,t.y=i+this.y0,t},inverse:function(t){var s,i,a,h,e,n,r,o,l;if(a=t.x-this.x0,h=t.y-this.y0,this.sphere)if(Math.abs(h+this.a*this.lat0)<=wt)s=Ht(a/this.a+this.long0),i=0;else{n=this.lat0+h/this.a,r=a*a/this.a/this.a+n*n,o=n;var u;for(e=Mi;e;--e)if(u=Math.tan(o),l=-1*(n*(o*u+1)-o-.5*(o*o+r)*u)/((o-n)/u-1),o+=l,Math.abs(l)<=wt){i=o;break}s=Ht(this.long0+Math.asin(a*Math.tan(o)/this.a)/Math.sin(i))}else if(Math.abs(h+this.ml0)<=wt)i=0,s=Ht(this.long0+a/this.a);else{n=(this.ml0+h)/this.a,r=a*a/this.a/this.a+n*n,o=n;var c,M,f,d,p;for(e=Mi;e;--e)if(p=this.e*Math.sin(o),c=Math.sqrt(1-p*p)*Math.tan(o),M=this.a*Us(this.e0,this.e1,this.e2,this.e3,o),f=this.e0-2*this.e1*Math.cos(2*o)+4*this.e2*Math.cos(4*o)-6*this.e3*Math.cos(6*o),d=M/this.a,l=(n*(c*d+1)-d-.5*c*(d*d+r))/(this.es*Math.sin(2*o)*(d*d+r-2*n*d)/(4*c)+(n-d)*(c*f-2/Math.sin(2*o))-f),o-=l,Math.abs(l)<=wt){i=o;break}c=Math.sqrt(1-this.es*Math.pow(Math.sin(i),2))*Math.tan(i),s=Ht(this.long0+Math.asin(a*c/this.a)/Math.sin(i))}return t.x=s,t.y=i,t},names:["Polyconic","poly"]},di={init:function(){this.A=[],this.A[1]=.6399175073,this.A[2]=-.1358797613,this.A[3]=.063294409,this.A[4]=-.02526853,this.A[5]=.0117879,this.A[6]=-.0055161,this.A[7]=.0026906,this.A[8]=-.001333,this.A[9]=67e-5,this.A[10]=-34e-5,this.B_re=[],this.B_im=[],this.B_re[1]=.7557853228,this.B_im[1]=0,this.B_re[2]=.249204646,this.B_im[2]=.003371507,this.B_re[3]=-.001541739,this.B_im[3]=.04105856,this.B_re[4]=-.10162907,this.B_im[4]=.01727609,this.B_re[5]=-.26623489,this.B_im[5]=-.36249218,this.B_re[6]=-.6870983,this.B_im[6]=-1.1651967,this.C_re=[],this.C_im=[],this.C_re[1]=1.3231270439,this.C_im[1]=0,this.C_re[2]=-.577245789,this.C_im[2]=-.007809598,this.C_re[3]=.508307513,this.C_im[3]=-.112208952,this.C_re[4]=-.15094762,this.C_im[4]=.18200602,this.C_re[5]=1.01418179,this.C_im[5]=1.64497696,this.C_re[6]=1.9660549,this.C_im[6]=2.5127645,this.D=[],this.D[1]=1.5627014243,this.D[2]=.5185406398,this.D[3]=-.03333098,this.D[4]=-.1052906,this.D[5]=-.0368594,this.D[6]=.007317,this.D[7]=.0122,this.D[8]=.00394,this.D[9]=-.0013},forward:function(t){var s,i=t.x,a=t.y-this.lat0,h=i-this.long0,e=a/_t*1e-5,n=h,r=1,o=0;for(s=1;s<=10;s++)r*=e,o+=this.A[s]*r;var l,u=o,c=n,M=1,f=0,d=0,p=0;for(s=1;s<=6;s++)l=f*u+M*c,M=M*u-f*c,f=l,d=d+this.B_re[s]*M-this.B_im[s]*f,p=p+this.B_im[s]*M+this.B_re[s]*f;return t.x=p*this.a+this.x0,t.y=d*this.a+this.y0,t},inverse:function(t){var s,i,a=t.x,h=t.y,e=a-this.x0,n=(h-this.y0)/this.a,r=e/this.a,o=1,l=0,u=0,c=0;for(s=1;s<=6;s++)i=l*n+o*r,o=o*n-l*r,l=i,u=u+this.C_re[s]*o-this.C_im[s]*l,c=c+this.C_im[s]*o+this.C_re[s]*l;for(var M=0;M.999999999999&&(i=.999999999999),s=Math.asin(i);var a=Ht(this.long0+t.x/(.900316316158*this.a*Math.cos(s)));a<-Math.PI&&(a=-Math.PI),a>Math.PI&&(a=Math.PI),i=(2*s+Math.sin(2*s))/Math.PI,Math.abs(i)>1&&(i=1);var h=Math.asin(i);return t.x=a,t.y=h,t},names:["Mollweide","moll"]},xi={init:function(){Math.abs(this.lat1+this.lat2)=0?(i=Math.sqrt(t.x*t.x+t.y*t.y),s=1):(i=-Math.sqrt(t.x*t.x+t.y*t.y),s=-1);var e=0;if(0!==i&&(e=Math.atan2(s*t.x,s*t.y)),this.sphere)return h=Ht(this.long0+e/this.ns),a=Ks(this.g-i/this.a),t.x=h,t.y=a,t;var n=this.g-i/this.a;return a=Vs(n,this.e0,this.e1,this.e2,this.e3),h=Ht(this.long0+e/this.ns),t.x=h,t.y=a,t},names:["Equidistant_Conic","eqdc"]},gi={init:function(){this.R=this.a},forward:function(t){var s,i,a=t.x,h=t.y,e=Ht(a-this.long0);Math.abs(h)<=wt&&(s=this.x0+this.R*e,i=this.y0);var n=ni(2*Math.abs(h/Math.PI));(Math.abs(e)<=wt||Math.abs(Math.abs(h)-xt)<=wt)&&(s=this.x0,i=h>=0?this.y0+Math.PI*this.R*Math.tan(.5*n):this.y0+Math.PI*this.R*-Math.tan(.5*n));var r=.5*Math.abs(Math.PI/e-e/Math.PI),o=r*r,l=Math.sin(n),u=Math.cos(n),c=u/(l+u-1),M=c*c,f=c*(2/l-1),d=f*f,p=Math.PI*this.R*(r*(c-d)+Math.sqrt(o*(c-d)*(c-d)-(d+o)*(M-d)))/(d+o);e<0&&(p=-p),s=this.x0+p;var m=o+c;return p=Math.PI*this.R*(f*m-r*Math.sqrt((d+o)*(o+1)-m*m))/(d+o),i=h>=0?this.y0+p:this.y0-p,t.x=s,t.y=i,t},inverse:function(t){var s,i,a,h,e,n,r,o,l,u,c,M,f;return t.x-=this.x0,t.y-=this.y0,c=Math.PI*this.R,a=t.x/c,h=t.y/c,e=a*a+h*h,n=-Math.abs(h)*(1+e),r=n-2*h*h+a*a,o=-2*n+1+2*h*h+e*e,f=h*h/o+(2*r*r*r/o/o/o-9*n*r/o/o)/27,l=(n-r*r/3/o)/o,u=2*Math.sqrt(-l/3),c=3*f/l/u,Math.abs(c)>1&&(c=c>=0?1:-1),M=Math.acos(c)/3,i=t.y>=0?(-u*Math.cos(M+Math.PI/3)-r/3/o)*Math.PI:-(-u*Math.cos(M+Math.PI/3)-r/3/o)*Math.PI,s=Math.abs(a)2*xt*this.a)return;return i=s/this.a,a=Math.sin(i),h=Math.cos(i),e=this.long0,Math.abs(s)<=wt?n=this.lat0:(n=ni(h*this.sin_p12+t.y*a*this.cos_p12/s),r=Math.abs(this.lat0)-xt,e=Ht(Math.abs(r)<=wt?this.lat0>=0?this.long0+Math.atan2(t.x,-t.y):this.long0-Math.atan2(-t.x,t.y):this.long0+Math.atan2(t.x*a,s*this.cos_p12*h-t.y*this.sin_p12*a))),t.x=e,t.y=n,t}return o=Qs(this.es),l=Ws(this.es),u=Hs(this.es),c=Xs(this.es),Math.abs(this.sin_p12-1)<=wt?(M=this.a*Us(o,l,u,c,xt),s=Math.sqrt(t.x*t.x+t.y*t.y),f=M-s,n=Vs(f/this.a,o,l,u,c),e=Ht(this.long0+Math.atan2(t.x,-1*t.y)),t.x=e,t.y=n,t):Math.abs(this.sin_p12+1)<=wt?(M=this.a*Us(o,l,u,c,xt),s=Math.sqrt(t.x*t.x+t.y*t.y),f=s-M,n=Vs(f/this.a,o,l,u,c),e=Ht(this.long0+Math.atan2(t.x,t.y)),t.x=e,t.y=n,t):(s=Math.sqrt(t.x*t.x+t.y*t.y),m=Math.atan2(t.x,t.y),d=Js(this.a,this.e,this.sin_p12),y=Math.cos(m),_=this.e*this.cos_p12*y,x=-_*_/(1-this.es),g=3*this.es*(1-x)*this.sin_p12*this.cos_p12*y/(1-this.es),v=s/d,b=v-x*(1+x)*Math.pow(v,3)/6-g*(1+3*x)*Math.pow(v,4)/24,w=1-x*b*b/2-v*b*b*b/6,p=Math.asin(this.sin_p12*Math.cos(b)+this.cos_p12*Math.sin(b)*y),e=Ht(this.long0+Math.asin(Math.sin(m)*Math.sin(b)/Math.cos(p))),N=Math.sin(p),n=Math.atan2((N-this.es*w*this.sin_p12)*Math.tan(p),N*(1-this.es)),t.x=e,t.y=n,t)},names:["Azimuthal_Equidistant","aeqd"]},bi={init:function(){this.sin_p14=Math.sin(this.lat0),this.cos_p14=Math.cos(this.lat0)},forward:function(t){var s,i,a,h,e,n,r,o=t.x,l=t.y;return a=Ht(o-this.long0),s=Math.sin(l),i=Math.cos(l),h=Math.cos(a),((e=this.sin_p14*s+this.cos_p14*i*h)>0||Math.abs(e)<=wt)&&(n=1*this.a*i*Math.sin(a),r=this.y0+1*this.a*(this.cos_p14*s-this.sin_p14*i*h)),t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n,r;return t.x-=this.x0,t.y-=this.y0,s=Math.sqrt(t.x*t.x+t.y*t.y),i=ni(s/this.a),a=Math.sin(i),h=Math.cos(i),n=this.long0,Math.abs(s)<=wt?(r=this.lat0,t.x=n,t.y=r,t):(r=ni(h*this.sin_p14+t.y*a*this.cos_p14/s),e=Math.abs(this.lat0)-xt,Math.abs(e)<=wt?(n=Ht(this.lat0>=0?this.long0+Math.atan2(t.x,-t.y):this.long0-Math.atan2(-t.x,t.y)),t.x=n,t.y=r,t):(n=Ht(this.long0+Math.atan2(t.x*a,s*this.cos_p14*h-t.y*this.sin_p14*a)),t.x=n,t.y=r,t))},names:["ortho"]},wi={FRONT:1,RIGHT:2,BACK:3,LEFT:4,TOP:5,BOTTOM:6},Ni={AREA_0:1,AREA_1:2,AREA_2:3,AREA_3:4},Ai={init:function(){this.x0=this.x0||0,this.y0=this.y0||0,this.lat0=this.lat0||0,this.long0=this.long0||0,this.lat_ts=this.lat_ts||0,this.title=this.title||"Quadrilateralized Spherical Cube",this.lat0>=xt-Et/2?this.face=wi.TOP:this.lat0<=-(xt-Et/2)?this.face=wi.BOTTOM:Math.abs(this.long0)<=Et?this.face=wi.FRONT:Math.abs(this.long0)<=xt+Et?this.face=this.long0>0?wi.RIGHT:wi.LEFT:this.face=wi.BACK,0!==this.es&&(this.one_minus_f=1-(this.a-this.b)/this.a,this.one_minus_f_squared=this.one_minus_f*this.one_minus_f)},forward:function(t){var s,i,a,h,e,n,r={x:0,y:0},o={value:0};if(t.x-=this.long0,s=0!==this.es?Math.atan(this.one_minus_f_squared*Math.tan(t.y)):t.y,i=t.x,this.face===wi.TOP)h=xt-s,i>=Et&&i<=xt+Et?(o.value=Ni.AREA_0,a=i-xt):i>xt+Et||i<=-(xt+Et)?(o.value=Ni.AREA_1,a=i>0?i-Pt:i+Pt):i>-(xt+Et)&&i<=-Et?(o.value=Ni.AREA_2,a=i+xt):(o.value=Ni.AREA_3,a=i);else if(this.face===wi.BOTTOM)h=xt+s,i>=Et&&i<=xt+Et?(o.value=Ni.AREA_0,a=-i+xt):i=-Et?(o.value=Ni.AREA_1,a=-i):i<-Et&&i>=-(xt+Et)?(o.value=Ni.AREA_2,a=-i-xt):(o.value=Ni.AREA_3,a=i>0?-i+Pt:-i-Pt);else{var l,u,c,M,f,d;this.face===wi.RIGHT?i=ct(i,+xt):this.face===wi.BACK?i=ct(i,+Pt):this.face===wi.LEFT&&(i=ct(i,-xt)),M=Math.sin(s),f=Math.cos(s),d=Math.sin(i),l=f*Math.cos(i),u=f*d,c=M,this.face===wi.FRONT?a=ut(h=Math.acos(l),c,u,o):this.face===wi.RIGHT?a=ut(h=Math.acos(u),c,-l,o):this.face===wi.BACK?a=ut(h=Math.acos(-l),c,-u,o):this.face===wi.LEFT?a=ut(h=Math.acos(-u),c,l,o):(h=a=0,o.value=Ni.AREA_0)}return n=Math.atan(12/Pt*(a+Math.acos(Math.sin(a)*Math.cos(Et))-xt)),e=Math.sqrt((1-Math.cos(h))/(Math.cos(n)*Math.cos(n))/(1-Math.cos(Math.atan(1/Math.cos(a))))),o.value===Ni.AREA_1?n+=xt:o.value===Ni.AREA_2?n+=Pt:o.value===Ni.AREA_3&&(n+=1.5*Pt),r.x=e*Math.cos(n),r.y=e*Math.sin(n),r.x=r.x*this.a+this.x0,r.y=r.y*this.a+this.y0,t.x=r.x,t.y=r.y,t},inverse:function(t){var s,i,a,h,e,n,r,o,l,u={lam:0,phi:0},c={value:0};if(t.x=(t.x-this.x0)/this.a,t.y=(t.y-this.y0)/this.a,i=Math.atan(Math.sqrt(t.x*t.x+t.y*t.y)),s=Math.atan2(t.y,t.x),t.x>=0&&t.x>=Math.abs(t.y)?c.value=Ni.AREA_0:t.y>=0&&t.y>=Math.abs(t.x)?(c.value=Ni.AREA_1,s-=xt):t.x<0&&-t.x>=Math.abs(t.y)?(c.value=Ni.AREA_2,s=s<0?s+Pt:s-Pt):(c.value=Ni.AREA_3,s+=xt),l=Pt/12*Math.tan(s),e=Math.sin(l)/(Math.cos(l)-1/Math.sqrt(2)),n=Math.atan(e),a=Math.cos(s),h=Math.tan(i),(r=1-a*a*h*h*(1-Math.cos(Math.atan(1/Math.cos(n)))))<-1?r=-1:r>1&&(r=1),this.face===wi.TOP)o=Math.acos(r),u.phi=xt-o,c.value===Ni.AREA_0?u.lam=n+xt:c.value===Ni.AREA_1?u.lam=n<0?n+Pt:n-Pt:c.value===Ni.AREA_2?u.lam=n-xt:u.lam=n;else if(this.face===wi.BOTTOM)o=Math.acos(r),u.phi=o-xt,c.value===Ni.AREA_0?u.lam=-n+xt:c.value===Ni.AREA_1?u.lam=-n:c.value===Ni.AREA_2?u.lam=-n-xt:u.lam=n<0?-n-Pt:-n+Pt;else{var M,f,d;l=(M=r)*M,f=(l+=(d=l>=1?0:Math.sqrt(1-l)*Math.sin(n))*d)>=1?0:Math.sqrt(1-l),c.value===Ni.AREA_1?(l=f,f=-d,d=l):c.value===Ni.AREA_2?(f=-f,d=-d):c.value===Ni.AREA_3&&(l=f,f=d,d=-l),this.face===wi.RIGHT?(l=M,M=-f,f=l):this.face===wi.BACK?(M=-M,f=-f):this.face===wi.LEFT&&(l=M,M=f,f=-l),u.phi=Math.acos(-d)-xt,u.lam=Math.atan2(f,M),this.face===wi.RIGHT?u.lam=ct(u.lam,-xt):this.face===wi.BACK?u.lam=ct(u.lam,-Pt):this.face===wi.LEFT&&(u.lam=ct(u.lam,+xt))}if(0!==this.es){var p,m,y;p=u.phi<0?1:0,m=Math.tan(u.phi),y=this.b/Math.sqrt(m*m+this.one_minus_f_squared),u.phi=Math.atan(Math.sqrt(this.a*this.a-y*y)/(this.one_minus_f*y)),p&&(u.phi=-u.phi)}return u.lam+=this.long0,t.x=u.lam,t.y=u.phi,t},names:["Quadrilateralized Spherical Cube","Quadrilateralized_Spherical_Cube","qsc"]},Ei=[[1,2.2199e-17,-715515e-10,31103e-10],[.9986,-482243e-9,-24897e-9,-13309e-10],[.9954,-83103e-8,-448605e-10,-9.86701e-7],[.99,-.00135364,-59661e-9,36777e-10],[.9822,-.00167442,-449547e-11,-572411e-11],[.973,-.00214868,-903571e-10,1.8736e-8],[.96,-.00305085,-900761e-10,164917e-11],[.9427,-.00382792,-653386e-10,-26154e-10],[.9216,-.00467746,-10457e-8,481243e-11],[.8962,-.00536223,-323831e-10,-543432e-11],[.8679,-.00609363,-113898e-9,332484e-11],[.835,-.00698325,-640253e-10,9.34959e-7],[.7986,-.00755338,-500009e-10,9.35324e-7],[.7597,-.00798324,-35971e-9,-227626e-11],[.7186,-.00851367,-701149e-10,-86303e-10],[.6732,-.00986209,-199569e-9,191974e-10],[.6213,-.010418,883923e-10,624051e-11],[.5722,-.00906601,182e-6,624051e-11],[.5322,-.00677797,275608e-9,624051e-11]],Ci=[[-5.20417e-18,.0124,1.21431e-18,-8.45284e-11],[.062,.0124,-1.26793e-9,4.22642e-10],[.124,.0124,5.07171e-9,-1.60604e-9],[.186,.0123999,-1.90189e-8,6.00152e-9],[.248,.0124002,7.10039e-8,-2.24e-8],[.31,.0123992,-2.64997e-7,8.35986e-8],[.372,.0124029,9.88983e-7,-3.11994e-7],[.434,.0123893,-369093e-11,-4.35621e-7],[.4958,.0123198,-102252e-10,-3.45523e-7],[.5571,.0121916,-154081e-10,-5.82288e-7],[.6176,.0119938,-241424e-10,-5.25327e-7],[.6769,.011713,-320223e-10,-5.16405e-7],[.7346,.0113541,-397684e-10,-6.09052e-7],[.7903,.0109107,-489042e-10,-104739e-11],[.8435,.0103431,-64615e-9,-1.40374e-9],[.8936,.00969686,-64636e-9,-8547e-9],[.9394,.00840947,-192841e-9,-42106e-10],[.9761,.00616527,-256e-6,-42106e-10],[1,.00328947,-319159e-9,-42106e-10]],Pi=.8487,Si=1.3523,Ii=At/5,Oi=1/Ii,ki=18,qi=function(t,s){return t[0]+s*(t[1]+s*(t[2]+s*t[3]))},Ri=function(t,s){return t[1]+s*(2*t[2]+3*s*t[3])},Li={init:function(){this.x0=this.x0||0,this.y0=this.y0||0,this.long0=this.long0||0,this.es=0,this.title=this.title||"Robinson"},forward:function(t){var s=Ht(t.x-this.long0),i=Math.abs(t.y),a=Math.floor(i*Ii);a<0?a=0:a>=ki&&(a=ki-1),i=At*(i-Oi*a);var h={x:qi(Ei[a],i)*s,y:qi(Ci[a],i)};return t.y<0&&(h.y=-h.y),h.x=h.x*this.a*Pi+this.x0,h.y=h.y*this.a*Si+this.y0,h},inverse:function(t){var s={x:(t.x-this.x0)/(this.a*Pi),y:Math.abs(t.y-this.y0)/(this.a*Si)};if(s.y>=1)s.x/=Ei[ki][0],s.y=t.y<0?-xt:xt;else{var i=Math.floor(s.y*ki);for(i<0?i=0:i>=ki&&(i=ki-1);;)if(Ci[i][0]>s.y)--i;else{if(!(Ci[i+1][0]<=s.y))break;++i}var a=Ci[i],h=5*(s.y-a[0])/(Ci[i+1][0]-a[0]);h=Mt(function(t){return(qi(a,t)-s.y)/Ri(a,t)},h,wt,100),s.x/=qi(Ei[i],h),s.y=(5*i+h)*Nt,t.y<0&&(s.y=-s.y)}return s.x=Ht(s.x+this.long0),s},names:["Robinson","robin"]},Ti={init:function(){this.name="geocent"},forward:function(t){return k(t,this.es,this.a)},inverse:function(t){return q(t,this.es,this.a,this.b)},names:["Geocentric","geocentric","geocent","Geocent"]},Gi={N_POLE:0,S_POLE:1,EQUIT:2,OBLIQ:3},ji={h:{def:1e5,num:!0},azi:{def:0,num:!0,degrees:!0},tilt:{def:0,num:!0,degrees:!0},long0:{def:0,num:!0},lat0:{def:0,num:!0}},Bi={init:function(){if(Object.keys(ji).forEach(function(t){if(void 0===this[t])this[t]=ji[t].def;else{if(ji[t].num&&isNaN(this[t]))throw new Error("Invalid parameter value, must be numeric "+t+" = "+this[t]);ji[t].num&&(this[t]=parseFloat(this[t]))}ji[t].degrees&&(this[t]=this[t]*Nt)}.bind(this)),Math.abs(Math.abs(this.lat0)-xt)1e10)throw new Error("Invalid height");this.p=1+this.pn1,this.rp=1/this.p,this.h1=1/this.pn1,this.pfact=(this.p+1)*this.h1,this.es=0;var t=this.tilt,s=this.azi;this.cg=Math.cos(s),this.sg=Math.sin(s),this.cw=Math.cos(t),this.sw=Math.sin(t)},forward:function(t){t.x-=this.long0;var s,i,a=Math.sin(t.y),h=Math.cos(t.y),e=Math.cos(t.x);switch(this.mode){case Gi.OBLIQ:i=this.sinph0*a+this.cosph0*h*e;break;case Gi.EQUIT:i=h*e;break;case Gi.S_POLE:i=-a;break;case Gi.N_POLE:i=a}switch(i=this.pn1/(this.p-i),s=i*h*Math.sin(t.x),this.mode){case Gi.OBLIQ:i*=this.cosph0*a-this.sinph0*h*e;break;case Gi.EQUIT:i*=a;break;case Gi.N_POLE:i*=-h*e;break;case Gi.S_POLE:i*=h*e}var n,r;return n=i*this.cg+s*this.sg,r=1/(n*this.sw*this.h1+this.cw),s=(s*this.cg-i*this.sg)*this.cw*r,i=n*r,t.x=s*this.a,t.y=i*this.a,t},inverse:function(t){t.x/=this.a,t.y/=this.a;var s,i,a,h={x:t.x,y:t.y};a=1/(this.pn1-t.y*this.sw),s=this.pn1*t.x*a,i=this.pn1*t.y*this.cw*a,t.x=s*this.cg+i*this.sg,t.y=i*this.cg-s*this.sg;var e=ws(t.x,t.y);if(Math.abs(e)1e10)throw new Error;if(this.radius_g=1+this.radius_g_1,this.C=this.radius_g*this.radius_g-1,0!==this.es){var t=1-this.es,s=1/t;this.radius_p=Math.sqrt(t),this.radius_p2=t,this.radius_p_inv2=s,this.shape="ellipse"}else this.radius_p=1,this.radius_p2=1,this.radius_p_inv2=1,this.shape="sphere";this.title||(this.title="Geostationary Satellite View")},forward:function(t){var s,i,a,h,e=t.x,n=t.y;if(e-=this.long0,"ellipse"===this.shape){n=Math.atan(this.radius_p2*Math.tan(n));var r=this.radius_p/ws(this.radius_p*Math.cos(n),Math.sin(n));if(i=r*Math.cos(e)*Math.cos(n),a=r*Math.sin(e)*Math.cos(n),h=r*Math.sin(n),(this.radius_g-i)*i-a*a-h*h*this.radius_p_inv2<0)return t.x=Number.NaN,t.y=Number.NaN,t;s=this.radius_g-i,this.flip_axis?(t.x=this.radius_g_1*Math.atan(a/ws(h,s)),t.y=this.radius_g_1*Math.atan(h/s)):(t.x=this.radius_g_1*Math.atan(a/s),t.y=this.radius_g_1*Math.atan(h/ws(a,s)))}else"sphere"===this.shape&&(s=Math.cos(n),i=Math.cos(e)*s,a=Math.sin(e)*s,h=Math.sin(n),s=this.radius_g-i,this.flip_axis?(t.x=this.radius_g_1*Math.atan(a/ws(h,s)),t.y=this.radius_g_1*Math.atan(h/s)):(t.x=this.radius_g_1*Math.atan(a/s),t.y=this.radius_g_1*Math.atan(h/ws(a,s))));return t.x=t.x*this.a,t.y=t.y*this.a,t},inverse:function(t){var s,i,a,h,e=-1,n=0,r=0;if(t.x=t.x/this.a,t.y=t.y/this.a,"ellipse"===this.shape){this.flip_axis?(r=Math.tan(t.y/this.radius_g_1),n=Math.tan(t.x/this.radius_g_1)*ws(1,r)):(n=Math.tan(t.x/this.radius_g_1),r=Math.tan(t.y/this.radius_g_1)*ws(1,n));var o=r/this.radius_p;if(s=n*n+o*o+e*e,i=2*this.radius_g*e,(a=i*i-4*s*this.C)<0)return t.x=Number.NaN,t.y=Number.NaN,t;h=(-i-Math.sqrt(a))/(2*s),e=this.radius_g+h*e,n*=h,r*=h,t.x=Math.atan2(n,e),t.y=Math.atan(r*Math.cos(t.x)/e),t.y=Math.atan(this.radius_p_inv2*Math.tan(t.y))}else if("sphere"===this.shape){if(this.flip_axis?(r=Math.tan(t.y/this.radius_g_1),n=Math.tan(t.x/this.radius_g_1)*Math.sqrt(1+r*r)):(n=Math.tan(t.x/this.radius_g_1),r=Math.tan(t.y/this.radius_g_1)*Math.sqrt(1+n*n)),s=n*n+r*r+e*e,i=2*this.radius_g*e,(a=i*i-4*s*this.C)<0)return t.x=Number.NaN,t.y=Number.NaN,t;h=(-i-Math.sqrt(a))/(2*s),e=this.radius_g+h*e,n*=h,r*=h,t.x=Math.atan2(n,e),t.y=Math.atan(r*Math.cos(t.x)/e)}return t.x=t.x+this.long0,t},names:["Geostationary Satellite View","Geostationary_Satellite","geos"]};return W.defaultDatum="WGS84",W.Proj=Projection,W.WGS84=new W.Proj("WGS84"),W.Point=Point,W.toPoint=es,W.defs=o,W.nadgrid=function(t,s){var i=new DataView(s),a=N(i),h=A(i,a);h.nSubgrids>1&&console.log("Only single NTv2 subgrids are currently supported, subsequent sub grids are ignored");var e={header:h,subgrids:C(i,h,a)};return is[t]=e,e},W.transform=D,W.mgrs=ms,W.version="2.9.0",function(proj4){proj4.Proj.projections.add(vs),proj4.Proj.projections.add(Is),proj4.Proj.projections.add(ks),proj4.Proj.projections.add(Ts),proj4.Proj.projections.add(Gs),proj4.Proj.projections.add(js),proj4.Proj.projections.add(zs),proj4.Proj.projections.add(Fs),proj4.Proj.projections.add(Ds),proj4.Proj.projections.add(Zs),proj4.Proj.projections.add(ei),proj4.Proj.projections.add(ri),proj4.Proj.projections.add(oi),proj4.Proj.projections.add(ui),proj4.Proj.projections.add(ci),proj4.Proj.projections.add(fi),proj4.Proj.projections.add(di),proj4.Proj.projections.add(pi),proj4.Proj.projections.add(yi),proj4.Proj.projections.add(_i),proj4.Proj.projections.add(xi),proj4.Proj.projections.add(gi),proj4.Proj.projections.add(vi),proj4.Proj.projections.add(bi),proj4.Proj.projections.add(Ai),proj4.Proj.projections.add(Li),proj4.Proj.projections.add(Ti),proj4.Proj.projections.add(Bi),proj4.Proj.projections.add(zi)}(W),W}); \ No newline at end of file diff --git a/node_modules/proj4/lib/Point.js b/node_modules/proj4/lib/Point.js new file mode 100644 index 0000000..91b12ab --- /dev/null +++ b/node_modules/proj4/lib/Point.js @@ -0,0 +1,34 @@ +import {toPoint, forward} from 'mgrs'; + +function Point(x, y, z) { + if (!(this instanceof Point)) { + return new Point(x, y, z); + } + if (Array.isArray(x)) { + this.x = x[0]; + this.y = x[1]; + this.z = x[2] || 0.0; + } else if(typeof x === 'object') { + this.x = x.x; + this.y = x.y; + this.z = x.z || 0.0; + } else if (typeof x === 'string' && typeof y === 'undefined') { + var coords = x.split(','); + this.x = parseFloat(coords[0], 10); + this.y = parseFloat(coords[1], 10); + this.z = parseFloat(coords[2], 10) || 0.0; + } else { + this.x = x; + this.y = y; + this.z = z || 0.0; + } + console.warn('proj4.Point will be removed in version 3, use proj4.toPoint'); +} + +Point.fromMGRS = function(mgrsStr) { + return new Point(toPoint(mgrsStr)); +}; +Point.prototype.toMGRS = function(accuracy) { + return forward([this.x, this.y], accuracy); +}; +export default Point; diff --git a/node_modules/proj4/lib/Proj.js b/node_modules/proj4/lib/Proj.js new file mode 100644 index 0000000..c4aa388 --- /dev/null +++ b/node_modules/proj4/lib/Proj.js @@ -0,0 +1,74 @@ +import parseCode from './parseCode'; +import extend from './extend'; +import projections from './projections'; +import {sphere as dc_sphere, eccentricity as dc_eccentricity} from './deriveConstants'; +import Datum from './constants/Datum'; +import datum from './datum'; +import match from './match'; +import {getNadgrids} from "./nadgrid"; + +function Projection(srsCode,callback) { + if (!(this instanceof Projection)) { + return new Projection(srsCode); + } + callback = callback || function(error){ + if(error){ + throw error; + } + }; + var json = parseCode(srsCode); + if(typeof json !== 'object'){ + callback(srsCode); + return; + } + var ourProj = Projection.projections.get(json.projName); + if(!ourProj){ + callback(srsCode); + return; + } + if (json.datumCode && json.datumCode !== 'none') { + var datumDef = match(Datum, json.datumCode); + if (datumDef) { + json.datum_params = json.datum_params || (datumDef.towgs84 ? datumDef.towgs84.split(',') : null); + json.ellps = datumDef.ellipse; + json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode; + } + } + json.k0 = json.k0 || 1.0; + json.axis = json.axis || 'enu'; + json.ellps = json.ellps || 'wgs84'; + json.lat1 = json.lat1 || json.lat0; // Lambert_Conformal_Conic_1SP, for example, needs this + + var sphere_ = dc_sphere(json.a, json.b, json.rf, json.ellps, json.sphere); + var ecc = dc_eccentricity(sphere_.a, sphere_.b, sphere_.rf, json.R_A); + var nadgrids = getNadgrids(json.nadgrids); + var datumObj = json.datum || datum(json.datumCode, json.datum_params, sphere_.a, sphere_.b, ecc.es, ecc.ep2, + nadgrids); + + extend(this, json); // transfer everything over from the projection because we don't know what we'll need + extend(this, ourProj); // transfer all the methods from the projection + + // copy the 4 things over we calculated in deriveConstants.sphere + this.a = sphere_.a; + this.b = sphere_.b; + this.rf = sphere_.rf; + this.sphere = sphere_.sphere; + + // copy the 3 things we calculated in deriveConstants.eccentricity + this.es = ecc.es; + this.e = ecc.e; + this.ep2 = ecc.ep2; + + // add in the datum object + this.datum = datumObj; + + // init the projection + this.init(); + + // legecy callback from back in the day when it went to spatialreference.org + callback(null, this); + +} +Projection.projections = projections; +Projection.projections.start(); +export default Projection; diff --git a/node_modules/proj4/lib/adjust_axis.js b/node_modules/proj4/lib/adjust_axis.js new file mode 100644 index 0000000..f36c895 --- /dev/null +++ b/node_modules/proj4/lib/adjust_axis.js @@ -0,0 +1,61 @@ +export default function(crs, denorm, point) { + var xin = point.x, + yin = point.y, + zin = point.z || 0.0; + var v, t, i; + var out = {}; + for (i = 0; i < 3; i++) { + if (denorm && i === 2 && point.z === undefined) { + continue; + } + if (i === 0) { + v = xin; + if ("ew".indexOf(crs.axis[i]) !== -1) { + t = 'x'; + } else { + t = 'y'; + } + + } + else if (i === 1) { + v = yin; + if ("ns".indexOf(crs.axis[i]) !== -1) { + t = 'y'; + } else { + t = 'x'; + } + } + else { + v = zin; + t = 'z'; + } + switch (crs.axis[i]) { + case 'e': + out[t] = v; + break; + case 'w': + out[t] = -v; + break; + case 'n': + out[t] = v; + break; + case 's': + out[t] = -v; + break; + case 'u': + if (point[t] !== undefined) { + out.z = v; + } + break; + case 'd': + if (point[t] !== undefined) { + out.z = -v; + } + break; + default: + //console.log("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName); + return null; + } + } + return out; +} diff --git a/node_modules/proj4/lib/checkSanity.js b/node_modules/proj4/lib/checkSanity.js new file mode 100644 index 0000000..d2bdf1d --- /dev/null +++ b/node_modules/proj4/lib/checkSanity.js @@ -0,0 +1,15 @@ +export default function (point) { + checkCoord(point.x); + checkCoord(point.y); +} +function checkCoord(num) { + if (typeof Number.isFinite === 'function') { + if (Number.isFinite(num)) { + return; + } + throw new TypeError('coordinates must be finite numbers'); + } + if (typeof num !== 'number' || num !== num || !isFinite(num)) { + throw new TypeError('coordinates must be finite numbers'); + } +} diff --git a/node_modules/proj4/lib/common/acosh.js b/node_modules/proj4/lib/common/acosh.js new file mode 100644 index 0000000..4997f3c --- /dev/null +++ b/node_modules/proj4/lib/common/acosh.js @@ -0,0 +1,3 @@ +export default function(x) { + return 2 * Math.log(Math.sqrt((x + 1) / 2) + Math.sqrt((x - 1) / 2)); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/adjust_lat.js b/node_modules/proj4/lib/common/adjust_lat.js new file mode 100644 index 0000000..be4c667 --- /dev/null +++ b/node_modules/proj4/lib/common/adjust_lat.js @@ -0,0 +1,6 @@ +import {HALF_PI} from '../constants/values'; +import sign from './sign'; + +export default function(x) { + return (Math.abs(x) < HALF_PI) ? x : (x - (sign(x) * Math.PI)); +} diff --git a/node_modules/proj4/lib/common/adjust_lon.js b/node_modules/proj4/lib/common/adjust_lon.js new file mode 100644 index 0000000..e2f60a3 --- /dev/null +++ b/node_modules/proj4/lib/common/adjust_lon.js @@ -0,0 +1,7 @@ + +import {TWO_PI, SPI} from '../constants/values'; +import sign from './sign'; + +export default function(x) { + return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI)); +} diff --git a/node_modules/proj4/lib/common/adjust_zone.js b/node_modules/proj4/lib/common/adjust_zone.js new file mode 100644 index 0000000..49d457b --- /dev/null +++ b/node_modules/proj4/lib/common/adjust_zone.js @@ -0,0 +1,14 @@ +import adjust_lon from './adjust_lon'; + +export default function(zone, lon) { + if (zone === undefined) { + zone = Math.floor((adjust_lon(lon) + Math.PI) * 30 / Math.PI) + 1; + + if (zone < 0) { + return 0; + } else if (zone > 60) { + return 60; + } + } + return zone; +} diff --git a/node_modules/proj4/lib/common/asinh.js b/node_modules/proj4/lib/common/asinh.js new file mode 100644 index 0000000..51627ee --- /dev/null +++ b/node_modules/proj4/lib/common/asinh.js @@ -0,0 +1,4 @@ +export default function(x) { + var s = (x >= 0 ? 1 : -1); + return s * (Math.log(Math.abs(x) + Math.sqrt(x * x + 1))); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/asinhy.js b/node_modules/proj4/lib/common/asinhy.js new file mode 100644 index 0000000..a153f17 --- /dev/null +++ b/node_modules/proj4/lib/common/asinhy.js @@ -0,0 +1,9 @@ +import hypot from './hypot'; +import log1py from './log1py'; + +export default function(x) { + var y = Math.abs(x); + y = log1py(y * (1 + y / (hypot(1, y) + 1))); + + return x < 0 ? -y : y; +} diff --git a/node_modules/proj4/lib/common/asinz.js b/node_modules/proj4/lib/common/asinz.js new file mode 100644 index 0000000..8f27ed6 --- /dev/null +++ b/node_modules/proj4/lib/common/asinz.js @@ -0,0 +1,6 @@ +export default function(x) { + if (Math.abs(x) > 1) { + x = (x > 1) ? 1 : -1; + } + return Math.asin(x); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/atanh.js b/node_modules/proj4/lib/common/atanh.js new file mode 100644 index 0000000..2b082dc --- /dev/null +++ b/node_modules/proj4/lib/common/atanh.js @@ -0,0 +1,3 @@ +export default function(x) { + return Math.log((x - 1) / (x + 1)) / 2; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/clens.js b/node_modules/proj4/lib/common/clens.js new file mode 100644 index 0000000..79ece52 --- /dev/null +++ b/node_modules/proj4/lib/common/clens.js @@ -0,0 +1,15 @@ +export default function(pp, arg_r) { + var r = 2 * Math.cos(arg_r); + var i = pp.length - 1; + var hr1 = pp[i]; + var hr2 = 0; + var hr; + + while (--i >= 0) { + hr = -hr2 + r * hr1 + pp[i]; + hr2 = hr1; + hr1 = hr; + } + + return Math.sin(arg_r) * hr; +} diff --git a/node_modules/proj4/lib/common/clens_cmplx.js b/node_modules/proj4/lib/common/clens_cmplx.js new file mode 100644 index 0000000..d149d8c --- /dev/null +++ b/node_modules/proj4/lib/common/clens_cmplx.js @@ -0,0 +1,32 @@ +import sinh from './sinh'; +import cosh from './cosh'; + +export default function(pp, arg_r, arg_i) { + var sin_arg_r = Math.sin(arg_r); + var cos_arg_r = Math.cos(arg_r); + var sinh_arg_i = sinh(arg_i); + var cosh_arg_i = cosh(arg_i); + var r = 2 * cos_arg_r * cosh_arg_i; + var i = -2 * sin_arg_r * sinh_arg_i; + var j = pp.length - 1; + var hr = pp[j]; + var hi1 = 0; + var hr1 = 0; + var hi = 0; + var hr2; + var hi2; + + while (--j >= 0) { + hr2 = hr1; + hi2 = hi1; + hr1 = hr; + hi1 = hi; + hr = -hr2 + r * hr1 - i * hi1 + pp[j]; + hi = -hi2 + i * hr1 + r * hi1; + } + + r = sin_arg_r * cosh_arg_i; + i = cos_arg_r * sinh_arg_i; + + return [r * hr - i * hi, r * hi + i * hr]; +} diff --git a/node_modules/proj4/lib/common/cosh.js b/node_modules/proj4/lib/common/cosh.js new file mode 100644 index 0000000..8b5174e --- /dev/null +++ b/node_modules/proj4/lib/common/cosh.js @@ -0,0 +1,5 @@ +export default function(x) { + var r = Math.exp(x); + r = (r + 1 / r) / 2; + return r; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/e0fn.js b/node_modules/proj4/lib/common/e0fn.js new file mode 100644 index 0000000..33501ac --- /dev/null +++ b/node_modules/proj4/lib/common/e0fn.js @@ -0,0 +1,3 @@ +export default function(x) { + return (1 - 0.25 * x * (1 + x / 16 * (3 + 1.25 * x))); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/e1fn.js b/node_modules/proj4/lib/common/e1fn.js new file mode 100644 index 0000000..c4c8500 --- /dev/null +++ b/node_modules/proj4/lib/common/e1fn.js @@ -0,0 +1,3 @@ +export default function(x) { + return (0.375 * x * (1 + 0.25 * x * (1 + 0.46875 * x))); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/e2fn.js b/node_modules/proj4/lib/common/e2fn.js new file mode 100644 index 0000000..55539a7 --- /dev/null +++ b/node_modules/proj4/lib/common/e2fn.js @@ -0,0 +1,3 @@ +export default function(x) { + return (0.05859375 * x * x * (1 + 0.75 * x)); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/e3fn.js b/node_modules/proj4/lib/common/e3fn.js new file mode 100644 index 0000000..6010428 --- /dev/null +++ b/node_modules/proj4/lib/common/e3fn.js @@ -0,0 +1,3 @@ +export default function(x) { + return (x * x * x * (35 / 3072)); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/fL.js b/node_modules/proj4/lib/common/fL.js new file mode 100644 index 0000000..8440cd5 --- /dev/null +++ b/node_modules/proj4/lib/common/fL.js @@ -0,0 +1,5 @@ +import {HALF_PI} from '../constants/values'; + +export default function(x, L) { + return 2 * Math.atan(x * Math.exp(L)) - HALF_PI; +} diff --git a/node_modules/proj4/lib/common/gN.js b/node_modules/proj4/lib/common/gN.js new file mode 100644 index 0000000..29bd5f0 --- /dev/null +++ b/node_modules/proj4/lib/common/gN.js @@ -0,0 +1,4 @@ +export default function(a, e, sinphi) { + var temp = e * sinphi; + return a / Math.sqrt(1 - temp * temp); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/gatg.js b/node_modules/proj4/lib/common/gatg.js new file mode 100644 index 0000000..597f196 --- /dev/null +++ b/node_modules/proj4/lib/common/gatg.js @@ -0,0 +1,15 @@ +export default function(pp, B) { + var cos_2B = 2 * Math.cos(2 * B); + var i = pp.length - 1; + var h1 = pp[i]; + var h2 = 0; + var h; + + while (--i >= 0) { + h = -h2 + cos_2B * h1 + pp[i]; + h2 = h1; + h1 = h; + } + + return (B + h * Math.sin(2 * B)); +} diff --git a/node_modules/proj4/lib/common/hypot.js b/node_modules/proj4/lib/common/hypot.js new file mode 100644 index 0000000..7b210a7 --- /dev/null +++ b/node_modules/proj4/lib/common/hypot.js @@ -0,0 +1,8 @@ +export default function(x, y) { + x = Math.abs(x); + y = Math.abs(y); + var a = Math.max(x, y); + var b = Math.min(x, y) / (a ? a : 1); + + return a * Math.sqrt(1 + Math.pow(b, 2)); +} diff --git a/node_modules/proj4/lib/common/imlfn.js b/node_modules/proj4/lib/common/imlfn.js new file mode 100644 index 0000000..70859dc --- /dev/null +++ b/node_modules/proj4/lib/common/imlfn.js @@ -0,0 +1,16 @@ +export default function(ml, e0, e1, e2, e3) { + var phi; + var dphi; + + phi = ml / e0; + for (var i = 0; i < 15; i++) { + dphi = (ml - (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi))) / (e0 - 2 * e1 * Math.cos(2 * phi) + 4 * e2 * Math.cos(4 * phi) - 6 * e3 * Math.cos(6 * phi)); + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + + //..reportError("IMLFN-CONV:Latitude failed to converge after 15 iterations"); + return NaN; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/invlatiso.js b/node_modules/proj4/lib/common/invlatiso.js new file mode 100644 index 0000000..1417f38 --- /dev/null +++ b/node_modules/proj4/lib/common/invlatiso.js @@ -0,0 +1,13 @@ +import fL from './fL'; + +export default function(eccent, ts) { + var phi = fL(1, ts); + var Iphi = 0; + var con = 0; + do { + Iphi = phi; + con = eccent * Math.sin(Iphi); + phi = fL(Math.exp(eccent * Math.log((1 + con) / (1 - con)) / 2), ts); + } while (Math.abs(phi - Iphi) > 1.0e-12); + return phi; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/iqsfnz.js b/node_modules/proj4/lib/common/iqsfnz.js new file mode 100644 index 0000000..6231355 --- /dev/null +++ b/node_modules/proj4/lib/common/iqsfnz.js @@ -0,0 +1,32 @@ +import {HALF_PI} from '../constants/values'; + +export default function(eccent, q) { + var temp = 1 - (1 - eccent * eccent) / (2 * eccent) * Math.log((1 - eccent) / (1 + eccent)); + if (Math.abs(Math.abs(q) - temp) < 1.0E-6) { + if (q < 0) { + return (-1 * HALF_PI); + } + else { + return HALF_PI; + } + } + //var phi = 0.5* q/(1-eccent*eccent); + var phi = Math.asin(0.5 * q); + var dphi; + var sin_phi; + var cos_phi; + var con; + for (var i = 0; i < 30; i++) { + sin_phi = Math.sin(phi); + cos_phi = Math.cos(phi); + con = eccent * sin_phi; + dphi = Math.pow(1 - con * con, 2) / (2 * cos_phi) * (q / (1 - eccent * eccent) - sin_phi / (1 - con * con) + 0.5 / eccent * Math.log((1 - con) / (1 + con))); + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + + //console.log("IQSFN-CONV:Latitude failed to converge after 30 iterations"); + return NaN; +} diff --git a/node_modules/proj4/lib/common/latiso.js b/node_modules/proj4/lib/common/latiso.js new file mode 100644 index 0000000..61e0b09 --- /dev/null +++ b/node_modules/proj4/lib/common/latiso.js @@ -0,0 +1,16 @@ +import {HALF_PI} from '../constants/values'; + +export default function(eccent, phi, sinphi) { + if (Math.abs(phi) > HALF_PI) { + return Number.NaN; + } + if (phi === HALF_PI) { + return Number.POSITIVE_INFINITY; + } + if (phi === -1 * HALF_PI) { + return Number.NEGATIVE_INFINITY; + } + + var con = eccent * sinphi; + return Math.log(Math.tan((HALF_PI + phi) / 2)) + eccent * Math.log((1 - con) / (1 + con)) / 2; +} diff --git a/node_modules/proj4/lib/common/log1py.js b/node_modules/proj4/lib/common/log1py.js new file mode 100644 index 0000000..ad63730 --- /dev/null +++ b/node_modules/proj4/lib/common/log1py.js @@ -0,0 +1,6 @@ +export default function(x) { + var y = 1 + x; + var z = y - 1; + + return z === 0 ? x : x * Math.log(y) / z; +} diff --git a/node_modules/proj4/lib/common/mlfn.js b/node_modules/proj4/lib/common/mlfn.js new file mode 100644 index 0000000..53dc3d2 --- /dev/null +++ b/node_modules/proj4/lib/common/mlfn.js @@ -0,0 +1,3 @@ +export default function(e0, e1, e2, e3, phi) { + return (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi)); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/msfnz.js b/node_modules/proj4/lib/common/msfnz.js new file mode 100644 index 0000000..433f347 --- /dev/null +++ b/node_modules/proj4/lib/common/msfnz.js @@ -0,0 +1,4 @@ +export default function(eccent, sinphi, cosphi) { + var con = eccent * sinphi; + return cosphi / (Math.sqrt(1 - con * con)); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/phi2z.js b/node_modules/proj4/lib/common/phi2z.js new file mode 100644 index 0000000..3c70422 --- /dev/null +++ b/node_modules/proj4/lib/common/phi2z.js @@ -0,0 +1,17 @@ +import {HALF_PI} from '../constants/values'; + +export default function(eccent, ts) { + var eccnth = 0.5 * eccent; + var con, dphi; + var phi = HALF_PI - 2 * Math.atan(ts); + for (var i = 0; i <= 15; i++) { + con = eccent * Math.sin(phi); + dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi; + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + //console.log("phi2z has NoConvergence"); + return -9999; +} diff --git a/node_modules/proj4/lib/common/pj_enfn.js b/node_modules/proj4/lib/common/pj_enfn.js new file mode 100644 index 0000000..5d9be38 --- /dev/null +++ b/node_modules/proj4/lib/common/pj_enfn.js @@ -0,0 +1,24 @@ +var C00 = 1; +var C02 = 0.25; +var C04 = 0.046875; +var C06 = 0.01953125; +var C08 = 0.01068115234375; +var C22 = 0.75; +var C44 = 0.46875; +var C46 = 0.01302083333333333333; +var C48 = 0.00712076822916666666; +var C66 = 0.36458333333333333333; +var C68 = 0.00569661458333333333; +var C88 = 0.3076171875; + +export default function(es) { + var en = []; + en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08))); + en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08))); + var t = es * es; + en[2] = t * (C44 - es * (C46 + es * C48)); + t *= es; + en[3] = t * (C66 - es * C68); + en[4] = t * es * C88; + return en; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/pj_inv_mlfn.js b/node_modules/proj4/lib/common/pj_inv_mlfn.js new file mode 100644 index 0000000..7f91931 --- /dev/null +++ b/node_modules/proj4/lib/common/pj_inv_mlfn.js @@ -0,0 +1,22 @@ +import pj_mlfn from "./pj_mlfn"; +import {EPSLN} from '../constants/values'; + +var MAX_ITER = 20; + +export default function(arg, es, en) { + var k = 1 / (1 - es); + var phi = arg; + for (var i = MAX_ITER; i; --i) { /* rarely goes over 2 iterations */ + var s = Math.sin(phi); + var t = 1 - es * s * s; + //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg; + //phi -= t * (t * Math.sqrt(t)) * k; + t = (pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k; + phi -= t; + if (Math.abs(t) < EPSLN) { + return phi; + } + } + //..reportError("cass:pj_inv_mlfn: Convergence error"); + return phi; +} diff --git a/node_modules/proj4/lib/common/pj_mlfn.js b/node_modules/proj4/lib/common/pj_mlfn.js new file mode 100644 index 0000000..6e898c3 --- /dev/null +++ b/node_modules/proj4/lib/common/pj_mlfn.js @@ -0,0 +1,5 @@ +export default function(phi, sphi, cphi, en) { + cphi *= sphi; + sphi *= sphi; + return (en[0] * phi - cphi * (en[1] + sphi * (en[2] + sphi * (en[3] + sphi * en[4])))); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/qsfnz.js b/node_modules/proj4/lib/common/qsfnz.js new file mode 100644 index 0000000..6afb50a --- /dev/null +++ b/node_modules/proj4/lib/common/qsfnz.js @@ -0,0 +1,10 @@ +export default function(eccent, sinphi) { + var con; + if (eccent > 1.0e-7) { + con = eccent * sinphi; + return ((1 - eccent * eccent) * (sinphi / (1 - con * con) - (0.5 / eccent) * Math.log((1 - con) / (1 + con)))); + } + else { + return (2 * sinphi); + } +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/sign.js b/node_modules/proj4/lib/common/sign.js new file mode 100644 index 0000000..c97da62 --- /dev/null +++ b/node_modules/proj4/lib/common/sign.js @@ -0,0 +1,3 @@ +export default function(x) { + return x<0 ? -1 : 1; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/sinh.js b/node_modules/proj4/lib/common/sinh.js new file mode 100644 index 0000000..db3fe4d --- /dev/null +++ b/node_modules/proj4/lib/common/sinh.js @@ -0,0 +1,5 @@ +export default function(x) { + var r = Math.exp(x); + r = (r - 1 / r) / 2; + return r; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/srat.js b/node_modules/proj4/lib/common/srat.js new file mode 100644 index 0000000..171b627 --- /dev/null +++ b/node_modules/proj4/lib/common/srat.js @@ -0,0 +1,3 @@ +export default function(esinp, exp) { + return (Math.pow((1 - esinp) / (1 + esinp), exp)); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/tanh.js b/node_modules/proj4/lib/common/tanh.js new file mode 100644 index 0000000..782414a --- /dev/null +++ b/node_modules/proj4/lib/common/tanh.js @@ -0,0 +1,5 @@ +export default function(x) { + var r = Math.exp(x); + r = (r - 1 / r) / (r + 1 / r); + return r; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/toPoint.js b/node_modules/proj4/lib/common/toPoint.js new file mode 100644 index 0000000..7226892 --- /dev/null +++ b/node_modules/proj4/lib/common/toPoint.js @@ -0,0 +1,13 @@ +export default function (array){ + var out = { + x: array[0], + y: array[1] + }; + if (array.length>2) { + out.z = array[2]; + } + if (array.length>3) { + out.m = array[3]; + } + return out; +} \ No newline at end of file diff --git a/node_modules/proj4/lib/common/tsfnz.js b/node_modules/proj4/lib/common/tsfnz.js new file mode 100644 index 0000000..6702d85 --- /dev/null +++ b/node_modules/proj4/lib/common/tsfnz.js @@ -0,0 +1,8 @@ +import {HALF_PI} from '../constants/values'; + +export default function(eccent, phi, sinphi) { + var con = eccent * sinphi; + var com = 0.5 * eccent; + con = Math.pow(((1 - con) / (1 + con)), com); + return (Math.tan(0.5 * (HALF_PI - phi)) / con); +} diff --git a/node_modules/proj4/lib/constants/Datum.js b/node_modules/proj4/lib/constants/Datum.js new file mode 100644 index 0000000..3faf343 --- /dev/null +++ b/node_modules/proj4/lib/constants/Datum.js @@ -0,0 +1,103 @@ +var exports = {}; +export {exports as default}; +exports.wgs84 = { + towgs84: "0,0,0", + ellipse: "WGS84", + datumName: "WGS84" +}; + +exports.ch1903 = { + towgs84: "674.374,15.056,405.346", + ellipse: "bessel", + datumName: "swiss" +}; + +exports.ggrs87 = { + towgs84: "-199.87,74.79,246.62", + ellipse: "GRS80", + datumName: "Greek_Geodetic_Reference_System_1987" +}; + +exports.nad83 = { + towgs84: "0,0,0", + ellipse: "GRS80", + datumName: "North_American_Datum_1983" +}; + +exports.nad27 = { + nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", + ellipse: "clrk66", + datumName: "North_American_Datum_1927" +}; + +exports.potsdam = { + towgs84: "598.1,73.7,418.2,0.202,0.045,-2.455,6.7", + ellipse: "bessel", + datumName: "Potsdam Rauenberg 1950 DHDN" +}; + +exports.carthage = { + towgs84: "-263.0,6.0,431.0", + ellipse: "clark80", + datumName: "Carthage 1934 Tunisia" +}; + +exports.hermannskogel = { + towgs84: "577.326,90.129,463.919,5.137,1.474,5.297,2.4232", + ellipse: "bessel", + datumName: "Hermannskogel" +}; + +exports.osni52 = { + towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", + ellipse: "airy", + datumName: "Irish National" +}; + +exports.ire65 = { + towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", + ellipse: "mod_airy", + datumName: "Ireland 1965" +}; + +exports.rassadiran = { + towgs84: "-133.63,-157.5,-158.62", + ellipse: "intl", + datumName: "Rassadiran" +}; + +exports.nzgd49 = { + towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", + ellipse: "intl", + datumName: "New Zealand Geodetic Datum 1949" +}; + +exports.osgb36 = { + towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", + ellipse: "airy", + datumName: "Airy 1830" +}; + +exports.s_jtsk = { + towgs84: "589,76,480", + ellipse: 'bessel', + datumName: 'S-JTSK (Ferro)' +}; + +exports.beduaram = { + towgs84: '-106,-87,188', + ellipse: 'clrk80', + datumName: 'Beduaram' +}; + +exports.gunung_segara = { + towgs84: '-403,684,41', + ellipse: 'bessel', + datumName: 'Gunung Segara Jakarta' +}; + +exports.rnb72 = { + towgs84: "106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1", + ellipse: "intl", + datumName: "Reseau National Belge 1972" +}; diff --git a/node_modules/proj4/lib/constants/Ellipsoid.js b/node_modules/proj4/lib/constants/Ellipsoid.js new file mode 100644 index 0000000..6e5fba1 --- /dev/null +++ b/node_modules/proj4/lib/constants/Ellipsoid.js @@ -0,0 +1,266 @@ +var exports = {}; +export {exports as default}; +exports.MERIT = { + a: 6378137.0, + rf: 298.257, + ellipseName: "MERIT 1983" +}; + +exports.SGS85 = { + a: 6378136.0, + rf: 298.257, + ellipseName: "Soviet Geodetic System 85" +}; + +exports.GRS80 = { + a: 6378137.0, + rf: 298.257222101, + ellipseName: "GRS 1980(IUGG, 1980)" +}; + +exports.IAU76 = { + a: 6378140.0, + rf: 298.257, + ellipseName: "IAU 1976" +}; + +exports.airy = { + a: 6377563.396, + b: 6356256.910, + ellipseName: "Airy 1830" +}; + +exports.APL4 = { + a: 6378137, + rf: 298.25, + ellipseName: "Appl. Physics. 1965" +}; + +exports.NWL9D = { + a: 6378145.0, + rf: 298.25, + ellipseName: "Naval Weapons Lab., 1965" +}; + +exports.mod_airy = { + a: 6377340.189, + b: 6356034.446, + ellipseName: "Modified Airy" +}; + +exports.andrae = { + a: 6377104.43, + rf: 300.0, + ellipseName: "Andrae 1876 (Den., Iclnd.)" +}; + +exports.aust_SA = { + a: 6378160.0, + rf: 298.25, + ellipseName: "Australian Natl & S. Amer. 1969" +}; + +exports.GRS67 = { + a: 6378160.0, + rf: 298.2471674270, + ellipseName: "GRS 67(IUGG 1967)" +}; + +exports.bessel = { + a: 6377397.155, + rf: 299.1528128, + ellipseName: "Bessel 1841" +}; + +exports.bess_nam = { + a: 6377483.865, + rf: 299.1528128, + ellipseName: "Bessel 1841 (Namibia)" +}; + +exports.clrk66 = { + a: 6378206.4, + b: 6356583.8, + ellipseName: "Clarke 1866" +}; + +exports.clrk80 = { + a: 6378249.145, + rf: 293.4663, + ellipseName: "Clarke 1880 mod." +}; + +exports.clrk80ign = { + a: 6378249.2, + b: 6356515, + rf: 293.4660213, + ellipseName: "Clarke 1880 (IGN)" +}; + +exports.clrk58 = { + a: 6378293.645208759, + rf: 294.2606763692654, + ellipseName: "Clarke 1858" +}; + +exports.CPM = { + a: 6375738.7, + rf: 334.29, + ellipseName: "Comm. des Poids et Mesures 1799" +}; + +exports.delmbr = { + a: 6376428.0, + rf: 311.5, + ellipseName: "Delambre 1810 (Belgium)" +}; + +exports.engelis = { + a: 6378136.05, + rf: 298.2566, + ellipseName: "Engelis 1985" +}; + +exports.evrst30 = { + a: 6377276.345, + rf: 300.8017, + ellipseName: "Everest 1830" +}; + +exports.evrst48 = { + a: 6377304.063, + rf: 300.8017, + ellipseName: "Everest 1948" +}; + +exports.evrst56 = { + a: 6377301.243, + rf: 300.8017, + ellipseName: "Everest 1956" +}; + +exports.evrst69 = { + a: 6377295.664, + rf: 300.8017, + ellipseName: "Everest 1969" +}; + +exports.evrstSS = { + a: 6377298.556, + rf: 300.8017, + ellipseName: "Everest (Sabah & Sarawak)" +}; + +exports.fschr60 = { + a: 6378166.0, + rf: 298.3, + ellipseName: "Fischer (Mercury Datum) 1960" +}; + +exports.fschr60m = { + a: 6378155.0, + rf: 298.3, + ellipseName: "Fischer 1960" +}; + +exports.fschr68 = { + a: 6378150.0, + rf: 298.3, + ellipseName: "Fischer 1968" +}; + +exports.helmert = { + a: 6378200.0, + rf: 298.3, + ellipseName: "Helmert 1906" +}; + +exports.hough = { + a: 6378270.0, + rf: 297.0, + ellipseName: "Hough" +}; + +exports.intl = { + a: 6378388.0, + rf: 297.0, + ellipseName: "International 1909 (Hayford)" +}; + +exports.kaula = { + a: 6378163.0, + rf: 298.24, + ellipseName: "Kaula 1961" +}; + +exports.lerch = { + a: 6378139.0, + rf: 298.257, + ellipseName: "Lerch 1979" +}; + +exports.mprts = { + a: 6397300.0, + rf: 191.0, + ellipseName: "Maupertius 1738" +}; + +exports.new_intl = { + a: 6378157.5, + b: 6356772.2, + ellipseName: "New International 1967" +}; + +exports.plessis = { + a: 6376523.0, + rf: 6355863.0, + ellipseName: "Plessis 1817 (France)" +}; + +exports.krass = { + a: 6378245.0, + rf: 298.3, + ellipseName: "Krassovsky, 1942" +}; + +exports.SEasia = { + a: 6378155.0, + b: 6356773.3205, + ellipseName: "Southeast Asia" +}; + +exports.walbeck = { + a: 6376896.0, + b: 6355834.8467, + ellipseName: "Walbeck" +}; + +exports.WGS60 = { + a: 6378165.0, + rf: 298.3, + ellipseName: "WGS 60" +}; + +exports.WGS66 = { + a: 6378145.0, + rf: 298.25, + ellipseName: "WGS 66" +}; + +exports.WGS7 = { + a: 6378135.0, + rf: 298.26, + ellipseName: "WGS 72" +}; + +export var WGS84 = exports.WGS84 = { + a: 6378137.0, + rf: 298.257223563, + ellipseName: "WGS 84" +}; + +exports.sphere = { + a: 6370997.0, + b: 6370997.0, + ellipseName: "Normal Sphere (r=6370997)" +}; diff --git a/node_modules/proj4/lib/constants/PrimeMeridian.js b/node_modules/proj4/lib/constants/PrimeMeridian.js new file mode 100644 index 0000000..8e81d50 --- /dev/null +++ b/node_modules/proj4/lib/constants/PrimeMeridian.js @@ -0,0 +1,16 @@ +var exports = {}; +export {exports as default}; + +exports.greenwich = 0.0; //"0dE", +exports.lisbon = -9.131906111111; //"9d07'54.862\"W", +exports.paris = 2.337229166667; //"2d20'14.025\"E", +exports.bogota = -74.080916666667; //"74d04'51.3\"W", +exports.madrid = -3.687938888889; //"3d41'16.58\"W", +exports.rome = 12.452333333333; //"12d27'8.4\"E", +exports.bern = 7.439583333333; //"7d26'22.5\"E", +exports.jakarta = 106.807719444444; //"106d48'27.79\"E", +exports.ferro = -17.666666666667; //"17d40'W", +exports.brussels = 4.367975; //"4d22'4.71\"E", +exports.stockholm = 18.058277777778; //"18d3'29.8\"E", +exports.athens = 23.7163375; //"23d42'58.815\"E", +exports.oslo = 10.722916666667; //"10d43'22.5\"E" diff --git a/node_modules/proj4/lib/constants/units.js b/node_modules/proj4/lib/constants/units.js new file mode 100644 index 0000000..39ed6f8 --- /dev/null +++ b/node_modules/proj4/lib/constants/units.js @@ -0,0 +1,4 @@ +export default { + ft: {to_meter: 0.3048}, + 'us-ft': {to_meter: 1200 / 3937} +}; diff --git a/node_modules/proj4/lib/constants/values.js b/node_modules/proj4/lib/constants/values.js new file mode 100644 index 0000000..2e89756 --- /dev/null +++ b/node_modules/proj4/lib/constants/values.js @@ -0,0 +1,29 @@ +export var PJD_3PARAM = 1; +export var PJD_7PARAM = 2; +export var PJD_GRIDSHIFT = 3; +export var PJD_WGS84 = 4; // WGS84 or equivalent +export var PJD_NODATUM = 5; // WGS84 or equivalent +export var SRS_WGS84_SEMIMAJOR = 6378137.0; // only used in grid shift transforms +export var SRS_WGS84_SEMIMINOR = 6356752.314; // only used in grid shift transforms +export var SRS_WGS84_ESQUARED = 0.0066943799901413165; // only used in grid shift transforms +export var SEC_TO_RAD = 4.84813681109535993589914102357e-6; +export var HALF_PI = Math.PI/2; +// ellipoid pj_set_ell.c +export var SIXTH = 0.1666666666666666667; +/* 1/6 */ +export var RA4 = 0.04722222222222222222; +/* 17/360 */ +export var RA6 = 0.02215608465608465608; +export var EPSLN = 1.0e-10; +// you'd think you could use Number.EPSILON above but that makes +// Mollweide get into an infinate loop. + +export var D2R = 0.01745329251994329577; +export var R2D = 57.29577951308232088; +export var FORTPI = Math.PI/4; +export var TWO_PI = Math.PI * 2; +// SPI is slightly greater than Math.PI, so values that exceed the -180..180 +// degree range by a tiny amount don't get wrapped. This prevents points that +// have drifted from their original location along the 180th meridian (due to +// floating point error) from changing their sign. +export var SPI = 3.14159265359; diff --git a/node_modules/proj4/lib/core.js b/node_modules/proj4/lib/core.js new file mode 100644 index 0000000..ad22446 --- /dev/null +++ b/node_modules/proj4/lib/core.js @@ -0,0 +1,86 @@ +import proj from './Proj'; +import transform from './transform'; +var wgs84 = proj('WGS84'); + +function transformer(from, to, coords, enforceAxis) { + var transformedArray, out, keys; + if (Array.isArray(coords)) { + transformedArray = transform(from, to, coords, enforceAxis) || {x: NaN, y: NaN}; + if (coords.length > 2) { + if ((typeof from.name !== 'undefined' && from.name === 'geocent') || (typeof to.name !== 'undefined' && to.name === 'geocent')) { + if (typeof transformedArray.z === 'number') { + return [transformedArray.x, transformedArray.y, transformedArray.z].concat(coords.splice(3)); + } else { + return [transformedArray.x, transformedArray.y, coords[2]].concat(coords.splice(3)); + } + } else { + return [transformedArray.x, transformedArray.y].concat(coords.splice(2)); + } + } else { + return [transformedArray.x, transformedArray.y]; + } + } else { + out = transform(from, to, coords, enforceAxis); + keys = Object.keys(coords); + if (keys.length === 2) { + return out; + } + keys.forEach(function (key) { + if ((typeof from.name !== 'undefined' && from.name === 'geocent') || (typeof to.name !== 'undefined' && to.name === 'geocent')) { + if (key === 'x' || key === 'y' || key === 'z') { + return; + } + } else { + if (key === 'x' || key === 'y') { + return; + } + } + out[key] = coords[key]; + }); + return out; + } +} + +function checkProj(item) { + if (item instanceof proj) { + return item; + } + if (item.oProj) { + return item.oProj; + } + return proj(item); +} + +function proj4(fromProj, toProj, coord) { + fromProj = checkProj(fromProj); + var single = false; + var obj; + if (typeof toProj === 'undefined') { + toProj = fromProj; + fromProj = wgs84; + single = true; + } else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) { + coord = toProj; + toProj = fromProj; + fromProj = wgs84; + single = true; + } + toProj = checkProj(toProj); + if (coord) { + return transformer(fromProj, toProj, coord); + } else { + obj = { + forward: function (coords, enforceAxis) { + return transformer(fromProj, toProj, coords, enforceAxis); + }, + inverse: function (coords, enforceAxis) { + return transformer(toProj, fromProj, coords, enforceAxis); + } + }; + if (single) { + obj.oProj = toProj; + } + return obj; + } +} +export default proj4; \ No newline at end of file diff --git a/node_modules/proj4/lib/datum.js b/node_modules/proj4/lib/datum.js new file mode 100644 index 0000000..9d82f52 --- /dev/null +++ b/node_modules/proj4/lib/datum.js @@ -0,0 +1,39 @@ +import {PJD_3PARAM, PJD_7PARAM, PJD_GRIDSHIFT, PJD_WGS84, PJD_NODATUM, SEC_TO_RAD} from './constants/values'; + +function datum(datumCode, datum_params, a, b, es, ep2, nadgrids) { + var out = {}; + + if (datumCode === undefined || datumCode === 'none') { + out.datum_type = PJD_NODATUM; + } else { + out.datum_type = PJD_WGS84; + } + + if (datum_params) { + out.datum_params = datum_params.map(parseFloat); + if (out.datum_params[0] !== 0 || out.datum_params[1] !== 0 || out.datum_params[2] !== 0) { + out.datum_type = PJD_3PARAM; + } + if (out.datum_params.length > 3) { + if (out.datum_params[3] !== 0 || out.datum_params[4] !== 0 || out.datum_params[5] !== 0 || out.datum_params[6] !== 0) { + out.datum_type = PJD_7PARAM; + out.datum_params[3] *= SEC_TO_RAD; + out.datum_params[4] *= SEC_TO_RAD; + out.datum_params[5] *= SEC_TO_RAD; + out.datum_params[6] = (out.datum_params[6] / 1000000.0) + 1.0; + } + } + } + + if (nadgrids) { + out.datum_type = PJD_GRIDSHIFT; + out.grids = nadgrids; + } + out.a = a; //datum object also uses these values + out.b = b; + out.es = es; + out.ep2 = ep2; + return out; +} + +export default datum; diff --git a/node_modules/proj4/lib/datumUtils.js b/node_modules/proj4/lib/datumUtils.js new file mode 100644 index 0000000..5eb07c6 --- /dev/null +++ b/node_modules/proj4/lib/datumUtils.js @@ -0,0 +1,245 @@ +'use strict'; +import {PJD_3PARAM, PJD_7PARAM, HALF_PI} from './constants/values'; +export function compareDatums(source, dest) { + if (source.datum_type !== dest.datum_type) { + return false; // false, datums are not equal + } else if (source.a !== dest.a || Math.abs(source.es - dest.es) > 0.000000000050) { + // the tolerance for es is to ensure that GRS80 and WGS84 + // are considered identical + return false; + } else if (source.datum_type === PJD_3PARAM) { + return (source.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2]); + } else if (source.datum_type === PJD_7PARAM) { + return (source.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2] && source.datum_params[3] === dest.datum_params[3] && source.datum_params[4] === dest.datum_params[4] && source.datum_params[5] === dest.datum_params[5] && source.datum_params[6] === dest.datum_params[6]); + } else { + return true; // datums are equal + } +} // cs_compare_datums() + +/* + * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates + * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), + * according to the current ellipsoid parameters. + * + * Latitude : Geodetic latitude in radians (input) + * Longitude : Geodetic longitude in radians (input) + * Height : Geodetic height, in meters (input) + * X : Calculated Geocentric X coordinate, in meters (output) + * Y : Calculated Geocentric Y coordinate, in meters (output) + * Z : Calculated Geocentric Z coordinate, in meters (output) + * + */ +export function geodeticToGeocentric(p, es, a) { + var Longitude = p.x; + var Latitude = p.y; + var Height = p.z ? p.z : 0; //Z value not always supplied + + var Rn; /* Earth radius at location */ + var Sin_Lat; /* Math.sin(Latitude) */ + var Sin2_Lat; /* Square of Math.sin(Latitude) */ + var Cos_Lat; /* Math.cos(Latitude) */ + + /* + ** Don't blow up if Latitude is just a little out of the value + ** range as it may just be a rounding issue. Also removed longitude + ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001. + */ + if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) { + Latitude = -HALF_PI; + } else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) { + Latitude = HALF_PI; + } else if (Latitude < -HALF_PI) { + /* Latitude out of range */ + //..reportError('geocent:lat out of range:' + Latitude); + return { x: -Infinity, y: -Infinity, z: p.z }; + } else if (Latitude > HALF_PI) { + /* Latitude out of range */ + return { x: Infinity, y: Infinity, z: p.z }; + } + + if (Longitude > Math.PI) { + Longitude -= (2 * Math.PI); + } + Sin_Lat = Math.sin(Latitude); + Cos_Lat = Math.cos(Latitude); + Sin2_Lat = Sin_Lat * Sin_Lat; + Rn = a / (Math.sqrt(1.0e0 - es * Sin2_Lat)); + return { + x: (Rn + Height) * Cos_Lat * Math.cos(Longitude), + y: (Rn + Height) * Cos_Lat * Math.sin(Longitude), + z: ((Rn * (1 - es)) + Height) * Sin_Lat + }; +} // cs_geodetic_to_geocentric() + +export function geocentricToGeodetic(p, es, a, b) { + /* local defintions and variables */ + /* end-criterium of loop, accuracy of sin(Latitude) */ + var genau = 1e-12; + var genau2 = (genau * genau); + var maxiter = 30; + + var P; /* distance between semi-minor axis and location */ + var RR; /* distance between center and location */ + var CT; /* sin of geocentric latitude */ + var ST; /* cos of geocentric latitude */ + var RX; + var RK; + var RN; /* Earth radius at location */ + var CPHI0; /* cos of start or old geodetic latitude in iterations */ + var SPHI0; /* sin of start or old geodetic latitude in iterations */ + var CPHI; /* cos of searched geodetic latitude */ + var SPHI; /* sin of searched geodetic latitude */ + var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ + var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */ + + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0.0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + P = Math.sqrt(X * X + Y * Y); + RR = Math.sqrt(X * X + Y * Y + Z * Z); + + /* special cases for latitude and longitude */ + if (P / a < genau) { + + /* special case, if P=0. (X=0., Y=0.) */ + Longitude = 0.0; + + /* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis + * of ellipsoid (=center of mass), Latitude becomes PI/2 */ + if (RR / a < genau) { + Latitude = HALF_PI; + Height = -b; + return { + x: p.x, + y: p.y, + z: p.z + }; + } + } else { + /* ellipsoidal (geodetic) longitude + * interval: -PI < Longitude <= +PI */ + Longitude = Math.atan2(Y, X); + } + + /* -------------------------------------------------------------- + * Following iterative algorithm was developped by + * "Institut for Erdmessung", University of Hannover, July 1988. + * Internet: www.ife.uni-hannover.de + * Iterative computation of CPHI,SPHI and Height. + * Iteration of CPHI and SPHI to 10**-12 radian resp. + * 2*10**-7 arcsec. + * -------------------------------------------------------------- + */ + CT = Z / RR; + ST = P / RR; + RX = 1.0 / Math.sqrt(1.0 - es * (2.0 - es) * ST * ST); + CPHI0 = ST * (1.0 - es) * RX; + SPHI0 = CT * RX; + iter = 0; + + /* loop to find sin(Latitude) resp. Latitude + * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ + do { + iter++; + RN = a / Math.sqrt(1.0 - es * SPHI0 * SPHI0); + + /* ellipsoidal (geodetic) height */ + Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - es * SPHI0 * SPHI0); + + RK = es * RN / (RN + Height); + RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST); + CPHI = ST * (1.0 - RK) * RX; + SPHI = CT * RX; + SDPHI = SPHI * CPHI0 - CPHI * SPHI0; + CPHI0 = CPHI; + SPHI0 = SPHI; + } + while (SDPHI * SDPHI > genau2 && iter < maxiter); + + /* ellipsoidal (geodetic) latitude */ + Latitude = Math.atan(SPHI / Math.abs(CPHI)); + return { + x: Longitude, + y: Latitude, + z: Height + }; +} // cs_geocentric_to_geodetic() + +/****************************************************************/ +// pj_geocentic_to_wgs84( p ) +// p = point to transform in geocentric coordinates (x,y,z) + + +/** point object, nothing fancy, just allows values to be + passed back and forth by reference rather than by value. + Other point classes may be used as long as they have + x and y properties, which will get modified in the transform method. +*/ +export function geocentricToWgs84(p, datum_type, datum_params) { + + if (datum_type === PJD_3PARAM) { + // if( x[io] === HUGE_VAL ) + // continue; + return { + x: p.x + datum_params[0], + y: p.y + datum_params[1], + z: p.z + datum_params[2], + }; + } else if (datum_type === PJD_7PARAM) { + var Dx_BF = datum_params[0]; + var Dy_BF = datum_params[1]; + var Dz_BF = datum_params[2]; + var Rx_BF = datum_params[3]; + var Ry_BF = datum_params[4]; + var Rz_BF = datum_params[5]; + var M_BF = datum_params[6]; + // if( x[io] === HUGE_VAL ) + // continue; + return { + x: M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF, + y: M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF, + z: M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF + }; + } +} // cs_geocentric_to_wgs84 + +/****************************************************************/ +// pj_geocentic_from_wgs84() +// coordinate system definition, +// point to transform in geocentric coordinates (x,y,z) +export function geocentricFromWgs84(p, datum_type, datum_params) { + + if (datum_type === PJD_3PARAM) { + //if( x[io] === HUGE_VAL ) + // continue; + return { + x: p.x - datum_params[0], + y: p.y - datum_params[1], + z: p.z - datum_params[2], + }; + + } else if (datum_type === PJD_7PARAM) { + var Dx_BF = datum_params[0]; + var Dy_BF = datum_params[1]; + var Dz_BF = datum_params[2]; + var Rx_BF = datum_params[3]; + var Ry_BF = datum_params[4]; + var Rz_BF = datum_params[5]; + var M_BF = datum_params[6]; + var x_tmp = (p.x - Dx_BF) / M_BF; + var y_tmp = (p.y - Dy_BF) / M_BF; + var z_tmp = (p.z - Dz_BF) / M_BF; + //if( x[io] === HUGE_VAL ) + // continue; + + return { + x: x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp, + y: -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp, + z: Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp + }; + } //cs_geocentric_from_wgs84() +} diff --git a/node_modules/proj4/lib/datum_transform.js b/node_modules/proj4/lib/datum_transform.js new file mode 100644 index 0000000..ad0df80 --- /dev/null +++ b/node_modules/proj4/lib/datum_transform.js @@ -0,0 +1,192 @@ +import { + PJD_3PARAM, + PJD_7PARAM, + PJD_GRIDSHIFT, + PJD_NODATUM, + R2D, + SRS_WGS84_ESQUARED, + SRS_WGS84_SEMIMAJOR, SRS_WGS84_SEMIMINOR +} from './constants/values'; + +import {geodeticToGeocentric, geocentricToGeodetic, geocentricToWgs84, geocentricFromWgs84, compareDatums} from './datumUtils'; +import adjust_lon from "./common/adjust_lon"; +function checkParams(type) { + return (type === PJD_3PARAM || type === PJD_7PARAM); +} + +export default function(source, dest, point) { + // Short cut if the datums are identical. + if (compareDatums(source, dest)) { + return point; // in this case, zero is sucess, + // whereas cs_compare_datums returns 1 to indicate TRUE + // confusing, should fix this + } + + // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest + if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) { + return point; + } + + // If this datum requires grid shifts, then apply it to geodetic coordinates. + var source_a = source.a; + var source_es = source.es; + if (source.datum_type === PJD_GRIDSHIFT) { + var gridShiftCode = applyGridShift(source, false, point); + if (gridShiftCode !== 0) { + return undefined; + } + source_a = SRS_WGS84_SEMIMAJOR; + source_es = SRS_WGS84_ESQUARED; + } + + var dest_a = dest.a; + var dest_b = dest.b; + var dest_es = dest.es; + if (dest.datum_type === PJD_GRIDSHIFT) { + dest_a = SRS_WGS84_SEMIMAJOR; + dest_b = SRS_WGS84_SEMIMINOR; + dest_es = SRS_WGS84_ESQUARED; + } + + // Do we need to go through geocentric coordinates? + if (source_es === dest_es && source_a === dest_a && !checkParams(source.datum_type) && !checkParams(dest.datum_type)) { + return point; + } + + // Convert to geocentric coordinates. + point = geodeticToGeocentric(point, source_es, source_a); + // Convert between datums + if (checkParams(source.datum_type)) { + point = geocentricToWgs84(point, source.datum_type, source.datum_params); + } + if (checkParams(dest.datum_type)) { + point = geocentricFromWgs84(point, dest.datum_type, dest.datum_params); + } + point = geocentricToGeodetic(point, dest_es, dest_a, dest_b); + + if (dest.datum_type === PJD_GRIDSHIFT) { + var destGridShiftResult = applyGridShift(dest, true, point); + if (destGridShiftResult !== 0) { + return undefined; + } + } + + return point; +} + +export function applyGridShift(source, inverse, point) { + if (source.grids === null || source.grids.length === 0) { + console.log('Grid shift grids not found'); + return -1; + } + var input = {x: -point.x, y: point.y}; + var output = {x: Number.NaN, y: Number.NaN}; + var onlyMandatoryGrids = false; + var attemptedGrids = []; + for (var i = 0; i < source.grids.length; i++) { + var grid = source.grids[i]; + attemptedGrids.push(grid.name); + if (grid.isNull) { + output = input; + break; + } + onlyMandatoryGrids = grid.mandatory; + if (grid.grid === null) { + if (grid.mandatory) { + console.log("Unable to find mandatory grid '" + grid.name + "'"); + return -1; + } + continue; + } + var subgrid = grid.grid.subgrids[0]; + // skip tables that don't match our point at all + var epsilon = (Math.abs(subgrid.del[1]) + Math.abs(subgrid.del[0])) / 10000.0; + var minX = subgrid.ll[0] - epsilon; + var minY = subgrid.ll[1] - epsilon; + var maxX = subgrid.ll[0] + (subgrid.lim[0] - 1) * subgrid.del[0] + epsilon; + var maxY = subgrid.ll[1] + (subgrid.lim[1] - 1) * subgrid.del[1] + epsilon; + if (minY > input.y || minX > input.x || maxY < input.y || maxX < input.x ) { + continue; + } + output = applySubgridShift(input, inverse, subgrid); + if (!isNaN(output.x)) { + break; + } + } + if (isNaN(output.x)) { + console.log("Failed to find a grid shift table for location '"+ + -input.x * R2D + " " + input.y * R2D + " tried: '" + attemptedGrids + "'"); + return -1; + } + point.x = -output.x; + point.y = output.y; + return 0; +} + +function applySubgridShift(pin, inverse, ct) { + var val = {x: Number.NaN, y: Number.NaN}; + if (isNaN(pin.x)) { return val; } + var tb = {x: pin.x, y: pin.y}; + tb.x -= ct.ll[0]; + tb.y -= ct.ll[1]; + tb.x = adjust_lon(tb.x - Math.PI) + Math.PI; + var t = nadInterpolate(tb, ct); + if (inverse) { + if (isNaN(t.x)) { + return val; + } + t.x = tb.x - t.x; + t.y = tb.y - t.y; + var i = 9, tol = 1e-12; + var dif, del; + do { + del = nadInterpolate(t, ct); + if (isNaN(del.x)) { + console.log("Inverse grid shift iteration failed, presumably at grid edge. Using first approximation."); + break; + } + dif = {x: tb.x - (del.x + t.x), y: tb.y - (del.y + t.y)}; + t.x += dif.x; + t.y += dif.y; + } while (i-- && Math.abs(dif.x) > tol && Math.abs(dif.y) > tol); + if (i < 0) { + console.log("Inverse grid shift iterator failed to converge."); + return val; + } + val.x = adjust_lon(t.x + ct.ll[0]); + val.y = t.y + ct.ll[1]; + } else { + if (!isNaN(t.x)) { + val.x = pin.x + t.x; + val.y = pin.y + t.y; + } + } + return val; +} + +function nadInterpolate(pin, ct) { + var t = {x: pin.x / ct.del[0], y: pin.y / ct.del[1]}; + var indx = {x: Math.floor(t.x), y: Math.floor(t.y)}; + var frct = {x: t.x - 1.0 * indx.x, y: t.y - 1.0 * indx.y}; + var val= {x: Number.NaN, y: Number.NaN}; + var inx; + if (indx.x < 0 || indx.x >= ct.lim[0]) { + return val; + } + if (indx.y < 0 || indx.y >= ct.lim[1]) { + return val; + } + inx = (indx.y * ct.lim[0]) + indx.x; + var f00 = {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + inx++; + var f10= {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + inx += ct.lim[0]; + var f11 = {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + inx--; + var f01 = {x: ct.cvs[inx][0], y: ct.cvs[inx][1]}; + var m11 = frct.x * frct.y, m10 = frct.x * (1.0 - frct.y), + m00 = (1.0 - frct.x) * (1.0 - frct.y), m01 = (1.0 - frct.x) * frct.y; + val.x = (m00 * f00.x + m10 * f10.x + m01 * f01.x + m11 * f11.x); + val.y = (m00 * f00.y + m10 * f10.y + m01 * f01.y + m11 * f11.y); + return val; +} diff --git a/node_modules/proj4/lib/defs.js b/node_modules/proj4/lib/defs.js new file mode 100644 index 0000000..6655c80 --- /dev/null +++ b/node_modules/proj4/lib/defs.js @@ -0,0 +1,55 @@ +import globals from './global'; +import parseProj from './projString'; +import wkt from 'wkt-parser'; + +function defs(name) { + /*global console*/ + var that = this; + if (arguments.length === 2) { + var def = arguments[1]; + if (typeof def === 'string') { + if (def.charAt(0) === '+') { + defs[name] = parseProj(arguments[1]); + } + else { + defs[name] = wkt(arguments[1]); + } + } else { + defs[name] = def; + } + } + else if (arguments.length === 1) { + if (Array.isArray(name)) { + return name.map(function(v) { + if (Array.isArray(v)) { + defs.apply(that, v); + } + else { + defs(v); + } + }); + } + else if (typeof name === 'string') { + if (name in defs) { + return defs[name]; + } + } + else if ('EPSG' in name) { + defs['EPSG:' + name.EPSG] = name; + } + else if ('ESRI' in name) { + defs['ESRI:' + name.ESRI] = name; + } + else if ('IAU2000' in name) { + defs['IAU2000:' + name.IAU2000] = name; + } + else { + console.log(name); + } + return; + } + + +} +globals(defs); +export default defs; diff --git a/node_modules/proj4/lib/deriveConstants.js b/node_modules/proj4/lib/deriveConstants.js new file mode 100644 index 0000000..fd8b382 --- /dev/null +++ b/node_modules/proj4/lib/deriveConstants.js @@ -0,0 +1,48 @@ +import {SIXTH, RA4, RA6, EPSLN} from './constants/values'; +import {default as Ellipsoid, WGS84} from './constants/Ellipsoid'; +import match from './match'; + +export function eccentricity(a, b, rf, R_A) { + var a2 = a * a; // used in geocentric + var b2 = b * b; // used in geocentric + var es = (a2 - b2) / a2; // e ^ 2 + var e = 0; + if (R_A) { + a *= 1 - es * (SIXTH + es * (RA4 + es * RA6)); + a2 = a * a; + es = 0; + } else { + e = Math.sqrt(es); // eccentricity + } + var ep2 = (a2 - b2) / b2; // used in geocentric + return { + es: es, + e: e, + ep2: ep2 + }; +} +export function sphere(a, b, rf, ellps, sphere) { + if (!a) { // do we have an ellipsoid? + var ellipse = match(Ellipsoid, ellps); + if (!ellipse) { + ellipse = WGS84; + } + a = ellipse.a; + b = ellipse.b; + rf = ellipse.rf; + } + + if (rf && !b) { + b = (1.0 - 1.0 / rf) * a; + } + if (rf === 0 || Math.abs(a - b) < EPSLN) { + sphere = true; + b = a; + } + return { + a: a, + b: b, + rf: rf, + sphere: sphere + }; +} diff --git a/node_modules/proj4/lib/extend.js b/node_modules/proj4/lib/extend.js new file mode 100644 index 0000000..bcd759f --- /dev/null +++ b/node_modules/proj4/lib/extend.js @@ -0,0 +1,14 @@ +export default function(destination, source) { + destination = destination || {}; + var value, property; + if (!source) { + return destination; + } + for (property in source) { + value = source[property]; + if (value !== undefined) { + destination[property] = value; + } + } + return destination; +} diff --git a/node_modules/proj4/lib/global.js b/node_modules/proj4/lib/global.js new file mode 100644 index 0000000..476a131 --- /dev/null +++ b/node_modules/proj4/lib/global.js @@ -0,0 +1,11 @@ +export default function(defs) { + defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"); + defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees"); + defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"); + + defs.WGS84 = defs['EPSG:4326']; + defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857 + defs.GOOGLE = defs['EPSG:3857']; + defs['EPSG:900913'] = defs['EPSG:3857']; + defs['EPSG:102113'] = defs['EPSG:3857']; +} diff --git a/node_modules/proj4/lib/includedProjections.js b/node_modules/proj4/lib/includedProjections.js new file mode 100644 index 0000000..22039ba --- /dev/null +++ b/node_modules/proj4/lib/includedProjections.js @@ -0,0 +1,65 @@ +import tmerc from "./projections/tmerc"; +import utm from "./projections/utm"; +import sterea from "./projections/sterea"; +import stere from "./projections/stere"; +import somerc from "./projections/somerc"; +import omerc from "./projections/omerc"; +import lcc from "./projections/lcc"; +import krovak from "./projections/krovak"; +import cass from "./projections/cass"; +import laea from "./projections/laea"; +import aea from "./projections/aea"; +import gnom from "./projections/gnom"; +import cea from "./projections/cea"; +import eqc from "./projections/eqc"; +import poly from "./projections/poly"; +import nzmg from "./projections/nzmg"; +import mill from "./projections/mill"; +import sinu from "./projections/sinu"; +import moll from "./projections/moll"; +import eqdc from "./projections/eqdc"; +import vandg from "./projections/vandg"; +import aegd from "./projections/aeqd"; +import etmerc from './projections/etmerc'; +import qsc from './projections/qsc'; +import robin from './projections/robin'; +import geocent from './projections/geocent'; +import tpers from './projections/tpers'; +import geos from './projections/geos'; + +var projs = [ + tmerc, + utm, + sterea, + stere, + somerc, + omerc, + lcc, + krovak, + cass, + laea, + aea, + gnom, + cea, + eqc, + poly, + nzmg, + mill, + sinu, + moll, + eqdc, + vandg, + aegd, + etmerc, + qsc, + robin, + geocent, + tpers, + geos, +]; + +export default function (proj4) { + projs.forEach(function (proj) { + proj4.Proj.projections.add(proj); + }); +} \ No newline at end of file diff --git a/node_modules/proj4/lib/index.js b/node_modules/proj4/lib/index.js new file mode 100644 index 0000000..bb5ec0b --- /dev/null +++ b/node_modules/proj4/lib/index.js @@ -0,0 +1,22 @@ +import proj4 from './core'; +import Proj from "./Proj"; +import Point from "./Point"; +import common from "./common/toPoint"; +import defs from "./defs"; +import nadgrid from "./nadgrid"; +import transform from "./transform"; +import mgrs from "mgrs"; +import includedProjections from "../projs"; + +proj4.defaultDatum = 'WGS84'; //default datum +proj4.Proj = Proj; +proj4.WGS84 = new proj4.Proj('WGS84'); +proj4.Point = Point; +proj4.toPoint = common; +proj4.defs = defs; +proj4.nadgrid = nadgrid; +proj4.transform = transform; +proj4.mgrs = mgrs; +proj4.version = '__VERSION__'; +includedProjections(proj4); +export default proj4; diff --git a/node_modules/proj4/lib/match.js b/node_modules/proj4/lib/match.js new file mode 100644 index 0000000..595e166 --- /dev/null +++ b/node_modules/proj4/lib/match.js @@ -0,0 +1,17 @@ +var ignoredChar = /[\s_\-\/\(\)]/g; +export default function match(obj, key) { + if (obj[key]) { + return obj[key]; + } + var keys = Object.keys(obj); + var lkey = key.toLowerCase().replace(ignoredChar, ''); + var i = -1; + var testkey, processedKey; + while (++i < keys.length) { + testkey = keys[i]; + processedKey = testkey.toLowerCase().replace(ignoredChar, ''); + if (processedKey === lkey) { + return obj[testkey]; + } + } +} diff --git a/node_modules/proj4/lib/nadgrid.js b/node_modules/proj4/lib/nadgrid.js new file mode 100644 index 0000000..4de1993 --- /dev/null +++ b/node_modules/proj4/lib/nadgrid.js @@ -0,0 +1,142 @@ +/** + * Resources for details of NTv2 file formats: + * - https://web.archive.org/web/20140127204822if_/http://www.mgs.gov.on.ca:80/stdprodconsume/groups/content/@mgs/@iandit/documents/resourcelist/stel02_047447.pdf + * - http://mimaka.com/help/gs/html/004_NTV2%20Data%20Format.htm + */ + +var loadedNadgrids = {}; + +/** + * Load a binary NTv2 file (.gsb) to a key that can be used in a proj string like +nadgrids=. Pass the NTv2 file + * as an ArrayBuffer. + */ +export default function nadgrid(key, data) { + var view = new DataView(data); + var isLittleEndian = detectLittleEndian(view); + var header = readHeader(view, isLittleEndian); + if (header.nSubgrids > 1) { + console.log('Only single NTv2 subgrids are currently supported, subsequent sub grids are ignored'); + } + var subgrids = readSubgrids(view, header, isLittleEndian); + var nadgrid = {header: header, subgrids: subgrids}; + loadedNadgrids[key] = nadgrid; + return nadgrid; +} + +/** + * Given a proj4 value for nadgrids, return an array of loaded grids + */ +export function getNadgrids(nadgrids) { + // Format details: http://proj.maptools.org/gen_parms.html + if (nadgrids === undefined) { return null; } + var grids = nadgrids.split(','); + return grids.map(parseNadgridString); +} + +function parseNadgridString(value) { + if (value.length === 0) { + return null; + } + var optional = value[0] === '@'; + if (optional) { + value = value.slice(1); + } + if (value === 'null') { + return {name: 'null', mandatory: !optional, grid: null, isNull: true}; + } + return { + name: value, + mandatory: !optional, + grid: loadedNadgrids[value] || null, + isNull: false + }; +} + +function secondsToRadians(seconds) { + return (seconds / 3600) * Math.PI / 180; +} + +function detectLittleEndian(view) { + var nFields = view.getInt32(8, false); + if (nFields === 11) { + return false; + } + nFields = view.getInt32(8, true); + if (nFields !== 11) { + console.warn('Failed to detect nadgrid endian-ness, defaulting to little-endian'); + } + return true; +} + +function readHeader(view, isLittleEndian) { + return { + nFields: view.getInt32(8, isLittleEndian), + nSubgridFields: view.getInt32(24, isLittleEndian), + nSubgrids: view.getInt32(40, isLittleEndian), + shiftType: decodeString(view, 56, 56 + 8).trim(), + fromSemiMajorAxis: view.getFloat64(120, isLittleEndian), + fromSemiMinorAxis: view.getFloat64(136, isLittleEndian), + toSemiMajorAxis: view.getFloat64(152, isLittleEndian), + toSemiMinorAxis: view.getFloat64(168, isLittleEndian), + }; +} + +function decodeString(view, start, end) { + return String.fromCharCode.apply(null, new Uint8Array(view.buffer.slice(start, end))); +} + +function readSubgrids(view, header, isLittleEndian) { + var gridOffset = 176; + var grids = []; + for (var i = 0; i < header.nSubgrids; i++) { + var subHeader = readGridHeader(view, gridOffset, isLittleEndian); + var nodes = readGridNodes(view, gridOffset, subHeader, isLittleEndian); + var lngColumnCount = Math.round( + 1 + (subHeader.upperLongitude - subHeader.lowerLongitude) / subHeader.longitudeInterval); + var latColumnCount = Math.round( + 1 + (subHeader.upperLatitude - subHeader.lowerLatitude) / subHeader.latitudeInterval); + // Proj4 operates on radians whereas the coordinates are in seconds in the grid + grids.push({ + ll: [secondsToRadians(subHeader.lowerLongitude), secondsToRadians(subHeader.lowerLatitude)], + del: [secondsToRadians(subHeader.longitudeInterval), secondsToRadians(subHeader.latitudeInterval)], + lim: [lngColumnCount, latColumnCount], + count: subHeader.gridNodeCount, + cvs: mapNodes(nodes) + }); + } + return grids; +} + +function mapNodes(nodes) { + return nodes.map(function (r) {return [secondsToRadians(r.longitudeShift), secondsToRadians(r.latitudeShift)];}); +} + +function readGridHeader(view, offset, isLittleEndian) { + return { + name: decodeString(view, offset + 8, offset + 16).trim(), + parent: decodeString(view, offset + 24, offset + 24 + 8).trim(), + lowerLatitude: view.getFloat64(offset + 72, isLittleEndian), + upperLatitude: view.getFloat64(offset + 88, isLittleEndian), + lowerLongitude: view.getFloat64(offset + 104, isLittleEndian), + upperLongitude: view.getFloat64(offset + 120, isLittleEndian), + latitudeInterval: view.getFloat64(offset + 136, isLittleEndian), + longitudeInterval: view.getFloat64(offset + 152, isLittleEndian), + gridNodeCount: view.getInt32(offset + 168, isLittleEndian) + }; +} + +function readGridNodes(view, offset, gridHeader, isLittleEndian) { + var nodesOffset = offset + 176; + var gridRecordLength = 16; + var gridShiftRecords = []; + for (var i = 0; i < gridHeader.gridNodeCount; i++) { + var record = { + latitudeShift: view.getFloat32(nodesOffset + i * gridRecordLength, isLittleEndian), + longitudeShift: view.getFloat32(nodesOffset + i * gridRecordLength + 4, isLittleEndian), + latitudeAccuracy: view.getFloat32(nodesOffset + i * gridRecordLength + 8, isLittleEndian), + longitudeAccuracy: view.getFloat32(nodesOffset + i * gridRecordLength + 12, isLittleEndian), + }; + gridShiftRecords.push(record); + } + return gridShiftRecords; +} diff --git a/node_modules/proj4/lib/parseCode.js b/node_modules/proj4/lib/parseCode.js new file mode 100644 index 0000000..6d2f95f --- /dev/null +++ b/node_modules/proj4/lib/parseCode.js @@ -0,0 +1,62 @@ +import defs from './defs'; +import wkt from 'wkt-parser'; +import projStr from './projString'; +import match from './match'; +function testObj(code){ + return typeof code === 'string'; +} +function testDef(code){ + return code in defs; +} +var codeWords = ['PROJECTEDCRS', 'PROJCRS', 'GEOGCS','GEOCCS','PROJCS','LOCAL_CS', 'GEODCRS', 'GEODETICCRS', 'GEODETICDATUM', 'ENGCRS', 'ENGINEERINGCRS']; +function testWKT(code){ + return codeWords.some(function (word) { + return code.indexOf(word) > -1; + }); +} +var codes = ['3857', '900913', '3785', '102113']; +function checkMercator(item) { + var auth = match(item, 'authority'); + if (!auth) { + return; + } + var code = match(auth, 'epsg'); + return code && codes.indexOf(code) > -1; +} +function checkProjStr(item) { + var ext = match(item, 'extension'); + if (!ext) { + return; + } + return match(ext, 'proj4'); +} +function testProj(code){ + return code[0] === '+'; +} +function parse(code){ + if (testObj(code)) { + //check to see if this is a WKT string + if (testDef(code)) { + return defs[code]; + } + if (testWKT(code)) { + var out = wkt(code); + // test of spetial case, due to this being a very common and often malformed + if (checkMercator(out)) { + return defs['EPSG:3857']; + } + var maybeProjStr = checkProjStr(out); + if (maybeProjStr) { + return projStr(maybeProjStr); + } + return out; + } + if (testProj(code)) { + return projStr(code); + } + }else{ + return code; + } +} + +export default parse; diff --git a/node_modules/proj4/lib/projString.js b/node_modules/proj4/lib/projString.js new file mode 100644 index 0000000..a03f18e --- /dev/null +++ b/node_modules/proj4/lib/projString.js @@ -0,0 +1,141 @@ +import {D2R} from './constants/values'; +import PrimeMeridian from './constants/PrimeMeridian'; +import units from './constants/units'; +import match from './match'; + +export default function(defData) { + var self = {}; + var paramObj = defData.split('+').map(function(v) { + return v.trim(); + }).filter(function(a) { + return a; + }).reduce(function(p, a) { + var split = a.split('='); + split.push(true); + p[split[0].toLowerCase()] = split[1]; + return p; + }, {}); + var paramName, paramVal, paramOutname; + var params = { + proj: 'projName', + datum: 'datumCode', + rf: function(v) { + self.rf = parseFloat(v); + }, + lat_0: function(v) { + self.lat0 = v * D2R; + }, + lat_1: function(v) { + self.lat1 = v * D2R; + }, + lat_2: function(v) { + self.lat2 = v * D2R; + }, + lat_ts: function(v) { + self.lat_ts = v * D2R; + }, + lon_0: function(v) { + self.long0 = v * D2R; + }, + lon_1: function(v) { + self.long1 = v * D2R; + }, + lon_2: function(v) { + self.long2 = v * D2R; + }, + alpha: function(v) { + self.alpha = parseFloat(v) * D2R; + }, + gamma: function(v) { + self.rectified_grid_angle = parseFloat(v); + }, + lonc: function(v) { + self.longc = v * D2R; + }, + x_0: function(v) { + self.x0 = parseFloat(v); + }, + y_0: function(v) { + self.y0 = parseFloat(v); + }, + k_0: function(v) { + self.k0 = parseFloat(v); + }, + k: function(v) { + self.k0 = parseFloat(v); + }, + a: function(v) { + self.a = parseFloat(v); + }, + b: function(v) { + self.b = parseFloat(v); + }, + r_a: function() { + self.R_A = true; + }, + zone: function(v) { + self.zone = parseInt(v, 10); + }, + south: function() { + self.utmSouth = true; + }, + towgs84: function(v) { + self.datum_params = v.split(",").map(function(a) { + return parseFloat(a); + }); + }, + to_meter: function(v) { + self.to_meter = parseFloat(v); + }, + units: function(v) { + self.units = v; + var unit = match(units, v); + if (unit) { + self.to_meter = unit.to_meter; + } + }, + from_greenwich: function(v) { + self.from_greenwich = v * D2R; + }, + pm: function(v) { + var pm = match(PrimeMeridian, v); + self.from_greenwich = (pm ? pm : parseFloat(v)) * D2R; + }, + nadgrids: function(v) { + if (v === '@null') { + self.datumCode = 'none'; + } + else { + self.nadgrids = v; + } + }, + axis: function(v) { + var legalAxis = "ewnsud"; + if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) { + self.axis = v; + } + }, + approx: function() { + self.approx = true; + } + }; + for (paramName in paramObj) { + paramVal = paramObj[paramName]; + if (paramName in params) { + paramOutname = params[paramName]; + if (typeof paramOutname === 'function') { + paramOutname(paramVal); + } + else { + self[paramOutname] = paramVal; + } + } + else { + self[paramName] = paramVal; + } + } + if(typeof self.datumCode === 'string' && self.datumCode !== "WGS84"){ + self.datumCode = self.datumCode.toLowerCase(); + } + return self; +} diff --git a/node_modules/proj4/lib/projections.js b/node_modules/proj4/lib/projections.js new file mode 100644 index 0000000..6667b44 --- /dev/null +++ b/node_modules/proj4/lib/projections.js @@ -0,0 +1,39 @@ +import merc from "./projections/merc"; +import longlat from "./projections/longlat"; +var projs = [merc, longlat]; +var names = {}; +var projStore = []; + +function add(proj, i) { + var len = projStore.length; + if (!proj.names) { + console.log(i); + return true; + } + projStore[len] = proj; + proj.names.forEach(function(n) { + names[n.toLowerCase()] = len; + }); + return this; +} + +export {add}; + +export function get(name) { + if (!name) { + return false; + } + var n = name.toLowerCase(); + if (typeof names[n] !== 'undefined' && projStore[names[n]]) { + return projStore[names[n]]; + } +} + +export function start() { + projs.forEach(add); +} +export default { + start: start, + add: add, + get: get +}; diff --git a/node_modules/proj4/lib/projections/aea.js b/node_modules/proj4/lib/projections/aea.js new file mode 100644 index 0000000..4cfbc97 --- /dev/null +++ b/node_modules/proj4/lib/projections/aea.js @@ -0,0 +1,129 @@ +import msfnz from '../common/msfnz'; +import qsfnz from '../common/qsfnz'; +import adjust_lon from '../common/adjust_lon'; +import asinz from '../common/asinz'; +import {EPSLN} from '../constants/values'; + +export function init() { + + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); + this.e3 = Math.sqrt(this.es); + + this.sin_po = Math.sin(this.lat1); + this.cos_po = Math.cos(this.lat1); + this.t1 = this.sin_po; + this.con = this.sin_po; + this.ms1 = msfnz(this.e3, this.sin_po, this.cos_po); + this.qs1 = qsfnz(this.e3, this.sin_po); + + this.sin_po = Math.sin(this.lat2); + this.cos_po = Math.cos(this.lat2); + this.t2 = this.sin_po; + this.ms2 = msfnz(this.e3, this.sin_po, this.cos_po); + this.qs2 = qsfnz(this.e3, this.sin_po); + + this.sin_po = Math.sin(this.lat0); + this.cos_po = Math.cos(this.lat0); + this.t3 = this.sin_po; + this.qs0 = qsfnz(this.e3, this.sin_po); + + if (Math.abs(this.lat1 - this.lat2) > EPSLN) { + this.ns0 = (this.ms1 * this.ms1 - this.ms2 * this.ms2) / (this.qs2 - this.qs1); + } + else { + this.ns0 = this.con; + } + this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1; + this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0) / this.ns0; +} + +/* Albers Conical Equal Area forward equations--mapping lat,long to x,y + -------------------------------------------------------------------*/ +export function forward(p) { + + var lon = p.x; + var lat = p.y; + + this.sin_phi = Math.sin(lat); + this.cos_phi = Math.cos(lat); + + var qs = qsfnz(this.e3, this.sin_phi); + var rh1 = this.a * Math.sqrt(this.c - this.ns0 * qs) / this.ns0; + var theta = this.ns0 * adjust_lon(lon - this.long0); + var x = rh1 * Math.sin(theta) + this.x0; + var y = this.rh - rh1 * Math.cos(theta) + this.y0; + + p.x = x; + p.y = y; + return p; +} + +export function inverse(p) { + var rh1, qs, con, theta, lon, lat; + + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + if (this.ns0 >= 0) { + rh1 = Math.sqrt(p.x * p.x + p.y * p.y); + con = 1; + } + else { + rh1 = -Math.sqrt(p.x * p.x + p.y * p.y); + con = -1; + } + theta = 0; + if (rh1 !== 0) { + theta = Math.atan2(con * p.x, con * p.y); + } + con = rh1 * this.ns0 / this.a; + if (this.sphere) { + lat = Math.asin((this.c - con * con) / (2 * this.ns0)); + } + else { + qs = (this.c - con * con) / this.ns0; + lat = this.phi1z(this.e3, qs); + } + + lon = adjust_lon(theta / this.ns0 + this.long0); + p.x = lon; + p.y = lat; + return p; +} + +/* Function to compute phi1, the latitude for the inverse of the + Albers Conical Equal-Area projection. +-------------------------------------------*/ +export function phi1z(eccent, qs) { + var sinphi, cosphi, con, com, dphi; + var phi = asinz(0.5 * qs); + if (eccent < EPSLN) { + return phi; + } + + var eccnts = eccent * eccent; + for (var i = 1; i <= 25; i++) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + con = eccent * sinphi; + com = 1 - con * con; + dphi = 0.5 * com * com / cosphi * (qs / (1 - eccnts) - sinphi / com + 0.5 / eccent * Math.log((1 - con) / (1 + con))); + phi = phi + dphi; + if (Math.abs(dphi) <= 1e-7) { + return phi; + } + } + return null; +} + +export var names = ["Albers_Conic_Equal_Area", "Albers", "aea"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names, + phi1z: phi1z +}; diff --git a/node_modules/proj4/lib/projections/aeqd.js b/node_modules/proj4/lib/projections/aeqd.js new file mode 100644 index 0000000..1a60c9d --- /dev/null +++ b/node_modules/proj4/lib/projections/aeqd.js @@ -0,0 +1,208 @@ +import adjust_lon from '../common/adjust_lon'; +import {HALF_PI, EPSLN} from '../constants/values'; + +import mlfn from '../common/mlfn'; +import e0fn from '../common/e0fn'; +import e1fn from '../common/e1fn'; +import e2fn from '../common/e2fn'; +import e3fn from '../common/e3fn'; +import gN from '../common/gN'; +import asinz from '../common/asinz'; +import imlfn from '../common/imlfn'; + + + +export function init() { + this.sin_p12 = Math.sin(this.lat0); + this.cos_p12 = Math.cos(this.lat0); +} + +export function forward(p) { + var lon = p.x; + var lat = p.y; + var sinphi = Math.sin(p.y); + var cosphi = Math.cos(p.y); + var dlon = adjust_lon(lon - this.long0); + var e0, e1, e2, e3, Mlp, Ml, tanphi, Nl1, Nl, psi, Az, G, H, GH, Hs, c, kp, cos_c, s, s2, s3, s4, s5; + if (this.sphere) { + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North Pole case + p.x = this.x0 + this.a * (HALF_PI - lat) * Math.sin(dlon); + p.y = this.y0 - this.a * (HALF_PI - lat) * Math.cos(dlon); + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South Pole case + p.x = this.x0 + this.a * (HALF_PI + lat) * Math.sin(dlon); + p.y = this.y0 + this.a * (HALF_PI + lat) * Math.cos(dlon); + return p; + } + else { + //default case + cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon); + c = Math.acos(cos_c); + kp = c ? c / Math.sin(c) : 1; + p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon); + p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon)); + return p; + } + } + else { + e0 = e0fn(this.es); + e1 = e1fn(this.es); + e2 = e2fn(this.es); + e3 = e3fn(this.es); + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North Pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + Ml = this.a * mlfn(e0, e1, e2, e3, lat); + p.x = this.x0 + (Mlp - Ml) * Math.sin(dlon); + p.y = this.y0 - (Mlp - Ml) * Math.cos(dlon); + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South Pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + Ml = this.a * mlfn(e0, e1, e2, e3, lat); + p.x = this.x0 + (Mlp + Ml) * Math.sin(dlon); + p.y = this.y0 + (Mlp + Ml) * Math.cos(dlon); + return p; + } + else { + //Default case + tanphi = sinphi / cosphi; + Nl1 = gN(this.a, this.e, this.sin_p12); + Nl = gN(this.a, this.e, sinphi); + psi = Math.atan((1 - this.es) * tanphi + this.es * Nl1 * this.sin_p12 / (Nl * cosphi)); + Az = Math.atan2(Math.sin(dlon), this.cos_p12 * Math.tan(psi) - this.sin_p12 * Math.cos(dlon)); + if (Az === 0) { + s = Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi)); + } + else if (Math.abs(Math.abs(Az) - Math.PI) <= EPSLN) { + s = -Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi)); + } + else { + s = Math.asin(Math.sin(dlon) * Math.cos(psi) / Math.sin(Az)); + } + G = this.e * this.sin_p12 / Math.sqrt(1 - this.es); + H = this.e * this.cos_p12 * Math.cos(Az) / Math.sqrt(1 - this.es); + GH = G * H; + Hs = H * H; + s2 = s * s; + s3 = s2 * s; + s4 = s3 * s; + s5 = s4 * s; + c = Nl1 * s * (1 - s2 * Hs * (1 - Hs) / 6 + s3 / 8 * GH * (1 - 2 * Hs) + s4 / 120 * (Hs * (4 - 7 * Hs) - 3 * G * G * (1 - 7 * Hs)) - s5 / 48 * GH); + p.x = this.x0 + c * Math.sin(Az); + p.y = this.y0 + c * Math.cos(Az); + return p; + } + } + + +} + +export function inverse(p) { + p.x -= this.x0; + p.y -= this.y0; + var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F, sinpsi; + if (this.sphere) { + rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (rh > (2 * HALF_PI * this.a)) { + return; + } + z = rh / this.a; + + sinz = Math.sin(z); + cosz = Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= EPSLN) { + lat = this.lat0; + } + else { + lat = asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh); + con = Math.abs(this.lat0) - HALF_PI; + if (Math.abs(con) <= EPSLN) { + if (this.lat0 >= 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y)); + } + else { + lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y)); + } + } + else { + /*con = cosz - this.sin_p12 * Math.sin(lat); + if ((Math.abs(con) < EPSLN) && (Math.abs(p.x) < EPSLN)) { + //no-op, just keep the lon value as is + } else { + var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh)); + lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh))); + }*/ + lon = adjust_lon(this.long0 + Math.atan2(p.x * sinz, rh * this.cos_p12 * cosz - p.y * this.sin_p12 * sinz)); + } + } + + p.x = lon; + p.y = lat; + return p; + } + else { + e0 = e0fn(this.es); + e1 = e1fn(this.es); + e2 = e2fn(this.es); + e3 = e3fn(this.es); + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + rh = Math.sqrt(p.x * p.x + p.y * p.y); + M = Mlp - rh; + lat = imlfn(M / this.a, e0, e1, e2, e3); + lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y)); + p.x = lon; + p.y = lat; + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + rh = Math.sqrt(p.x * p.x + p.y * p.y); + M = rh - Mlp; + + lat = imlfn(M / this.a, e0, e1, e2, e3); + lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y)); + p.x = lon; + p.y = lat; + return p; + } + else { + //default case + rh = Math.sqrt(p.x * p.x + p.y * p.y); + Az = Math.atan2(p.x, p.y); + N1 = gN(this.a, this.e, this.sin_p12); + cosAz = Math.cos(Az); + tmp = this.e * this.cos_p12 * cosAz; + A = -tmp * tmp / (1 - this.es); + B = 3 * this.es * (1 - A) * this.sin_p12 * this.cos_p12 * cosAz / (1 - this.es); + D = rh / N1; + Ee = D - A * (1 + A) * Math.pow(D, 3) / 6 - B * (1 + 3 * A) * Math.pow(D, 4) / 24; + F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6; + psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz); + lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi))); + sinpsi = Math.sin(psi); + lat = Math.atan2((sinpsi - this.es * F * this.sin_p12) * Math.tan(psi), sinpsi * (1 - this.es)); + p.x = lon; + p.y = lat; + return p; + } + } + +} + +export var names = ["Azimuthal_Equidistant", "aeqd"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/cass.js b/node_modules/proj4/lib/projections/cass.js new file mode 100644 index 0000000..74f4d38 --- /dev/null +++ b/node_modules/proj4/lib/projections/cass.js @@ -0,0 +1,108 @@ +import mlfn from '../common/mlfn'; +import e0fn from '../common/e0fn'; +import e1fn from '../common/e1fn'; +import e2fn from '../common/e2fn'; +import e3fn from '../common/e3fn'; +import gN from '../common/gN'; +import adjust_lon from '../common/adjust_lon'; +import adjust_lat from '../common/adjust_lat'; +import imlfn from '../common/imlfn'; +import {HALF_PI, EPSLN} from '../constants/values'; + +export function init() { + if (!this.sphere) { + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); + } +} + +/* Cassini forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ +export function forward(p) { + + /* Forward equations + -----------------*/ + var x, y; + var lam = p.x; + var phi = p.y; + lam = adjust_lon(lam - this.long0); + + if (this.sphere) { + x = this.a * Math.asin(Math.cos(phi) * Math.sin(lam)); + y = this.a * (Math.atan2(Math.tan(phi), Math.cos(lam)) - this.lat0); + } + else { + //ellipsoid + var sinphi = Math.sin(phi); + var cosphi = Math.cos(phi); + var nl = gN(this.a, this.e, sinphi); + var tl = Math.tan(phi) * Math.tan(phi); + var al = lam * Math.cos(phi); + var asq = al * al; + var cl = this.es * cosphi * cosphi / (1 - this.es); + var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi); + + x = nl * al * (1 - asq * tl * (1 / 6 - (8 - tl + 8 * cl) * asq / 120)); + y = ml - this.ml0 + nl * sinphi / cosphi * asq * (0.5 + (5 - tl + 6 * cl) * asq / 24); + + + } + + p.x = x + this.x0; + p.y = y + this.y0; + return p; +} + +/* Inverse equations + -----------------*/ +export function inverse(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x / this.a; + var y = p.y / this.a; + var phi, lam; + + if (this.sphere) { + var dd = y + this.lat0; + phi = Math.asin(Math.sin(dd) * Math.cos(x)); + lam = Math.atan2(Math.tan(x), Math.cos(dd)); + } + else { + /* ellipsoid */ + var ml1 = this.ml0 / this.a + y; + var phi1 = imlfn(ml1, this.e0, this.e1, this.e2, this.e3); + if (Math.abs(Math.abs(phi1) - HALF_PI) <= EPSLN) { + p.x = this.long0; + p.y = HALF_PI; + if (y < 0) { + p.y *= -1; + } + return p; + } + var nl1 = gN(this.a, this.e, Math.sin(phi1)); + + var rl1 = nl1 * nl1 * nl1 / this.a / this.a * (1 - this.es); + var tl1 = Math.pow(Math.tan(phi1), 2); + var dl = x * this.a / nl1; + var dsq = dl * dl; + phi = phi1 - nl1 * Math.tan(phi1) / rl1 * dl * dl * (0.5 - (1 + 3 * tl1) * dl * dl / 24); + lam = dl * (1 - dsq * (tl1 / 3 + (1 + 3 * tl1) * tl1 * dsq / 15)) / Math.cos(phi1); + + } + + p.x = adjust_lon(lam + this.long0); + p.y = adjust_lat(phi); + return p; + +} + +export var names = ["Cassini", "Cassini_Soldner", "cass"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/cea.js b/node_modules/proj4/lib/projections/cea.js new file mode 100644 index 0000000..68fc2ad --- /dev/null +++ b/node_modules/proj4/lib/projections/cea.js @@ -0,0 +1,70 @@ +import adjust_lon from '../common/adjust_lon'; +import qsfnz from '../common/qsfnz'; +import msfnz from '../common/msfnz'; +import iqsfnz from '../common/iqsfnz'; + +/* + reference: + "Cartographic Projection Procedures for the UNIX Environment- + A User's Manual" by Gerald I. Evenden, + USGS Open File Report 90-284and Release 4 Interim Reports (2003) +*/ +export function init() { + //no-op + if (!this.sphere) { + this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } +} + +/* Cylindrical Equal Area forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ +export function forward(p) { + var lon = p.x; + var lat = p.y; + var x, y; + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + if (this.sphere) { + x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts); + } + else { + var qs = qsfnz(this.e, Math.sin(lat)); + x = this.x0 + this.a * this.k0 * dlon; + y = this.y0 + this.a * qs * 0.5 / this.k0; + } + + p.x = x; + p.y = y; + return p; +} + +/* Cylindrical Equal Area inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ +export function inverse(p) { + p.x -= this.x0; + p.y -= this.y0; + var lon, lat; + + if (this.sphere) { + lon = adjust_lon(this.long0 + (p.x / this.a) / Math.cos(this.lat_ts)); + lat = Math.asin((p.y / this.a) * Math.cos(this.lat_ts)); + } + else { + lat = iqsfnz(this.e, 2 * p.y * this.k0 / this.a); + lon = adjust_lon(this.long0 + p.x / (this.a * this.k0)); + } + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["cea"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/eqc.js b/node_modules/proj4/lib/projections/eqc.js new file mode 100644 index 0000000..4451328 --- /dev/null +++ b/node_modules/proj4/lib/projections/eqc.js @@ -0,0 +1,48 @@ +import adjust_lon from '../common/adjust_lon'; +import adjust_lat from '../common/adjust_lat'; + +export function init() { + + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.lat0 = this.lat0 || 0; + this.long0 = this.long0 || 0; + this.lat_ts = this.lat_ts || 0; + this.title = this.title || "Equidistant Cylindrical (Plate Carre)"; + + this.rc = Math.cos(this.lat_ts); +} + +// forward equations--mapping lat,long to x,y +// ----------------------------------------------------------------- +export function forward(p) { + + var lon = p.x; + var lat = p.y; + + var dlon = adjust_lon(lon - this.long0); + var dlat = adjust_lat(lat - this.lat0); + p.x = this.x0 + (this.a * dlon * this.rc); + p.y = this.y0 + (this.a * dlat); + return p; +} + +// inverse equations--mapping x,y to lat/long +// ----------------------------------------------------------------- +export function inverse(p) { + + var x = p.x; + var y = p.y; + + p.x = adjust_lon(this.long0 + ((x - this.x0) / (this.a * this.rc))); + p.y = adjust_lat(this.lat0 + ((y - this.y0) / (this.a))); + return p; +} + +export var names = ["Equirectangular", "Equidistant_Cylindrical", "eqc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/eqdc.js b/node_modules/proj4/lib/projections/eqdc.js new file mode 100644 index 0000000..fcf03e1 --- /dev/null +++ b/node_modules/proj4/lib/projections/eqdc.js @@ -0,0 +1,117 @@ +import e0fn from '../common/e0fn'; +import e1fn from '../common/e1fn'; +import e2fn from '../common/e2fn'; +import e3fn from '../common/e3fn'; +import msfnz from '../common/msfnz'; +import mlfn from '../common/mlfn'; +import adjust_lon from '../common/adjust_lon'; +import adjust_lat from '../common/adjust_lat'; +import imlfn from '../common/imlfn'; +import {EPSLN} from '../constants/values'; + +export function init() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + this.lat2 = this.lat2 || this.lat1; + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); + this.e = Math.sqrt(this.es); + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + + this.sinphi = Math.sin(this.lat1); + this.cosphi = Math.cos(this.lat1); + + this.ms1 = msfnz(this.e, this.sinphi, this.cosphi); + this.ml1 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat1); + + if (Math.abs(this.lat1 - this.lat2) < EPSLN) { + this.ns = this.sinphi; + } + else { + this.sinphi = Math.sin(this.lat2); + this.cosphi = Math.cos(this.lat2); + this.ms2 = msfnz(this.e, this.sinphi, this.cosphi); + this.ml2 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2); + this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1); + } + this.g = this.ml1 + this.ms1 / this.ns; + this.ml0 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); + this.rh = this.a * (this.g - this.ml0); +} + +/* Equidistant Conic forward equations--mapping lat,long to x,y + -----------------------------------------------------------*/ +export function forward(p) { + var lon = p.x; + var lat = p.y; + var rh1; + + /* Forward equations + -----------------*/ + if (this.sphere) { + rh1 = this.a * (this.g - lat); + } + else { + var ml = mlfn(this.e0, this.e1, this.e2, this.e3, lat); + rh1 = this.a * (this.g - ml); + } + var theta = this.ns * adjust_lon(lon - this.long0); + var x = this.x0 + rh1 * Math.sin(theta); + var y = this.y0 + this.rh - rh1 * Math.cos(theta); + p.x = x; + p.y = y; + return p; +} + +/* Inverse equations + -----------------*/ +export function inverse(p) { + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + var con, rh1, lat, lon; + if (this.ns >= 0) { + rh1 = Math.sqrt(p.x * p.x + p.y * p.y); + con = 1; + } + else { + rh1 = -Math.sqrt(p.x * p.x + p.y * p.y); + con = -1; + } + var theta = 0; + if (rh1 !== 0) { + theta = Math.atan2(con * p.x, con * p.y); + } + + if (this.sphere) { + lon = adjust_lon(this.long0 + theta / this.ns); + lat = adjust_lat(this.g - rh1 / this.a); + p.x = lon; + p.y = lat; + return p; + } + else { + var ml = this.g - rh1 / this.a; + lat = imlfn(ml, this.e0, this.e1, this.e2, this.e3); + lon = adjust_lon(this.long0 + theta / this.ns); + p.x = lon; + p.y = lat; + return p; + } + +} + +export var names = ["Equidistant_Conic", "eqdc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/equi.js b/node_modules/proj4/lib/projections/equi.js new file mode 100644 index 0000000..f91a522 --- /dev/null +++ b/node_modules/proj4/lib/projections/equi.js @@ -0,0 +1,48 @@ +import adjust_lon from '../common/adjust_lon'; + +export function init() { + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.lat0 = this.lat0 || 0; + this.long0 = this.long0 || 0; + ///this.t2; +} + +/* Equirectangular forward equations--mapping lat,long to x,y + ---------------------------------------------------------*/ +export function forward(p) { + + var lon = p.x; + var lat = p.y; + + var dlon = adjust_lon(lon - this.long0); + var x = this.x0 + this.a * dlon * Math.cos(this.lat0); + var y = this.y0 + this.a * lat; + + this.t1 = x; + this.t2 = Math.cos(this.lat0); + p.x = x; + p.y = y; + return p; +} + +/* Equirectangular inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ +export function inverse(p) { + + p.x -= this.x0; + p.y -= this.y0; + var lat = p.y / this.a; + + var lon = adjust_lon(this.long0 + p.x / (this.a * Math.cos(this.lat0))); + p.x = lon; + p.y = lat; +} + +export var names = ["equi"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/etmerc.js b/node_modules/proj4/lib/projections/etmerc.js new file mode 100644 index 0000000..cd0a9a3 --- /dev/null +++ b/node_modules/proj4/lib/projections/etmerc.js @@ -0,0 +1,172 @@ +// Heavily based on this etmerc projection implementation +// https://github.com/mbloch/mapshaper-proj/blob/master/src/projections/etmerc.js + +import tmerc from '../projections/tmerc'; +import sinh from '../common/sinh'; +import hypot from '../common/hypot'; +import asinhy from '../common/asinhy'; +import gatg from '../common/gatg'; +import clens from '../common/clens'; +import clens_cmplx from '../common/clens_cmplx'; +import adjust_lon from '../common/adjust_lon'; + +export function init() { + if (!this.approx && (isNaN(this.es) || this.es <= 0)) { + throw new Error('Incorrect elliptical usage. Try using the +approx option in the proj string, or PROJECTION["Fast_Transverse_Mercator"] in the WKT.'); + } + if (this.approx) { + // When '+approx' is set, use tmerc instead + tmerc.init.apply(this); + this.forward = tmerc.forward; + this.inverse = tmerc.inverse; + } + + this.x0 = this.x0 !== undefined ? this.x0 : 0; + this.y0 = this.y0 !== undefined ? this.y0 : 0; + this.long0 = this.long0 !== undefined ? this.long0 : 0; + this.lat0 = this.lat0 !== undefined ? this.lat0 : 0; + + this.cgb = []; + this.cbg = []; + this.utg = []; + this.gtu = []; + + var f = this.es / (1 + Math.sqrt(1 - this.es)); + var n = f / (2 - f); + var np = n; + + this.cgb[0] = n * (2 + n * (-2 / 3 + n * (-2 + n * (116 / 45 + n * (26 / 45 + n * (-2854 / 675 )))))); + this.cbg[0] = n * (-2 + n * ( 2 / 3 + n * ( 4 / 3 + n * (-82 / 45 + n * (32 / 45 + n * (4642 / 4725)))))); + + np = np * n; + this.cgb[1] = np * (7 / 3 + n * (-8 / 5 + n * (-227 / 45 + n * (2704 / 315 + n * (2323 / 945))))); + this.cbg[1] = np * (5 / 3 + n * (-16 / 15 + n * ( -13 / 9 + n * (904 / 315 + n * (-1522 / 945))))); + + np = np * n; + this.cgb[2] = np * (56 / 15 + n * (-136 / 35 + n * (-1262 / 105 + n * (73814 / 2835)))); + this.cbg[2] = np * (-26 / 15 + n * (34 / 21 + n * (8 / 5 + n * (-12686 / 2835)))); + + np = np * n; + this.cgb[3] = np * (4279 / 630 + n * (-332 / 35 + n * (-399572 / 14175))); + this.cbg[3] = np * (1237 / 630 + n * (-12 / 5 + n * ( -24832 / 14175))); + + np = np * n; + this.cgb[4] = np * (4174 / 315 + n * (-144838 / 6237)); + this.cbg[4] = np * (-734 / 315 + n * (109598 / 31185)); + + np = np * n; + this.cgb[5] = np * (601676 / 22275); + this.cbg[5] = np * (444337 / 155925); + + np = Math.pow(n, 2); + this.Qn = this.k0 / (1 + n) * (1 + np * (1 / 4 + np * (1 / 64 + np / 256))); + + this.utg[0] = n * (-0.5 + n * ( 2 / 3 + n * (-37 / 96 + n * ( 1 / 360 + n * (81 / 512 + n * (-96199 / 604800)))))); + this.gtu[0] = n * (0.5 + n * (-2 / 3 + n * (5 / 16 + n * (41 / 180 + n * (-127 / 288 + n * (7891 / 37800)))))); + + this.utg[1] = np * (-1 / 48 + n * (-1 / 15 + n * (437 / 1440 + n * (-46 / 105 + n * (1118711 / 3870720))))); + this.gtu[1] = np * (13 / 48 + n * (-3 / 5 + n * (557 / 1440 + n * (281 / 630 + n * (-1983433 / 1935360))))); + + np = np * n; + this.utg[2] = np * (-17 / 480 + n * (37 / 840 + n * (209 / 4480 + n * (-5569 / 90720 )))); + this.gtu[2] = np * (61 / 240 + n * (-103 / 140 + n * (15061 / 26880 + n * (167603 / 181440)))); + + np = np * n; + this.utg[3] = np * (-4397 / 161280 + n * (11 / 504 + n * (830251 / 7257600))); + this.gtu[3] = np * (49561 / 161280 + n * (-179 / 168 + n * (6601661 / 7257600))); + + np = np * n; + this.utg[4] = np * (-4583 / 161280 + n * (108847 / 3991680)); + this.gtu[4] = np * (34729 / 80640 + n * (-3418889 / 1995840)); + + np = np * n; + this.utg[5] = np * (-20648693 / 638668800); + this.gtu[5] = np * (212378941 / 319334400); + + var Z = gatg(this.cbg, this.lat0); + this.Zb = -this.Qn * (Z + clens(this.gtu, 2 * Z)); +} + +export function forward(p) { + var Ce = adjust_lon(p.x - this.long0); + var Cn = p.y; + + Cn = gatg(this.cbg, Cn); + var sin_Cn = Math.sin(Cn); + var cos_Cn = Math.cos(Cn); + var sin_Ce = Math.sin(Ce); + var cos_Ce = Math.cos(Ce); + + Cn = Math.atan2(sin_Cn, cos_Ce * cos_Cn); + Ce = Math.atan2(sin_Ce * cos_Cn, hypot(sin_Cn, cos_Cn * cos_Ce)); + Ce = asinhy(Math.tan(Ce)); + + var tmp = clens_cmplx(this.gtu, 2 * Cn, 2 * Ce); + + Cn = Cn + tmp[0]; + Ce = Ce + tmp[1]; + + var x; + var y; + + if (Math.abs(Ce) <= 2.623395162778) { + x = this.a * (this.Qn * Ce) + this.x0; + y = this.a * (this.Qn * Cn + this.Zb) + this.y0; + } + else { + x = Infinity; + y = Infinity; + } + + p.x = x; + p.y = y; + + return p; +} + +export function inverse(p) { + var Ce = (p.x - this.x0) * (1 / this.a); + var Cn = (p.y - this.y0) * (1 / this.a); + + Cn = (Cn - this.Zb) / this.Qn; + Ce = Ce / this.Qn; + + var lon; + var lat; + + if (Math.abs(Ce) <= 2.623395162778) { + var tmp = clens_cmplx(this.utg, 2 * Cn, 2 * Ce); + + Cn = Cn + tmp[0]; + Ce = Ce + tmp[1]; + Ce = Math.atan(sinh(Ce)); + + var sin_Cn = Math.sin(Cn); + var cos_Cn = Math.cos(Cn); + var sin_Ce = Math.sin(Ce); + var cos_Ce = Math.cos(Ce); + + Cn = Math.atan2(sin_Cn * cos_Ce, hypot(sin_Ce, cos_Ce * cos_Cn)); + Ce = Math.atan2(sin_Ce, cos_Ce * cos_Cn); + + lon = adjust_lon(Ce + this.long0); + lat = gatg(this.cgb, Cn); + } + else { + lon = Infinity; + lat = Infinity; + } + + p.x = lon; + p.y = lat; + + return p; +} + +export var names = ["Extended_Transverse_Mercator", "Extended Transverse Mercator", "etmerc", "Transverse_Mercator", "Transverse Mercator", "tmerc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/gauss.js b/node_modules/proj4/lib/projections/gauss.js new file mode 100644 index 0000000..df23797 --- /dev/null +++ b/node_modules/proj4/lib/projections/gauss.js @@ -0,0 +1,52 @@ +import srat from '../common/srat'; +var MAX_ITER = 20; +import {HALF_PI, FORTPI} from '../constants/values'; + +export function init() { + var sphi = Math.sin(this.lat0); + var cphi = Math.cos(this.lat0); + cphi *= cphi; + this.rc = Math.sqrt(1 - this.es) / (1 - this.es * sphi * sphi); + this.C = Math.sqrt(1 + this.es * cphi * cphi / (1 - this.es)); + this.phic0 = Math.asin(sphi / this.C); + this.ratexp = 0.5 * this.C * this.e; + this.K = Math.tan(0.5 * this.phic0 + FORTPI) / (Math.pow(Math.tan(0.5 * this.lat0 + FORTPI), this.C) * srat(this.e * sphi, this.ratexp)); +} + +export function forward(p) { + var lon = p.x; + var lat = p.y; + + p.y = 2 * Math.atan(this.K * Math.pow(Math.tan(0.5 * lat + FORTPI), this.C) * srat(this.e * Math.sin(lat), this.ratexp)) - HALF_PI; + p.x = this.C * lon; + return p; +} + +export function inverse(p) { + var DEL_TOL = 1e-14; + var lon = p.x / this.C; + var lat = p.y; + var num = Math.pow(Math.tan(0.5 * lat + FORTPI) / this.K, 1 / this.C); + for (var i = MAX_ITER; i > 0; --i) { + lat = 2 * Math.atan(num * srat(this.e * Math.sin(p.y), - 0.5 * this.e)) - HALF_PI; + if (Math.abs(lat - p.y) < DEL_TOL) { + break; + } + p.y = lat; + } + /* convergence failed */ + if (!i) { + return null; + } + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["gauss"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/geocent.js b/node_modules/proj4/lib/projections/geocent.js new file mode 100644 index 0000000..8ceadf8 --- /dev/null +++ b/node_modules/proj4/lib/projections/geocent.js @@ -0,0 +1,27 @@ +import { + geodeticToGeocentric, + geocentricToGeodetic +} from '../datumUtils'; + +export function init() { + this.name = 'geocent'; + +} + +export function forward(p) { + var point = geodeticToGeocentric(p, this.es, this.a); + return point; +} + +export function inverse(p) { + var point = geocentricToGeodetic(p, this.es, this.a, this.b); + return point; +} + +export var names = ["Geocentric", 'geocentric', "geocent", "Geocent"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; \ No newline at end of file diff --git a/node_modules/proj4/lib/projections/geos.js b/node_modules/proj4/lib/projections/geos.js new file mode 100644 index 0000000..9a44095 --- /dev/null +++ b/node_modules/proj4/lib/projections/geos.js @@ -0,0 +1,159 @@ +import hypot from '../common/hypot'; + +export function init() { + this.flip_axis = (this.sweep === 'x' ? 1 : 0); + this.h = Number(this.h); + this.radius_g_1 = this.h / this.a; + + if (this.radius_g_1 <= 0 || this.radius_g_1 > 1e10) { + throw new Error(); + } + + this.radius_g = 1.0 + this.radius_g_1; + this.C = this.radius_g * this.radius_g - 1.0; + + if (this.es !== 0.0) { + var one_es = 1.0 - this.es; + var rone_es = 1 / one_es; + + this.radius_p = Math.sqrt(one_es); + this.radius_p2 = one_es; + this.radius_p_inv2 = rone_es; + + this.shape = 'ellipse'; // Use as a condition in the forward and inverse functions. + } else { + this.radius_p = 1.0; + this.radius_p2 = 1.0; + this.radius_p_inv2 = 1.0; + + this.shape = 'sphere'; // Use as a condition in the forward and inverse functions. + } + + if (!this.title) { + this.title = "Geostationary Satellite View"; + } +} + +function forward(p) { + var lon = p.x; + var lat = p.y; + var tmp, v_x, v_y, v_z; + lon = lon - this.long0; + + if (this.shape === 'ellipse') { + lat = Math.atan(this.radius_p2 * Math.tan(lat)); + var r = this.radius_p / hypot(this.radius_p * Math.cos(lat), Math.sin(lat)); + + v_x = r * Math.cos(lon) * Math.cos(lat); + v_y = r * Math.sin(lon) * Math.cos(lat); + v_z = r * Math.sin(lat); + + if (((this.radius_g - v_x) * v_x - v_y * v_y - v_z * v_z * this.radius_p_inv2) < 0.0) { + p.x = Number.NaN; + p.y = Number.NaN; + return p; + } + + tmp = this.radius_g - v_x; + if (this.flip_axis) { + p.x = this.radius_g_1 * Math.atan(v_y / hypot(v_z, tmp)); + p.y = this.radius_g_1 * Math.atan(v_z / tmp); + } else { + p.x = this.radius_g_1 * Math.atan(v_y / tmp); + p.y = this.radius_g_1 * Math.atan(v_z / hypot(v_y, tmp)); + } + } else if (this.shape === 'sphere') { + tmp = Math.cos(lat); + v_x = Math.cos(lon) * tmp; + v_y = Math.sin(lon) * tmp; + v_z = Math.sin(lat); + tmp = this.radius_g - v_x; + + if (this.flip_axis) { + p.x = this.radius_g_1 * Math.atan(v_y / hypot(v_z, tmp)); + p.y = this.radius_g_1 * Math.atan(v_z / tmp); + } else { + p.x = this.radius_g_1 * Math.atan(v_y / tmp); + p.y = this.radius_g_1 * Math.atan(v_z / hypot(v_y, tmp)); + } + } + p.x = p.x * this.a; + p.y = p.y * this.a; + return p; +} + +function inverse(p) { + var v_x = -1.0; + var v_y = 0.0; + var v_z = 0.0; + var a, b, det, k; + + p.x = p.x / this.a; + p.y = p.y / this.a; + + if (this.shape === 'ellipse') { + if (this.flip_axis) { + v_z = Math.tan(p.y / this.radius_g_1); + v_y = Math.tan(p.x / this.radius_g_1) * hypot(1.0, v_z); + } else { + v_y = Math.tan(p.x / this.radius_g_1); + v_z = Math.tan(p.y / this.radius_g_1) * hypot(1.0, v_y); + } + + var v_zp = v_z / this.radius_p; + a = v_y * v_y + v_zp * v_zp + v_x * v_x; + b = 2 * this.radius_g * v_x; + det = (b * b) - 4 * a * this.C; + + if (det < 0.0) { + p.x = Number.NaN; + p.y = Number.NaN; + return p; + } + + k = (-b - Math.sqrt(det)) / (2.0 * a); + v_x = this.radius_g + k * v_x; + v_y *= k; + v_z *= k; + + p.x = Math.atan2(v_y, v_x); + p.y = Math.atan(v_z * Math.cos(p.x) / v_x); + p.y = Math.atan(this.radius_p_inv2 * Math.tan(p.y)); + } else if (this.shape === 'sphere') { + if (this.flip_axis) { + v_z = Math.tan(p.y / this.radius_g_1); + v_y = Math.tan(p.x / this.radius_g_1) * Math.sqrt(1.0 + v_z * v_z); + } else { + v_y = Math.tan(p.x / this.radius_g_1); + v_z = Math.tan(p.y / this.radius_g_1) * Math.sqrt(1.0 + v_y * v_y); + } + + a = v_y * v_y + v_z * v_z + v_x * v_x; + b = 2 * this.radius_g * v_x; + det = (b * b) - 4 * a * this.C; + if (det < 0.0) { + p.x = Number.NaN; + p.y = Number.NaN; + return p; + } + + k = (-b - Math.sqrt(det)) / (2.0 * a); + v_x = this.radius_g + k * v_x; + v_y *= k; + v_z *= k; + + p.x = Math.atan2(v_y, v_x); + p.y = Math.atan(v_z * Math.cos(p.x) / v_x); + } + p.x = p.x + this.long0; + return p; +} + +export var names = ["Geostationary Satellite View", "Geostationary_Satellite", "geos"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names, +}; + diff --git a/node_modules/proj4/lib/projections/gnom.js b/node_modules/proj4/lib/projections/gnom.js new file mode 100644 index 0000000..066cff8 --- /dev/null +++ b/node_modules/proj4/lib/projections/gnom.js @@ -0,0 +1,104 @@ +import adjust_lon from '../common/adjust_lon'; +import asinz from '../common/asinz'; +import {EPSLN} from '../constants/values'; + +/* + reference: + Wolfram Mathworld "Gnomonic Projection" + http://mathworld.wolfram.com/GnomonicProjection.html + Accessed: 12th November 2009 + */ +export function init() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14 = Math.sin(this.lat0); + this.cos_p14 = Math.cos(this.lat0); + // Approximation for projecting points to the horizon (infinity) + this.infinity_dist = 1000 * this.a; + this.rc = 1; +} + +/* Gnomonic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ +export function forward(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + dlon = adjust_lon(lon - this.long0); + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1; + if ((g > 0) || (Math.abs(g) <= EPSLN)) { + x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g; + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g; + } + else { + + // Point is in the opposing hemisphere and is unprojectable + // We still need to return a reasonable point, so we project + // to infinity, on a bearing + // equivalent to the northern hemisphere equivalent + // This is a reasonable approximation for short shapes and lines that + // straddle the horizon. + + x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon); + y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + + } + p.x = x; + p.y = y; + return p; +} + +export function inverse(p) { + var rh; /* Rho */ + var sinc, cosc; + var c; + var lon, lat; + + /* Inverse equations + -----------------*/ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + + if ((rh = Math.sqrt(p.x * p.x + p.y * p.y))) { + c = Math.atan2(rh, this.rc); + sinc = Math.sin(c); + cosc = Math.cos(c); + + lat = asinz(cosc * this.sin_p14 + (p.y * sinc * this.cos_p14) / rh); + lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc); + lon = adjust_lon(this.long0 + lon); + } + else { + lat = this.phic0; + lon = 0; + } + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["gnom"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/gstmerc.js b/node_modules/proj4/lib/projections/gstmerc.js new file mode 100644 index 0000000..763dc68 --- /dev/null +++ b/node_modules/proj4/lib/projections/gstmerc.js @@ -0,0 +1,63 @@ +import latiso from '../common/latiso'; +import sinh from '../common/sinh'; +import cosh from '../common/cosh'; +import invlatiso from '../common/invlatiso'; + +export function init() { + + // array of: a, b, lon0, lat0, k0, x0, y0 + var temp = this.b / this.a; + this.e = Math.sqrt(1 - temp * temp); + this.lc = this.long0; + this.rs = Math.sqrt(1 + this.e * this.e * Math.pow(Math.cos(this.lat0), 4) / (1 - this.e * this.e)); + var sinz = Math.sin(this.lat0); + var pc = Math.asin(sinz / this.rs); + var sinzpc = Math.sin(pc); + this.cp = latiso(0, pc, sinzpc) - this.rs * latiso(this.e, this.lat0, sinz); + this.n2 = this.k0 * this.a * Math.sqrt(1 - this.e * this.e) / (1 - this.e * this.e * sinz * sinz); + this.xs = this.x0; + this.ys = this.y0 - this.n2 * pc; + + if (!this.title) { + this.title = "Gauss Schreiber transverse mercator"; + } +} + +// forward equations--mapping lat,long to x,y +// ----------------------------------------------------------------- +export function forward(p) { + + var lon = p.x; + var lat = p.y; + + var L = this.rs * (lon - this.lc); + var Ls = this.cp + (this.rs * latiso(this.e, lat, Math.sin(lat))); + var lat1 = Math.asin(Math.sin(L) / cosh(Ls)); + var Ls1 = latiso(0, lat1, Math.sin(lat1)); + p.x = this.xs + (this.n2 * Ls1); + p.y = this.ys + (this.n2 * Math.atan(sinh(Ls) / Math.cos(L))); + return p; +} + +// inverse equations--mapping x,y to lat/long +// ----------------------------------------------------------------- +export function inverse(p) { + + var x = p.x; + var y = p.y; + + var L = Math.atan(sinh((x - this.xs) / this.n2) / Math.cos((y - this.ys) / this.n2)); + var lat1 = Math.asin(Math.sin((y - this.ys) / this.n2) / cosh((x - this.xs) / this.n2)); + var LC = latiso(0, lat1, Math.sin(lat1)); + p.x = this.lc + L / this.rs; + p.y = invlatiso(this.e, (LC - this.cp) / this.rs); + return p; +} + +export var names = ["gstmerg", "gstmerc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/krovak.js b/node_modules/proj4/lib/projections/krovak.js new file mode 100644 index 0000000..620cf7d --- /dev/null +++ b/node_modules/proj4/lib/projections/krovak.js @@ -0,0 +1,106 @@ +import adjust_lon from '../common/adjust_lon'; + +export function init() { + this.a = 6377397.155; + this.es = 0.006674372230614; + this.e = Math.sqrt(this.es); + if (!this.lat0) { + this.lat0 = 0.863937979737193; + } + if (!this.long0) { + this.long0 = 0.7417649320975901 - 0.308341501185665; + } + /* if scale not set default to 0.9999 */ + if (!this.k0) { + this.k0 = 0.9999; + } + this.s45 = 0.785398163397448; /* 45 */ + this.s90 = 2 * this.s45; + this.fi0 = this.lat0; + this.e2 = this.es; + this.e = Math.sqrt(this.e2); + this.alfa = Math.sqrt(1 + (this.e2 * Math.pow(Math.cos(this.fi0), 4)) / (1 - this.e2)); + this.uq = 1.04216856380474; + this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa); + this.g = Math.pow((1 + this.e * Math.sin(this.fi0)) / (1 - this.e * Math.sin(this.fi0)), this.alfa * this.e / 2); + this.k = Math.tan(this.u0 / 2 + this.s45) / Math.pow(Math.tan(this.fi0 / 2 + this.s45), this.alfa) * this.g; + this.k1 = this.k0; + this.n0 = this.a * Math.sqrt(1 - this.e2) / (1 - this.e2 * Math.pow(Math.sin(this.fi0), 2)); + this.s0 = 1.37008346281555; + this.n = Math.sin(this.s0); + this.ro0 = this.k1 * this.n0 / Math.tan(this.s0); + this.ad = this.s90 - this.uq; +} + +/* ellipsoid */ +/* calculate xy from lat/lon */ +/* Constants, identical to inverse transform function */ +export function forward(p) { + var gfi, u, deltav, s, d, eps, ro; + var lon = p.x; + var lat = p.y; + var delta_lon = adjust_lon(lon - this.long0); + /* Transformation */ + gfi = Math.pow(((1 + this.e * Math.sin(lat)) / (1 - this.e * Math.sin(lat))), (this.alfa * this.e / 2)); + u = 2 * (Math.atan(this.k * Math.pow(Math.tan(lat / 2 + this.s45), this.alfa) / gfi) - this.s45); + deltav = -delta_lon * this.alfa; + s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav)); + d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s)); + eps = this.n * d; + ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2 + this.s45), this.n) / Math.pow(Math.tan(s / 2 + this.s45), this.n); + p.y = ro * Math.cos(eps) / 1; + p.x = ro * Math.sin(eps) / 1; + + if (!this.czech) { + p.y *= -1; + p.x *= -1; + } + return (p); +} + +/* calculate lat/lon from xy */ +export function inverse(p) { + var u, deltav, s, d, eps, ro, fi1; + var ok; + + /* Transformation */ + /* revert y, x*/ + var tmp = p.x; + p.x = p.y; + p.y = tmp; + if (!this.czech) { + p.y *= -1; + p.x *= -1; + } + ro = Math.sqrt(p.x * p.x + p.y * p.y); + eps = Math.atan2(p.y, p.x); + d = eps / Math.sin(this.s0); + s = 2 * (Math.atan(Math.pow(this.ro0 / ro, 1 / this.n) * Math.tan(this.s0 / 2 + this.s45)) - this.s45); + u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d)); + deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u)); + p.x = this.long0 - deltav / this.alfa; + fi1 = u; + ok = 0; + var iter = 0; + do { + p.y = 2 * (Math.atan(Math.pow(this.k, - 1 / this.alfa) * Math.pow(Math.tan(u / 2 + this.s45), 1 / this.alfa) * Math.pow((1 + this.e * Math.sin(fi1)) / (1 - this.e * Math.sin(fi1)), this.e / 2)) - this.s45); + if (Math.abs(fi1 - p.y) < 0.0000000001) { + ok = 1; + } + fi1 = p.y; + iter += 1; + } while (ok === 0 && iter < 15); + if (iter >= 15) { + return null; + } + + return (p); +} + +export var names = ["Krovak", "krovak"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/laea.js b/node_modules/proj4/lib/projections/laea.js new file mode 100644 index 0000000..b3f6a51 --- /dev/null +++ b/node_modules/proj4/lib/projections/laea.js @@ -0,0 +1,298 @@ + +import {HALF_PI, EPSLN, FORTPI} from '../constants/values'; + +import qsfnz from '../common/qsfnz'; +import adjust_lon from '../common/adjust_lon'; + +/* + reference + "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + */ + +export var S_POLE = 1; + +export var N_POLE = 2; +export var EQUIT = 3; +export var OBLIQ = 4; + +/* Initialize the Lambert Azimuthal Equal Area projection + ------------------------------------------------------*/ +export function init() { + var t = Math.abs(this.lat0); + if (Math.abs(t - HALF_PI) < EPSLN) { + this.mode = this.lat0 < 0 ? this.S_POLE : this.N_POLE; + } + else if (Math.abs(t) < EPSLN) { + this.mode = this.EQUIT; + } + else { + this.mode = this.OBLIQ; + } + if (this.es > 0) { + var sinphi; + + this.qp = qsfnz(this.e, 1); + this.mmf = 0.5 / (1 - this.es); + this.apa = authset(this.es); + switch (this.mode) { + case this.N_POLE: + this.dd = 1; + break; + case this.S_POLE: + this.dd = 1; + break; + case this.EQUIT: + this.rq = Math.sqrt(0.5 * this.qp); + this.dd = 1 / this.rq; + this.xmf = 1; + this.ymf = 0.5 * this.qp; + break; + case this.OBLIQ: + this.rq = Math.sqrt(0.5 * this.qp); + sinphi = Math.sin(this.lat0); + this.sinb1 = qsfnz(this.e, sinphi) / this.qp; + this.cosb1 = Math.sqrt(1 - this.sinb1 * this.sinb1); + this.dd = Math.cos(this.lat0) / (Math.sqrt(1 - this.es * sinphi * sinphi) * this.rq * this.cosb1); + this.ymf = (this.xmf = this.rq) / this.dd; + this.xmf *= this.dd; + break; + } + } + else { + if (this.mode === this.OBLIQ) { + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + } +} + +/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ +export function forward(p) { + + /* Forward equations + -----------------*/ + var x, y, coslam, sinlam, sinphi, q, sinb, cosb, b, cosphi; + var lam = p.x; + var phi = p.y; + + lam = adjust_lon(lam - this.long0); + if (this.sphere) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + coslam = Math.cos(lam); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + y = (this.mode === this.EQUIT) ? 1 + cosphi * coslam : 1 + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= EPSLN) { + return null; + } + y = Math.sqrt(2 / y); + x = y * cosphi * Math.sin(lam); + y *= (this.mode === this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + } + else if (this.mode === this.N_POLE || this.mode === this.S_POLE) { + if (this.mode === this.N_POLE) { + coslam = -coslam; + } + if (Math.abs(phi + this.lat0) < EPSLN) { + return null; + } + y = FORTPI - phi * 0.5; + y = 2 * ((this.mode === this.S_POLE) ? Math.cos(y) : Math.sin(y)); + x = y * Math.sin(lam); + y *= coslam; + } + } + else { + sinb = 0; + cosb = 0; + b = 0; + coslam = Math.cos(lam); + sinlam = Math.sin(lam); + sinphi = Math.sin(phi); + q = qsfnz(this.e, sinphi); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + sinb = q / this.qp; + cosb = Math.sqrt(1 - sinb * sinb); + } + switch (this.mode) { + case this.OBLIQ: + b = 1 + this.sinb1 * sinb + this.cosb1 * cosb * coslam; + break; + case this.EQUIT: + b = 1 + cosb * coslam; + break; + case this.N_POLE: + b = HALF_PI + phi; + q = this.qp - q; + break; + case this.S_POLE: + b = phi - HALF_PI; + q = this.qp + q; + break; + } + if (Math.abs(b) < EPSLN) { + return null; + } + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + b = Math.sqrt(2 / b); + if (this.mode === this.OBLIQ) { + y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam); + } + else { + y = (b = Math.sqrt(2 / (1 + cosb * coslam))) * sinb * this.ymf; + } + x = this.xmf * b * cosb * sinlam; + break; + case this.N_POLE: + case this.S_POLE: + if (q >= 0) { + x = (b = Math.sqrt(q)) * sinlam; + y = coslam * ((this.mode === this.S_POLE) ? b : -b); + } + else { + x = y = 0; + } + break; + } + } + + p.x = this.a * x + this.x0; + p.y = this.a * y + this.y0; + return p; +} + +/* Inverse equations + -----------------*/ +export function inverse(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x / this.a; + var y = p.y / this.a; + var lam, phi, cCe, sCe, q, rho, ab; + if (this.sphere) { + var cosz = 0, + rh, sinz = 0; + + rh = Math.sqrt(x * x + y * y); + phi = rh * 0.5; + if (phi > 1) { + return null; + } + phi = 2 * Math.asin(phi); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + sinz = Math.sin(phi); + cosz = Math.cos(phi); + } + switch (this.mode) { + case this.EQUIT: + phi = (Math.abs(rh) <= EPSLN) ? 0 : Math.asin(y * sinz / rh); + x *= sinz; + y = cosz * rh; + break; + case this.OBLIQ: + phi = (Math.abs(rh) <= EPSLN) ? this.lat0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh); + x *= sinz * this.cosph0; + y = (cosz - Math.sin(phi) * this.sinph0) * rh; + break; + case this.N_POLE: + y = -y; + phi = HALF_PI - phi; + break; + case this.S_POLE: + phi -= HALF_PI; + break; + } + lam = (y === 0 && (this.mode === this.EQUIT || this.mode === this.OBLIQ)) ? 0 : Math.atan2(x, y); + } + else { + ab = 0; + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + x /= this.dd; + y *= this.dd; + rho = Math.sqrt(x * x + y * y); + if (rho < EPSLN) { + p.x = this.long0; + p.y = this.lat0; + return p; + } + sCe = 2 * Math.asin(0.5 * rho / this.rq); + cCe = Math.cos(sCe); + x *= (sCe = Math.sin(sCe)); + if (this.mode === this.OBLIQ) { + ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho; + q = this.qp * ab; + y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe; + } + else { + ab = y * sCe / rho; + q = this.qp * ab; + y = rho * cCe; + } + } + else if (this.mode === this.N_POLE || this.mode === this.S_POLE) { + if (this.mode === this.N_POLE) { + y = -y; + } + q = (x * x + y * y); + if (!q) { + p.x = this.long0; + p.y = this.lat0; + return p; + } + ab = 1 - q / this.qp; + if (this.mode === this.S_POLE) { + ab = -ab; + } + } + lam = Math.atan2(x, y); + phi = authlat(Math.asin(ab), this.apa); + } + + p.x = adjust_lon(this.long0 + lam); + p.y = phi; + return p; +} + +/* determine latitude from authalic latitude */ +var P00 = 0.33333333333333333333; + +var P01 = 0.17222222222222222222; +var P02 = 0.10257936507936507936; +var P10 = 0.06388888888888888888; +var P11 = 0.06640211640211640211; +var P20 = 0.01641501294219154443; + +function authset(es) { + var t; + var APA = []; + APA[0] = es * P00; + t = es * es; + APA[0] += t * P01; + APA[1] = t * P10; + t *= es; + APA[0] += t * P02; + APA[1] += t * P11; + APA[2] = t * P20; + return APA; +} + +function authlat(beta, APA) { + var t = beta + beta; + return (beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t + t) + APA[2] * Math.sin(t + t + t)); +} + +export var names = ["Lambert Azimuthal Equal Area", "Lambert_Azimuthal_Equal_Area", "laea"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names, + S_POLE: S_POLE, + N_POLE: N_POLE, + EQUIT: EQUIT, + OBLIQ: OBLIQ +}; diff --git a/node_modules/proj4/lib/projections/lcc.js b/node_modules/proj4/lib/projections/lcc.js new file mode 100644 index 0000000..bb92b3f --- /dev/null +++ b/node_modules/proj4/lib/projections/lcc.js @@ -0,0 +1,150 @@ +import msfnz from '../common/msfnz'; +import tsfnz from '../common/tsfnz'; +import sign from '../common/sign'; +import adjust_lon from '../common/adjust_lon'; +import phi2z from '../common/phi2z'; +import {HALF_PI, EPSLN} from '../constants/values'; +export function init() { + + //double lat0; /* the reference latitude */ + //double long0; /* the reference longitude */ + //double lat1; /* first standard parallel */ + //double lat2; /* second standard parallel */ + //double r_maj; /* major axis */ + //double r_min; /* minor axis */ + //double false_east; /* x offset in meters */ + //double false_north; /* y offset in meters */ + + //the above value can be set with proj4.defs + //example: proj4.defs("EPSG:2154","+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"); + + if (!this.lat2) { + this.lat2 = this.lat1; + } //if lat2 is not defined + if (!this.k0) { + this.k0 = 1; + } + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + + var temp = this.b / this.a; + this.e = Math.sqrt(1 - temp * temp); + + var sin1 = Math.sin(this.lat1); + var cos1 = Math.cos(this.lat1); + var ms1 = msfnz(this.e, sin1, cos1); + var ts1 = tsfnz(this.e, this.lat1, sin1); + + var sin2 = Math.sin(this.lat2); + var cos2 = Math.cos(this.lat2); + var ms2 = msfnz(this.e, sin2, cos2); + var ts2 = tsfnz(this.e, this.lat2, sin2); + + var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0)); + + if (Math.abs(this.lat1 - this.lat2) > EPSLN) { + this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2); + } + else { + this.ns = sin1; + } + if (isNaN(this.ns)) { + this.ns = sin1; + } + this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns)); + this.rh = this.a * this.f0 * Math.pow(ts0, this.ns); + if (!this.title) { + this.title = "Lambert Conformal Conic"; + } +} + +// Lambert Conformal conic forward equations--mapping lat,long to x,y +// ----------------------------------------------------------------- +export function forward(p) { + + var lon = p.x; + var lat = p.y; + + // singular cases : + if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) { + lat = sign(lat) * (HALF_PI - 2 * EPSLN); + } + + var con = Math.abs(Math.abs(lat) - HALF_PI); + var ts, rh1; + if (con > EPSLN) { + ts = tsfnz(this.e, lat, Math.sin(lat)); + rh1 = this.a * this.f0 * Math.pow(ts, this.ns); + } + else { + con = lat * this.ns; + if (con <= 0) { + return null; + } + rh1 = 0; + } + var theta = this.ns * adjust_lon(lon - this.long0); + p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0; + p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0; + + return p; +} + +// Lambert Conformal Conic inverse equations--mapping x,y to lat/long +// ----------------------------------------------------------------- +export function inverse(p) { + + var rh1, con, ts; + var lat, lon; + var x = (p.x - this.x0) / this.k0; + var y = (this.rh - (p.y - this.y0) / this.k0); + if (this.ns > 0) { + rh1 = Math.sqrt(x * x + y * y); + con = 1; + } + else { + rh1 = -Math.sqrt(x * x + y * y); + con = -1; + } + var theta = 0; + if (rh1 !== 0) { + theta = Math.atan2((con * x), (con * y)); + } + if ((rh1 !== 0) || (this.ns > 0)) { + con = 1 / this.ns; + ts = Math.pow((rh1 / (this.a * this.f0)), con); + lat = phi2z(this.e, ts); + if (lat === -9999) { + return null; + } + } + else { + lat = -HALF_PI; + } + lon = adjust_lon(theta / this.ns + this.long0); + + p.x = lon; + p.y = lat; + return p; +} + +export var names = [ + "Lambert Tangential Conformal Conic Projection", + "Lambert_Conformal_Conic", + "Lambert_Conformal_Conic_1SP", + "Lambert_Conformal_Conic_2SP", + "lcc", + "Lambert Conic Conformal (1SP)", + "Lambert Conic Conformal (2SP)" +]; + +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/longlat.js b/node_modules/proj4/lib/projections/longlat.js new file mode 100644 index 0000000..7e66e7d --- /dev/null +++ b/node_modules/proj4/lib/projections/longlat.js @@ -0,0 +1,16 @@ +export function init() { + //no-op for longlat +} + +function identity(pt) { + return pt; +} +export {identity as forward}; +export {identity as inverse}; +export var names = ["longlat", "identity"]; +export default { + init: init, + forward: identity, + inverse: identity, + names: names +}; diff --git a/node_modules/proj4/lib/projections/merc.js b/node_modules/proj4/lib/projections/merc.js new file mode 100644 index 0000000..31ca6c0 --- /dev/null +++ b/node_modules/proj4/lib/projections/merc.js @@ -0,0 +1,100 @@ +import msfnz from '../common/msfnz'; + +import adjust_lon from '../common/adjust_lon'; +import tsfnz from '../common/tsfnz'; +import phi2z from '../common/phi2z'; +import {FORTPI, R2D, EPSLN, HALF_PI} from '../constants/values'; +export function init() { + var con = this.b / this.a; + this.es = 1 - con * con; + if(!('x0' in this)){ + this.x0 = 0; + } + if(!('y0' in this)){ + this.y0 = 0; + } + this.e = Math.sqrt(this.es); + if (this.lat_ts) { + if (this.sphere) { + this.k0 = Math.cos(this.lat_ts); + } + else { + this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } + } + else { + if (!this.k0) { + if (this.k) { + this.k0 = this.k; + } + else { + this.k0 = 1; + } + } + } +} + +/* Mercator forward equations--mapping lat,long to x,y + --------------------------------------------------*/ + +export function forward(p) { + var lon = p.x; + var lat = p.y; + // convert to radians + if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) { + return null; + } + + var x, y; + if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) { + return null; + } + else { + if (this.sphere) { + x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0); + y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat)); + } + else { + var sinphi = Math.sin(lat); + var ts = tsfnz(this.e, lat, sinphi); + x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0); + y = this.y0 - this.a * this.k0 * Math.log(ts); + } + p.x = x; + p.y = y; + return p; + } +} + +/* Mercator inverse equations--mapping x,y to lat/long + --------------------------------------------------*/ +export function inverse(p) { + + var x = p.x - this.x0; + var y = p.y - this.y0; + var lon, lat; + + if (this.sphere) { + lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0))); + } + else { + var ts = Math.exp(-y / (this.a * this.k0)); + lat = phi2z(this.e, ts); + if (lat === -9999) { + return null; + } + } + lon = adjust_lon(this.long0 + x / (this.a * this.k0)); + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["Mercator", "Popular Visualisation Pseudo Mercator", "Mercator_1SP", "Mercator_Auxiliary_Sphere", "merc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/mill.js b/node_modules/proj4/lib/projections/mill.js new file mode 100644 index 0000000..3d6ff0d --- /dev/null +++ b/node_modules/proj4/lib/projections/mill.js @@ -0,0 +1,52 @@ +import adjust_lon from '../common/adjust_lon'; + +/* + reference + "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + */ + + +/* Initialize the Miller Cylindrical projection + -------------------------------------------*/ +export function init() { + //no-op +} + +/* Miller Cylindrical forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ +export function forward(p) { + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + var x = this.x0 + this.a * dlon; + var y = this.y0 + this.a * Math.log(Math.tan((Math.PI / 4) + (lat / 2.5))) * 1.25; + + p.x = x; + p.y = y; + return p; +} + +/* Miller Cylindrical inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ +export function inverse(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = adjust_lon(this.long0 + p.x / this.a); + var lat = 2.5 * (Math.atan(Math.exp(0.8 * p.y / this.a)) - Math.PI / 4); + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["Miller_Cylindrical", "mill"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/moll.js b/node_modules/proj4/lib/projections/moll.js new file mode 100644 index 0000000..faa2e51 --- /dev/null +++ b/node_modules/proj4/lib/projections/moll.js @@ -0,0 +1,83 @@ +import adjust_lon from '../common/adjust_lon'; +export function init() {} +import {EPSLN} from '../constants/values'; +/* Mollweide forward equations--mapping lat,long to x,y + ----------------------------------------------------*/ +export function forward(p) { + + /* Forward equations + -----------------*/ + var lon = p.x; + var lat = p.y; + + var delta_lon = adjust_lon(lon - this.long0); + var theta = lat; + var con = Math.PI * Math.sin(lat); + + /* Iterate using the Newton-Raphson method to find theta + -----------------------------------------------------*/ + while (true) { + var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta)); + theta += delta_theta; + if (Math.abs(delta_theta) < EPSLN) { + break; + } + } + theta /= 2; + + /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting" + this is done here because of precision problems with "cos(theta)" + --------------------------------------------------------------------------*/ + if (Math.PI / 2 - Math.abs(lat) < EPSLN) { + delta_lon = 0; + } + var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0; + var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0; + + p.x = x; + p.y = y; + return p; +} + +export function inverse(p) { + var theta; + var arg; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + arg = p.y / (1.4142135623731 * this.a); + + /* Because of division by zero problems, 'arg' can not be 1. Therefore + a number very close to one is used instead. + -------------------------------------------------------------------*/ + if (Math.abs(arg) > 0.999999999999) { + arg = 0.999999999999; + } + theta = Math.asin(arg); + var lon = adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta)))); + if (lon < (-Math.PI)) { + lon = -Math.PI; + } + if (lon > Math.PI) { + lon = Math.PI; + } + arg = (2 * theta + Math.sin(2 * theta)) / Math.PI; + if (Math.abs(arg) > 1) { + arg = 1; + } + var lat = Math.asin(arg); + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["Mollweide", "moll"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/nzmg.js b/node_modules/proj4/lib/projections/nzmg.js new file mode 100644 index 0000000..be0741d --- /dev/null +++ b/node_modules/proj4/lib/projections/nzmg.js @@ -0,0 +1,226 @@ +import {SEC_TO_RAD} from '../constants/values'; + +/* + reference + Department of Land and Survey Technical Circular 1973/32 + http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf + OSG Technical Report 4.1 + http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf + */ + +/** + * iterations: Number of iterations to refine inverse transform. + * 0 -> km accuracy + * 1 -> m accuracy -- suitable for most mapping applications + * 2 -> mm accuracy + */ +export var iterations = 1; + +export function init() { + this.A = []; + this.A[1] = 0.6399175073; + this.A[2] = -0.1358797613; + this.A[3] = 0.063294409; + this.A[4] = -0.02526853; + this.A[5] = 0.0117879; + this.A[6] = -0.0055161; + this.A[7] = 0.0026906; + this.A[8] = -0.001333; + this.A[9] = 0.00067; + this.A[10] = -0.00034; + + this.B_re = []; + this.B_im = []; + this.B_re[1] = 0.7557853228; + this.B_im[1] = 0; + this.B_re[2] = 0.249204646; + this.B_im[2] = 0.003371507; + this.B_re[3] = -0.001541739; + this.B_im[3] = 0.041058560; + this.B_re[4] = -0.10162907; + this.B_im[4] = 0.01727609; + this.B_re[5] = -0.26623489; + this.B_im[5] = -0.36249218; + this.B_re[6] = -0.6870983; + this.B_im[6] = -1.1651967; + + this.C_re = []; + this.C_im = []; + this.C_re[1] = 1.3231270439; + this.C_im[1] = 0; + this.C_re[2] = -0.577245789; + this.C_im[2] = -0.007809598; + this.C_re[3] = 0.508307513; + this.C_im[3] = -0.112208952; + this.C_re[4] = -0.15094762; + this.C_im[4] = 0.18200602; + this.C_re[5] = 1.01418179; + this.C_im[5] = 1.64497696; + this.C_re[6] = 1.9660549; + this.C_im[6] = 2.5127645; + + this.D = []; + this.D[1] = 1.5627014243; + this.D[2] = 0.5185406398; + this.D[3] = -0.03333098; + this.D[4] = -0.1052906; + this.D[5] = -0.0368594; + this.D[6] = 0.007317; + this.D[7] = 0.01220; + this.D[8] = 0.00394; + this.D[9] = -0.0013; +} + +/** + New Zealand Map Grid Forward - long/lat to x/y + long/lat in radians + */ +export function forward(p) { + var n; + var lon = p.x; + var lat = p.y; + + var delta_lat = lat - this.lat0; + var delta_lon = lon - this.long0; + + // 1. Calculate d_phi and d_psi ... // and d_lambda + // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians. + var d_phi = delta_lat / SEC_TO_RAD * 1E-5; + var d_lambda = delta_lon; + var d_phi_n = 1; // d_phi^0 + + var d_psi = 0; + for (n = 1; n <= 10; n++) { + d_phi_n = d_phi_n * d_phi; + d_psi = d_psi + this.A[n] * d_phi_n; + } + + // 2. Calculate theta + var th_re = d_psi; + var th_im = d_lambda; + + // 3. Calculate z + var th_n_re = 1; + var th_n_im = 0; // theta^0 + var th_n_re1; + var th_n_im1; + + var z_re = 0; + var z_im = 0; + for (n = 1; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + z_re = z_re + this.B_re[n] * th_n_re - this.B_im[n] * th_n_im; + z_im = z_im + this.B_im[n] * th_n_re + this.B_re[n] * th_n_im; + } + + // 4. Calculate easting and northing + p.x = (z_im * this.a) + this.x0; + p.y = (z_re * this.a) + this.y0; + + return p; +} + +/** + New Zealand Map Grid Inverse - x/y to long/lat + */ +export function inverse(p) { + var n; + var x = p.x; + var y = p.y; + + var delta_x = x - this.x0; + var delta_y = y - this.y0; + + // 1. Calculate z + var z_re = delta_y / this.a; + var z_im = delta_x / this.a; + + // 2a. Calculate theta - first approximation gives km accuracy + var z_n_re = 1; + var z_n_im = 0; // z^0 + var z_n_re1; + var z_n_im1; + + var th_re = 0; + var th_im = 0; + for (n = 1; n <= 6; n++) { + z_n_re1 = z_n_re * z_re - z_n_im * z_im; + z_n_im1 = z_n_im * z_re + z_n_re * z_im; + z_n_re = z_n_re1; + z_n_im = z_n_im1; + th_re = th_re + this.C_re[n] * z_n_re - this.C_im[n] * z_n_im; + th_im = th_im + this.C_im[n] * z_n_re + this.C_re[n] * z_n_im; + } + + // 2b. Iterate to refine the accuracy of the calculation + // 0 iterations gives km accuracy + // 1 iteration gives m accuracy -- good enough for most mapping applications + // 2 iterations bives mm accuracy + for (var i = 0; i < this.iterations; i++) { + var th_n_re = th_re; + var th_n_im = th_im; + var th_n_re1; + var th_n_im1; + + var num_re = z_re; + var num_im = z_im; + for (n = 2; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + num_re = num_re + (n - 1) * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im); + num_im = num_im + (n - 1) * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im); + } + + th_n_re = 1; + th_n_im = 0; + var den_re = this.B_re[1]; + var den_im = this.B_im[1]; + for (n = 2; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + den_re = den_re + n * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im); + den_im = den_im + n * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im); + } + + // Complex division + var den2 = den_re * den_re + den_im * den_im; + th_re = (num_re * den_re + num_im * den_im) / den2; + th_im = (num_im * den_re - num_re * den_im) / den2; + } + + // 3. Calculate d_phi ... // and d_lambda + var d_psi = th_re; + var d_lambda = th_im; + var d_psi_n = 1; // d_psi^0 + + var d_phi = 0; + for (n = 1; n <= 9; n++) { + d_psi_n = d_psi_n * d_psi; + d_phi = d_phi + this.D[n] * d_psi_n; + } + + // 4. Calculate latitude and longitude + // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians. + var lat = this.lat0 + (d_phi * SEC_TO_RAD * 1E5); + var lon = this.long0 + d_lambda; + + p.x = lon; + p.y = lat; + + return p; +} + +export var names = ["New_Zealand_Map_Grid", "nzmg"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/omerc.js b/node_modules/proj4/lib/projections/omerc.js new file mode 100644 index 0000000..7c47e3e --- /dev/null +++ b/node_modules/proj4/lib/projections/omerc.js @@ -0,0 +1,241 @@ +import tsfnz from '../common/tsfnz'; +import adjust_lon from '../common/adjust_lon'; +import phi2z from '../common/phi2z'; +import { D2R, EPSLN, HALF_PI, TWO_PI, FORTPI } from '../constants/values'; + +var TOL = 1e-7; + +function isTypeA(P) { + var typeAProjections = ['Hotine_Oblique_Mercator','Hotine_Oblique_Mercator_Azimuth_Natural_Origin']; + var projectionName = typeof P.PROJECTION === "object" ? Object.keys(P.PROJECTION)[0] : P.PROJECTION; + + return 'no_uoff' in P || 'no_off' in P || typeAProjections.indexOf(projectionName) !== -1; +} + + +/* Initialize the Oblique Mercator projection + ------------------------------------------*/ +export function init() { + var con, com, cosph0, D, F, H, L, sinph0, p, J, gamma = 0, + gamma0, lamc = 0, lam1 = 0, lam2 = 0, phi1 = 0, phi2 = 0, alpha_c = 0, AB; + + // only Type A uses the no_off or no_uoff property + // https://github.com/OSGeo/proj.4/issues/104 + this.no_off = isTypeA(this); + this.no_rot = 'no_rot' in this; + + var alp = false; + if ("alpha" in this) { + alp = true; + } + + var gam = false; + if ("rectified_grid_angle" in this) { + gam = true; + } + + if (alp) { + alpha_c = this.alpha; + } + + if (gam) { + gamma = (this.rectified_grid_angle * D2R); + } + + if (alp || gam) { + lamc = this.longc; + } else { + lam1 = this.long1; + phi1 = this.lat1; + lam2 = this.long2; + phi2 = this.lat2; + + if (Math.abs(phi1 - phi2) <= TOL || (con = Math.abs(phi1)) <= TOL || + Math.abs(con - HALF_PI) <= TOL || Math.abs(Math.abs(this.lat0) - HALF_PI) <= TOL || + Math.abs(Math.abs(phi2) - HALF_PI) <= TOL) { + throw new Error(); + } + } + + var one_es = 1.0 - this.es; + com = Math.sqrt(one_es); + + if (Math.abs(this.lat0) > EPSLN) { + sinph0 = Math.sin(this.lat0); + cosph0 = Math.cos(this.lat0); + con = 1 - this.es * sinph0 * sinph0; + this.B = cosph0 * cosph0; + this.B = Math.sqrt(1 + this.es * this.B * this.B / one_es); + this.A = this.B * this.k0 * com / con; + D = this.B * com / (cosph0 * Math.sqrt(con)); + F = D * D -1; + + if (F <= 0) { + F = 0; + } else { + F = Math.sqrt(F); + if (this.lat0 < 0) { + F = -F; + } + } + + this.E = F += D; + this.E *= Math.pow(tsfnz(this.e, this.lat0, sinph0), this.B); + } else { + this.B = 1 / com; + this.A = this.k0; + this.E = D = F = 1; + } + + if (alp || gam) { + if (alp) { + gamma0 = Math.asin(Math.sin(alpha_c) / D); + if (!gam) { + gamma = alpha_c; + } + } else { + gamma0 = gamma; + alpha_c = Math.asin(D * Math.sin(gamma0)); + } + this.lam0 = lamc - Math.asin(0.5 * (F - 1 / F) * Math.tan(gamma0)) / this.B; + } else { + H = Math.pow(tsfnz(this.e, phi1, Math.sin(phi1)), this.B); + L = Math.pow(tsfnz(this.e, phi2, Math.sin(phi2)), this.B); + F = this.E / H; + p = (L - H) / (L + H); + J = this.E * this.E; + J = (J - L * H) / (J + L * H); + con = lam1 - lam2; + + if (con < -Math.pi) { + lam2 -=TWO_PI; + } else if (con > Math.pi) { + lam2 += TWO_PI; + } + + this.lam0 = adjust_lon(0.5 * (lam1 + lam2) - Math.atan(J * Math.tan(0.5 * this.B * (lam1 - lam2)) / p) / this.B); + gamma0 = Math.atan(2 * Math.sin(this.B * adjust_lon(lam1 - this.lam0)) / (F - 1 / F)); + gamma = alpha_c = Math.asin(D * Math.sin(gamma0)); + } + + this.singam = Math.sin(gamma0); + this.cosgam = Math.cos(gamma0); + this.sinrot = Math.sin(gamma); + this.cosrot = Math.cos(gamma); + + this.rB = 1 / this.B; + this.ArB = this.A * this.rB; + this.BrA = 1 / this.ArB; + AB = this.A * this.B; + + if (this.no_off) { + this.u_0 = 0; + } else { + this.u_0 = Math.abs(this.ArB * Math.atan(Math.sqrt(D * D - 1) / Math.cos(alpha_c))); + + if (this.lat0 < 0) { + this.u_0 = - this.u_0; + } + } + + F = 0.5 * gamma0; + this.v_pole_n = this.ArB * Math.log(Math.tan(FORTPI - F)); + this.v_pole_s = this.ArB * Math.log(Math.tan(FORTPI + F)); +} + + +/* Oblique Mercator forward equations--mapping lat,long to x,y + ----------------------------------------------------------*/ +export function forward(p) { + var coords = {}; + var S, T, U, V, W, temp, u, v; + p.x = p.x - this.lam0; + + if (Math.abs(Math.abs(p.y) - HALF_PI) > EPSLN) { + W = this.E / Math.pow(tsfnz(this.e, p.y, Math.sin(p.y)), this.B); + + temp = 1 / W; + S = 0.5 * (W - temp); + T = 0.5 * (W + temp); + V = Math.sin(this.B * p.x); + U = (S * this.singam - V * this.cosgam) / T; + + if (Math.abs(Math.abs(U) - 1.0) < EPSLN) { + throw new Error(); + } + + v = 0.5 * this.ArB * Math.log((1 - U)/(1 + U)); + temp = Math.cos(this.B * p.x); + + if (Math.abs(temp) < TOL) { + u = this.A * p.x; + } else { + u = this.ArB * Math.atan2((S * this.cosgam + V * this.singam), temp); + } + } else { + v = p.y > 0 ? this.v_pole_n : this.v_pole_s; + u = this.ArB * p.y; + } + + if (this.no_rot) { + coords.x = u; + coords.y = v; + } else { + u -= this.u_0; + coords.x = v * this.cosrot + u * this.sinrot; + coords.y = u * this.cosrot - v * this.sinrot; + } + + coords.x = (this.a * coords.x + this.x0); + coords.y = (this.a * coords.y + this.y0); + + return coords; +} + +export function inverse(p) { + var u, v, Qp, Sp, Tp, Vp, Up; + var coords = {}; + + p.x = (p.x - this.x0) * (1.0 / this.a); + p.y = (p.y - this.y0) * (1.0 / this.a); + + if (this.no_rot) { + v = p.y; + u = p.x; + } else { + v = p.x * this.cosrot - p.y * this.sinrot; + u = p.y * this.cosrot + p.x * this.sinrot + this.u_0; + } + + Qp = Math.exp(-this.BrA * v); + Sp = 0.5 * (Qp - 1 / Qp); + Tp = 0.5 * (Qp + 1 / Qp); + Vp = Math.sin(this.BrA * u); + Up = (Vp * this.cosgam + Sp * this.singam) / Tp; + + if (Math.abs(Math.abs(Up) - 1) < EPSLN) { + coords.x = 0; + coords.y = Up < 0 ? -HALF_PI : HALF_PI; + } else { + coords.y = this.E / Math.sqrt((1 + Up) / (1 - Up)); + coords.y = phi2z(this.e, Math.pow(coords.y, 1 / this.B)); + + if (coords.y === Infinity) { + throw new Error(); + } + + coords.x = -this.rB * Math.atan2((Sp * this.cosgam - Vp * this.singam), Math.cos(this.BrA * u)); + } + + coords.x += this.lam0; + + return coords; +} + +export var names = ["Hotine_Oblique_Mercator", "Hotine Oblique Mercator", "Hotine_Oblique_Mercator_Azimuth_Natural_Origin", "Hotine_Oblique_Mercator_Two_Point_Natural_Origin", "Hotine_Oblique_Mercator_Azimuth_Center", "Oblique_Mercator", "omerc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/ortho.js b/node_modules/proj4/lib/projections/ortho.js new file mode 100644 index 0000000..ed9f32e --- /dev/null +++ b/node_modules/proj4/lib/projections/ortho.js @@ -0,0 +1,91 @@ +import adjust_lon from '../common/adjust_lon'; +import asinz from '../common/asinz'; +import {EPSLN, HALF_PI} from '../constants/values'; + +export function init() { + //double temp; /* temporary variable */ + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14 = Math.sin(this.lat0); + this.cos_p14 = Math.cos(this.lat0); +} + +/* Orthographic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ +export function forward(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g, x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + dlon = adjust_lon(lon - this.long0); + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1; + if ((g > 0) || (Math.abs(g) <= EPSLN)) { + x = this.a * ksp * cosphi * Math.sin(dlon); + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + } + p.x = x; + p.y = y; + return p; +} + +export function inverse(p) { + var rh; /* height above ellipsoid */ + var z; /* angle */ + var sinz, cosz; /* sin of z and cos of z */ + var con; + var lon, lat; + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + rh = Math.sqrt(p.x * p.x + p.y * p.y); + z = asinz(rh / this.a); + + sinz = Math.sin(z); + cosz = Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= EPSLN) { + lat = this.lat0; + p.x = lon; + p.y = lat; + return p; + } + lat = asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14) / rh); + con = Math.abs(this.lat0) - HALF_PI; + if (Math.abs(con) <= EPSLN) { + if (this.lat0 >= 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y)); + } + else { + lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y)); + } + p.x = lon; + p.y = lat; + return p; + } + lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz), rh * this.cos_p14 * cosz - p.y * this.sin_p14 * sinz)); + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["ortho"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/poly.js b/node_modules/proj4/lib/projections/poly.js new file mode 100644 index 0000000..be6f77b --- /dev/null +++ b/node_modules/proj4/lib/projections/poly.js @@ -0,0 +1,135 @@ +import e0fn from '../common/e0fn'; +import e1fn from '../common/e1fn'; +import e2fn from '../common/e2fn'; +import e3fn from '../common/e3fn'; +import adjust_lon from '../common/adjust_lon'; +import adjust_lat from '../common/adjust_lat'; +import mlfn from '../common/mlfn'; +import {EPSLN} from '../constants/values'; + +import gN from '../common/gN'; +var MAX_ITER = 20; + +export function init() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); // devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles + this.e = Math.sqrt(this.es); + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); //si que des zeros le calcul ne se fait pas +} + +/* Polyconic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ +export function forward(p) { + var lon = p.x; + var lat = p.y; + var x, y, el; + var dlon = adjust_lon(lon - this.long0); + el = dlon * Math.sin(lat); + if (this.sphere) { + if (Math.abs(lat) <= EPSLN) { + x = this.a * dlon; + y = -1 * this.a * this.lat0; + } + else { + x = this.a * Math.sin(el) / Math.tan(lat); + y = this.a * (adjust_lat(lat - this.lat0) + (1 - Math.cos(el)) / Math.tan(lat)); + } + } + else { + if (Math.abs(lat) <= EPSLN) { + x = this.a * dlon; + y = -1 * this.ml0; + } + else { + var nl = gN(this.a, this.e, Math.sin(lat)) / Math.tan(lat); + x = nl * Math.sin(el); + y = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat) - this.ml0 + nl * (1 - Math.cos(el)); + } + + } + p.x = x + this.x0; + p.y = y + this.y0; + return p; +} + +/* Inverse equations + -----------------*/ +export function inverse(p) { + var lon, lat, x, y, i; + var al, bl; + var phi, dphi; + x = p.x - this.x0; + y = p.y - this.y0; + + if (this.sphere) { + if (Math.abs(y + this.a * this.lat0) <= EPSLN) { + lon = adjust_lon(x / this.a + this.long0); + lat = 0; + } + else { + al = this.lat0 + y / this.a; + bl = x * x / this.a / this.a + al * al; + phi = al; + var tanphi; + for (i = MAX_ITER; i; --i) { + tanphi = Math.tan(phi); + dphi = -1 * (al * (phi * tanphi + 1) - phi - 0.5 * (phi * phi + bl) * tanphi) / ((phi - al) / tanphi - 1); + phi += dphi; + if (Math.abs(dphi) <= EPSLN) { + lat = phi; + break; + } + } + lon = adjust_lon(this.long0 + (Math.asin(x * Math.tan(phi) / this.a)) / Math.sin(lat)); + } + } + else { + if (Math.abs(y + this.ml0) <= EPSLN) { + lat = 0; + lon = adjust_lon(this.long0 + x / this.a); + } + else { + + al = (this.ml0 + y) / this.a; + bl = x * x / this.a / this.a + al * al; + phi = al; + var cl, mln, mlnp, ma; + var con; + for (i = MAX_ITER; i; --i) { + con = this.e * Math.sin(phi); + cl = Math.sqrt(1 - con * con) * Math.tan(phi); + mln = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi); + mlnp = this.e0 - 2 * this.e1 * Math.cos(2 * phi) + 4 * this.e2 * Math.cos(4 * phi) - 6 * this.e3 * Math.cos(6 * phi); + ma = mln / this.a; + dphi = (al * (cl * ma + 1) - ma - 0.5 * cl * (ma * ma + bl)) / (this.es * Math.sin(2 * phi) * (ma * ma + bl - 2 * al * ma) / (4 * cl) + (al - ma) * (cl * mlnp - 2 / Math.sin(2 * phi)) - mlnp); + phi -= dphi; + if (Math.abs(dphi) <= EPSLN) { + lat = phi; + break; + } + } + + //lat=phi4z(this.e,this.e0,this.e1,this.e2,this.e3,al,bl,0,0); + cl = Math.sqrt(1 - this.es * Math.pow(Math.sin(lat), 2)) * Math.tan(lat); + lon = adjust_lon(this.long0 + Math.asin(x * cl / this.a) / Math.sin(lat)); + } + } + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["Polyconic", "poly"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/qsc.js b/node_modules/proj4/lib/projections/qsc.js new file mode 100644 index 0000000..2ce4bf6 --- /dev/null +++ b/node_modules/proj4/lib/projections/qsc.js @@ -0,0 +1,368 @@ +// QSC projection rewritten from the original PROJ4 +// https://github.com/OSGeo/proj.4/blob/master/src/PJ_qsc.c + +import {EPSLN, TWO_PI, SPI, HALF_PI, FORTPI} from '../constants/values'; + +/* constants */ +var FACE_ENUM = { + FRONT: 1, + RIGHT: 2, + BACK: 3, + LEFT: 4, + TOP: 5, + BOTTOM: 6 +}; + +var AREA_ENUM = { + AREA_0: 1, + AREA_1: 2, + AREA_2: 3, + AREA_3: 4 +}; + +export function init() { + + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.lat0 = this.lat0 || 0; + this.long0 = this.long0 || 0; + this.lat_ts = this.lat_ts || 0; + this.title = this.title || "Quadrilateralized Spherical Cube"; + + /* Determine the cube face from the center of projection. */ + if (this.lat0 >= HALF_PI - FORTPI / 2.0) { + this.face = FACE_ENUM.TOP; + } else if (this.lat0 <= -(HALF_PI - FORTPI / 2.0)) { + this.face = FACE_ENUM.BOTTOM; + } else if (Math.abs(this.long0) <= FORTPI) { + this.face = FACE_ENUM.FRONT; + } else if (Math.abs(this.long0) <= HALF_PI + FORTPI) { + this.face = this.long0 > 0.0 ? FACE_ENUM.RIGHT : FACE_ENUM.LEFT; + } else { + this.face = FACE_ENUM.BACK; + } + + /* Fill in useful values for the ellipsoid <-> sphere shift + * described in [LK12]. */ + if (this.es !== 0) { + this.one_minus_f = 1 - (this.a - this.b) / this.a; + this.one_minus_f_squared = this.one_minus_f * this.one_minus_f; + } +} + +// QSC forward equations--mapping lat,long to x,y +// ----------------------------------------------------------------- +export function forward(p) { + var xy = {x: 0, y: 0}; + var lat, lon; + var theta, phi; + var t, mu; + /* nu; */ + var area = {value: 0}; + + // move lon according to projection's lon + p.x -= this.long0; + + /* Convert the geodetic latitude to a geocentric latitude. + * This corresponds to the shift from the ellipsoid to the sphere + * described in [LK12]. */ + if (this.es !== 0) {//if (P->es != 0) { + lat = Math.atan(this.one_minus_f_squared * Math.tan(p.y)); + } else { + lat = p.y; + } + + /* Convert the input lat, lon into theta, phi as used by QSC. + * This depends on the cube face and the area on it. + * For the top and bottom face, we can compute theta and phi + * directly from phi, lam. For the other faces, we must use + * unit sphere cartesian coordinates as an intermediate step. */ + lon = p.x; //lon = lp.lam; + if (this.face === FACE_ENUM.TOP) { + phi = HALF_PI - lat; + if (lon >= FORTPI && lon <= HALF_PI + FORTPI) { + area.value = AREA_ENUM.AREA_0; + theta = lon - HALF_PI; + } else if (lon > HALF_PI + FORTPI || lon <= -(HALF_PI + FORTPI)) { + area.value = AREA_ENUM.AREA_1; + theta = (lon > 0.0 ? lon - SPI : lon + SPI); + } else if (lon > -(HALF_PI + FORTPI) && lon <= -FORTPI) { + area.value = AREA_ENUM.AREA_2; + theta = lon + HALF_PI; + } else { + area.value = AREA_ENUM.AREA_3; + theta = lon; + } + } else if (this.face === FACE_ENUM.BOTTOM) { + phi = HALF_PI + lat; + if (lon >= FORTPI && lon <= HALF_PI + FORTPI) { + area.value = AREA_ENUM.AREA_0; + theta = -lon + HALF_PI; + } else if (lon < FORTPI && lon >= -FORTPI) { + area.value = AREA_ENUM.AREA_1; + theta = -lon; + } else if (lon < -FORTPI && lon >= -(HALF_PI + FORTPI)) { + area.value = AREA_ENUM.AREA_2; + theta = -lon - HALF_PI; + } else { + area.value = AREA_ENUM.AREA_3; + theta = (lon > 0.0 ? -lon + SPI : -lon - SPI); + } + } else { + var q, r, s; + var sinlat, coslat; + var sinlon, coslon; + + if (this.face === FACE_ENUM.RIGHT) { + lon = qsc_shift_lon_origin(lon, +HALF_PI); + } else if (this.face === FACE_ENUM.BACK) { + lon = qsc_shift_lon_origin(lon, +SPI); + } else if (this.face === FACE_ENUM.LEFT) { + lon = qsc_shift_lon_origin(lon, -HALF_PI); + } + sinlat = Math.sin(lat); + coslat = Math.cos(lat); + sinlon = Math.sin(lon); + coslon = Math.cos(lon); + q = coslat * coslon; + r = coslat * sinlon; + s = sinlat; + + if (this.face === FACE_ENUM.FRONT) { + phi = Math.acos(q); + theta = qsc_fwd_equat_face_theta(phi, s, r, area); + } else if (this.face === FACE_ENUM.RIGHT) { + phi = Math.acos(r); + theta = qsc_fwd_equat_face_theta(phi, s, -q, area); + } else if (this.face === FACE_ENUM.BACK) { + phi = Math.acos(-q); + theta = qsc_fwd_equat_face_theta(phi, s, -r, area); + } else if (this.face === FACE_ENUM.LEFT) { + phi = Math.acos(-r); + theta = qsc_fwd_equat_face_theta(phi, s, q, area); + } else { + /* Impossible */ + phi = theta = 0; + area.value = AREA_ENUM.AREA_0; + } + } + + /* Compute mu and nu for the area of definition. + * For mu, see Eq. (3-21) in [OL76], but note the typos: + * compare with Eq. (3-14). For nu, see Eq. (3-38). */ + mu = Math.atan((12 / SPI) * (theta + Math.acos(Math.sin(theta) * Math.cos(FORTPI)) - HALF_PI)); + t = Math.sqrt((1 - Math.cos(phi)) / (Math.cos(mu) * Math.cos(mu)) / (1 - Math.cos(Math.atan(1 / Math.cos(theta))))); + + /* Apply the result to the real area. */ + if (area.value === AREA_ENUM.AREA_1) { + mu += HALF_PI; + } else if (area.value === AREA_ENUM.AREA_2) { + mu += SPI; + } else if (area.value === AREA_ENUM.AREA_3) { + mu += 1.5 * SPI; + } + + /* Now compute x, y from mu and nu */ + xy.x = t * Math.cos(mu); + xy.y = t * Math.sin(mu); + xy.x = xy.x * this.a + this.x0; + xy.y = xy.y * this.a + this.y0; + + p.x = xy.x; + p.y = xy.y; + return p; +} + +// QSC inverse equations--mapping x,y to lat/long +// ----------------------------------------------------------------- +export function inverse(p) { + var lp = {lam: 0, phi: 0}; + var mu, nu, cosmu, tannu; + var tantheta, theta, cosphi, phi; + var t; + var area = {value: 0}; + + /* de-offset */ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + /* Convert the input x, y to the mu and nu angles as used by QSC. + * This depends on the area of the cube face. */ + nu = Math.atan(Math.sqrt(p.x * p.x + p.y * p.y)); + mu = Math.atan2(p.y, p.x); + if (p.x >= 0.0 && p.x >= Math.abs(p.y)) { + area.value = AREA_ENUM.AREA_0; + } else if (p.y >= 0.0 && p.y >= Math.abs(p.x)) { + area.value = AREA_ENUM.AREA_1; + mu -= HALF_PI; + } else if (p.x < 0.0 && -p.x >= Math.abs(p.y)) { + area.value = AREA_ENUM.AREA_2; + mu = (mu < 0.0 ? mu + SPI : mu - SPI); + } else { + area.value = AREA_ENUM.AREA_3; + mu += HALF_PI; + } + + /* Compute phi and theta for the area of definition. + * The inverse projection is not described in the original paper, but some + * good hints can be found here (as of 2011-12-14): + * http://fits.gsfc.nasa.gov/fitsbits/saf.93/saf.9302 + * (search for "Message-Id: <9302181759.AA25477 at fits.cv.nrao.edu>") */ + t = (SPI / 12) * Math.tan(mu); + tantheta = Math.sin(t) / (Math.cos(t) - (1 / Math.sqrt(2))); + theta = Math.atan(tantheta); + cosmu = Math.cos(mu); + tannu = Math.tan(nu); + cosphi = 1 - cosmu * cosmu * tannu * tannu * (1 - Math.cos(Math.atan(1 / Math.cos(theta)))); + if (cosphi < -1) { + cosphi = -1; + } else if (cosphi > +1) { + cosphi = +1; + } + + /* Apply the result to the real area on the cube face. + * For the top and bottom face, we can compute phi and lam directly. + * For the other faces, we must use unit sphere cartesian coordinates + * as an intermediate step. */ + if (this.face === FACE_ENUM.TOP) { + phi = Math.acos(cosphi); + lp.phi = HALF_PI - phi; + if (area.value === AREA_ENUM.AREA_0) { + lp.lam = theta + HALF_PI; + } else if (area.value === AREA_ENUM.AREA_1) { + lp.lam = (theta < 0.0 ? theta + SPI : theta - SPI); + } else if (area.value === AREA_ENUM.AREA_2) { + lp.lam = theta - HALF_PI; + } else /* area.value == AREA_ENUM.AREA_3 */ { + lp.lam = theta; + } + } else if (this.face === FACE_ENUM.BOTTOM) { + phi = Math.acos(cosphi); + lp.phi = phi - HALF_PI; + if (area.value === AREA_ENUM.AREA_0) { + lp.lam = -theta + HALF_PI; + } else if (area.value === AREA_ENUM.AREA_1) { + lp.lam = -theta; + } else if (area.value === AREA_ENUM.AREA_2) { + lp.lam = -theta - HALF_PI; + } else /* area.value == AREA_ENUM.AREA_3 */ { + lp.lam = (theta < 0.0 ? -theta - SPI : -theta + SPI); + } + } else { + /* Compute phi and lam via cartesian unit sphere coordinates. */ + var q, r, s; + q = cosphi; + t = q * q; + if (t >= 1) { + s = 0; + } else { + s = Math.sqrt(1 - t) * Math.sin(theta); + } + t += s * s; + if (t >= 1) { + r = 0; + } else { + r = Math.sqrt(1 - t); + } + /* Rotate q,r,s into the correct area. */ + if (area.value === AREA_ENUM.AREA_1) { + t = r; + r = -s; + s = t; + } else if (area.value === AREA_ENUM.AREA_2) { + r = -r; + s = -s; + } else if (area.value === AREA_ENUM.AREA_3) { + t = r; + r = s; + s = -t; + } + /* Rotate q,r,s into the correct cube face. */ + if (this.face === FACE_ENUM.RIGHT) { + t = q; + q = -r; + r = t; + } else if (this.face === FACE_ENUM.BACK) { + q = -q; + r = -r; + } else if (this.face === FACE_ENUM.LEFT) { + t = q; + q = r; + r = -t; + } + /* Now compute phi and lam from the unit sphere coordinates. */ + lp.phi = Math.acos(-s) - HALF_PI; + lp.lam = Math.atan2(r, q); + if (this.face === FACE_ENUM.RIGHT) { + lp.lam = qsc_shift_lon_origin(lp.lam, -HALF_PI); + } else if (this.face === FACE_ENUM.BACK) { + lp.lam = qsc_shift_lon_origin(lp.lam, -SPI); + } else if (this.face === FACE_ENUM.LEFT) { + lp.lam = qsc_shift_lon_origin(lp.lam, +HALF_PI); + } + } + + /* Apply the shift from the sphere to the ellipsoid as described + * in [LK12]. */ + if (this.es !== 0) { + var invert_sign; + var tanphi, xa; + invert_sign = (lp.phi < 0 ? 1 : 0); + tanphi = Math.tan(lp.phi); + xa = this.b / Math.sqrt(tanphi * tanphi + this.one_minus_f_squared); + lp.phi = Math.atan(Math.sqrt(this.a * this.a - xa * xa) / (this.one_minus_f * xa)); + if (invert_sign) { + lp.phi = -lp.phi; + } + } + + lp.lam += this.long0; + p.x = lp.lam; + p.y = lp.phi; + return p; +} + +/* Helper function for forward projection: compute the theta angle + * and determine the area number. */ +function qsc_fwd_equat_face_theta(phi, y, x, area) { + var theta; + if (phi < EPSLN) { + area.value = AREA_ENUM.AREA_0; + theta = 0.0; + } else { + theta = Math.atan2(y, x); + if (Math.abs(theta) <= FORTPI) { + area.value = AREA_ENUM.AREA_0; + } else if (theta > FORTPI && theta <= HALF_PI + FORTPI) { + area.value = AREA_ENUM.AREA_1; + theta -= HALF_PI; + } else if (theta > HALF_PI + FORTPI || theta <= -(HALF_PI + FORTPI)) { + area.value = AREA_ENUM.AREA_2; + theta = (theta >= 0.0 ? theta - SPI : theta + SPI); + } else { + area.value = AREA_ENUM.AREA_3; + theta += HALF_PI; + } + } + return theta; +} + +/* Helper function: shift the longitude. */ +function qsc_shift_lon_origin(lon, offset) { + var slon = lon + offset; + if (slon < -SPI) { + slon += TWO_PI; + } else if (slon > +SPI) { + slon -= TWO_PI; + } + return slon; +} + +export var names = ["Quadrilateralized Spherical Cube", "Quadrilateralized_Spherical_Cube", "qsc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; + diff --git a/node_modules/proj4/lib/projections/robin.js b/node_modules/proj4/lib/projections/robin.js new file mode 100644 index 0000000..f335bd7 --- /dev/null +++ b/node_modules/proj4/lib/projections/robin.js @@ -0,0 +1,161 @@ +// Robinson projection +// Based on https://github.com/OSGeo/proj.4/blob/master/src/PJ_robin.c +// Polynomial coeficients from http://article.gmane.org/gmane.comp.gis.proj-4.devel/6039 + +import {HALF_PI, D2R, R2D, EPSLN} from '../constants/values'; +import adjust_lon from '../common/adjust_lon'; + +var COEFS_X = [ + [1.0000, 2.2199e-17, -7.15515e-05, 3.1103e-06], + [0.9986, -0.000482243, -2.4897e-05, -1.3309e-06], + [0.9954, -0.00083103, -4.48605e-05, -9.86701e-07], + [0.9900, -0.00135364, -5.9661e-05, 3.6777e-06], + [0.9822, -0.00167442, -4.49547e-06, -5.72411e-06], + [0.9730, -0.00214868, -9.03571e-05, 1.8736e-08], + [0.9600, -0.00305085, -9.00761e-05, 1.64917e-06], + [0.9427, -0.00382792, -6.53386e-05, -2.6154e-06], + [0.9216, -0.00467746, -0.00010457, 4.81243e-06], + [0.8962, -0.00536223, -3.23831e-05, -5.43432e-06], + [0.8679, -0.00609363, -0.000113898, 3.32484e-06], + [0.8350, -0.00698325, -6.40253e-05, 9.34959e-07], + [0.7986, -0.00755338, -5.00009e-05, 9.35324e-07], + [0.7597, -0.00798324, -3.5971e-05, -2.27626e-06], + [0.7186, -0.00851367, -7.01149e-05, -8.6303e-06], + [0.6732, -0.00986209, -0.000199569, 1.91974e-05], + [0.6213, -0.010418, 8.83923e-05, 6.24051e-06], + [0.5722, -0.00906601, 0.000182, 6.24051e-06], + [0.5322, -0.00677797, 0.000275608, 6.24051e-06] +]; + +var COEFS_Y = [ + [-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11], + [0.0620, 0.0124, -1.26793e-09, 4.22642e-10], + [0.1240, 0.0124, 5.07171e-09, -1.60604e-09], + [0.1860, 0.0123999, -1.90189e-08, 6.00152e-09], + [0.2480, 0.0124002, 7.10039e-08, -2.24e-08], + [0.3100, 0.0123992, -2.64997e-07, 8.35986e-08], + [0.3720, 0.0124029, 9.88983e-07, -3.11994e-07], + [0.4340, 0.0123893, -3.69093e-06, -4.35621e-07], + [0.4958, 0.0123198, -1.02252e-05, -3.45523e-07], + [0.5571, 0.0121916, -1.54081e-05, -5.82288e-07], + [0.6176, 0.0119938, -2.41424e-05, -5.25327e-07], + [0.6769, 0.011713, -3.20223e-05, -5.16405e-07], + [0.7346, 0.0113541, -3.97684e-05, -6.09052e-07], + [0.7903, 0.0109107, -4.89042e-05, -1.04739e-06], + [0.8435, 0.0103431, -6.4615e-05, -1.40374e-09], + [0.8936, 0.00969686, -6.4636e-05, -8.547e-06], + [0.9394, 0.00840947, -0.000192841, -4.2106e-06], + [0.9761, 0.00616527, -0.000256, -4.2106e-06], + [1.0000, 0.00328947, -0.000319159, -4.2106e-06] +]; + +var FXC = 0.8487; +var FYC = 1.3523; +var C1 = R2D/5; // rad to 5-degree interval +var RC1 = 1/C1; +var NODES = 18; + +var poly3_val = function(coefs, x) { + return coefs[0] + x * (coefs[1] + x * (coefs[2] + x * coefs[3])); +}; + +var poly3_der = function(coefs, x) { + return coefs[1] + x * (2 * coefs[2] + x * 3 * coefs[3]); +}; + +function newton_rapshon(f_df, start, max_err, iters) { + var x = start; + for (; iters; --iters) { + var upd = f_df(x); + x -= upd; + if (Math.abs(upd) < max_err) { + break; + } + } + return x; +} + +export function init() { + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.long0 = this.long0 || 0; + this.es = 0; + this.title = this.title || "Robinson"; +} + +export function forward(ll) { + var lon = adjust_lon(ll.x - this.long0); + + var dphi = Math.abs(ll.y); + var i = Math.floor(dphi * C1); + if (i < 0) { + i = 0; + } else if (i >= NODES) { + i = NODES - 1; + } + dphi = R2D * (dphi - RC1 * i); + var xy = { + x: poly3_val(COEFS_X[i], dphi) * lon, + y: poly3_val(COEFS_Y[i], dphi) + }; + if (ll.y < 0) { + xy.y = -xy.y; + } + + xy.x = xy.x * this.a * FXC + this.x0; + xy.y = xy.y * this.a * FYC + this.y0; + return xy; +} + +export function inverse(xy) { + var ll = { + x: (xy.x - this.x0) / (this.a * FXC), + y: Math.abs(xy.y - this.y0) / (this.a * FYC) + }; + + if (ll.y >= 1) { // pathologic case + ll.x /= COEFS_X[NODES][0]; + ll.y = xy.y < 0 ? -HALF_PI : HALF_PI; + } else { + // find table interval + var i = Math.floor(ll.y * NODES); + if (i < 0) { + i = 0; + } else if (i >= NODES) { + i = NODES - 1; + } + for (;;) { + if (COEFS_Y[i][0] > ll.y) { + --i; + } else if (COEFS_Y[i+1][0] <= ll.y) { + ++i; + } else { + break; + } + } + // linear interpolation in 5 degree interval + var coefs = COEFS_Y[i]; + var t = 5 * (ll.y - coefs[0]) / (COEFS_Y[i+1][0] - coefs[0]); + // find t so that poly3_val(coefs, t) = ll.y + t = newton_rapshon(function(x) { + return (poly3_val(coefs, x) - ll.y) / poly3_der(coefs, x); + }, t, EPSLN, 100); + + ll.x /= poly3_val(COEFS_X[i], t); + ll.y = (5 * i + t) * D2R; + if (xy.y < 0) { + ll.y = -ll.y; + } + } + + ll.x = adjust_lon(ll.x + this.long0); + return ll; +} + +export var names = ["Robinson", "robin"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/sinu.js b/node_modules/proj4/lib/projections/sinu.js new file mode 100644 index 0000000..7ff5763 --- /dev/null +++ b/node_modules/proj4/lib/projections/sinu.js @@ -0,0 +1,115 @@ +import adjust_lon from '../common/adjust_lon'; +import adjust_lat from '../common/adjust_lat'; +import pj_enfn from '../common/pj_enfn'; +var MAX_ITER = 20; +import pj_mlfn from '../common/pj_mlfn'; +import pj_inv_mlfn from '../common/pj_inv_mlfn'; +import {EPSLN, HALF_PI} from '../constants/values'; + +import asinz from '../common/asinz'; + + +export function init() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + + if (!this.sphere) { + this.en = pj_enfn(this.es); + } + else { + this.n = 1; + this.m = 0; + this.es = 0; + this.C_y = Math.sqrt((this.m + 1) / this.n); + this.C_x = this.C_y / (this.m + 1); + } + +} + +/* Sinusoidal forward equations--mapping lat,long to x,y + -----------------------------------------------------*/ +export function forward(p) { + var x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + lon = adjust_lon(lon - this.long0); + + if (this.sphere) { + if (!this.m) { + lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat; + } + else { + var k = this.n * Math.sin(lat); + for (var i = MAX_ITER; i; --i) { + var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat)); + lat -= V; + if (Math.abs(V) < EPSLN) { + break; + } + } + } + x = this.a * this.C_x * lon * (this.m + Math.cos(lat)); + y = this.a * this.C_y * lat; + + } + else { + + var s = Math.sin(lat); + var c = Math.cos(lat); + y = this.a * pj_mlfn(lat, s, c, this.en); + x = this.a * lon * c / Math.sqrt(1 - this.es * s * s); + } + + p.x = x; + p.y = y; + return p; +} + +export function inverse(p) { + var lat, temp, lon, s; + + p.x -= this.x0; + lon = p.x / this.a; + p.y -= this.y0; + lat = p.y / this.a; + + if (this.sphere) { + lat /= this.C_y; + lon = lon / (this.C_x * (this.m + Math.cos(lat))); + if (this.m) { + lat = asinz((this.m * lat + Math.sin(lat)) / this.n); + } + else if (this.n !== 1) { + lat = asinz(Math.sin(lat) / this.n); + } + lon = adjust_lon(lon + this.long0); + lat = adjust_lat(lat); + } + else { + lat = pj_inv_mlfn(p.y / this.a, this.es, this.en); + s = Math.abs(lat); + if (s < HALF_PI) { + s = Math.sin(lat); + temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat)); + //temp = this.long0 + p.x / (this.a * Math.cos(lat)); + lon = adjust_lon(temp); + } + else if ((s - EPSLN) < HALF_PI) { + lon = this.long0; + } + } + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["Sinusoidal", "sinu"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/somerc.js b/node_modules/proj4/lib/projections/somerc.js new file mode 100644 index 0000000..18cdccb --- /dev/null +++ b/node_modules/proj4/lib/projections/somerc.js @@ -0,0 +1,86 @@ +/* + references: + Formules et constantes pour le Calcul pour la + projection cylindrique conforme à axe oblique et pour la transformation entre + des systèmes de référence. + http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf + */ + +export function init() { + var phy0 = this.lat0; + this.lambda0 = this.long0; + var sinPhy0 = Math.sin(phy0); + var semiMajorAxis = this.a; + var invF = this.rf; + var flattening = 1 / invF; + var e2 = 2 * flattening - Math.pow(flattening, 2); + var e = this.e = Math.sqrt(e2); + this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2)); + this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4)); + this.b0 = Math.asin(sinPhy0 / this.alpha); + var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2)); + var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2)); + var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0)); + this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3; +} + +export function forward(p) { + var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2)); + var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y))); + var S = -this.alpha * (Sa1 + Sa2) + this.K; + + // spheric latitude + var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4); + + // spheric longitude + var I = this.alpha * (p.x - this.lambda0); + + // psoeudo equatorial rotation + var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I))); + + var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I)); + + p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0; + p.x = this.R * rotI + this.x0; + return p; +} + +export function inverse(p) { + var Y = p.x - this.x0; + var X = p.y - this.y0; + + var rotI = Y / this.R; + var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4); + + var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI)); + var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB))); + + var lambda = this.lambda0 + I / this.alpha; + + var S = 0; + var phy = b; + var prevPhy = -1000; + var iteration = 0; + while (Math.abs(phy - prevPhy) > 0.0000001) { + if (++iteration > 20) { + //...reportError("omercFwdInfinity"); + return; + } + //S = Math.log(Math.tan(Math.PI / 4 + phy / 2)); + S = 1 / this.alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - this.K) + this.e * Math.log(Math.tan(Math.PI / 4 + Math.asin(this.e * Math.sin(phy)) / 2)); + prevPhy = phy; + phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2; + } + + p.x = lambda; + p.y = phy; + return p; +} + +export var names = ["somerc"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/stere.js b/node_modules/proj4/lib/projections/stere.js new file mode 100644 index 0000000..6c30db1 --- /dev/null +++ b/node_modules/proj4/lib/projections/stere.js @@ -0,0 +1,174 @@ +import {EPSLN, HALF_PI} from '../constants/values'; + +import sign from '../common/sign'; +import msfnz from '../common/msfnz'; +import tsfnz from '../common/tsfnz'; +import phi2z from '../common/phi2z'; +import adjust_lon from '../common/adjust_lon'; + +export function ssfn_(phit, sinphi, eccen) { + sinphi *= eccen; + return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen)); +} + +export function init() { + this.coslat0 = Math.cos(this.lat0); + this.sinlat0 = Math.sin(this.lat0); + if (this.sphere) { + if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) { + this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts)); + } + } + else { + if (Math.abs(this.coslat0) <= EPSLN) { + if (this.lat0 > 0) { + //North pole + //trace('stere:north pole'); + this.con = 1; + } + else { + //South pole + //trace('stere:south pole'); + this.con = -1; + } + } + this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e)); + if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) { + this.k0 = 0.5 * this.cons * msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)) / tsfnz(this.e, this.con * this.lat_ts, this.con * Math.sin(this.lat_ts)); + } + this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0); + this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI; + this.cosX0 = Math.cos(this.X0); + this.sinX0 = Math.sin(this.X0); + } +} + +// Stereographic forward equations--mapping lat,long to x,y +export function forward(p) { + var lon = p.x; + var lat = p.y; + var sinlat = Math.sin(lat); + var coslat = Math.cos(lat); + var A, X, sinX, cosX, ts, rh; + var dlon = adjust_lon(lon - this.long0); + + if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) { + //case of the origine point + //trace('stere:this is the origin point'); + p.x = NaN; + p.y = NaN; + return p; + } + if (this.sphere) { + //trace('stere:sphere case'); + A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon)); + p.x = this.a * A * coslat * Math.sin(dlon) + this.x0; + p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0; + return p; + } + else { + X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI; + cosX = Math.cos(X); + sinX = Math.sin(X); + if (Math.abs(this.coslat0) <= EPSLN) { + ts = tsfnz(this.e, lat * this.con, this.con * sinlat); + rh = 2 * this.a * this.k0 * ts / this.cons; + p.x = this.x0 + rh * Math.sin(lon - this.long0); + p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0); + //trace(p.toString()); + return p; + } + else if (Math.abs(this.sinlat0) < EPSLN) { + //Eq + //trace('stere:equateur'); + A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon)); + p.y = A * sinX; + } + else { + //other case + //trace('stere:normal case'); + A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon))); + p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0; + } + p.x = A * cosX * Math.sin(dlon) + this.x0; + } + //trace(p.toString()); + return p; +} + +//* Stereographic inverse equations--mapping x,y to lat/long +export function inverse(p) { + p.x -= this.x0; + p.y -= this.y0; + var lon, lat, ts, ce, Chi; + var rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (this.sphere) { + var c = 2 * Math.atan(rh / (2 * this.a * this.k0)); + lon = this.long0; + lat = this.lat0; + if (rh <= EPSLN) { + p.x = lon; + p.y = lat; + return p; + } + lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh); + if (Math.abs(this.coslat0) < EPSLN) { + if (this.lat0 > 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y)); + } + else { + lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y)); + } + } + else { + lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(c), rh * this.coslat0 * Math.cos(c) - p.y * this.sinlat0 * Math.sin(c))); + } + p.x = lon; + p.y = lat; + return p; + } + else { + if (Math.abs(this.coslat0) <= EPSLN) { + if (rh <= EPSLN) { + lat = this.lat0; + lon = this.long0; + p.x = lon; + p.y = lat; + //trace(p.toString()); + return p; + } + p.x *= this.con; + p.y *= this.con; + ts = rh * this.cons / (2 * this.a * this.k0); + lat = this.con * phi2z(this.e, ts); + lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y)); + } + else { + ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1)); + lon = this.long0; + if (rh <= EPSLN) { + Chi = this.X0; + } + else { + Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh); + lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(ce), rh * this.cosX0 * Math.cos(ce) - p.y * this.sinX0 * Math.sin(ce))); + } + lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi))); + } + } + p.x = lon; + p.y = lat; + + //trace(p.toString()); + return p; + +} + +export var names = ["stere", "Stereographic_South_Pole", "Polar Stereographic (variant B)"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names, + ssfn_: ssfn_ +}; diff --git a/node_modules/proj4/lib/projections/sterea.js b/node_modules/proj4/lib/projections/sterea.js new file mode 100644 index 0000000..9a54078 --- /dev/null +++ b/node_modules/proj4/lib/projections/sterea.js @@ -0,0 +1,64 @@ +import gauss from './gauss'; +import adjust_lon from '../common/adjust_lon'; + +export function init() { + gauss.init.apply(this); + if (!this.rc) { + return; + } + this.sinc0 = Math.sin(this.phic0); + this.cosc0 = Math.cos(this.phic0); + this.R2 = 2 * this.rc; + if (!this.title) { + this.title = "Oblique Stereographic Alternative"; + } +} + +export function forward(p) { + var sinc, cosc, cosl, k; + p.x = adjust_lon(p.x - this.long0); + gauss.forward.apply(this, [p]); + sinc = Math.sin(p.y); + cosc = Math.cos(p.y); + cosl = Math.cos(p.x); + k = this.k0 * this.R2 / (1 + this.sinc0 * sinc + this.cosc0 * cosc * cosl); + p.x = k * cosc * Math.sin(p.x); + p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl); + p.x = this.a * p.x + this.x0; + p.y = this.a * p.y + this.y0; + return p; +} + +export function inverse(p) { + var sinc, cosc, lon, lat, rho; + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + if ((rho = Math.sqrt(p.x * p.x + p.y * p.y))) { + var c = 2 * Math.atan2(rho, this.R2); + sinc = Math.sin(c); + cosc = Math.cos(c); + lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho); + lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc); + } + else { + lat = this.phic0; + lon = 0; + } + + p.x = lon; + p.y = lat; + gauss.inverse.apply(this, [p]); + p.x = adjust_lon(p.x + this.long0); + return p; +} + +export var names = ["Stereographic_North_Pole", "Oblique_Stereographic", "Polar_Stereographic", "sterea","Oblique Stereographic Alternative","Double_Stereographic"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/tmerc.js b/node_modules/proj4/lib/projections/tmerc.js new file mode 100644 index 0000000..738c392 --- /dev/null +++ b/node_modules/proj4/lib/projections/tmerc.js @@ -0,0 +1,173 @@ +// Heavily based on this tmerc projection implementation +// https://github.com/mbloch/mapshaper-proj/blob/master/src/projections/tmerc.js + +import pj_enfn from '../common/pj_enfn'; +import pj_mlfn from '../common/pj_mlfn'; +import pj_inv_mlfn from '../common/pj_inv_mlfn'; +import adjust_lon from '../common/adjust_lon'; + +import {EPSLN, HALF_PI} from '../constants/values'; +import sign from '../common/sign'; + +export function init() { + this.x0 = this.x0 !== undefined ? this.x0 : 0; + this.y0 = this.y0 !== undefined ? this.y0 : 0; + this.long0 = this.long0 !== undefined ? this.long0 : 0; + this.lat0 = this.lat0 !== undefined ? this.lat0 : 0; + + if (this.es) { + this.en = pj_enfn(this.es); + this.ml0 = pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en); + } +} + +/** + Transverse Mercator Forward - long/lat to x/y + long/lat in radians + */ +export function forward(p) { + var lon = p.x; + var lat = p.y; + + var delta_lon = adjust_lon(lon - this.long0); + var con; + var x, y; + var sin_phi = Math.sin(lat); + var cos_phi = Math.cos(lat); + + if (!this.es) { + var b = cos_phi * Math.sin(delta_lon); + + if ((Math.abs(Math.abs(b) - 1)) < EPSLN) { + return (93); + } + else { + x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b)) + this.x0; + y = cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - Math.pow(b, 2)); + b = Math.abs(y); + + if (b >= 1) { + if ((b - 1) > EPSLN) { + return (93); + } + else { + y = 0; + } + } + else { + y = Math.acos(y); + } + + if (lat < 0) { + y = -y; + } + + y = this.a * this.k0 * (y - this.lat0) + this.y0; + } + } + else { + var al = cos_phi * delta_lon; + var als = Math.pow(al, 2); + var c = this.ep2 * Math.pow(cos_phi, 2); + var cs = Math.pow(c, 2); + var tq = Math.abs(cos_phi) > EPSLN ? Math.tan(lat) : 0; + var t = Math.pow(tq, 2); + var ts = Math.pow(t, 2); + con = 1 - this.es * Math.pow(sin_phi, 2); + al = al / Math.sqrt(con); + var ml = pj_mlfn(lat, sin_phi, cos_phi, this.en); + + x = this.a * (this.k0 * al * (1 + + als / 6 * (1 - t + c + + als / 20 * (5 - 18 * t + ts + 14 * c - 58 * t * c + + als / 42 * (61 + 179 * ts - ts * t - 479 * t))))) + + this.x0; + + y = this.a * (this.k0 * (ml - this.ml0 + + sin_phi * delta_lon * al / 2 * (1 + + als / 12 * (5 - t + 9 * c + 4 * cs + + als / 30 * (61 + ts - 58 * t + 270 * c - 330 * t * c + + als / 56 * (1385 + 543 * ts - ts * t - 3111 * t)))))) + + this.y0; + } + + p.x = x; + p.y = y; + + return p; +} + +/** + Transverse Mercator Inverse - x/y to long/lat + */ +export function inverse(p) { + var con, phi; + var lat, lon; + var x = (p.x - this.x0) * (1 / this.a); + var y = (p.y - this.y0) * (1 / this.a); + + if (!this.es) { + var f = Math.exp(x / this.k0); + var g = 0.5 * (f - 1 / f); + var temp = this.lat0 + y / this.k0; + var h = Math.cos(temp); + con = Math.sqrt((1 - Math.pow(h, 2)) / (1 + Math.pow(g, 2))); + lat = Math.asin(con); + + if (y < 0) { + lat = -lat; + } + + if ((g === 0) && (h === 0)) { + lon = 0; + } + else { + lon = adjust_lon(Math.atan2(g, h) + this.long0); + } + } + else { // ellipsoidal form + con = this.ml0 + y / this.k0; + phi = pj_inv_mlfn(con, this.es, this.en); + + if (Math.abs(phi) < HALF_PI) { + var sin_phi = Math.sin(phi); + var cos_phi = Math.cos(phi); + var tan_phi = Math.abs(cos_phi) > EPSLN ? Math.tan(phi) : 0; + var c = this.ep2 * Math.pow(cos_phi, 2); + var cs = Math.pow(c, 2); + var t = Math.pow(tan_phi, 2); + var ts = Math.pow(t, 2); + con = 1 - this.es * Math.pow(sin_phi, 2); + var d = x * Math.sqrt(con) / this.k0; + var ds = Math.pow(d, 2); + con = con * tan_phi; + + lat = phi - (con * ds / (1 - this.es)) * 0.5 * (1 - + ds / 12 * (5 + 3 * t - 9 * c * t + c - 4 * cs - + ds / 30 * (61 + 90 * t - 252 * c * t + 45 * ts + 46 * c - + ds / 56 * (1385 + 3633 * t + 4095 * ts + 1574 * ts * t)))); + + lon = adjust_lon(this.long0 + (d * (1 - + ds / 6 * (1 + 2 * t + c - + ds / 20 * (5 + 28 * t + 24 * ts + 8 * c * t + 6 * c - + ds / 42 * (61 + 662 * t + 1320 * ts + 720 * ts * t)))) / cos_phi)); + } + else { + lat = HALF_PI * sign(y); + lon = 0; + } + } + + p.x = lon; + p.y = lat; + + return p; +} + +export var names = ["Fast_Transverse_Mercator", "Fast Transverse Mercator"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/tpers.js b/node_modules/proj4/lib/projections/tpers.js new file mode 100644 index 0000000..4514142 --- /dev/null +++ b/node_modules/proj4/lib/projections/tpers.js @@ -0,0 +1,169 @@ + +var mode = { + N_POLE: 0, + S_POLE: 1, + EQUIT: 2, + OBLIQ: 3 +}; + +import { D2R, HALF_PI, EPSLN } from "../constants/values"; +import hypot from "../common/hypot"; + +var params = { + h: { def: 100000, num: true }, // default is Karman line, no default in PROJ.7 + azi: { def: 0, num: true, degrees: true }, // default is North + tilt: { def: 0, num: true, degrees: true }, // default is Nadir + long0: { def: 0, num: true }, // default is Greenwich, conversion to rad is automatic + lat0: { def: 0, num: true } // default is Equator, conversion to rad is automatic +}; + +export function init() { + Object.keys(params).forEach(function (p) { + if (typeof this[p] === "undefined") { + this[p] = params[p].def; + } else if (params[p].num && isNaN(this[p])) { + throw new Error("Invalid parameter value, must be numeric " + p + " = " + this[p]); + } else if (params[p].num) { + this[p] = parseFloat(this[p]); + } + if (params[p].degrees) { + this[p] = this[p] * D2R; + } + }.bind(this)); + + if (Math.abs((Math.abs(this.lat0) - HALF_PI)) < EPSLN) { + this.mode = this.lat0 < 0 ? mode.S_POLE : mode.N_POLE; + } else if (Math.abs(this.lat0) < EPSLN) { + this.mode = mode.EQUIT; + } else { + this.mode = mode.OBLIQ; + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + + this.pn1 = this.h / this.a; // Normalize relative to the Earth's radius + + if (this.pn1 <= 0 || this.pn1 > 1e10) { + throw new Error("Invalid height"); + } + + this.p = 1 + this.pn1; + this.rp = 1 / this.p; + this.h1 = 1 / this.pn1; + this.pfact = (this.p + 1) * this.h1; + this.es = 0; + + var omega = this.tilt; + var gamma = this.azi; + this.cg = Math.cos(gamma); + this.sg = Math.sin(gamma); + this.cw = Math.cos(omega); + this.sw = Math.sin(omega); +} + +export function forward(p) { + p.x -= this.long0; + var sinphi = Math.sin(p.y); + var cosphi = Math.cos(p.y); + var coslam = Math.cos(p.x); + var x, y; + switch (this.mode) { + case mode.OBLIQ: + y = this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + break; + case mode.EQUIT: + y = cosphi * coslam; + break; + case mode.S_POLE: + y = -sinphi; + break; + case mode.N_POLE: + y = sinphi; + break; + } + y = this.pn1 / (this.p - y); + x = y * cosphi * Math.sin(p.x); + + switch (this.mode) { + case mode.OBLIQ: + y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + break; + case mode.EQUIT: + y *= sinphi; + break; + case mode.N_POLE: + y *= -(cosphi * coslam); + break; + case mode.S_POLE: + y *= cosphi * coslam; + break; + } + + // Tilt + var yt, ba; + yt = y * this.cg + x * this.sg; + ba = 1 / (yt * this.sw * this.h1 + this.cw); + x = (x * this.cg - y * this.sg) * this.cw * ba; + y = yt * ba; + + p.x = x * this.a; + p.y = y * this.a; + return p; +} + +export function inverse(p) { + p.x /= this.a; + p.y /= this.a; + var r = { x: p.x, y: p.y }; + + // Un-Tilt + var bm, bq, yt; + yt = 1 / (this.pn1 - p.y * this.sw); + bm = this.pn1 * p.x * yt; + bq = this.pn1 * p.y * this.cw * yt; + p.x = bm * this.cg + bq * this.sg; + p.y = bq * this.cg - bm * this.sg; + + var rh = hypot(p.x, p.y); + if (Math.abs(rh) < EPSLN) { + r.x = 0; + r.y = p.y; + } else { + var cosz, sinz; + sinz = 1 - rh * rh * this.pfact; + sinz = (this.p - Math.sqrt(sinz)) / (this.pn1 / rh + rh / this.pn1); + cosz = Math.sqrt(1 - sinz * sinz); + switch (this.mode) { + case mode.OBLIQ: + r.y = Math.asin(cosz * this.sinph0 + p.y * sinz * this.cosph0 / rh); + p.y = (cosz - this.sinph0 * Math.sin(r.y)) * rh; + p.x *= sinz * this.cosph0; + break; + case mode.EQUIT: + r.y = Math.asin(p.y * sinz / rh); + p.y = cosz * rh; + p.x *= sinz; + break; + case mode.N_POLE: + r.y = Math.asin(cosz); + p.y = -p.y; + break; + case mode.S_POLE: + r.y = -Math.asin(cosz); + break; + } + r.x = Math.atan2(p.x, p.y); + } + + p.x = r.x + this.long0; + p.y = r.y; + return p; +} + +export var names = ["Tilted_Perspective", "tpers"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/projections/utm.js b/node_modules/proj4/lib/projections/utm.js new file mode 100644 index 0000000..5b126a0 --- /dev/null +++ b/node_modules/proj4/lib/projections/utm.js @@ -0,0 +1,28 @@ +import adjust_zone from '../common/adjust_zone'; +import etmerc from './etmerc'; +export var dependsOn = 'etmerc'; +import {D2R} from '../constants/values'; + + +export function init() { + var zone = adjust_zone(this.zone, this.long0); + if (zone === undefined) { + throw new Error('unknown utm zone'); + } + this.lat0 = 0; + this.long0 = ((6 * Math.abs(zone)) - 183) * D2R; + this.x0 = 500000; + this.y0 = this.utmSouth ? 10000000 : 0; + this.k0 = 0.9996; + + etmerc.init.apply(this); + this.forward = etmerc.forward; + this.inverse = etmerc.inverse; +} + +export var names = ["Universal Transverse Mercator System", "utm"]; +export default { + init: init, + names: names, + dependsOn: dependsOn +}; diff --git a/node_modules/proj4/lib/projections/vandg.js b/node_modules/proj4/lib/projections/vandg.js new file mode 100644 index 0000000..1f1b503 --- /dev/null +++ b/node_modules/proj4/lib/projections/vandg.js @@ -0,0 +1,129 @@ +import adjust_lon from '../common/adjust_lon'; + +import {HALF_PI, EPSLN} from '../constants/values'; + +import asinz from '../common/asinz'; + +/* Initialize the Van Der Grinten projection + ----------------------------------------*/ +export function init() { + //this.R = 6370997; //Radius of earth + this.R = this.a; +} + +export function forward(p) { + + var lon = p.x; + var lat = p.y; + + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + var x, y; + + if (Math.abs(lat) <= EPSLN) { + x = this.x0 + this.R * dlon; + y = this.y0; + } + var theta = asinz(2 * Math.abs(lat / Math.PI)); + if ((Math.abs(dlon) <= EPSLN) || (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN)) { + x = this.x0; + if (lat >= 0) { + y = this.y0 + Math.PI * this.R * Math.tan(0.5 * theta); + } + else { + y = this.y0 + Math.PI * this.R * -Math.tan(0.5 * theta); + } + // return(OK); + } + var al = 0.5 * Math.abs((Math.PI / dlon) - (dlon / Math.PI)); + var asq = al * al; + var sinth = Math.sin(theta); + var costh = Math.cos(theta); + + var g = costh / (sinth + costh - 1); + var gsq = g * g; + var m = g * (2 / sinth - 1); + var msq = m * m; + var con = Math.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq); + if (dlon < 0) { + con = -con; + } + x = this.x0 + con; + //con = Math.abs(con / (Math.PI * this.R)); + var q = asq + g; + con = Math.PI * this.R * (m * q - al * Math.sqrt((msq + asq) * (asq + 1) - q * q)) / (msq + asq); + if (lat >= 0) { + //y = this.y0 + Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con); + y = this.y0 + con; + } + else { + //y = this.y0 - Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con); + y = this.y0 - con; + } + p.x = x; + p.y = y; + return p; +} + +/* Van Der Grinten inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ +export function inverse(p) { + var lon, lat; + var xx, yy, xys, c1, c2, c3; + var a1; + var m1; + var con; + var th1; + var d; + + /* inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + con = Math.PI * this.R; + xx = p.x / con; + yy = p.y / con; + xys = xx * xx + yy * yy; + c1 = -Math.abs(yy) * (1 + xys); + c2 = c1 - 2 * yy * yy + xx * xx; + c3 = -2 * c1 + 1 + 2 * yy * yy + xys * xys; + d = yy * yy / c3 + (2 * c2 * c2 * c2 / c3 / c3 / c3 - 9 * c1 * c2 / c3 / c3) / 27; + a1 = (c1 - c2 * c2 / 3 / c3) / c3; + m1 = 2 * Math.sqrt(-a1 / 3); + con = ((3 * d) / a1) / m1; + if (Math.abs(con) > 1) { + if (con >= 0) { + con = 1; + } + else { + con = -1; + } + } + th1 = Math.acos(con) / 3; + if (p.y >= 0) { + lat = (-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI; + } + else { + lat = -(-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI; + } + + if (Math.abs(xx) < EPSLN) { + lon = this.long0; + } + else { + lon = adjust_lon(this.long0 + Math.PI * (xys - 1 + Math.sqrt(1 + 2 * (xx * xx - yy * yy) + xys * xys)) / 2 / xx); + } + + p.x = lon; + p.y = lat; + return p; +} + +export var names = ["Van_der_Grinten_I", "VanDerGrinten", "vandg"]; +export default { + init: init, + forward: forward, + inverse: inverse, + names: names +}; diff --git a/node_modules/proj4/lib/transform.js b/node_modules/proj4/lib/transform.js new file mode 100644 index 0000000..beda6df --- /dev/null +++ b/node_modules/proj4/lib/transform.js @@ -0,0 +1,106 @@ +import {D2R, R2D, PJD_3PARAM, PJD_7PARAM, PJD_GRIDSHIFT} from './constants/values'; +import datum_transform from './datum_transform'; +import adjust_axis from './adjust_axis'; +import proj from './Proj'; +import toPoint from './common/toPoint'; +import checkSanity from './checkSanity'; + +function checkNotWGS(source, dest) { + return ( + (source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM || source.datum.datum_type === PJD_GRIDSHIFT) && dest.datumCode !== 'WGS84') || + ((dest.datum.datum_type === PJD_3PARAM || dest.datum.datum_type === PJD_7PARAM || dest.datum.datum_type === PJD_GRIDSHIFT) && source.datumCode !== 'WGS84'); +} + +export default function transform(source, dest, point, enforceAxis) { + var wgs84; + if (Array.isArray(point)) { + point = toPoint(point); + } else { + // Clone the point object so inputs don't get modified + point = { + x: point.x, + y: point.y, + z: point.z, + m: point.m + }; + } + var hasZ = point.z !== undefined; + checkSanity(point); + // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84 + if (source.datum && dest.datum && checkNotWGS(source, dest)) { + wgs84 = new proj('WGS84'); + point = transform(source, wgs84, point, enforceAxis); + source = wgs84; + } + // DGR, 2010/11/12 + if (enforceAxis && source.axis !== 'enu') { + point = adjust_axis(source, false, point); + } + // Transform source points to long/lat, if they aren't already. + if (source.projName === 'longlat') { + point = { + x: point.x * D2R, + y: point.y * D2R, + z: point.z || 0 + }; + } else { + if (source.to_meter) { + point = { + x: point.x * source.to_meter, + y: point.y * source.to_meter, + z: point.z || 0 + }; + } + point = source.inverse(point); // Convert Cartesian to longlat + if (!point) { + return; + } + } + // Adjust for the prime meridian if necessary + if (source.from_greenwich) { + point.x += source.from_greenwich; + } + + // Convert datums if needed, and if possible. + point = datum_transform(source.datum, dest.datum, point); + if (!point) { + return; + } + + // Adjust for the prime meridian if necessary + if (dest.from_greenwich) { + point = { + x: point.x - dest.from_greenwich, + y: point.y, + z: point.z || 0 + }; + } + + if (dest.projName === 'longlat') { + // convert radians to decimal degrees + point = { + x: point.x * R2D, + y: point.y * R2D, + z: point.z || 0 + }; + } else { // else project + point = dest.forward(point); + if (dest.to_meter) { + point = { + x: point.x / dest.to_meter, + y: point.y / dest.to_meter, + z: point.z || 0 + }; + } + } + + // DGR, 2010/11/12 + if (enforceAxis && dest.axis !== 'enu') { + return adjust_axis(dest, true, point); + } + + if (!hasZ) { + delete point.z; + } + return point; +} diff --git a/node_modules/proj4/package.json b/node_modules/proj4/package.json new file mode 100644 index 0000000..ee51f6a --- /dev/null +++ b/node_modules/proj4/package.json @@ -0,0 +1,46 @@ +{ + "name": "proj4", + "version": "2.9.0", + "description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.", + "homepage": "https://proj4js.github.io/proj4js/", + "main": "dist/proj4-src.js", + "module": "lib/index.js", + "directories": { + "test": "test", + "doc": "docs" + }, + "scripts": { + "prepare": "grunt", + "build": "grunt", + "build:tmerc": "grunt build:tmerc", + "test": "npm run build && istanbul test node_modules/mocha/bin/_mocha test/test.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/proj4js/proj4js.git" + }, + "author": "", + "license": "MIT", + "devDependencies": { + "chai": "~4.1.2", + "curl-amd": "^0.8.12", + "grunt": "^1.0.1", + "grunt-cli": "~1.2.0", + "grunt-contrib-connect": "~1.0.2", + "grunt-contrib-jshint": "~3.2.0", + "grunt-contrib-uglify": "~3.1.0", + "grunt-mocha-phantomjs": "~4.0.0", + "grunt-rollup": "^6.0.0", + "istanbul": "~0.4.5", + "mocha": "~4.0.0", + "rollup": "^0.50.0", + "rollup-plugin-json": "^2.3.0", + "rollup-plugin-node-resolve": "^3.0.0", + "rollup-plugin-replace": "^2.0.0", + "tin": "~0.5.0" + }, + "dependencies": { + "mgrs": "1.0.0", + "wkt-parser": "^1.3.1" + } +} diff --git a/node_modules/proj4/projs.js b/node_modules/proj4/projs.js new file mode 100644 index 0000000..5209f54 --- /dev/null +++ b/node_modules/proj4/projs.js @@ -0,0 +1,60 @@ +import tmerc from './lib/projections/tmerc'; +import etmerc from './lib/projections/etmerc'; +import utm from './lib/projections/utm'; +import sterea from './lib/projections/sterea'; +import stere from './lib/projections/stere'; +import somerc from './lib/projections/somerc'; +import omerc from './lib/projections/omerc'; +import lcc from './lib/projections/lcc'; +import krovak from './lib/projections/krovak'; +import cass from './lib/projections/cass'; +import laea from './lib/projections/laea'; +import aea from './lib/projections/aea'; +import gnom from './lib/projections/gnom'; +import cea from './lib/projections/cea'; +import eqc from './lib/projections/eqc'; +import poly from './lib/projections/poly'; +import nzmg from './lib/projections/nzmg'; +import mill from './lib/projections/mill'; +import sinu from './lib/projections/sinu'; +import moll from './lib/projections/moll'; +import eqdc from './lib/projections/eqdc'; +import vandg from './lib/projections/vandg'; +import aeqd from './lib/projections/aeqd'; +import ortho from './lib/projections/ortho'; +import qsc from './lib/projections/qsc'; +import robin from './lib/projections/robin'; +import geocent from './lib/projections/geocent'; +import tpers from './lib/projections/tpers'; +import geos from './lib/projections/geos'; +export default function(proj4){ + proj4.Proj.projections.add(tmerc); + proj4.Proj.projections.add(etmerc); + proj4.Proj.projections.add(utm); + proj4.Proj.projections.add(sterea); + proj4.Proj.projections.add(stere); + proj4.Proj.projections.add(somerc); + proj4.Proj.projections.add(omerc); + proj4.Proj.projections.add(lcc); + proj4.Proj.projections.add(krovak); + proj4.Proj.projections.add(cass); + proj4.Proj.projections.add(laea); + proj4.Proj.projections.add(aea); + proj4.Proj.projections.add(gnom); + proj4.Proj.projections.add(cea); + proj4.Proj.projections.add(eqc); + proj4.Proj.projections.add(poly); + proj4.Proj.projections.add(nzmg); + proj4.Proj.projections.add(mill); + proj4.Proj.projections.add(sinu); + proj4.Proj.projections.add(moll); + proj4.Proj.projections.add(eqdc); + proj4.Proj.projections.add(vandg); + proj4.Proj.projections.add(aeqd); + proj4.Proj.projections.add(ortho); + proj4.Proj.projections.add(qsc); + proj4.Proj.projections.add(robin); + proj4.Proj.projections.add(geocent); + proj4.Proj.projections.add(tpers); + proj4.Proj.projections.add(geos); +} \ No newline at end of file diff --git a/node_modules/proj4/publish.sh b/node_modules/proj4/publish.sh new file mode 100644 index 0000000..a31f4cc --- /dev/null +++ b/node_modules/proj4/publish.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# get current version +VERSION=$(node -e "console.log(require('./package.json').version)") + +# Build +git checkout -b build +node_modules/.bin/grunt +git add dist -f +git commit -m "build $VERSION" + +# Tag and push +git tag $VERSION +git push --tags git@github.com:proj4js/proj4js.git $VERSION + +# Publish +npm publish + +# Cleanup +git checkout master +git branch -D build diff --git a/node_modules/proj4/test/BETA2007.gsb b/node_modules/proj4/test/BETA2007.gsb new file mode 100644 index 0000000..69cd334 Binary files /dev/null and b/node_modules/proj4/test/BETA2007.gsb differ diff --git a/node_modules/proj4/test/amd.html b/node_modules/proj4/test/amd.html new file mode 100644 index 0000000..f658cda --- /dev/null +++ b/node_modules/proj4/test/amd.html @@ -0,0 +1,63 @@ + + + + Mocha Tests + + + + +
+ + + + + + + diff --git a/node_modules/proj4/test/ntv2_0_downsampled.gsb b/node_modules/proj4/test/ntv2_0_downsampled.gsb new file mode 100644 index 0000000..06b8111 Binary files /dev/null and b/node_modules/proj4/test/ntv2_0_downsampled.gsb differ diff --git a/node_modules/proj4/test/opt.html b/node_modules/proj4/test/opt.html new file mode 100644 index 0000000..4d00a1e --- /dev/null +++ b/node_modules/proj4/test/opt.html @@ -0,0 +1,25 @@ + + + + Mocha Tests + + +
+ + + + + + + + \ No newline at end of file diff --git a/node_modules/proj4/test/package.json.js b/node_modules/proj4/test/package.json.js new file mode 100644 index 0000000..b82c0d2 --- /dev/null +++ b/node_modules/proj4/test/package.json.js @@ -0,0 +1 @@ +define({version : "curl is dumb"}); \ No newline at end of file diff --git a/node_modules/proj4/test/test.js b/node_modules/proj4/test/test.js new file mode 100644 index 0000000..158c4cd --- /dev/null +++ b/node_modules/proj4/test/test.js @@ -0,0 +1,550 @@ +// You can do this in the grunt config for each mocha task, see the `options` config + + +// Start the main app logic. + +function startTests(chai, proj4, testPoints) { + + + var assert = chai.assert; + proj4.defs([ + ["EPSG:102018", "+proj=gnom +lat_0=90 +lon_0=0 +x_0=6300000 +y_0=6300000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"], + ["testmerc", "+proj=merc +lon_0=5.937 +lat_ts=45.027 +ellps=sphere"], + ["testmerc2", "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +units=m +k=1.0 +nadgrids=@null +no_defs"] + ]); + proj4.defs('esriOnline', 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'); + + describe('parse', function() { + it('should parse units', function() { + assert.equal(proj4.defs('testmerc2').units, 'm'); + }); + }); + + describe('proj2proj', function() { + it('should work transforming from one projection to another', function() { + var sweref99tm = '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'; + var rt90 = '+lon_0=15.808277777799999 +lat_0=0.0 +k=1.0 +x_0=1500000.0 +y_0=0.0 +proj=tmerc +ellps=bessel +units=m +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +no_defs'; + var rslt = proj4(sweref99tm, rt90).forward([319180, 6399862]); + assert.closeTo(rslt[0], 1271137.927561178, 0.000001); + assert.closeTo(rslt[1], 6404230.291456626, 0.000001); + }); + it('should work with a proj object', function() { + var sweref99tm = proj4('+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'); + var rt90 = proj4('+lon_0=15.808277777799999 +lat_0=0.0 +k=1.0 +x_0=1500000.0 +y_0=0.0 +proj=tmerc +ellps=bessel +units=m +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +no_defs'); + var rslt = proj4(sweref99tm, rt90).forward([319180, 6399862]); + assert.closeTo(rslt[0], 1271137.927561178, 0.000001); + assert.closeTo(rslt[1], 6404230.291456626, 0.000001); + }); + }); + + describe('proj4', function() { + describe('core', function() { + testPoints.forEach(function(testPoint) { + describe(testPoint.code, function() { + var xyAcc = 2, + llAcc = 6; + if ('acc' in testPoint) { + if ('xy' in testPoint.acc) { + xyAcc = testPoint.acc.xy; + } + if ('ll' in testPoint.acc) { + llAcc = testPoint.acc.ll; + } + } + var xyEPSLN = Math.pow(10, - 1 * xyAcc); + var llEPSLN = Math.pow(10, - 1 * llAcc); + describe('traditional', function() { + it('should work with forwards', function() { + var proj = new proj4.Proj(testPoint.code); + var xy = proj4.transform(proj4.WGS84, proj, proj4.toPoint(testPoint.ll)); + assert.closeTo(xy.x, testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy.y, testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('should work with backwards', function() { + var proj = new proj4.Proj(testPoint.code); + var ll = proj4.transform(proj, proj4.WGS84, proj4.toPoint(testPoint.xy)); + assert.closeTo(ll.x, testPoint.ll[0], llEPSLN, 'lng is close'); + assert.closeTo(ll.y, testPoint.ll[1], llEPSLN, 'lat is close'); + }); + }); + describe('new method 2 param', function() { + it('shortcut method should work with an array', function() { + var xy = proj4(testPoint.code, testPoint.ll); + assert.closeTo(xy[0], testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy[1], testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('shortcut method should work with an object', function() { + var pt = { + x: testPoint.ll[0], + y: testPoint.ll[1] + }; + var xy = proj4(testPoint.code, pt); + assert.closeTo(xy.x, testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy.y, testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('shortcut method should work with a point object', function() { + var pt = proj4.toPoint(testPoint.ll); + var xy = proj4(testPoint.code, pt); + assert.closeTo(xy.x, testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy.y, testPoint.xy[1], xyEPSLN, 'y is close'); + }); + }); + describe('new method 3 param', function() { + it('shortcut method should work with an array', function() { + var xy = proj4(proj4.WGS84, testPoint.code, testPoint.ll); + assert.closeTo(xy[0], testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy[1], testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('shortcut method should work with an object', function() { + var pt = { + x: testPoint.ll[0], + y: testPoint.ll[1] + }; + var xy = proj4(proj4.WGS84, testPoint.code, pt); + assert.closeTo(xy.x, testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy.y, testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('shortcut method should work with a point object', function() { + var pt = proj4.toPoint(testPoint.ll); + var xy = proj4(proj4.WGS84, testPoint.code, pt); + assert.closeTo(xy.x, testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy.y, testPoint.xy[1], xyEPSLN, 'y is close'); + }); + }); + describe('new method 3 param other way', function() { + it('shortcut method should work with an array', function() { + var ll = proj4(testPoint.code, proj4.WGS84, testPoint.xy); + assert.closeTo(ll[0], testPoint.ll[0], llEPSLN, 'x is close'); + assert.closeTo(ll[1], testPoint.ll[1], llEPSLN, 'y is close'); + }); + it('shortcut method should work with an object', function() { + var pt = { + x: testPoint.xy[0], + y: testPoint.xy[1] + }; + // in case of geocentric proj we need Z value. + if (typeof testPoint.xy[2] === 'number') { + pt.z = testPoint.xy[2] + } + var ll = proj4(testPoint.code, proj4.WGS84, pt); + assert.closeTo(ll.x, testPoint.ll[0], llEPSLN, 'x is close'); + assert.closeTo(ll.y, testPoint.ll[1], llEPSLN, 'y is close'); + }); + it('shortcut method should work with a point object', function() { + var pt = proj4.toPoint(testPoint.xy); + var ll = proj4(testPoint.code, proj4.WGS84, pt); + assert.closeTo(ll.x, testPoint.ll[0], llEPSLN, 'x is close'); + assert.closeTo(ll.y, testPoint.ll[1], llEPSLN, 'y is close'); + }); + }); + describe('1 param', function() { + it('forwards', function() { + var xy = proj4(testPoint.code).forward(testPoint.ll); + assert.closeTo(xy[0], testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy[1], testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('inverse', function() { + var ll = proj4(testPoint.code).inverse(testPoint.xy); + assert.closeTo(ll[0], testPoint.ll[0], llEPSLN, 'x is close'); + assert.closeTo(ll[1], testPoint.ll[1], llEPSLN, 'y is close'); + }); + }); + describe('proj object', function() { + it('should work with a 2 element array', function() { + var xy = proj4(new proj4.Proj(testPoint.code), testPoint.ll); + assert.closeTo(xy[0], testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy[1], testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('should work on element', function() { + var xy = proj4(new proj4.Proj(testPoint.code)).forward(testPoint.ll); + assert.closeTo(xy[0], testPoint.xy[0], xyEPSLN, 'x is close'); + assert.closeTo(xy[1], testPoint.xy[1], xyEPSLN, 'y is close'); + }); + it('should work 3 element point object', function() { + var pt = proj4.toPoint(testPoint.xy); + var ll = proj4(new proj4.Proj(testPoint.code), proj4.WGS84, pt); + assert.closeTo(ll.x, testPoint.ll[0], llEPSLN, 'x is close'); + assert.closeTo(ll.y, testPoint.ll[1], llEPSLN, 'y is close'); + }); + }); + describe('proj coord object', function() { + it('should not be modified', function() { + var expected = {x: 100000, y: 100000}; + var inpxy = {x: expected.x, y: expected.y}; + proj4('EPSG:3857', proj4.WGS84, inpxy); + + assert.deepEqual(inpxy, expected, "input is unmodified"); + }); + }); + }); + }); + }); + describe('points', function () { + it('should not create a z if none was provided', function() { + const result = proj4( + 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', + 'PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB_1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4277"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",-2],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000],PARAMETER["false_northing",-100000],AUTHORITY["EPSG","27700"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', + {x: -0.12793738, y: 51.507747}); + assert.closeTo(result.x, 530018.229301635, 1e-6); + assert.closeTo(result.y, 180418.4380560551, 1e-6); + assert.equal(result.z, undefined); + }); + it('should ignore stuff it does not know', function () { + var sweref99tm = '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'; + var rt90 = '+lon_0=15.808277777799999 +lat_0=0.0 +k=1.0 +x_0=1500000.0 +y_0=0.0 +proj=tmerc +ellps=bessel +units=m +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +no_defs'; + var rslt = proj4(sweref99tm, rt90).forward({ + x: 319180, + y: 6399862, + z: 0, + m: 1000, + method: function () { + return 'correct answer'; + } + }); + assert.closeTo(rslt.x, 1271137.927561178, 0.000001); + assert.closeTo(rslt.y, 6404230.291456626, 0.000001); + assert.equal(rslt.z, 0); + assert.equal(rslt.m, 1000); + assert.equal(rslt.method(), 'correct answer'); + }); + it('should be able to compute X Y Z M in geocenteric coordinates', function () { + var epsg4978 = '+proj=geocent +datum=WGS84 +units=m +no_defs'; + var rslt = proj4(epsg4978).forward({ + x: -7.76166, + y: 39.19685, + z: 0, + m: 1000, + method: function () { + return 'correct answer'; + } + }); + assert.closeTo(rslt.x, 4904199.584207411, 0.000001); + assert.closeTo(rslt.y, -668448.8153664203, 0.000001); + assert.closeTo(rslt.z, 4009276.930771821, 0.000001); + assert.equal(rslt.m, 1000); + assert.equal(rslt.method(), 'correct answer'); + }); + }); + describe('points array', function () { + it('should ignore stuff it does not know', function () { + var sweref99tm = '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'; + var rt90 = '+lon_0=15.808277777799999 +lat_0=0.0 +k=1.0 +x_0=1500000.0 +y_0=0.0 +proj=tmerc +ellps=bessel +units=m +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +no_defs'; + var rslt = proj4(sweref99tm, rt90).forward([ + 319180, + 6399862, + 0, + 1000, + ]); + assert.closeTo(rslt[0], 1271137.927561178, 0.000001); + assert.closeTo(rslt[1], 6404230.291456626, 0.000001); + assert.equal(rslt[2], 0); + assert.equal(rslt[3], 1000); + }); + it('should be able to compute X Y Z M in geocenteric coordinates', function () { + var epsg4978 = '+proj=geocent +datum=WGS84 +units=m +no_defs'; + var rslt = proj4(epsg4978).forward([ + -7.76166, + 39.19685, + 0, + 1000 + ]); + assert.closeTo(rslt[0], 4904199.584207411, 0.000001); + assert.closeTo(rslt[1], -668448.8153664203, 0.000001); + assert.closeTo(rslt[2], 4009276.930771821, 0.000001); + assert.equal(rslt[3], 1000); + }); + }); + + it('should use [x,y] axis order', function() { + var enu = 'PROJCS["NAD83 / Massachusetts Mainland", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26986"]]'; + var neu = 'PROJCS["NAD83 / Massachusetts Mainland NE", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Northing", NORTH], AXIS["Easting", EAST], AUTHORITY["EPSG","26986"]]'; + var rslt = proj4(enu, neu).forward({ + x: 10.2, + y: 43.4 + }); + assert.closeTo(rslt.x, 10.2, 0.000001); + assert.closeTo(rslt.y, 43.4, 0.000001); + }); + + it('should use correct axis order with proj4.transform()', function() { + var enu = 'PROJCS["NAD83 / Massachusetts Mainland", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26986"]]'; + var neu = 'PROJCS["NAD83 / Massachusetts Mainland NE", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Northing", NORTH], AXIS["Easting", EAST], AUTHORITY["EPSG","26986"]]'; + var rslt = proj4(enu, neu).forward({ + x: 10.2, + y: 43.4 + }, true); + assert.closeTo(rslt.x, 43.4, 0.000001); + assert.closeTo(rslt.y, 10.2, 0.000001); + }); + + it('axes should be invertable with proj4.transform()', function () { + var enu = '+proj=longlat +axis=enu'; + var esu = '+proj=longlat +axis=esu'; + var wnu = '+proj=longlat +axis=wnu'; + var result = proj4(enu, esu).forward({x: 40, y: 50}, true); + assert.closeTo(result.x, 40, 0.000001); + assert.closeTo(result.y, -50, 0.000001); + var result = proj4(enu, wnu).forward({x: 40, y: 50}, true); + assert.closeTo(result.x, -40, 0.000001); + assert.closeTo(result.y, 50, 0.000001); + }); + + describe('defs', function () { + assert.equal(proj4.defs('testmerc'), proj4.defs['testmerc']); + proj4.defs('foo', '+proj=merc +lon_0=5.937 +lat_ts=45.027 +ellps=sphere'); + assert.typeOf(proj4.defs['foo'], 'object'); + proj4.defs('urn:x-ogc:def:crs:EPSG:4326', proj4.defs('EPSG:4326')); + assert.strictEqual(proj4.defs['urn:x-ogc:def:crs:EPSG:4326'], proj4.defs['EPSG:4326']); + + describe('wkt', function () { + it('should provide the correct conversion factor for WKT GEOGCS projections', function () { + proj4.defs('EPSG:4269', 'GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]]'); + assert.equal(proj4.defs['EPSG:4269'].to_meter, 6378137 * 0.01745329251994328); + + proj4.defs('EPSG:4279', 'GEOGCS["OS(SN)80",DATUM["OS_SN_1980",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],AUTHORITY["EPSG","6279"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4279"]]'); + assert.equal(proj4.defs['EPSG:4279'].to_meter, 6377563.396 * 0.01745329251994328); + }); + it('should parse wkt and proj4 of the same crs and result in the same params', function () { + var s1 = 'GEOGCS["PSD93",DATUM["PDO_Survey_Datum_1993",SPHEROID["Clarke 1880 (RGS)",6378249.145,293.465,AUTHORITY["EPSG","7012"]],TOWGS84[-180.624,-225.516,173.919,-0.81,-1.898,8.336,16.7101],AUTHORITY["EPSG","6134"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4134"]]'; + var s2 = '+proj=longlat +ellps=clrk80 +towgs84=-180.624,-225.516,173.919,-0.81,-1.898,8.336,16.7101 +no_defs'; + var crs1 = proj4(s1); + var crs2 = proj4(s2); + assert.equal(crs1.oProj.a, crs2.oProj.a); + // proj4 has different ellipsoid parameters that EPSG: http://epsg.io/4134 + // assert.equal(crs1.oProj.b, crs2.oProj.b); + }); + it('should handled defined points correctly', function () { + var prj = '+proj=utm +zone=31'; + var proj = proj4(prj); + var res = proj.forward([3, 0]); + assert.deepEqual(res, [500000, 0]); + }); + }); + }); + describe('errors', function() { + it('should throw an error for an unknown ref', function() { + assert.throws(function() { + new proj4.Proj('fake one'); + }, 'fake one', 'should work'); + }); + it('should throw when passed null', function() { + assert.throws(function() { + proj4('+proj=utm +zone=31', [null, 0]); + }, 'coordinates must be finite numbers', 'should work'); + }); + it('should throw when passed NaN', function() { + assert.throws(function() { + proj4('+proj=utm +zone=31', [0, NaN]); + }, 'coordinates must be finite numbers', 'should work'); + }); + it('should throw when passed Infinity', function() { + assert.throws(function() { + proj4('+proj=utm +zone=31', [Infinity, 0]); + }, 'coordinates must be finite numbers', 'should work'); + }); + it('should throw when passed -Infinity', function() { + assert.throws(function() { + proj4('+proj=utm +zone=31', [-Infinity, 0]); + }, 'coordinates must be finite numbers', 'should work'); + }); + }); + describe('utility', function() { + it('should have MGRS available in the proj4.util namespace', function() { + assert.typeOf(proj4.mgrs, "object", "MGRS available in the proj4.util namespace"); + }); + it('should have fromMGRS method added to proj4.Point prototype', function() { + assert.typeOf(proj4.Point.fromMGRS, "function", "fromMGRS method added to proj4.Point prototype"); + }); + it('should have toMGRS method added to proj4.Point prototype', function() { + assert.typeOf(proj4.Point.prototype.toMGRS, "function", "toMGRS method added to proj4.Point prototype"); + }); + + describe('First MGRS set', function() { + var mgrs = "33UXP04"; + var point = proj4.Point.fromMGRS(mgrs); + it('Longitude of point from MGRS correct.', function() { + assert.equal(point.x.toPrecision(7), "16.41450", "Longitude of point from MGRS correct."); + }); + it('Latitude of point from MGRS correct.', function() { + assert.equal(point.y.toPrecision(7), "48.24949", "Latitude of point from MGRS correct."); + }); + it('MGRS reference with highest accuracy correct.', function() { + assert.equal(point.toMGRS(), "33UXP0500444998", "MGRS reference with highest accuracy correct."); + }); + it('MGRS reference with 1-digit accuracy correct.', function() { + assert.equal(point.toMGRS(1), mgrs, "MGRS reference with 1-digit accuracy correct."); + }); + }); + describe('Second MGRS set', function() { + var mgrs = "24XWT783908"; // near UTM zone border, so there are two ways to reference this + var point = proj4.Point.fromMGRS(mgrs); + it("Longitude of point from MGRS correct.", function() { + assert.equal(point.x.toPrecision(7), "-32.66433", "Longitude of point from MGRS correct."); + }); + it("Latitude of point from MGRS correct.", function() { + assert.equal(point.y.toPrecision(7), "83.62778", "Latitude of point from MGRS correct."); + }); + it("MGRS reference with 3-digit accuracy correct.", function() { + assert.equal(point.toMGRS(3), "25XEN041865", "MGRS reference with 3-digit accuracy correct."); + }); + }); + describe('Defs and Datum definition', function() { + proj4.defs("EPSG:5514", "+proj=krovak +lat_0=49.5 +lon_0=24.83333333333333 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +pm=greenwich +units=m +no_defs +towgs84=570.8,85.7,462.8,4.998,1.587,5.261,3.56"); + var point = proj4.transform(proj4.Proj("WGS84"), proj4.Proj("EPSG:5514"), + proj4.toPoint([12.806988, 49.452262])); + it("Longitude of point from WGS84 correct.", function() { + assert.equal(point.x.toPrecision(8), "-868208.61", "Longitude of point from WGS84 correct."); + }); + it("Latitude of point from WGS84 correct.", function() { + assert.equal(point.y.toPrecision(9), "-1095793.64", "Latitude of point from WGS84 correct."); + }); + var point2 = proj4.transform(proj4.Proj("WGS84"), proj4.Proj("EPSG:5514"), + proj4.toPoint([12.806988, 49.452262])); + it("Longitude of point from WGS84 with second call for EPSG:5514 correct.", function() { + assert.equal(point2.x.toPrecision(8), "-868208.61", "Longitude of point from WGS84 correct."); + }); + it("Latitude of point from WGS84 with second call for EPSG:5514 correct.", function() { + assert.equal(point2.y.toPrecision(9), "-1095793.64", "Latitude of point from WGS84 correct."); + }); + }); + }); + + describe('Nadgrids BETA2007', function() { + var tests = [ + ['EPSG:31466', 'EPSG:4326', 2559552, 5670982, 6.850861772, 51.170707759, 0.0000001, 0.01], + ['EPSG:31466', 'EPSG:3857', 2559552, 5670982, 762634.443931574, 6651545.680265270, 0.01, 0.01], + ['EPSG:31466', 'EPSG:25832', 2559552, 5670982, 349757.381712518, 5671004.065049540, 0.01, 0.01], + ]; + + function initializeNadgrid(buffer) { + proj4.nadgrid('BETA2007.gsb', buffer); + proj4.defs('EPSG:31466', '+proj=tmerc +lat_0=0 +lon_0=6 +k=1 +x_0=2500000 +y_0=0 +ellps=bessel +nadgrids=BETA2007.gsb +units=m +no_defs +type=crs'); + proj4.defs('EPSG:25832', '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs'); + } + + before(function(done) { + if (typeof XMLHttpRequest !== 'undefined') { + const xhr = new XMLHttpRequest(); + xhr.open('GET', 'BETA2007.gsb', true); + xhr.responseType = 'arraybuffer'; + xhr.addEventListener('load', function() { + initializeNadgrid(xhr.response); + done(); + }); + xhr.addEventListener('error', done); + xhr.send(); + } else if (typeof require === 'function') { + const fs = require('fs'); + const path = require('path'); + fs.readFile(path.join(__dirname, 'BETA2007.gsb'), function(err, data) { + if (err) { + done(err); + } else { + initializeNadgrid(data.buffer); + done(); + } + }) + } + }); + + tests.forEach(function(test) { + var fromProj = test[0]; + var toProj = test[1]; + var fromX = test[2]; + var fromY = test[3]; + var toX = test[4]; + var toY = test[5]; + var fromPrecision = test[6]; + var toPrecision = test[7]; + it('should transform ' + fromProj + ' to ' + toProj, function () { + var transformed = proj4(fromProj, toProj, [fromX, fromY]); + assert.approximately(transformed[0], toX, fromPrecision); + assert.approximately(transformed[1], toY, fromPrecision); + }); + it('should transform ' + toProj + ' to ' + fromProj, function () { + var transformed = proj4(toProj, fromProj, [toX, toY]); + assert.approximately(transformed[0], fromX, toPrecision); + assert.approximately(transformed[1], fromY, toPrecision); + }); + }); + }); + + describe('Nadgrids ntv2', function() { + var tests = [ + [-44.382211538462, 40.3768, -44.380749, 40.377457], // just inside the lower limit + [-87.617788, 59.623262, -87.617659, 59.623441], // just inside the upper limit + [-44.5, 40.5, -44.498553, 40.500632], // inside the first square + [-60, 50, -59.999192, 50.000058], // a general point towards the middle of the grid + [0, 0, 0, 0] // fall back to null + ]; + + var converter; + + function initializeNadgrid(buffer) { + proj4.nadgrid('ntv2', buffer); + proj4.defs('ntv2_from', '+proj=longlat +ellps=clrk66 +nadgrids=@ignorable,ntv2,null'); + proj4.defs('ntv2_to', '+proj=longlat +datum=WGS84 +no_defs'); + converter = proj4('ntv2_from', 'ntv2_to'); + } + + before(function(done) { + if (typeof XMLHttpRequest !== 'undefined') { + const xhr = new XMLHttpRequest(); + xhr.open('GET', 'ntv2_0_downsampled.gsb', true); + xhr.responseType = 'arraybuffer'; + xhr.addEventListener('load', function() { + initializeNadgrid(xhr.response); + done(); + }); + xhr.addEventListener('error', done); + xhr.send(); + } else if (typeof require === 'function') { + const fs = require('fs'); + const path = require('path'); + fs.readFile(path.join(__dirname, 'ntv2_0_downsampled.gsb'), function(err, data) { + if (err) { + done(err); + } else { + initializeNadgrid(data.buffer); + done(); + } + }) + } + }); + + tests.forEach(function(test) { + var fromLng = test[0]; + var fromLat = test[1]; + var toLng = test[2]; + var toLat = test[3]; + it('should interpolate ' + [fromLng, fromLat] + ' to ' + [toLng, toLat], function () { + var actual = converter.forward([fromLng, fromLat]); + assert.approximately(actual[0], toLng, 0.000001); + assert.approximately(actual[1], toLat, 0.000001); + }); + }); + + var inverseTests = [ + [-44.5, 40.5, -44.498553, 40.500632], + [-60, 50, -59.999192, 50.000058] + ]; + + inverseTests.forEach(function(test) { + var fromLng = test[0]; + var fromLat = test[1]; + var toLng = test[2]; + var toLat = test[3]; + it('should inverse interpolate ' + [toLng, toLat] + ' to ' + [fromLng, fromLat], function () { + var actual = converter.inverse([toLng, toLat]); + assert.approximately(actual[0], fromLng, 0.000001); + assert.approximately(actual[1], fromLat, 0.000001); + }); + }); + }); + }); +} +if(typeof process !== 'undefined'&&process.toString() === '[object process]'){ + (function(){ + startTests(require('chai'), require('../dist/proj4-src'), require('./testData')); + })(); +} diff --git a/node_modules/proj4/test/testData.js b/node_modules/proj4/test/testData.js new file mode 100644 index 0000000..da6a0b0 --- /dev/null +++ b/node_modules/proj4/test/testData.js @@ -0,0 +1,835 @@ +var testPoints = [ + {code: 'testmerc', + xy: [-45007.0787624, 4151725.59875], + ll: [5.364315,46.623154] + }, + {code: 'testmerc2', + xy: [4156404,7480076.5], + ll: [37.33761240175515, 55.60447049026976] + }, + {code: 'PROJCS["CH1903 / LV03",GEOGCS["CH1903",DATUM["D_CH1903",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["latitude_of_center",46.95240555555556],PARAMETER["longitude_of_center",7.439583333333333],PARAMETER["azimuth",90],PARAMETER["scale_factor",1],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],UNIT["Meter",1]]', + xy: [660013.4882918689, 185172.17110117766], + ll: [8.225, 46.815], + acc:{ + xy: 0.1, + ll: 5 + } + }, + {code: 'PROJCS["CH1903 / LV03",GEOGCS["CH1903",DATUM["CH1903",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[674.4,15.1,405.3,0,0,0,0],AUTHORITY["EPSG","6149"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4149"]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["latitude_of_center",46.95240555555556],PARAMETER["longitude_of_center",7.439583333333333],PARAMETER["azimuth",90],PARAMETER["rectified_grid_angle",90],PARAMETER["scale_factor",1],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Y",EAST],AXIS["X",NORTH],AUTHORITY["EPSG","21781"]]', + xy: [660013.4882918689, 185172.17110117766], + ll: [8.225, 46.815], + acc:{ + xy: 0.1, + ll: 5 + } + }, + {code: 'PROJCS["NAD83 / Massachusetts Mainland",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",42.68333333333333],PARAMETER["standard_parallel_2",41.71666666666667],PARAMETER["latitude_of_origin",41],PARAMETER["central_meridian",-71.5],PARAMETER["false_easting",200000],PARAMETER["false_northing",750000],AUTHORITY["EPSG","26986"],AXIS["X",EAST],AXIS["Y",NORTH]]', + xy: [ 231394.84,902621.11], + ll: [-71.11881762742996,42.37346263960867] + }, + {code: 'PROJCS["NAD83 / Massachusetts Mainland",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["standard_parallel_1",42.68333333333333],PARAMETER["standard_parallel_2",41.71666666666667],PARAMETER["latitude_of_origin",41],PARAMETER["central_meridian",-71.5],PARAMETER["false_easting",200000],PARAMETER["false_northing",750000],UNIT["Meter",1]]', + xy: [ 231394.84,902621.11], + ll: [-71.11881762742996,42.37346263960867] + }, + {code:'PROJCS["NAD83 / Massachusetts Mainland", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26986"]]', + xy: [ 231394.84,902621.11], + ll: [-71.11881762742996,42.37346263960867] + }, + {code: 'PROJCS["Asia_North_Equidistant_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Equidistant_Conic"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",95],PARAMETER["Standard_Parallel_1",15],PARAMETER["Standard_Parallel_2",65],PARAMETER["Latitude_Of_Origin",30],UNIT["Meter",1]]', + xy: [88280.59904432714, 111340.90165417176], + ll: [96,31] + }, + {code: 'PROJCS["Asia_North_Equidistant_Conic",GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Equidistant_Conic"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",95],PARAMETER["Standard_Parallel_1",15],PARAMETER["Standard_Parallel_2",65],PARAMETER["Latitude_Of_Origin",30],UNIT["Meter",1],AUTHORITY["EPSG","102026"]]', + xy: [88280.59904432714, 111340.90165417176], + ll: [96,31] + }, + {code: 'PROJCS["World_Sinusoidal",GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Sinusoidal"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1],AUTHORITY["EPSG","54008"]]', + xy: [738509.49,5874620.38], + ll: [11.0, 53.0] + }, + {code: 'PROJCS["World_Sinusoidal",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Sinusoidal"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1]]', + xy: [738509.49,5874620.38], + ll: [11.0, 53.0] + }, + {code: 'PROJCS["ETRS89 / ETRS-LAEA",GEOGCS["ETRS89",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",10],PARAMETER["false_easting",4321000],PARAMETER["false_northing",3210000],UNIT["Meter",1]]', + xy: [4388138.60, 3321736.46], + ll: [11.0, 53.0] + }, + {code: 'PROJCS["ETRS89 / ETRS-LAEA",GEOGCS["ETRS89",DATUM["European_Terrestrial_Reference_System_1989",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6258"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4258"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["latitude_of_center",52],PARAMETER["longitude_of_center",10],PARAMETER["false_easting",4321000],PARAMETER["false_northing",3210000],AUTHORITY["EPSG","3035"],AXIS["X",EAST],AXIS["Y",NORTH]]', + xy: [4388138.60, 3321736.46], + ll: [11.0, 53.0] + }, + {code: 'EPSG:102018', + xy: [350577.5930806119, 4705857.070634324], + ll: [-75,46] + }, {code: '+proj=gnom +lat_0=90 +lon_0=0 +x_0=6300000 +y_0=6300000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs', + xy: [350577.5930806119, 4705857.070634324], + ll: [-75,46] + }, + {code: 'PROJCS["NAD83(CSRS) / UTM zone 17N",GEOGCS["NAD83(CSRS)",DATUM["D_North_American_1983_CSRS98",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-81],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]', + xy: [411461.807497, 4700123.744402], + ll: [-82.07666015625, 42.448388671875] + }, + {code: 'PROJCS["NAD83(CSRS) / UTM zone 17N",GEOGCS["NAD83(CSRS)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4617"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-81],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],AUTHORITY["EPSG","2958"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', + xy: [411461.807497, 4700123.744402], + ll: [-82.07666015625, 42.448388671875] + }, + {code: 'PROJCS["ETRS89 / UTM zone 32N",GEOGCS["ETRS89",DATUM["European_Terrestrial_Reference_System_1989",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6258"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4258"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",9],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","25832"]]', + xy: [-1877994.66, 3932281.56], + ll: [-16.10000000237, 32.879999998812] + }, + {code: 'PROJCS["NAD27 / UTM zone 14N",GEOGCS["NAD27 Coordinate System",DATUM["D_North American Datum 1927 (NAD27)",SPHEROID["Clarke_1866",6378206.4,294.97869821391]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-99],PARAMETER["scale_factor",0.9996],UNIT["Meter (m)",1]]', + xy: [2026074.9192811155, 12812891.606450122], + ll: [51.517955776474096, 61.56941794249017] + }, + {code: 'PROJCS["World_Mollweide",GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mollweide"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1],AUTHORITY["EPSG","54009"]]', + xy: [3891383.58309223, 6876758.9933288], + ll: [60,60] + }, + {code: 'PROJCS["World_Mollweide",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mollweide"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1]]', + xy: [3891383.58309223, 6876758.9933288], + ll: [60,60] + }, + { + code:'PROJCS["NAD83 / BC Albers",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Albers_Conic_Equal_Area"],PARAMETER["standard_parallel_1",50],PARAMETER["standard_parallel_2",58.5],PARAMETER["latitude_of_center",45],PARAMETER["longitude_of_center",-126],PARAMETER["false_easting",1000000],PARAMETER["false_northing",0],AUTHORITY["EPSG","3005"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', + ll:[-126.54, 54.15], + xy:[964813.103719, 1016486.305862] + }, { + code:'PROJCS["NAD83 / BC Albers",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Albers"],PARAMETER["standard_parallel_1",50],PARAMETER["standard_parallel_2",58.5],PARAMETER["latitude_of_origin",45],PARAMETER["central_meridian",-126],PARAMETER["false_easting",1000000],PARAMETER["false_northing",0],UNIT["Meter",1]]', + ll:[-126.54, 54.15], + xy:[964813.103719, 1016486.305862] + }, + { + code:'PROJCS["Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],PARAMETER["Latitude_Of_Origin",0],UNIT["Meter",1]]', + ll:[0, 0], + xy:[0, 0] + }, + { + code:'PROJCS["Sphere_Azimuthal_Equidistant",GEOGCS["GCS_Sphere",DATUM["Not_specified_based_on_Authalic_Sphere",SPHEROID["Sphere",6371000,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],PARAMETER["Latitude_Of_Origin",0],UNIT["Meter",1]]', + ll:[0, 0], + xy:[0, 0] + }, + { + code:'PROJCS["North_Pole_Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],PARAMETER["Latitude_Of_Origin",90],UNIT["Meter",1]]', + ll:[50.977303830208, 30.915260093747], + xy:[5112279.911077, -4143196.76625] + }, + { + code:'PROJCS["North_Pole_Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],PARAMETER["Latitude_Of_Origin",90],UNIT["Meter",1],AUTHORITY["EPSG","102016"]]', + ll:[50.977303830208, 30.915260093747], + xy:[5112279.911077, -4143196.76625] + }, + { + code:'PROJCS["Mount Dillon / Tobago Grid",GEOGCS["Mount Dillon",DATUM["Mount_Dillon",SPHEROID["Clarke 1858",6378293.645208759,294.2606763692654,AUTHORITY["EPSG","7007"]],AUTHORITY["EPSG","6157"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4157"]],UNIT["Clarke\'s link",0.201166195164,AUTHORITY["EPSG","9039"]],PROJECTION["Cassini_Soldner"],PARAMETER["latitude_of_origin",11.25217861111111],PARAMETER["central_meridian",-60.68600888888889],PARAMETER["false_easting",187500],PARAMETER["false_northing",180000],AUTHORITY["EPSG","2066"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', + ll:[-60.676753018, 11.2487234308], + xy:[192524.3061766178, 178100.2740019509], + acc:{ + ll:1, + xy:-4 + } + }, { + code:'PROJCS["Mount Dillon / Tobago Grid",GEOGCS["Mount Dillon",DATUM["D_Mount_Dillon",SPHEROID["Clarke_1858",6378293.645208759,294.2606763692654]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Cassini"],PARAMETER["latitude_of_origin",11.25217861111111],PARAMETER["central_meridian",-60.68600888888889],PARAMETER["false_easting",187500],PARAMETER["false_northing",180000],UNIT["Clarke\'s link",0.201166195164]]', + ll:[-60.676753018, 11.2487234308], + xy:[192524.3061766178, 178100.2740019509], + acc:{ + ll:1, + xy:-4 + } + }, + // { + // code:'EPSG:3975', + // ll:[-9.764450683, 25.751953], + // xy:[-942135.525095996, 3178441.8667094777] + // }, + { + code:'PROJCS["World Equidistant Cylindrical (Sphere)",GEOGCS["Unspecified datum based upon the GRS 1980 Authalic Sphere",DATUM["Not_specified_based_on_GRS_1980_Authalic_Sphere",SPHEROID["GRS 1980 Authalic Sphere",6371007,0,AUTHORITY["EPSG","7048"]],AUTHORITY["EPSG","6047"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4047"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Equirectangular"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],AUTHORITY["EPSG","3786"],AXIS["X",EAST],AXIS["Y",NORTH]]', + ll:[-1.7539371169976, 12.632997701986], + xy:[-195029.12334755991, 1395621.9368162225], + acc:{ + ll:2 + } + }, { + code:'PROJCS["World Equidistant Cylindrical (Sphere)",GEOGCS["Unspecified datum based upon the GRS 1980 Authalic Sphere",DATUM["D_",SPHEROID["GRS_1980_Authalic_Sphere",6371007,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Equidistant_Cylindrical"],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]]', + ll:[-1.7539371169976, 12.632997701986], + xy:[-195029.12334755991, 1395621.9368162225], + acc:{ + ll:2 + } + }, + { + code:'PROJCS["Segara / NEIEZ",GEOGCS["Segara",DATUM["Gunung_Segara",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],AUTHORITY["EPSG","6613"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4613"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",110],PARAMETER["scale_factor",0.997],PARAMETER["false_easting",3900000],PARAMETER["false_northing",900000],AUTHORITY["EPSG","3000"],AXIS["X",EAST],AXIS["Y",NORTH]]', + ll:[116.65547897884308 , -0.6595605286983485], + xy:[4638523.040740433, 827245.2586932715] + }, { + code:'PROJCS["Segara / NEIEZ",GEOGCS["Segara",DATUM["D_Gunung_Segara",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",110],PARAMETER["scale_factor",0.997],PARAMETER["false_easting",3900000],PARAMETER["false_northing",900000],UNIT["Meter",1]]', + ll:[116.65547897884308 , -0.6595605286983485], + xy:[4638523.040740433, 827245.2586932715] + }, + { + code:'PROJCS["Beduaram / TM 13 NE",GEOGCS["Beduaram",DATUM["Beduaram",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-106,-87,188,0,0,0,0],AUTHORITY["EPSG","6213"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4213"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",13],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],AUTHORITY["EPSG","2931"],AXIS["X",EAST],AXIS["Y",NORTH]]', + ll:[5, 25], + xy:[-308919.1234711099, 2788738.255936392] + }, + { + code:'PROJCS["Beduaram / TM 13 NE",GEOGCS["Beduaram",DATUM["D_Beduaram",SPHEROID["Clarke_1880_IGN",6378249.2,293.4660212936269]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",13],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]', + ll:[5, 25], + xy:[-308919.1234711099, 2788738.255936392] + }, + { + code: '+proj=lcc +lat_1=49.5 +lat_0=49.5 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +ellps=clrk80ign +pm=paris +towgs84=-168,-60,320,0,0,0,0 +units=m +no_defs +type=crs', + ll:[2.294482, 48.859045], + xy:[596916.561147926957, 1128733.073948238511] + }, + { + code:'PROJCS["S-JTSK (Ferro) / Krovak",GEOGCS["S-JTSK (Ferro)",DATUM["S_JTSK_Ferro",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],AUTHORITY["EPSG","6818"]],PRIMEM["Ferro",-17.66666666666667,AUTHORITY["EPSG","8909"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4818"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Krovak"],PARAMETER["latitude_of_center",49.5],PARAMETER["longitude_of_center",42.5],PARAMETER["azimuth",30.28813972222222],PARAMETER["pseudo_standard_parallel_1",78.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",0],PARAMETER["false_northing",0],AUTHORITY["EPSG","2065"],AXIS["Y",WEST],AXIS["X",SOUTH]]', + ll:[17.323583231075897, 49.39440725405376], + xy:[-544115.474379, -1144058.330762] + },{ + code:'PROJCS["S-JTSK (Ferro) / Krovak",GEOGCS["S-JTSK (Ferro)",DATUM["D_S_JTSK",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Ferro",-17.66666666666667],UNIT["Degree",0.017453292519943295]],PROJECTION["Krovak"],PARAMETER["latitude_of_center",49.5],PARAMETER["longitude_of_center",42.5],PARAMETER["azimuth",30.28813972222222],PARAMETER["pseudo_standard_parallel_1",78.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]]', + ll:[17.323583231075897, 49.39440725405376], + xy:[-544115.474379, -1144058.330762] + },{ + code:'PROJCS["Sphere_Miller_Cylindrical",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Miller_Cylindrical"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1]]', + ll:[-1.3973289073953, 12.649176474268513 ], + xy:[-155375.88535614178, 1404635.2633403721], + acc:{ + ll:3 + } + },{ + code:'PROJCS["Sphere_Miller_Cylindrical",GEOGCS["GCS_Sphere",DATUM["Not_specified_based_on_Authalic_Sphere",SPHEROID["Sphere",6371000,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Miller_Cylindrical"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1],AUTHORITY["EPSG","53003"]]', + ll:[-1.3973289073953, 12.649176474268513 ], + xy:[-155375.88535614178, 1404635.2633403721], + acc:{ + ll:3 + } + },{ + code:'PROJCS["NZGD49 / New Zealand Map Grid",GEOGCS["NZGD49",DATUM["D_New_Zealand_1949",SPHEROID["International_1924",6378388,297]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["New_Zealand_Map_Grid"],PARAMETER["latitude_of_origin",-41],PARAMETER["central_meridian",173],PARAMETER["false_easting",2510000],PARAMETER["false_northing",6023150],UNIT["Meter",1]]', + ll:[172.465, -40.7], + xy:[2464770.343667, 6056137.861919] + },{ + code:'PROJCS["NZGD49 / New Zealand Map Grid",GEOGCS["NZGD49",DATUM["New_Zealand_Geodetic_Datum_1949",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993],AUTHORITY["EPSG","6272"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4272"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["New_Zealand_Map_Grid"],PARAMETER["latitude_of_origin",-41],PARAMETER["central_meridian",173],PARAMETER["false_easting",2510000],PARAMETER["false_northing",6023150],AUTHORITY["EPSG","27200"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', + ll:[172.465, -40.7], + xy:[2464770.343667, 6056137.861919] + },{ + code: 'PROJCS["Rassadiran / Nakhl e Taqi", GEOGCS["Rassadiran", DATUM["Rassadiran", SPHEROID["International 1924",6378388,297, AUTHORITY["EPSG","7022"]], TOWGS84[-133.63,-157.5,-158.62,0,0,0,0], AUTHORITY["EPSG","6153"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4153"]], PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"], PARAMETER["latitude_of_center",27.51882880555555], PARAMETER["longitude_of_center",52.60353916666667], PARAMETER["azimuth",0.5716611944444444], PARAMETER["rectified_grid_angle",0.5716611944444444], PARAMETER["scale_factor",0.999895934], PARAMETER["false_easting",658377.437], PARAMETER["false_northing",3044969.194], UNIT["metre",1, AUTHORITY["EPSG","9001"]], AXIS["Easting",EAST], AXIS["Northing",NORTH], AUTHORITY["EPSG","2057"]]', + ll: [52.605, 27.5], + xy: [658511.261946, 3043003.05468], + acc: { + ll: 8, + xy: 6 + } + },{ + code:'PROJCS["SAD69 / Brazil Polyconic",GEOGCS["SAD69",DATUM["D_South_American_1969",SPHEROID["GRS_1967_SAD69",6378160,298.25]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Polyconic"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-54],PARAMETER["false_easting",5000000],PARAMETER["false_northing",10000000],UNIT["Meter",1]]', + ll:[-49.221772553812, -0.34551739237581], + xy:[5531902.134932, 9961660.779347], + acc:{ + ll:3, + xy:-2 + } + },{ + code:'PROJCS["SAD69 / Brazil Polyconic",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967 (SAD69)",6378160,298.25,AUTHORITY["EPSG","7050"]],AUTHORITY["EPSG","6618"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4618"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Polyconic"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-54],PARAMETER["false_easting",5000000],PARAMETER["false_northing",10000000],AUTHORITY["EPSG","29101"],AXIS["X",EAST],AXIS["Y",NORTH]]', + ll:[-49.221772553812, -0.34551739237581], + xy:[5531902.134932, 9961660.779347], + acc:{ + ll:3, + xy:-2 + } + },{ + code:'PROJCS["WGS 84 / UPS North",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.994],PARAMETER["false_easting",2000000],PARAMETER["false_northing",2000000],AUTHORITY["EPSG","32661"],AXIS["Easting",UNKNOWN],AXIS["Northing",UNKNOWN]]', + ll:[0, 75], + xy:[2000000, 325449.806286] + },{ + code:'PROJCS["WGS 84 / UPS North",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Stereographic_North_Pole"],PARAMETER["standard_parallel_1",90],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.994],PARAMETER["false_easting",2000000],PARAMETER["false_northing",2000000],UNIT["Meter",1]]', + ll:[0, 75], + xy:[2000000, 325449.806286] + },{ + code:'+proj=aeqd +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs', + ll:[2, 0], + xy:[222638.98158654713, 0] + },{ + code:'+proj=aeqd +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs', + ll:[89, 0], + xy:[9907434.680601358, 0] + },{ +// code:'+proj=aeqd +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs', +// ll:[91, 0], +// xy:[10130073.6622, 0] +// },{ + code:'+proj=aeqd +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + ll:[91, 0], + xy:[10118738.32, 0.00] + },{ + code:'+proj=laea +lat_0=2 +lon_0=1 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + ll:[1, 2], + xy:[0, 0] + },{ + code:'+proj=laea +lat_0=1 +lon_0=1 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + ll:[1, 1], + xy:[0, 0] + },{ + code:'+proj=laea +lat_0=1 +lon_0=1 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + ll:[2, 1], + xy:[111176.58, 16.93] + },{ + code:'+proj=laea +lat_0=1 +lon_0=1 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + ll:[1, 2], + xy:[0.00,111193.52] + },{ + code:'+proj=laea +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + ll:[19, 0], + xy:[2103036.59, 0.00] + },{ + code:'+proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs"', + ll:[0, -72.5], + xy:[0, 1910008.78441421] + },{ + code:'+proj=stere +lat_0=-90 +lon_0=0 +x_0=0 +y_0=0 +a=3396000 +b=3396000 +units=m +no_defs', + ll:[0, -72.5], + xy:[0, 1045388.79] + },{ + code:'PROJCS["WGS 84 / NSIDC Sea Ice Polar Stereographic South", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", -70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3976"]]', + ll:[0, -72.5], + xy:[0, 1910008.78441421] + },{ + code:'PROJCS["NAD83(CSRS98) / New Brunswick Stereo (deprecated)",GEOGCS["NAD83(CSRS98)",DATUM["D_North_American_1983_CSRS98",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Stereographic_North_Pole"],PARAMETER["standard_parallel_1",46.5],PARAMETER["central_meridian",-66.5],PARAMETER["scale_factor",0.999912],PARAMETER["false_easting",2500000],PARAMETER["false_northing",7500000],UNIT["Meter",1]]', + ll:[-66.415, 46.34], + xy:[2506543.370459, 7482219.546176] + },{ + code:'PROJCS["NAD83(CSRS98) / New Brunswick Stereo (deprecated)",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Oblique_Stereographic"],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",-66.5],PARAMETER["scale_factor",0.999912],PARAMETER["false_easting",2500000],PARAMETER["false_northing",7500000],AUTHORITY["EPSG","2036"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', + ll:[-66.415, 46.34], + xy:[2506543.370459, 7482219.546176] + },{ + code:'PROJCS["Sphere_Van_der_Grinten_I",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Van_der_Grinten_I"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1]]', + ll:[-1.41160801956, 67.40891366748], + xy:[-125108.675828, 9016899.042114], + acc:{ + ll:0, + xy:-5 + } + },{ + code:'PROJCS["Sphere_Van_der_Grinten_I",GEOGCS["GCS_Sphere",DATUM["Not_specified_based_on_Authalic_Sphere",SPHEROID["Sphere",6371000,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["VanDerGrinten"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1],AUTHORITY["EPSG","53029"]]', + ll:[-1.41160801956, 67.40891366748], + xy:[-125108.675828, 9016899.042114], + acc:{ + ll:0, + xy:-5 + } + },{ + code:'PROJCS["NAD_1983_StatePlane_New_Jersey_FIPS_2900_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",492125.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-74.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",38.83333333333334],UNIT["Foot_US",0.3048006096012192]]', + ll:[-74,41], + xy:[630128.205,789591.522] + }, + { + code:'esriOnline', + ll:[-74,41], + xy:[-8237642.318702244, 5012341.663847514] + }, + { + code: '+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs', + xy: [736106.55, 5893331.11], + ll: [11.0, 53.0] + }, + { + code:'PROJCS["Belge 1972 / Belgian Lambert 72",GEOGCS["Belge 1972",DATUM["Reseau_National_Belge_1972",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1],AUTHORITY["EPSG","6313"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4313"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",51.16666723333333],PARAMETER["standard_parallel_2",49.8333339],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",4.367486666666666],PARAMETER["false_easting",150000.013],PARAMETER["false_northing",5400088.438],AUTHORITY["EPSG","31370"],AXIS["X",EAST],AXIS["Y",NORTH]]', + xy:[104588.196404, 193175.582367], + ll:[3.7186701465384533,51.04642936832842] + }, + { + code:'PROJCS["Belge 1972 / Belgian Lambert 72",GEOGCS["Belge 1972",DATUM["D_Belge_1972",SPHEROID["International_1924",6378388,297]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["standard_parallel_1",51.16666723333333],PARAMETER["standard_parallel_2",49.8333339],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",4.367486666666666],PARAMETER["false_easting",150000.013],PARAMETER["false_northing",5400088.438],UNIT["Meter",1]]', + xy:[104588.196404, 193175.582367], + ll:[3.7186701465384533,51.04642936832842] + }, + { + code:'PROJCS["Belge 1972 / Belgian Lambert 72",GEOGCS["Belge 1972",DATUM["Reseau_National_Belge_1972",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[-106.8686,52.2978,-103.7239,-0.3366,0.457,-1.8422,-1.2747],AUTHORITY["EPSG","6313"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4313"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",51.16666723333333],PARAMETER["standard_parallel_2",49.8333339],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",4.367486666666666],PARAMETER["false_easting",150000.013],PARAMETER["false_northing",5400088.438],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","31370"]]', + xy:[104469.69796438649, 193146.39675426576], + ll:[3.7186701465384533,51.04642936832842] + }, + { + code:'PROJCS["Belge 1972 / Belgian Lambert 72",GEOGCS["Belge 1972",DATUM["Reseau_National_Belge_1972",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[-99.059,53.322,-112.486,-0.419,0.83,-1.885,-1],AUTHORITY["EPSG","6313"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4313"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",51.16666723333333],PARAMETER["standard_parallel_2",49.8333339],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",4.367486666666666],PARAMETER["false_easting",150000.013],PARAMETER["false_northing",5400088.438],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","31370"]]', + xy:[104468.8305227503, 193169.6828284394], + ll:[3.7186701465384533,51.04642936832842] + }, + { + code:'PROJCS["Belge 1972 / Belgian Lambert 72",GEOGCS["Belge 1972",DATUM["Reseau_National_Belge_1972",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[-125.8,79.9,-100.5,0,0,0,0],AUTHORITY["EPSG","6313"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4313"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",51.16666723333333],PARAMETER["standard_parallel_2",49.8333339],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",4.367486666666666],PARAMETER["false_easting",150000.013],PARAMETER["false_northing",5400088.438],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","31370"]]', + xy:[104412.1099068548, 193116.8535417635], + ll:[3.7186701465384533,51.04642936832842] + }, + { + code:'+proj=lcc +lat_1=51.16666723333333 +lat_2=49.8333339 +lat_0=90 +lon_0=4.367486666666666 +x_0=150000.013 +y_0=5400088.438 +ellps=intl +towgs84=106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1 +units=m +no_defs ', + xy:[104588.196404, 193175.582367], + ll:[3.7186701465384533,51.04642936832842] + }, + { + code: 'PROJCS["JAD2001 / Jamaica Metric Grid",GEOGCS["JAD2001",DATUM["Jamaica_2001",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6758"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4758"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",18],PARAMETER["central_meridian",-77],PARAMETER["scale_factor",1],PARAMETER["false_easting",750000],PARAMETER["false_northing",650000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","3448"]]', + xy: [7578825.28673236, 11374595.814939449], + ll: [44.2312, 76.4860], + }, + { + code:"+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs", + ll:[-3.20078, 55.96056], + xy:[325132.0089586496, 674822.638235305] + }, + { + code:"+proj=krovak +lat_0=49.5 +lon_0=24.83333333333333 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +pm=greenwich +units=m +no_defs +towgs84=570.8,85.7,462.8,4.998,1.587,5.261,3.56", + ll: [12.806988, 49.452262], + xy: [-868208.61, -1095793.64] + }, + { + code:"+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000.0000101599 +y_0=99999.99998983997 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=us-ft +no_defs", + ll: [-110.8, 43.5], + xy: [2434515.870, 1422072.711] + }, + // QSC WGS84 + { + code: '+proj=qsc +lat_0=0 +lon_0=0 +units=m +datum=WGS84', + ll: [2, 1], + xy: [304638.4508447283296846, 164123.8709293559950311] + }, + { + code: '+proj=qsc +lat_0=0 +lon_0=90 +units=m +datum=WGS84', + ll: [2, 1], + xy: [-11576764.4717786349356174, 224687.8649776891397778] + }, + { + code: '+proj=qsc +lat_0=0 +lon_0=180 +units=m +datum=WGS84', + ll: [2, 1], + xy: [-15631296.4526007361710072, 8421356.1168374437838793] + }, + { + code: '+proj=qsc +lat_0=0 +lon_0=-90 +units=m +datum=WGS84', + ll: [2, 1], + xy: [11988027.5987015366554260, 232669.8736086514254566 + ] + }, + { + code: '+proj=qsc +lat_0=90 +lon_0=0 +units=m +datum=WGS84', + ll: [2, 1], + xy: [456180.4073964518611319, -11678366.5914389267563820 + ] + }, + { + code: '+proj=qsc +lat_0=-90 +lon_0=0 +units=m +datum=WGS84', + ll: [2, 1], + xy: [464158.3228444084525108, 11882603.8180405404418707] + }, + // QSC WGS84 WKT + { + code: 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Quadrilateralized_Spherical_Cube"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",0],UNIT["Meter",1]]', + ll: [2, 1], + xy: [304638.4508447283296846, 164123.8709293559950311] + }, + { + code: 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Quadrilateralized_Spherical_Cube"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",90],UNIT["Meter",1]]', + ll: [2, 1], + xy: [-11576764.4717786349356174, 224687.8649776891397778] + }, + { + code: 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Quadrilateralized_Spherical_Cube"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",180],UNIT["Meter",1]]', + ll: [2, 1], + xy: [-15631296.4526007361710072, 8421356.1168374437838793] + }, + { + code: 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Quadrilateralized_Spherical_Cube"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-90],UNIT["Meter",1]]', + ll: [2, 1], + xy: [11988027.5987015366554260, 232669.8736086514254566 + ] + }, + { + code: 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Quadrilateralized_Spherical_Cube"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",0],UNIT["Meter",1]]', + ll: [2, 1], + xy: [456180.4073964518611319, -11678366.5914389267563820 + ] + }, + { + code: 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Quadrilateralized_Spherical_Cube"],PARAMETER["latitude_of_origin",-90],PARAMETER["central_meridian",0],UNIT["Meter",1]]', + ll: [2, 1], + xy: [464158.3228444084525108, 11882603.8180405404418707] + }, + // QSC Mars + { + code: '+proj=qsc +units=m +a=3396190 +b=3376200 +lat_0=0 +lon_0=0', + ll: [2, 1], + xy: [162139.9347801624389831, 86935.6184961361577734] + }, + { + code: '+proj=qsc +units=m +a=3396190 +b=3376200 +lat_0=0 +lon_0=90', + ll: [2, 1], + xy: [-6164327.7345527401193976,119033.1141843862715177] + }, + { + code: '+proj=qsc +units=m +a=3396190 +b=3376200 +lat_0=0 +lon_0=180', + ll: [2, 1], + xy: [-8327904.7183852149173617, 4465226.5862284321337938] + }, + { + code: '+proj=qsc +units=m +a=3396190 +b=3376200 +lat_0=0 +lon_0=-90', + ll: [2, 1], + xy: [6383315.0547841880470514, 123261.7574065744993277] + }, + { + code: '+proj=qsc +units=m +a=3396190 +b=3376200 +lat_0=90 +lon_0=0', + ll: [2, 1], + xy: [242914.9289354820502922, -6218701.0766915259882808] + }, + { + code: '+proj=qsc +units=m +a=3396190 +b=3376200 +lat_0=-90 +lon_0=0', + ll: [2, 1], + xy: [247141.3965058987669181, 6326900.0192015860229731] + }, + // Robinson + { + code: '+proj=robin +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs', + ll: [-15, -35], + xy: [-1335949.91, -3743319.07], + acc: {ll: 4, xy: 0} + }, + { + code: '+proj=robin +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs', + ll: [-10, 50], + xy: [-819964.60, 5326895.52], + acc: {ll: 4, xy: 0} + }, + { + code: '+proj=robin +a=6400000', + ll: [80, -20], + xy: [7449059.80, -2146370.56], + acc: {ll: 4, xy: 0} + }, + { + code: '+proj=robin +lon_0=15 +x_0=100000 +y_0=100000 +datum=WGS84', + ll: [-35, 40], + xy: [-4253493.26, 4376351.58], + acc: {ll: 4, xy: 0} + }, + { + code: 'PROJCS["World_Robinson",GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Robinson"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["Meter",1]]', + ll: [20, 40], + xy: [1741397.30, 4276351.58], + acc: {ll: 4, xy: 0} + }, + { + code: 'PROJCS["World_Robinson",GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Robinson"],PARAMETER["False_Easting",100000],PARAMETER["False_Northing",100000],PARAMETER["Central_Meridian",15],UNIT["Meter",1]]', + ll: [-35, 40], + xy: [-4253493.26, 4376351.58], + acc: {ll: 4, xy: 0} + }, + { + code: '+proj=robin +lon_0=162 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs', + ll: [-90, 22], + xy: [9987057.08, 2352946.55], + acc: {ll: 4, xy: 0} + }, + // check that coordinates at 180 and -180 deg. longitude don't wrap around + { + code: 'EPSG:3857', + ll: [-180, 0], + xy: [-20037508.342789, 0] + }, + { + code: 'EPSG:3857', + ll: [180, 0], + xy: [20037508.342789, 0] + }, + // these test cases are taken from mapshaper-proj and the test results match + { + code: '+proj=tmerc +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5', + ll: [2, 1], + xy: [222650.79679577847, 110642.2294119271] + }, + { + code: '+proj=tmerc +approx +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5', + ll: [2, 1], + xy: [223413.46640632232, 111769.14504059685] + }, + { + code: '+proj=etmerc +zone=30 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5', + ll: [2, 1], + xy: [222650.7967975856, 110642.2294119332] + }, + { + code: '+proj=etmerc +k=0.998 +lon_0=-20 +datum=WGS84 +x_0=10000 +y_0=20000', + ll: [2, 1], + xy: [2516532.477709202, 139083.35793371277] + }, + { + code: '+proj=utm +zone=30 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5', + ll: [2, 1], + xy: [1057002.405491298, 110955.14117594929] + }, + { + code: '+proj=utm +lon_0=-3 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5', + ll: [2, 1], + xy: [1057002.4052152266, 110955.14117382761] + }, + // these test cases are related to the original issue on GitHub + { + code: '+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs', + ll: [2, 1], + xy: [-959006.4926646841, 113457.31956265299] + }, + { + code: '+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs', + ll: [31, 70], + xy: [1104629.4356366363, 7845845.077685604] + }, + // these test cases are for Norway snow flake zones + { + code: '+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs', + ll: [59.121778, 1.508527], + xy: [8089746.634775677, 301230.8618526573] + }, + { + code: '+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs', + ll: [59.121778, 1.508527], + xy: [6969865.865375574, 261237.08330733588] + }, + { + code: '+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs', + ll: [59.121778, 1.508527], + xy: [5984417.050333044, 232959.75386279594] + }, + { + code: '+proj=utm +zone=34 +datum=WGS84 +units=m +no_defs', + ll: [79.070672, 20.520579], + xy: [7421462.108989433, 3922366.25143021] + }, + { + code: '+proj=utm +zone=35 +datum=WGS84 +units=m +no_defs', + ll: [79.070672, 20.520579], + xy: [6548241.281523044, 3478520.1422119136] + }, + // these test cases are for the margin zones 1 and 60 + { + code: '+proj=utm +zone=1 +datum=WGS84 +units=m +no_defs', + ll: [-177, 60], + xy: [500000, 6651411.190362714] + }, + { + code: '+proj=utm +zone=60 +datum=WGS84 +units=m +no_defs', + ll: [177, 60], + xy: [500000.0000000014, 6651411.190362714] + }, + { + code: '+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs', + ll: [1.4477496, 46.8692953], + xy: [532247.285, 2208091.8723] + }, + { + code: '+proj=utm +zone=33 +units=m +no_defs', + ll: [2, 1], + xy: [-959006.4926646841, 113457.31956265299] + }, + { + code: '+proj=utm +zone=33 +units=m', + ll: [2, 1], + xy: [-959006.4926646841, 113457.31956265299] + }, + { + code: '+proj=utm +zone=33', + ll: [2, 1], + xy: [-959006.4926646841, 113457.31956265299] + }, + { + code: 'PROJCS["CUSTOM_OBLIQUE_MERCATOR", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST]], PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center", AUTHORITY["EPSG", "9815"]], PARAMETER["latitude_of_center", 37.50832038], PARAMETER["longitude_of_center", -122.25064809], PARAMETER["azimuth", 45.0], PARAMETER["rectified_grid_angle", -3.99], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -361.25], PARAMETER["false_northing", 254.915], UNIT["foot", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH]]', + xy: [-361.2499999983702, 254.91500000283122], + ll: [-122.25064809, 37.50832038], + acc:{ + ll: 3, + xy: 8 + } + }, + // Omerc Type A - #273 + { + code: '+proj=omerc +lat_0=4 +lonc=102.25 +alpha=323.0257964666666 +k=0.99984 +x_0=804671 +y_0=0 +no_uoff +gamma=323.1301023611111 +ellps=GRS80 +units=m +no_defs', + xy: [412597.532715, 338944.957259], + ll: [101.70979078430528, 3.06268465621428], + acc:{ + ll: 2, + xy: -3 + } + }, + { + code: 'PROJCS["GDM2000 / Peninsula RSO", GEOGCS["GDM2000", DATUM["Geodetic_Datum_of_Malaysia_2000", SPHEROID["GRS 1980",6378137,298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4742"]], PROJECTION["Hotine_Oblique_Mercator"], PARAMETER["latitude_of_center",4], PARAMETER["longitude_of_center",102.25], PARAMETER["azimuth",323.0257964666666], PARAMETER["rectified_grid_angle",323.1301023611111], PARAMETER["scale_factor",0.99984], PARAMETER["false_easting",804671], PARAMETER["false_northing",0], UNIT["metre",1, AUTHORITY["EPSG","9001"]], AXIS["Easting",EAST], AXIS["Northing",NORTH], AUTHORITY["EPSG","3375"]]', + xy: [412597.532715, 338944.957259], + ll: [101.70979078430528, 3.06268465621428], + acc:{ + ll: 7, + xy: 6 + } + }, + // EPSG:3468 + { + code: '+proj=omerc +lat_0=57 +lonc=-133.6666666666667 +alpha=323.1301023611111 +k=0.9999 +x_0=5000000 +y_0=-5000000 +no_uoff +gamma=323.1301023611111 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs', + xy: [1264314.74, -763162.04], + ll: [-128.115000029, 44.8150000066], + acc:{ + ll: 9, + xy: 4 + } + }, + { + code: 'PROJCS["NAD83(NSRS2007) / Alaska zone 1", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83_National_Spatial_Reference_System_2007", SPHEROID["GRS 1980",6378137,298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0,0,0,0,0,0,0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4759"]], PROJECTION["Hotine_Oblique_Mercator"], PARAMETER["latitude_of_center",57], PARAMETER["longitude_of_center",-133.6666666666667], PARAMETER["azimuth",323.1301023611111], PARAMETER["rectified_grid_angle",323.1301023611111], PARAMETER["scale_factor",0.9999], PARAMETER["false_easting",5000000], PARAMETER["false_northing",-5000000], UNIT["metre",1, AUTHORITY["EPSG","9001"]], AXIS["X",EAST], AXIS["Y",NORTH], AUTHORITY["EPSG","3468"]]', + xy: [1264314.74, -763162.04], + ll: [-128.115000029, 44.8150000066], + acc:{ + ll: 9, + xy: 4 + } + }, + // Omerc Type B - #308 + { + code: '+proj=omerc +lat_0=37.4769061 +lonc=141.0039618 +alpha=202.22 +k=1 +x_0=138 +y_0=77.65 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs', + xy: [168.2438, 64.1736], + ll: [141.003611, 37.476802], + acc:{ + ll: 9, + xy: 4 + } + }, + { + code: 'PROJCS["UNK / Oblique_Mercator",GEOGCS["UNK",DATUM["Unknown datum",SPHEROID["WGS 84", 6378137.0, 298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.017453292519943295]],PROJECTION["Oblique_Mercator"],PARAMETER["latitude_of_center",37.4769061],PARAMETER["longitude_of_center",141.0039618],PARAMETER["central_meridian",141.0039618],PARAMETER["azimuth",202.22],PARAMETER["scale_factor",1],PARAMETER["false_easting",138],PARAMETER["false_northing",77.65],UNIT["Meter",1]]', + xy: [168.2438, 64.1736], + ll: [141.003611, 37.476802], + acc:{ + ll: 9, + xy: 4 + } + }, + // Test with Feet + { + code: 'PROJCS["UNK / Oblique_Mercator",GEOGCS["UNK",DATUM["Unknown datum",SPHEROID["WGS 84", 6378137.0, 298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.017453292519943295]],PROJECTION["Oblique_Mercator"],PARAMETER["latitude_of_center",37.4769061],PARAMETER["longitude_of_center",141.0039618],PARAMETER["central_meridian",141.0039618],PARAMETER["azimuth",202.22],PARAMETER["scale_factor",1],PARAMETER["false_easting",138],PARAMETER["false_northing",77.65],UNIT["Foot_US",0.3048006096012192]]', + xy: [237.22488871325027, 33.43626458451221], + ll: [141.003611, 37.476802], + }, + { + code: 'PROJCS["WGS 84 / Pseudo-Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 0, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4326"]], PROJECTION["Popular Visualisation Pseudo Mercator", AUTHORITY["EPSG","1024"]], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3857"]]', + xy: [-12523490.49256873, 5166512.50707369], + ll: [-112.50042920000004, 42.036926809999976] + }, + { + code: 'PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","9999"]]', + xy: [-12523490.49256873, 5166512.50707369], + ll: [-112.50042920000004, 42.036926809999976] + }, + { + code: '+proj=geocent +datum=WGS84 +units=m +no_defs', + ll: [-7.56234, 38.96618, 0], + xy: [4922499, -653508, 3989398], + acc: { + ll: 0, + xy: 0 + } + }, + { + code: '+proj=geocent +ellps=GRS80 +units=m +no_defs', + ll: [-7.56234, 38.96618, 1], + xy: [4922499, -653508, 3989399], + acc: { + ll: 0, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +azi=20', + ll: [2, 1], + xy: [170820.288955531, 180460.865555805], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +azi=20', + ll: [2, -1], + xy: [246853.941538942, -28439.878035775], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +azi=20', + ll: [-2, 1], + xy: [-246853.941538942, 28439.878035775], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +azi=20', + ll: [-2, -1], + xy: [-170820.288955531, -180460.865555805], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +tilt=20', + ll: [2, 1], + xy: [213598.340357101, 113687.930830744], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +tilt=20', + ll: [2, -1], + xy: [231609.982792523, -123274.645577324], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +tilt=20', + ll: [-2, 1], + xy: [-213598.340357101, 113687.930830744], + acc: { + ll: 5, + xy: 0 + } + }, + { + code: '+proj=tpers +a=6400000 +h=1000000 +tilt=20', + ll: [-2, -1], + xy: [-231609.982792523, -123274.645577324], + acc: { + ll: 5, + xy: 0 + } + }, + // Geostationary - Ellipsoid - X Sweep + { + code: '+proj=geos +sweep=x +lon_0=-75 +h=35786023 +a=6378137.0 +b=6356752.314', + ll: [-95, 25], + xy: [-1920508.77, 2605680.03], + }, + // Geostationary - Ellipsoid - Y Sweep + { + code: '+proj=geos +sweep=y +lon_0=-75 +h=35786023 +a=6378137.0 +b=6356752.314', + ll: [-95, 25], + xy: [-1925601.20, 2601922.01], + }, + // Geostationary - Sphere - X Sweep + { + code: '+proj=geos +sweep=x +lon_0=-75 +h=35786023 +a=6378137.0 +b=6378137.0', + ll: [-95, 25], + xy: [-1919131.48, 2621384.15], + }, + // Geostationary - Sphere - Y Sweep + { + code: '+proj=geos +sweep=y +lon_0=-75 +h=35786023 +a=6378137.0 +b=6378137.0', + ll: [-95, 25], + xy: [-1924281.93, 2617608.82], + } +]; +if (typeof module !== 'undefined') { + module.exports = testPoints; +} else if (typeof define === 'function') { + define(function () { + return testPoints; + }); +} diff --git a/node_modules/sax/LICENSE b/node_modules/sax/LICENSE new file mode 100644 index 0000000..ccffa08 --- /dev/null +++ b/node_modules/sax/LICENSE @@ -0,0 +1,41 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +==== + +`String.fromCodePoint` by Mathias Bynens used according to terms of MIT +License, as follows: + + Copyright Mathias Bynens + + 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/node_modules/sax/README.md b/node_modules/sax/README.md new file mode 100644 index 0000000..afcd3f3 --- /dev/null +++ b/node_modules/sax/README.md @@ -0,0 +1,225 @@ +# sax js + +A sax-style parser for XML and HTML. + +Designed with [node](http://nodejs.org/) in mind, but should work fine in +the browser or other CommonJS implementations. + +## What This Is + +* A very simple tool to parse through an XML string. +* A stepping stone to a streaming HTML parser. +* A handy way to deal with RSS and other mostly-ok-but-kinda-broken XML + docs. + +## What This Is (probably) Not + +* An HTML Parser - That's a fine goal, but this isn't it. It's just + XML. +* A DOM Builder - You can use it to build an object model out of XML, + but it doesn't do that out of the box. +* XSLT - No DOM = no querying. +* 100% Compliant with (some other SAX implementation) - Most SAX + implementations are in Java and do a lot more than this does. +* An XML Validator - It does a little validation when in strict mode, but + not much. +* A Schema-Aware XSD Thing - Schemas are an exercise in fetishistic + masochism. +* A DTD-aware Thing - Fetching DTDs is a much bigger job. + +## Regarding `Hello, world!').close(); + +// stream usage +// takes the same options as the parser +var saxStream = require("sax").createStream(strict, options) +saxStream.on("error", function (e) { + // unhandled errors will throw, since this is a proper node + // event emitter. + console.error("error!", e) + // clear the error + this._parser.error = null + this._parser.resume() +}) +saxStream.on("opentag", function (node) { + // same object as above +}) +// pipe is supported, and it's readable/writable +// same chunks coming in also go out. +fs.createReadStream("file.xml") + .pipe(saxStream) + .pipe(fs.createWriteStream("file-copy.xml")) +``` + + +## Arguments + +Pass the following arguments to the parser function. All are optional. + +`strict` - Boolean. Whether or not to be a jerk. Default: `false`. + +`opt` - Object bag of settings regarding string formatting. All default to `false`. + +Settings supported: + +* `trim` - Boolean. Whether or not to trim text and comment nodes. +* `normalize` - Boolean. If true, then turn any whitespace into a single + space. +* `lowercase` - Boolean. If true, then lowercase tag names and attribute names + in loose mode, rather than uppercasing them. +* `xmlns` - Boolean. If true, then namespaces are supported. +* `position` - Boolean. If false, then don't track line/col/position. +* `strictEntities` - Boolean. If true, only parse [predefined XML + entities](http://www.w3.org/TR/REC-xml/#sec-predefined-ent) + (`&`, `'`, `>`, `<`, and `"`) + +## Methods + +`write` - Write bytes onto the stream. You don't have to do this all at +once. You can keep writing as much as you want. + +`close` - Close the stream. Once closed, no more data may be written until +it is done processing the buffer, which is signaled by the `end` event. + +`resume` - To gracefully handle errors, assign a listener to the `error` +event. Then, when the error is taken care of, you can call `resume` to +continue parsing. Otherwise, the parser will not continue while in an error +state. + +## Members + +At all times, the parser object will have the following members: + +`line`, `column`, `position` - Indications of the position in the XML +document where the parser currently is looking. + +`startTagPosition` - Indicates the position where the current tag starts. + +`closed` - Boolean indicating whether or not the parser can be written to. +If it's `true`, then wait for the `ready` event to write again. + +`strict` - Boolean indicating whether or not the parser is a jerk. + +`opt` - Any options passed into the constructor. + +`tag` - The current tag being dealt with. + +And a bunch of other stuff that you probably shouldn't touch. + +## Events + +All events emit with a single argument. To listen to an event, assign a +function to `on`. Functions get executed in the this-context of +the parser object. The list of supported events are also in the exported +`EVENTS` array. + +When using the stream interface, assign handlers using the EventEmitter +`on` function in the normal fashion. + +`error` - Indication that something bad happened. The error will be hanging +out on `parser.error`, and must be deleted before parsing can continue. By +listening to this event, you can keep an eye on that kind of stuff. Note: +this happens *much* more in strict mode. Argument: instance of `Error`. + +`text` - Text node. Argument: string of text. + +`doctype` - The ``. Argument: +object with `name` and `body` members. Attributes are not parsed, as +processing instructions have implementation dependent semantics. + +`sgmldeclaration` - Random SGML declarations. Stuff like `` +would trigger this kind of event. This is a weird thing to support, so it +might go away at some point. SAX isn't intended to be used to parse SGML, +after all. + +`opentagstart` - Emitted immediately when the tag name is available, +but before any attributes are encountered. Argument: object with a +`name` field and an empty `attributes` set. Note that this is the +same object that will later be emitted in the `opentag` event. + +`opentag` - An opening tag. Argument: object with `name` and `attributes`. +In non-strict mode, tag names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, then it will contain +namespace binding information on the `ns` member, and will have a +`local`, `prefix`, and `uri` member. + +`closetag` - A closing tag. In loose mode, tags are auto-closed if their +parent closes. In strict mode, well-formedness is enforced. Note that +self-closing tags will have `closeTag` emitted immediately after `openTag`. +Argument: tag name. + +`attribute` - An attribute node. Argument: object with `name` and `value`. +In non-strict mode, attribute names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, it will also contains namespace +information. + +`comment` - A comment node. Argument: the string of the comment. + +`opencdata` - The opening tag of a ``) of a `` tags trigger a `"script"` +event, and their contents are not checked for special xml characters. +If you pass `noscript: true`, then this behavior is suppressed. + +## Reporting Problems + +It's best to write a failing test if you find an issue. I will always +accept pull requests with failing tests if they demonstrate intended +behavior, but it is very hard to figure out what issue you're describing +without a test. Writing a test is also the best way for you yourself +to figure out if you really understand the issue you think you have with +sax-js. diff --git a/node_modules/sax/lib/sax.js b/node_modules/sax/lib/sax.js new file mode 100644 index 0000000..795d607 --- /dev/null +++ b/node_modules/sax/lib/sax.js @@ -0,0 +1,1565 @@ +;(function (sax) { // wrapper for non-node envs + sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } + sax.SAXParser = SAXParser + sax.SAXStream = SAXStream + sax.createStream = createStream + + // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. + // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), + // since that's the earliest that a buffer overrun could occur. This way, checks are + // as rare as required, but as often as necessary to ensure never crossing this bound. + // Furthermore, buffers are only tested at most once per write(), so passing a very + // large string into write() might have undesirable effects, but this is manageable by + // the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme + // edge case, result in creating at most one complete copy of the string passed in. + // Set to Infinity to have unlimited buffers. + sax.MAX_BUFFER_LENGTH = 64 * 1024 + + var buffers = [ + 'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype', + 'procInstName', 'procInstBody', 'entity', 'attribName', + 'attribValue', 'cdata', 'script' + ] + + sax.EVENTS = [ + 'text', + 'processinginstruction', + 'sgmldeclaration', + 'doctype', + 'comment', + 'opentagstart', + 'attribute', + 'opentag', + 'closetag', + 'opencdata', + 'cdata', + 'closecdata', + 'error', + 'end', + 'ready', + 'script', + 'opennamespace', + 'closenamespace' + ] + + function SAXParser (strict, opt) { + if (!(this instanceof SAXParser)) { + return new SAXParser(strict, opt) + } + + var parser = this + clearBuffers(parser) + parser.q = parser.c = '' + parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH + parser.opt = opt || {} + parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags + parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase' + parser.tags = [] + parser.closed = parser.closedRoot = parser.sawRoot = false + parser.tag = parser.error = null + parser.strict = !!strict + parser.noscript = !!(strict || parser.opt.noscript) + parser.state = S.BEGIN + parser.strictEntities = parser.opt.strictEntities + parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES) + parser.attribList = [] + + // namespaces form a prototype chain. + // it always points at the current tag, + // which protos to its parent tag. + if (parser.opt.xmlns) { + parser.ns = Object.create(rootNS) + } + + // mostly just for error reporting + parser.trackPosition = parser.opt.position !== false + if (parser.trackPosition) { + parser.position = parser.line = parser.column = 0 + } + emit(parser, 'onready') + } + + if (!Object.create) { + Object.create = function (o) { + function F () {} + F.prototype = o + var newf = new F() + return newf + } + } + + if (!Object.keys) { + Object.keys = function (o) { + var a = [] + for (var i in o) if (o.hasOwnProperty(i)) a.push(i) + return a + } + } + + function checkBufferLength (parser) { + var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) + var maxActual = 0 + for (var i = 0, l = buffers.length; i < l; i++) { + var len = parser[buffers[i]].length + if (len > maxAllowed) { + // Text/cdata nodes can get big, and since they're buffered, + // we can get here under normal conditions. + // Avoid issues by emitting the text node now, + // so at least it won't get any bigger. + switch (buffers[i]) { + case 'textNode': + closeText(parser) + break + + case 'cdata': + emitNode(parser, 'oncdata', parser.cdata) + parser.cdata = '' + break + + case 'script': + emitNode(parser, 'onscript', parser.script) + parser.script = '' + break + + default: + error(parser, 'Max buffer length exceeded: ' + buffers[i]) + } + } + maxActual = Math.max(maxActual, len) + } + // schedule the next check for the earliest possible buffer overrun. + var m = sax.MAX_BUFFER_LENGTH - maxActual + parser.bufferCheckPosition = m + parser.position + } + + function clearBuffers (parser) { + for (var i = 0, l = buffers.length; i < l; i++) { + parser[buffers[i]] = '' + } + } + + function flushBuffers (parser) { + closeText(parser) + if (parser.cdata !== '') { + emitNode(parser, 'oncdata', parser.cdata) + parser.cdata = '' + } + if (parser.script !== '') { + emitNode(parser, 'onscript', parser.script) + parser.script = '' + } + } + + SAXParser.prototype = { + end: function () { end(this) }, + write: write, + resume: function () { this.error = null; return this }, + close: function () { return this.write(null) }, + flush: function () { flushBuffers(this) } + } + + var Stream + try { + Stream = require('stream').Stream + } catch (ex) { + Stream = function () {} + } + + var streamWraps = sax.EVENTS.filter(function (ev) { + return ev !== 'error' && ev !== 'end' + }) + + function createStream (strict, opt) { + return new SAXStream(strict, opt) + } + + function SAXStream (strict, opt) { + if (!(this instanceof SAXStream)) { + return new SAXStream(strict, opt) + } + + Stream.apply(this) + + this._parser = new SAXParser(strict, opt) + this.writable = true + this.readable = true + + var me = this + + this._parser.onend = function () { + me.emit('end') + } + + this._parser.onerror = function (er) { + me.emit('error', er) + + // if didn't throw, then means error was handled. + // go ahead and clear error, so we can write again. + me._parser.error = null + } + + this._decoder = null + + streamWraps.forEach(function (ev) { + Object.defineProperty(me, 'on' + ev, { + get: function () { + return me._parser['on' + ev] + }, + set: function (h) { + if (!h) { + me.removeAllListeners(ev) + me._parser['on' + ev] = h + return h + } + me.on(ev, h) + }, + enumerable: true, + configurable: false + }) + }) + } + + SAXStream.prototype = Object.create(Stream.prototype, { + constructor: { + value: SAXStream + } + }) + + SAXStream.prototype.write = function (data) { + if (typeof Buffer === 'function' && + typeof Buffer.isBuffer === 'function' && + Buffer.isBuffer(data)) { + if (!this._decoder) { + var SD = require('string_decoder').StringDecoder + this._decoder = new SD('utf8') + } + data = this._decoder.write(data) + } + + this._parser.write(data.toString()) + this.emit('data', data) + return true + } + + SAXStream.prototype.end = function (chunk) { + if (chunk && chunk.length) { + this.write(chunk) + } + this._parser.end() + return true + } + + SAXStream.prototype.on = function (ev, handler) { + var me = this + if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) { + me._parser['on' + ev] = function () { + var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments) + args.splice(0, 0, ev) + me.emit.apply(me, args) + } + } + + return Stream.prototype.on.call(me, ev, handler) + } + + // this really needs to be replaced with character classes. + // XML allows all manner of ridiculous numbers and digits. + var CDATA = '[CDATA[' + var DOCTYPE = 'DOCTYPE' + var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace' + var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/' + var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } + + // http://www.w3.org/TR/REC-xml/#NT-NameStartChar + // This implementation works on strings, a single character at a time + // as such, it cannot ever support astral-plane characters (10000-EFFFF) + // without a significant breaking change to either this parser, or the + // JavaScript language. Implementation of an emoji-capable xml parser + // is left as an exercise for the reader. + var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ + + var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/ + + var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ + var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/ + + function isWhitespace (c) { + return c === ' ' || c === '\n' || c === '\r' || c === '\t' + } + + function isQuote (c) { + return c === '"' || c === '\'' + } + + function isAttribEnd (c) { + return c === '>' || isWhitespace(c) + } + + function isMatch (regex, c) { + return regex.test(c) + } + + function notMatch (regex, c) { + return !isMatch(regex, c) + } + + var S = 0 + sax.STATE = { + BEGIN: S++, // leading byte order mark or whitespace + BEGIN_WHITESPACE: S++, // leading whitespace + TEXT: S++, // general stuff + TEXT_ENTITY: S++, // & and such. + OPEN_WAKA: S++, // < + SGML_DECL: S++, // + SCRIPT: S++, //