From 87d22a45162a2b436c874b644630a36af5017d58 Mon Sep 17 00:00:00 2001 From: Thomas Fuhrmann Date: Mon, 2 Oct 2023 15:04:02 +0200 Subject: [PATCH] First commit --- cdconfig.json | 12 + config/default.json | 6 + node_modules/.bin/json5 | 12 + node_modules/.bin/json5.cmd | 17 + node_modules/.bin/json5.ps1 | 28 + node_modules/.bin/xml-js | 12 + node_modules/.bin/xml-js.cmd | 17 + node_modules/.bin/xml-js.ps1 | 28 + node_modules/.package-lock.json | 101 + node_modules/config/History.md | 710 ++ node_modules/config/LICENSE | 19 + node_modules/config/README.md | 176 + node_modules/config/async.js | 70 + node_modules/config/defer.js | 23 + node_modules/config/lib/config.js | 1521 +++ node_modules/config/package.json | 52 + node_modules/config/parser.js | 368 + node_modules/config/raw.js | 15 + node_modules/json5/LICENSE.md | 23 + node_modules/json5/README.md | 282 + node_modules/json5/dist/index.js | 1737 ++++ node_modules/json5/dist/index.min.js | 1 + node_modules/json5/dist/index.min.mjs | 1 + node_modules/json5/dist/index.mjs | 1426 +++ node_modules/json5/lib/cli.js | 152 + node_modules/json5/lib/index.d.ts | 4 + node_modules/json5/lib/index.js | 9 + node_modules/json5/lib/parse.d.ts | 15 + node_modules/json5/lib/parse.js | 1114 +++ node_modules/json5/lib/register.js | 13 + node_modules/json5/lib/require.js | 4 + node_modules/json5/lib/stringify.d.ts | 89 + node_modules/json5/lib/stringify.js | 261 + node_modules/json5/lib/unicode.d.ts | 3 + node_modules/json5/lib/unicode.js | 4 + node_modules/json5/lib/util.d.ts | 5 + node_modules/json5/lib/util.js | 35 + node_modules/json5/package.json | 72 + node_modules/mgrs/.npmignore | 4 + node_modules/mgrs/PUBLISHING.md | 17 + node_modules/mgrs/dist/mgrs.js | 758 ++ node_modules/mgrs/license.md | 19 + node_modules/mgrs/mgrs.js | 746 ++ node_modules/mgrs/openmap.md | 145 + node_modules/mgrs/package.json | 31 + node_modules/mgrs/publish.sh | 21 + node_modules/mgrs/readme.md | 44 + node_modules/mgrs/rollup.config.js | 8 + node_modules/mgrs/test/test.js | 37 + node_modules/node-fetch/LICENSE.md | 22 + node_modules/node-fetch/README.md | 633 ++ node_modules/node-fetch/browser.js | 25 + node_modules/node-fetch/lib/index.es.js | 1781 ++++ node_modules/node-fetch/lib/index.js | 1790 ++++ node_modules/node-fetch/lib/index.mjs | 1779 ++++ node_modules/node-fetch/package.json | 89 + .../.github/workflows/build-and-test.yml | 31 + node_modules/proj4/.jshintrc | 12 + node_modules/proj4/AUTHORS | 25 + node_modules/proj4/Gruntfile.js | 126 + node_modules/proj4/LICENSE.md | 29 + node_modules/proj4/PUBLISHING.md | 21 + node_modules/proj4/README.md | 194 + node_modules/proj4/REFERENCES.md | 33 + node_modules/proj4/bower.json | 24 + node_modules/proj4/changelog.md | 21 + node_modules/proj4/component.json | 17 + node_modules/proj4/dist/proj4-src.js | 7355 +++++++++++++++ node_modules/proj4/dist/proj4.js | 1 + node_modules/proj4/lib/Point.js | 34 + node_modules/proj4/lib/Proj.js | 74 + node_modules/proj4/lib/adjust_axis.js | 61 + node_modules/proj4/lib/checkSanity.js | 15 + node_modules/proj4/lib/common/acosh.js | 3 + node_modules/proj4/lib/common/adjust_lat.js | 6 + node_modules/proj4/lib/common/adjust_lon.js | 7 + node_modules/proj4/lib/common/adjust_zone.js | 14 + node_modules/proj4/lib/common/asinh.js | 4 + node_modules/proj4/lib/common/asinhy.js | 9 + node_modules/proj4/lib/common/asinz.js | 6 + node_modules/proj4/lib/common/atanh.js | 3 + node_modules/proj4/lib/common/clens.js | 15 + node_modules/proj4/lib/common/clens_cmplx.js | 32 + node_modules/proj4/lib/common/cosh.js | 5 + node_modules/proj4/lib/common/e0fn.js | 3 + node_modules/proj4/lib/common/e1fn.js | 3 + node_modules/proj4/lib/common/e2fn.js | 3 + node_modules/proj4/lib/common/e3fn.js | 3 + node_modules/proj4/lib/common/fL.js | 5 + node_modules/proj4/lib/common/gN.js | 4 + node_modules/proj4/lib/common/gatg.js | 15 + node_modules/proj4/lib/common/hypot.js | 8 + node_modules/proj4/lib/common/imlfn.js | 16 + node_modules/proj4/lib/common/invlatiso.js | 13 + node_modules/proj4/lib/common/iqsfnz.js | 32 + node_modules/proj4/lib/common/latiso.js | 16 + node_modules/proj4/lib/common/log1py.js | 6 + node_modules/proj4/lib/common/mlfn.js | 3 + node_modules/proj4/lib/common/msfnz.js | 4 + node_modules/proj4/lib/common/phi2z.js | 17 + node_modules/proj4/lib/common/pj_enfn.js | 24 + node_modules/proj4/lib/common/pj_inv_mlfn.js | 22 + node_modules/proj4/lib/common/pj_mlfn.js | 5 + node_modules/proj4/lib/common/qsfnz.js | 10 + node_modules/proj4/lib/common/sign.js | 3 + node_modules/proj4/lib/common/sinh.js | 5 + node_modules/proj4/lib/common/srat.js | 3 + node_modules/proj4/lib/common/tanh.js | 5 + node_modules/proj4/lib/common/toPoint.js | 13 + node_modules/proj4/lib/common/tsfnz.js | 8 + node_modules/proj4/lib/constants/Datum.js | 103 + node_modules/proj4/lib/constants/Ellipsoid.js | 266 + .../proj4/lib/constants/PrimeMeridian.js | 16 + node_modules/proj4/lib/constants/units.js | 4 + node_modules/proj4/lib/constants/values.js | 29 + node_modules/proj4/lib/core.js | 86 + node_modules/proj4/lib/datum.js | 39 + node_modules/proj4/lib/datumUtils.js | 245 + node_modules/proj4/lib/datum_transform.js | 192 + node_modules/proj4/lib/defs.js | 55 + node_modules/proj4/lib/deriveConstants.js | 48 + node_modules/proj4/lib/extend.js | 14 + node_modules/proj4/lib/global.js | 11 + node_modules/proj4/lib/includedProjections.js | 65 + node_modules/proj4/lib/index.js | 22 + node_modules/proj4/lib/match.js | 17 + node_modules/proj4/lib/nadgrid.js | 142 + node_modules/proj4/lib/parseCode.js | 62 + node_modules/proj4/lib/projString.js | 141 + node_modules/proj4/lib/projections.js | 39 + node_modules/proj4/lib/projections/aea.js | 129 + node_modules/proj4/lib/projections/aeqd.js | 208 + node_modules/proj4/lib/projections/cass.js | 108 + node_modules/proj4/lib/projections/cea.js | 70 + node_modules/proj4/lib/projections/eqc.js | 48 + node_modules/proj4/lib/projections/eqdc.js | 117 + node_modules/proj4/lib/projections/equi.js | 48 + node_modules/proj4/lib/projections/etmerc.js | 172 + node_modules/proj4/lib/projections/gauss.js | 52 + node_modules/proj4/lib/projections/geocent.js | 27 + node_modules/proj4/lib/projections/geos.js | 159 + node_modules/proj4/lib/projections/gnom.js | 104 + node_modules/proj4/lib/projections/gstmerc.js | 63 + node_modules/proj4/lib/projections/krovak.js | 106 + node_modules/proj4/lib/projections/laea.js | 298 + node_modules/proj4/lib/projections/lcc.js | 150 + node_modules/proj4/lib/projections/longlat.js | 16 + node_modules/proj4/lib/projections/merc.js | 100 + node_modules/proj4/lib/projections/mill.js | 52 + node_modules/proj4/lib/projections/moll.js | 83 + node_modules/proj4/lib/projections/nzmg.js | 226 + node_modules/proj4/lib/projections/omerc.js | 241 + node_modules/proj4/lib/projections/ortho.js | 91 + node_modules/proj4/lib/projections/poly.js | 135 + node_modules/proj4/lib/projections/qsc.js | 368 + node_modules/proj4/lib/projections/robin.js | 161 + node_modules/proj4/lib/projections/sinu.js | 115 + node_modules/proj4/lib/projections/somerc.js | 86 + node_modules/proj4/lib/projections/stere.js | 174 + node_modules/proj4/lib/projections/sterea.js | 64 + node_modules/proj4/lib/projections/tmerc.js | 173 + node_modules/proj4/lib/projections/tpers.js | 169 + node_modules/proj4/lib/projections/utm.js | 28 + node_modules/proj4/lib/projections/vandg.js | 129 + node_modules/proj4/lib/transform.js | 106 + node_modules/proj4/package.json | 46 + node_modules/proj4/projs.js | 60 + node_modules/proj4/publish.sh | 21 + node_modules/proj4/test/BETA2007.gsb | Bin 0 -> 83696 bytes node_modules/proj4/test/amd.html | 63 + .../proj4/test/ntv2_0_downsampled.gsb | Bin 0 -> 245824 bytes node_modules/proj4/test/opt.html | 25 + node_modules/proj4/test/package.json.js | 1 + node_modules/proj4/test/test.js | 550 ++ node_modules/proj4/test/testData.js | 835 ++ node_modules/sax/LICENSE | 41 + node_modules/sax/README.md | 225 + node_modules/sax/lib/sax.js | 1565 ++++ node_modules/sax/package.json | 25 + node_modules/tr46/.npmignore | 4 + node_modules/tr46/index.js | 193 + node_modules/tr46/lib/.gitkeep | 0 node_modules/tr46/lib/mappingTable.json | 1 + node_modules/tr46/package.json | 31 + node_modules/webidl-conversions/LICENSE.md | 12 + node_modules/webidl-conversions/README.md | 53 + node_modules/webidl-conversions/lib/index.js | 189 + node_modules/webidl-conversions/package.json | 23 + node_modules/whatwg-url/LICENSE.txt | 21 + node_modules/whatwg-url/README.md | 67 + node_modules/whatwg-url/lib/URL-impl.js | 200 + node_modules/whatwg-url/lib/URL.js | 196 + node_modules/whatwg-url/lib/public-api.js | 11 + .../whatwg-url/lib/url-state-machine.js | 1297 +++ node_modules/whatwg-url/lib/utils.js | 20 + node_modules/whatwg-url/package.json | 32 + node_modules/wkt-parser/.eslintrc | 21 + node_modules/wkt-parser/LICENSE.md | 29 + node_modules/wkt-parser/README.md | 4 + node_modules/wkt-parser/index.js | 205 + node_modules/wkt-parser/package.json | 40 + node_modules/wkt-parser/parser.js | 169 + node_modules/wkt-parser/process.js | 113 + node_modules/wkt-parser/rollup.config.js | 6 + node_modules/wkt-parser/test-fixtures.json | 474 + node_modules/wkt-parser/test.js | 14 + node_modules/wkt-parser/wkt.build.js | 484 + node_modules/xml-js/LICENSE | 21 + node_modules/xml-js/README.md | 390 + node_modules/xml-js/bin/cli-helper.js | 47 + node_modules/xml-js/bin/cli.js | 83 + node_modules/xml-js/bin/test.json | 23 + node_modules/xml-js/bin/test.xml | 3 + node_modules/xml-js/dist/xml-js.js | 8310 +++++++++++++++++ node_modules/xml-js/dist/xml-js.min.js | 8 + node_modules/xml-js/index.js | 1 + node_modules/xml-js/lib/array-helper.js | 11 + node_modules/xml-js/lib/index.js | 13 + node_modules/xml-js/lib/js2xml.js | 320 + node_modules/xml-js/lib/json2xml.js | 18 + node_modules/xml-js/lib/options-helper.js | 43 + node_modules/xml-js/lib/xml2js.js | 362 + node_modules/xml-js/lib/xml2json.js | 22 + node_modules/xml-js/package.json | 111 + node_modules/xml-js/types/index.d.ts | 154 + node_modules/xml-js/types/tsconfig.json | 14 + node_modules/xml-js/types/typings.json | 4 + node_modules/xml-js/types/xml-js-tests.ts | 60 + node_modules/xml-js/webpack.config.js | 28 + package-lock.json | 3410 +++++++ package.json | 25 + src/index.js | 13 + src/model.js | 125 + test/index.test.js | 14 + test/model.test.js | 19 + 235 files changed, 51802 insertions(+) create mode 100644 cdconfig.json create mode 100644 config/default.json create mode 100644 node_modules/.bin/json5 create mode 100644 node_modules/.bin/json5.cmd create mode 100644 node_modules/.bin/json5.ps1 create mode 100644 node_modules/.bin/xml-js create mode 100644 node_modules/.bin/xml-js.cmd create mode 100644 node_modules/.bin/xml-js.ps1 create mode 100644 node_modules/.package-lock.json create mode 100644 node_modules/config/History.md create mode 100644 node_modules/config/LICENSE create mode 100644 node_modules/config/README.md create mode 100644 node_modules/config/async.js create mode 100644 node_modules/config/defer.js create mode 100644 node_modules/config/lib/config.js create mode 100644 node_modules/config/package.json create mode 100644 node_modules/config/parser.js create mode 100644 node_modules/config/raw.js create mode 100644 node_modules/json5/LICENSE.md create mode 100644 node_modules/json5/README.md create mode 100644 node_modules/json5/dist/index.js create mode 100644 node_modules/json5/dist/index.min.js create mode 100644 node_modules/json5/dist/index.min.mjs create mode 100644 node_modules/json5/dist/index.mjs create mode 100644 node_modules/json5/lib/cli.js create mode 100644 node_modules/json5/lib/index.d.ts create mode 100644 node_modules/json5/lib/index.js create mode 100644 node_modules/json5/lib/parse.d.ts create mode 100644 node_modules/json5/lib/parse.js create mode 100644 node_modules/json5/lib/register.js create mode 100644 node_modules/json5/lib/require.js create mode 100644 node_modules/json5/lib/stringify.d.ts create mode 100644 node_modules/json5/lib/stringify.js create mode 100644 node_modules/json5/lib/unicode.d.ts create mode 100644 node_modules/json5/lib/unicode.js create mode 100644 node_modules/json5/lib/util.d.ts create mode 100644 node_modules/json5/lib/util.js create mode 100644 node_modules/json5/package.json create mode 100644 node_modules/mgrs/.npmignore create mode 100644 node_modules/mgrs/PUBLISHING.md create mode 100644 node_modules/mgrs/dist/mgrs.js create mode 100644 node_modules/mgrs/license.md create mode 100644 node_modules/mgrs/mgrs.js create mode 100644 node_modules/mgrs/openmap.md create mode 100644 node_modules/mgrs/package.json create mode 100644 node_modules/mgrs/publish.sh create mode 100644 node_modules/mgrs/readme.md create mode 100644 node_modules/mgrs/rollup.config.js create mode 100644 node_modules/mgrs/test/test.js create mode 100644 node_modules/node-fetch/LICENSE.md create mode 100644 node_modules/node-fetch/README.md create mode 100644 node_modules/node-fetch/browser.js create mode 100644 node_modules/node-fetch/lib/index.es.js create mode 100644 node_modules/node-fetch/lib/index.js create mode 100644 node_modules/node-fetch/lib/index.mjs create mode 100644 node_modules/node-fetch/package.json create mode 100644 node_modules/proj4/.github/workflows/build-and-test.yml create mode 100644 node_modules/proj4/.jshintrc create mode 100644 node_modules/proj4/AUTHORS create mode 100644 node_modules/proj4/Gruntfile.js create mode 100644 node_modules/proj4/LICENSE.md create mode 100644 node_modules/proj4/PUBLISHING.md create mode 100644 node_modules/proj4/README.md create mode 100644 node_modules/proj4/REFERENCES.md create mode 100644 node_modules/proj4/bower.json create mode 100644 node_modules/proj4/changelog.md create mode 100644 node_modules/proj4/component.json create mode 100644 node_modules/proj4/dist/proj4-src.js create mode 100644 node_modules/proj4/dist/proj4.js create mode 100644 node_modules/proj4/lib/Point.js create mode 100644 node_modules/proj4/lib/Proj.js create mode 100644 node_modules/proj4/lib/adjust_axis.js create mode 100644 node_modules/proj4/lib/checkSanity.js create mode 100644 node_modules/proj4/lib/common/acosh.js create mode 100644 node_modules/proj4/lib/common/adjust_lat.js create mode 100644 node_modules/proj4/lib/common/adjust_lon.js create mode 100644 node_modules/proj4/lib/common/adjust_zone.js create mode 100644 node_modules/proj4/lib/common/asinh.js create mode 100644 node_modules/proj4/lib/common/asinhy.js create mode 100644 node_modules/proj4/lib/common/asinz.js create mode 100644 node_modules/proj4/lib/common/atanh.js create mode 100644 node_modules/proj4/lib/common/clens.js create mode 100644 node_modules/proj4/lib/common/clens_cmplx.js create mode 100644 node_modules/proj4/lib/common/cosh.js create mode 100644 node_modules/proj4/lib/common/e0fn.js create mode 100644 node_modules/proj4/lib/common/e1fn.js create mode 100644 node_modules/proj4/lib/common/e2fn.js create mode 100644 node_modules/proj4/lib/common/e3fn.js create mode 100644 node_modules/proj4/lib/common/fL.js create mode 100644 node_modules/proj4/lib/common/gN.js create mode 100644 node_modules/proj4/lib/common/gatg.js create mode 100644 node_modules/proj4/lib/common/hypot.js create mode 100644 node_modules/proj4/lib/common/imlfn.js create mode 100644 node_modules/proj4/lib/common/invlatiso.js create mode 100644 node_modules/proj4/lib/common/iqsfnz.js create mode 100644 node_modules/proj4/lib/common/latiso.js create mode 100644 node_modules/proj4/lib/common/log1py.js create mode 100644 node_modules/proj4/lib/common/mlfn.js create mode 100644 node_modules/proj4/lib/common/msfnz.js create mode 100644 node_modules/proj4/lib/common/phi2z.js create mode 100644 node_modules/proj4/lib/common/pj_enfn.js create mode 100644 node_modules/proj4/lib/common/pj_inv_mlfn.js create mode 100644 node_modules/proj4/lib/common/pj_mlfn.js create mode 100644 node_modules/proj4/lib/common/qsfnz.js create mode 100644 node_modules/proj4/lib/common/sign.js create mode 100644 node_modules/proj4/lib/common/sinh.js create mode 100644 node_modules/proj4/lib/common/srat.js create mode 100644 node_modules/proj4/lib/common/tanh.js create mode 100644 node_modules/proj4/lib/common/toPoint.js create mode 100644 node_modules/proj4/lib/common/tsfnz.js create mode 100644 node_modules/proj4/lib/constants/Datum.js create mode 100644 node_modules/proj4/lib/constants/Ellipsoid.js create mode 100644 node_modules/proj4/lib/constants/PrimeMeridian.js create mode 100644 node_modules/proj4/lib/constants/units.js create mode 100644 node_modules/proj4/lib/constants/values.js create mode 100644 node_modules/proj4/lib/core.js create mode 100644 node_modules/proj4/lib/datum.js create mode 100644 node_modules/proj4/lib/datumUtils.js create mode 100644 node_modules/proj4/lib/datum_transform.js create mode 100644 node_modules/proj4/lib/defs.js create mode 100644 node_modules/proj4/lib/deriveConstants.js create mode 100644 node_modules/proj4/lib/extend.js create mode 100644 node_modules/proj4/lib/global.js create mode 100644 node_modules/proj4/lib/includedProjections.js create mode 100644 node_modules/proj4/lib/index.js create mode 100644 node_modules/proj4/lib/match.js create mode 100644 node_modules/proj4/lib/nadgrid.js create mode 100644 node_modules/proj4/lib/parseCode.js create mode 100644 node_modules/proj4/lib/projString.js create mode 100644 node_modules/proj4/lib/projections.js create mode 100644 node_modules/proj4/lib/projections/aea.js create mode 100644 node_modules/proj4/lib/projections/aeqd.js create mode 100644 node_modules/proj4/lib/projections/cass.js create mode 100644 node_modules/proj4/lib/projections/cea.js create mode 100644 node_modules/proj4/lib/projections/eqc.js create mode 100644 node_modules/proj4/lib/projections/eqdc.js create mode 100644 node_modules/proj4/lib/projections/equi.js create mode 100644 node_modules/proj4/lib/projections/etmerc.js create mode 100644 node_modules/proj4/lib/projections/gauss.js create mode 100644 node_modules/proj4/lib/projections/geocent.js create mode 100644 node_modules/proj4/lib/projections/geos.js create mode 100644 node_modules/proj4/lib/projections/gnom.js create mode 100644 node_modules/proj4/lib/projections/gstmerc.js create mode 100644 node_modules/proj4/lib/projections/krovak.js create mode 100644 node_modules/proj4/lib/projections/laea.js create mode 100644 node_modules/proj4/lib/projections/lcc.js create mode 100644 node_modules/proj4/lib/projections/longlat.js create mode 100644 node_modules/proj4/lib/projections/merc.js create mode 100644 node_modules/proj4/lib/projections/mill.js create mode 100644 node_modules/proj4/lib/projections/moll.js create mode 100644 node_modules/proj4/lib/projections/nzmg.js create mode 100644 node_modules/proj4/lib/projections/omerc.js create mode 100644 node_modules/proj4/lib/projections/ortho.js create mode 100644 node_modules/proj4/lib/projections/poly.js create mode 100644 node_modules/proj4/lib/projections/qsc.js create mode 100644 node_modules/proj4/lib/projections/robin.js create mode 100644 node_modules/proj4/lib/projections/sinu.js create mode 100644 node_modules/proj4/lib/projections/somerc.js create mode 100644 node_modules/proj4/lib/projections/stere.js create mode 100644 node_modules/proj4/lib/projections/sterea.js create mode 100644 node_modules/proj4/lib/projections/tmerc.js create mode 100644 node_modules/proj4/lib/projections/tpers.js create mode 100644 node_modules/proj4/lib/projections/utm.js create mode 100644 node_modules/proj4/lib/projections/vandg.js create mode 100644 node_modules/proj4/lib/transform.js create mode 100644 node_modules/proj4/package.json create mode 100644 node_modules/proj4/projs.js create mode 100644 node_modules/proj4/publish.sh create mode 100644 node_modules/proj4/test/BETA2007.gsb create mode 100644 node_modules/proj4/test/amd.html create mode 100644 node_modules/proj4/test/ntv2_0_downsampled.gsb create mode 100644 node_modules/proj4/test/opt.html create mode 100644 node_modules/proj4/test/package.json.js create mode 100644 node_modules/proj4/test/test.js create mode 100644 node_modules/proj4/test/testData.js create mode 100644 node_modules/sax/LICENSE create mode 100644 node_modules/sax/README.md create mode 100644 node_modules/sax/lib/sax.js create mode 100644 node_modules/sax/package.json create mode 100644 node_modules/tr46/.npmignore create mode 100644 node_modules/tr46/index.js create mode 100644 node_modules/tr46/lib/.gitkeep create mode 100644 node_modules/tr46/lib/mappingTable.json create mode 100644 node_modules/tr46/package.json create mode 100644 node_modules/webidl-conversions/LICENSE.md create mode 100644 node_modules/webidl-conversions/README.md create mode 100644 node_modules/webidl-conversions/lib/index.js create mode 100644 node_modules/webidl-conversions/package.json create mode 100644 node_modules/whatwg-url/LICENSE.txt create mode 100644 node_modules/whatwg-url/README.md create mode 100644 node_modules/whatwg-url/lib/URL-impl.js create mode 100644 node_modules/whatwg-url/lib/URL.js create mode 100644 node_modules/whatwg-url/lib/public-api.js create mode 100644 node_modules/whatwg-url/lib/url-state-machine.js create mode 100644 node_modules/whatwg-url/lib/utils.js create mode 100644 node_modules/whatwg-url/package.json create mode 100644 node_modules/wkt-parser/.eslintrc create mode 100644 node_modules/wkt-parser/LICENSE.md create mode 100644 node_modules/wkt-parser/README.md create mode 100644 node_modules/wkt-parser/index.js create mode 100644 node_modules/wkt-parser/package.json create mode 100644 node_modules/wkt-parser/parser.js create mode 100644 node_modules/wkt-parser/process.js create mode 100644 node_modules/wkt-parser/rollup.config.js create mode 100644 node_modules/wkt-parser/test-fixtures.json create mode 100644 node_modules/wkt-parser/test.js create mode 100644 node_modules/wkt-parser/wkt.build.js create mode 100644 node_modules/xml-js/LICENSE create mode 100644 node_modules/xml-js/README.md create mode 100644 node_modules/xml-js/bin/cli-helper.js create mode 100644 node_modules/xml-js/bin/cli.js create mode 100644 node_modules/xml-js/bin/test.json create mode 100644 node_modules/xml-js/bin/test.xml create mode 100644 node_modules/xml-js/dist/xml-js.js create mode 100644 node_modules/xml-js/dist/xml-js.min.js create mode 100644 node_modules/xml-js/index.js create mode 100644 node_modules/xml-js/lib/array-helper.js create mode 100644 node_modules/xml-js/lib/index.js create mode 100644 node_modules/xml-js/lib/js2xml.js create mode 100644 node_modules/xml-js/lib/json2xml.js create mode 100644 node_modules/xml-js/lib/options-helper.js create mode 100644 node_modules/xml-js/lib/xml2js.js create mode 100644 node_modules/xml-js/lib/xml2json.js create mode 100644 node_modules/xml-js/package.json create mode 100644 node_modules/xml-js/types/index.d.ts create mode 100644 node_modules/xml-js/types/tsconfig.json create mode 100644 node_modules/xml-js/types/typings.json create mode 100644 node_modules/xml-js/types/xml-js-tests.ts create mode 100644 node_modules/xml-js/webpack.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/index.js create mode 100644 src/model.js create mode 100644 test/index.test.js create mode 100644 test/model.test.js 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 0000000000000000000000000000000000000000..69cd3346164266d56d9756a35026b0a615e02a94 GIT binary patch literal 83696 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 UhWPx~qdaiLfHwa;YW)B4Kc0^;4FCWD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..06b811105655277eeba8bfe2ae644e9d4b2e3fca GIT binary patch literal 245824 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 F{tK)VQrrLl literal 0 HcmV?d00001 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++, //