@accelint/geo 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +233 -1
- package/catalog-info.yaml +1 -1
- package/dist/cartesian.d.ts +2 -0
- package/dist/cartesian.js +3 -1
- package/dist/cartesian.js.map +1 -1
- package/dist/coordinates/coordinate.d.ts +42 -8
- package/dist/coordinates/coordinate.js +103 -13
- package/dist/coordinates/coordinate.js.map +1 -1
- package/dist/coordinates/latlon/decimal-degrees/formatter.d.ts +21 -1
- package/dist/coordinates/latlon/decimal-degrees/formatter.js +39 -1
- package/dist/coordinates/latlon/decimal-degrees/formatter.js.map +1 -1
- package/dist/coordinates/latlon/decimal-degrees/parser.d.ts +69 -3
- package/dist/coordinates/latlon/decimal-degrees/parser.js +67 -6
- package/dist/coordinates/latlon/decimal-degrees/parser.js.map +1 -1
- package/dist/coordinates/latlon/decimal-degrees/system.d.ts +33 -1
- package/dist/coordinates/latlon/decimal-degrees/system.js +32 -1
- package/dist/coordinates/latlon/decimal-degrees/system.js.map +1 -1
- package/dist/coordinates/latlon/degrees-decimal-minutes/formatter.d.ts +21 -1
- package/dist/coordinates/latlon/degrees-decimal-minutes/formatter.js +43 -3
- package/dist/coordinates/latlon/degrees-decimal-minutes/formatter.js.map +1 -1
- package/dist/coordinates/latlon/degrees-decimal-minutes/parser.d.ts +73 -3
- package/dist/coordinates/latlon/degrees-decimal-minutes/parser.js +67 -4
- package/dist/coordinates/latlon/degrees-decimal-minutes/parser.js.map +1 -1
- package/dist/coordinates/latlon/degrees-decimal-minutes/system.d.ts +33 -1
- package/dist/coordinates/latlon/degrees-decimal-minutes/system.js +32 -1
- package/dist/coordinates/latlon/degrees-decimal-minutes/system.js.map +1 -1
- package/dist/coordinates/latlon/degrees-minutes-seconds/formatter.d.ts +21 -1
- package/dist/coordinates/latlon/degrees-minutes-seconds/formatter.js +46 -4
- package/dist/coordinates/latlon/degrees-minutes-seconds/formatter.js.map +1 -1
- package/dist/coordinates/latlon/degrees-minutes-seconds/parser.d.ts +75 -3
- package/dist/coordinates/latlon/degrees-minutes-seconds/parser.js +67 -4
- package/dist/coordinates/latlon/degrees-minutes-seconds/parser.js.map +1 -1
- package/dist/coordinates/latlon/degrees-minutes-seconds/system.d.ts +33 -1
- package/dist/coordinates/latlon/degrees-minutes-seconds/system.js +32 -1
- package/dist/coordinates/latlon/degrees-minutes-seconds/system.js.map +1 -1
- package/dist/coordinates/latlon/internal/coordinate-system.d.ts +23 -1
- package/dist/coordinates/latlon/internal/coordinate-system.js +1 -1
- package/dist/coordinates/latlon/internal/create-cache.d.ts +18 -2
- package/dist/coordinates/latlon/internal/create-cache.js +20 -4
- package/dist/coordinates/latlon/internal/create-cache.js.map +1 -1
- package/dist/coordinates/latlon/internal/exhaustive-errors.d.ts +15 -0
- package/dist/coordinates/latlon/internal/exhaustive-errors.js +29 -1
- package/dist/coordinates/latlon/internal/exhaustive-errors.js.map +1 -1
- package/dist/coordinates/latlon/internal/format.d.ts +20 -0
- package/dist/coordinates/latlon/internal/format.js +21 -1
- package/dist/coordinates/latlon/internal/format.js.map +1 -1
- package/dist/coordinates/latlon/internal/in-range.d.ts +23 -0
- package/dist/coordinates/latlon/internal/in-range.js +25 -1
- package/dist/coordinates/latlon/internal/in-range.js.map +1 -1
- package/dist/coordinates/latlon/internal/index.d.ts +16 -1
- package/dist/coordinates/latlon/internal/index.js +26 -2
- package/dist/coordinates/latlon/internal/index.js.map +1 -1
- package/dist/coordinates/latlon/internal/lexer.d.ts +2 -0
- package/dist/coordinates/latlon/internal/lexer.js +27 -1
- package/dist/coordinates/latlon/internal/lexer.js.map +1 -1
- package/dist/coordinates/latlon/internal/normalize.d.ts +67 -0
- package/dist/coordinates/latlon/internal/normalize.js +87 -0
- package/dist/coordinates/latlon/internal/normalize.js.map +1 -0
- package/dist/coordinates/latlon/internal/ordinal.d.ts +25 -0
- package/dist/coordinates/latlon/internal/ordinal.js +26 -1
- package/dist/coordinates/latlon/internal/ordinal.js.map +1 -1
- package/dist/coordinates/latlon/internal/parse-format.d.ts +23 -1
- package/dist/coordinates/latlon/internal/parse-format.js +44 -2
- package/dist/coordinates/latlon/internal/parse-format.js.map +1 -1
- package/dist/coordinates/latlon/internal/parse.d.ts +3 -1
- package/dist/coordinates/latlon/internal/parse.js +5 -2
- package/dist/coordinates/latlon/internal/parse.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/check-ambiguous.d.ts +18 -1
- package/dist/coordinates/latlon/internal/pipes/check-ambiguous.js +17 -1
- package/dist/coordinates/latlon/internal/pipes/check-ambiguous.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/check-numbers.d.ts +26 -1
- package/dist/coordinates/latlon/internal/pipes/check-numbers.js +34 -1
- package/dist/coordinates/latlon/internal/pipes/check-numbers.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/fix-bearings.d.ts +18 -1
- package/dist/coordinates/latlon/internal/pipes/fix-bearings.js +32 -1
- package/dist/coordinates/latlon/internal/pipes/fix-bearings.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/fix-dividers.d.ts +18 -1
- package/dist/coordinates/latlon/internal/pipes/fix-dividers.js +30 -1
- package/dist/coordinates/latlon/internal/pipes/fix-dividers.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/genome.d.ts +17 -1
- package/dist/coordinates/latlon/internal/pipes/genome.js +42 -1
- package/dist/coordinates/latlon/internal/pipes/genome.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/index.d.ts +33 -3
- package/dist/coordinates/latlon/internal/pipes/index.js +58 -5
- package/dist/coordinates/latlon/internal/pipes/index.js.map +1 -1
- package/dist/coordinates/latlon/internal/pipes/simpler.d.ts +17 -4
- package/dist/coordinates/latlon/internal/pipes/simpler.js +16 -4
- package/dist/coordinates/latlon/internal/pipes/simpler.js.map +1 -1
- package/dist/coordinates/latlon/internal/validate.d.ts +75 -0
- package/dist/coordinates/latlon/internal/validate.js +105 -0
- package/dist/coordinates/latlon/internal/validate.js.map +1 -0
- package/dist/coordinates/latlon/internal/violation.d.ts +18 -0
- package/dist/coordinates/latlon/internal/violation.js +19 -1
- package/dist/coordinates/latlon/internal/violation.js.map +1 -1
- package/dist/coordinates/mgrs/parser.d.ts +25 -1
- package/dist/coordinates/mgrs/parser.js +57 -1
- package/dist/coordinates/mgrs/parser.js.map +1 -1
- package/dist/coordinates/mgrs/system.d.ts +32 -1
- package/dist/coordinates/mgrs/system.js +31 -1
- package/dist/coordinates/mgrs/system.js.map +1 -1
- package/dist/coordinates/utm/parser.d.ts +25 -1
- package/dist/coordinates/utm/parser.js +57 -1
- package/dist/coordinates/utm/parser.js.map +1 -1
- package/dist/coordinates/utm/system.d.ts +22 -1
- package/dist/coordinates/utm/system.js +21 -1
- package/dist/coordinates/utm/system.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/patterning.d.ts +12 -2
- package/dist/patterning.js +13 -3
- package/dist/patterning.js.map +1 -1
- package/package.json +5 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -13,8 +13,33 @@
|
|
|
13
13
|
import { Tokens } from "../lexer.js";
|
|
14
14
|
|
|
15
15
|
//#region src/coordinates/latlon/internal/pipes/check-numbers.d.ts
|
|
16
|
+
|
|
16
17
|
/**
|
|
17
18
|
* Check for problems in the numeric values.
|
|
19
|
+
*
|
|
20
|
+
* Validates that there are at least 2 numbers, no more than 6 numbers total,
|
|
21
|
+
* and that negative values only appear in the first position (degrees).
|
|
22
|
+
*
|
|
23
|
+
* @param tokens - Array of parsed coordinate tokens.
|
|
24
|
+
* @returns Pipe result with tokens and error message (or false if valid).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* checkNumberValues(['45', '30']);
|
|
29
|
+
* // Returns tokens with error=false (valid number count)
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* checkNumberValues(['45']);
|
|
35
|
+
* // Returns error: 'Too few numbers.'
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* checkNumberValues(['1', '2', '3', '4', '5', '6', '7']);
|
|
41
|
+
* // Returns error: 'Too many numbers.'
|
|
42
|
+
* ```
|
|
18
43
|
*/
|
|
19
44
|
declare function checkNumberValues(tokens: Tokens): [string[], string | boolean];
|
|
20
45
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -11,12 +11,37 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
import { SYMBOLS } from "../index.js";
|
|
14
15
|
import { simpler } from "./simpler.js";
|
|
15
16
|
import { pipesResult } from "./index.js";
|
|
16
17
|
|
|
17
18
|
//#region src/coordinates/latlon/internal/pipes/check-numbers.ts
|
|
18
19
|
/**
|
|
19
20
|
* Check for problems in the numeric values.
|
|
21
|
+
*
|
|
22
|
+
* Validates that there are at least 2 numbers, no more than 6 numbers total,
|
|
23
|
+
* and that negative values only appear in the first position (degrees).
|
|
24
|
+
*
|
|
25
|
+
* @param tokens - Array of parsed coordinate tokens.
|
|
26
|
+
* @returns Pipe result with tokens and error message (or false if valid).
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* checkNumberValues(['45', '30']);
|
|
31
|
+
* // Returns tokens with error=false (valid number count)
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* checkNumberValues(['45']);
|
|
37
|
+
* // Returns error: 'Too few numbers.'
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* checkNumberValues(['1', '2', '3', '4', '5', '6', '7']);
|
|
43
|
+
* // Returns error: 'Too many numbers.'
|
|
44
|
+
* ```
|
|
20
45
|
*/
|
|
21
46
|
function checkNumberValues(tokens) {
|
|
22
47
|
const simple = simpler(tokens);
|
|
@@ -28,6 +53,14 @@ function checkNumberValues(tokens) {
|
|
|
28
53
|
return acc;
|
|
29
54
|
}, []).join("");
|
|
30
55
|
if (!!pattern.match(/[^_]-./) && pattern !== "_--_") return pipesResult(tokens, "Negative value for non-degrees value found.");
|
|
56
|
+
if (tokens.includes(SYMBOLS.DIVIDER)) {
|
|
57
|
+
const divIdx = tokens.indexOf(SYMBOLS.DIVIDER);
|
|
58
|
+
const halves = [tokens.slice(0, divIdx), tokens.slice(divIdx + 1)];
|
|
59
|
+
for (const half of halves) {
|
|
60
|
+
const nums = half.filter((t) => /\d/.test(t));
|
|
61
|
+
if (nums.length > 1 && nums.some((n, i) => i > 0 && Number.parseFloat(n) < 0)) return pipesResult(tokens, "Negative value for non-degrees value found.");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
31
64
|
return pipesResult(tokens, false);
|
|
32
65
|
}
|
|
33
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-numbers.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/check-numbers.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { pipesResult } from '../pipes';\nimport { simpler } from './simpler';\nimport type { Tokens } from '../lexer';\n\n/**\n * Check for problems in the numeric values.\n */\nexport function checkNumberValues(tokens: Tokens) {\n const simple = simpler(tokens);\n\n if ((simple.match(/N/g) ?? []).length < 2) {\n return pipesResult(tokens, 'Too few numbers.');\n }\n\n const error =\n // 4 consecutive numbers in specific formation is not going to be valid\n /(?:N{4,}BN+)|(?:N+BN{4,})/.test(simple) ||\n // more than 6 numbers total\n (simple.match(/N/g) ?? []).length > 6;\n\n if (error) {\n return pipesResult(tokens, 'Too many numbers.');\n }\n\n const pattern = tokens\n .reduce((acc, t) => {\n if (/\\d/.test(t)) {\n acc.push(Number.parseFloat(t) < 0 ? '-' : '+');\n } else {\n acc.push('_');\n }\n\n return acc;\n }, [] as string[])\n .join('');\n\n const matches = pattern.match(/[^_]-./);\n\n // special case '_--_' when the input is something like 'S -1 -1 W'\n // which is invalid for other reasons and will be caught elsewhere\n if (!!matches && pattern !== '_--_') {\n return pipesResult(tokens, 'Negative value for non-degrees value found.');\n }\n\n return pipesResult(tokens, false);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"check-numbers.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/check-numbers.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { SYMBOLS } from '..';\nimport { pipesResult } from '../pipes';\nimport { simpler } from './simpler';\nimport type { Tokens } from '../lexer';\n\n/**\n * Check for problems in the numeric values.\n *\n * Validates that there are at least 2 numbers, no more than 6 numbers total,\n * and that negative values only appear in the first position (degrees).\n *\n * @param tokens - Array of parsed coordinate tokens.\n * @returns Pipe result with tokens and error message (or false if valid).\n *\n * @example\n * ```typescript\n * checkNumberValues(['45', '30']);\n * // Returns tokens with error=false (valid number count)\n * ```\n *\n * @example\n * ```typescript\n * checkNumberValues(['45']);\n * // Returns error: 'Too few numbers.'\n * ```\n *\n * @example\n * ```typescript\n * checkNumberValues(['1', '2', '3', '4', '5', '6', '7']);\n * // Returns error: 'Too many numbers.'\n * ```\n */\nexport function checkNumberValues(tokens: Tokens) {\n const simple = simpler(tokens);\n\n if ((simple.match(/N/g) ?? []).length < 2) {\n return pipesResult(tokens, 'Too few numbers.');\n }\n\n const error =\n // 4 consecutive numbers in specific formation is not going to be valid\n /(?:N{4,}BN+)|(?:N+BN{4,})/.test(simple) ||\n // more than 6 numbers total\n (simple.match(/N/g) ?? []).length > 6;\n\n if (error) {\n return pipesResult(tokens, 'Too many numbers.');\n }\n\n const pattern = tokens\n .reduce((acc, t) => {\n if (/\\d/.test(t)) {\n acc.push(Number.parseFloat(t) < 0 ? '-' : '+');\n } else {\n acc.push('_');\n }\n\n return acc;\n }, [] as string[])\n .join('');\n\n const matches = pattern.match(/[^_]-./);\n\n // special case '_--_' when the input is something like 'S -1 -1 W'\n // which is invalid for other reasons and will be caught elsewhere\n if (!!matches && pattern !== '_--_') {\n return pipesResult(tokens, 'Negative value for non-degrees value found.');\n }\n\n if (tokens.includes(SYMBOLS.DIVIDER)) {\n const divIdx = tokens.indexOf(SYMBOLS.DIVIDER);\n const halves = [tokens.slice(0, divIdx), tokens.slice(divIdx + 1)];\n\n for (const half of halves) {\n const nums = half.filter((t) => /\\d/.test(t));\n\n if (\n nums.length > 1 &&\n nums.some((n, i) => i > 0 && Number.parseFloat(n) < 0)\n ) {\n return pipesResult(\n tokens,\n 'Negative value for non-degrees value found.',\n );\n }\n }\n }\n\n return pipesResult(tokens, false);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,kBAAkB,QAAgB;CAChD,MAAM,SAAS,QAAQ,OAAO;AAE9B,MAAK,OAAO,MAAM,KAAK,IAAI,EAAE,EAAE,SAAS,EACtC,QAAO,YAAY,QAAQ,mBAAmB;AAShD,KAJE,4BAA4B,KAAK,OAAO,KAEvC,OAAO,MAAM,KAAK,IAAI,EAAE,EAAE,SAAS,EAGpC,QAAO,YAAY,QAAQ,oBAAoB;CAGjD,MAAM,UAAU,OACb,QAAQ,KAAK,MAAM;AAClB,MAAI,KAAK,KAAK,EAAE,CACd,KAAI,KAAK,OAAO,WAAW,EAAE,GAAG,IAAI,MAAM,IAAI;MAE9C,KAAI,KAAK,IAAI;AAGf,SAAO;IACN,EAAE,CAAa,CACjB,KAAK,GAAG;AAMX,KAAI,CAAC,CAJW,QAAQ,MAAM,SAAS,IAItB,YAAY,OAC3B,QAAO,YAAY,QAAQ,8CAA8C;AAG3E,KAAI,OAAO,SAAS,QAAQ,QAAQ,EAAE;EACpC,MAAM,SAAS,OAAO,QAAQ,QAAQ,QAAQ;EAC9C,MAAM,SAAS,CAAC,OAAO,MAAM,GAAG,OAAO,EAAE,OAAO,MAAM,SAAS,EAAE,CAAC;AAElE,OAAK,MAAM,QAAQ,QAAQ;GACzB,MAAM,OAAO,KAAK,QAAQ,MAAM,KAAK,KAAK,EAAE,CAAC;AAE7C,OACE,KAAK,SAAS,KACd,KAAK,MAAM,GAAG,MAAM,IAAI,KAAK,OAAO,WAAW,EAAE,GAAG,EAAE,CAEtD,QAAO,YACL,QACA,8CACD;;;AAKP,QAAO,YAAY,QAAQ,MAAM"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -15,10 +15,27 @@ import { Tokens } from "../lexer.js";
|
|
|
15
15
|
import { PipeResult } from "./index.js";
|
|
16
16
|
|
|
17
17
|
//#region src/coordinates/latlon/internal/pipes/fix-bearings.d.ts
|
|
18
|
+
|
|
18
19
|
/**
|
|
19
20
|
* Normalize bearings - negative and positive numeric values to NSEW - and
|
|
20
21
|
* positioning of bearings - after the numeric values - and fill in any missing
|
|
21
22
|
* bearings if only one is provided.
|
|
23
|
+
*
|
|
24
|
+
* @param tokens - Array of parsed coordinate tokens containing a divider.
|
|
25
|
+
* @param format - Optional coordinate format (LATLON or LONLAT) to infer missing bearings.
|
|
26
|
+
* @returns Pipe result with normalized tokens and error status.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* fixBearings(['45', 'N', '/', '122', 'W'], 'LATLON');
|
|
31
|
+
* // Returns ['45', 'N', '/', '122', 'W'] with error=false
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* fixBearings(['-45', '/', '122'], 'LATLON');
|
|
37
|
+
* // Returns ['45', 'S', '/', '122', 'E'] with error=false
|
|
38
|
+
* ```
|
|
22
39
|
*/
|
|
23
40
|
declare function fixBearings(tokens: Tokens, format?: Format): PipeResult;
|
|
24
41
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -27,6 +27,22 @@ const conflict = ([a, b]) => `Bearing (${a}) conflicts with negative number (${b
|
|
|
27
27
|
* Normalize bearings - negative and positive numeric values to NSEW - and
|
|
28
28
|
* positioning of bearings - after the numeric values - and fill in any missing
|
|
29
29
|
* bearings if only one is provided.
|
|
30
|
+
*
|
|
31
|
+
* @param tokens - Array of parsed coordinate tokens containing a divider.
|
|
32
|
+
* @param format - Optional coordinate format (LATLON or LONLAT) to infer missing bearings.
|
|
33
|
+
* @returns Pipe result with normalized tokens and error status.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* fixBearings(['45', 'N', '/', '122', 'W'], 'LATLON');
|
|
38
|
+
* // Returns ['45', 'N', '/', '122', 'W'] with error=false
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* fixBearings(['-45', '/', '122'], 'LATLON');
|
|
44
|
+
* // Returns ['45', 'S', '/', '122', 'E'] with error=false
|
|
45
|
+
* ```
|
|
30
46
|
*/
|
|
31
47
|
function fixBearings(tokens, format) {
|
|
32
48
|
const [left, right] = [tokens.slice(0, tokens.indexOf(SYMBOLS.DIVIDER)), tokens.slice(1 + tokens.indexOf(SYMBOLS.DIVIDER))].map(moveBearingsToHead);
|
|
@@ -65,6 +81,21 @@ function fixBearings(tokens, format) {
|
|
|
65
81
|
* module only - so that it is easier to work with; moving a bearing to the
|
|
66
82
|
* "head" allows for `push()` of subsequent number processing will keep the
|
|
67
83
|
* order of the numeric values intact.
|
|
84
|
+
*
|
|
85
|
+
* @param coord - Array of tokens for one coordinate half (before or after divider).
|
|
86
|
+
* @returns New array with bearing moved to first position.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* moveBearingsToHead(['45', '30', 'N']);
|
|
91
|
+
* // ['N', '45', '30']
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* moveBearingsToHead(['122', '15']);
|
|
97
|
+
* // ['122', '15']
|
|
98
|
+
* ```
|
|
68
99
|
*/
|
|
69
100
|
function moveBearingsToHead(coord) {
|
|
70
101
|
return coord.reduce((acc, t) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix-bearings.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/fix-bearings.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { BEARINGS, type Format, SYMBOL_PATTERNS, SYMBOLS } from '..';\nimport type { Tokens } from '../lexer';\nimport type { PipeResult } from '../pipes';\n\nconst orthogonal = {\n N: BEARINGS.LON,\n S: BEARINGS.LON,\n E: BEARINGS.LAT,\n W: BEARINGS.LAT,\n};\n\nconst bearingConflictsWithNumber = (tokens: Tokens) =>\n tokens[0] &&\n tokens[1] &&\n SYMBOL_PATTERNS.NEGATIVE_SIGN.test(tokens[1]) &&\n SYMBOL_PATTERNS.NSEW.test(tokens[0]) &&\n !SYMBOL_PATTERNS.NEGATIVE_BEARINGS.test(tokens[0]);\n\nconst bePositive = (n: string) => n.replace(SYMBOL_PATTERNS.NEGATIVE_SIGN, '');\n\nconst conflict = ([a, b]: Tokens) =>\n `Bearing (${a}) conflicts with negative number (${b}).`;\n\n/**\n * Normalize bearings - negative and positive numeric values to NSEW - and\n * positioning of bearings - after the numeric values - and fill in any missing\n * bearings if only one is provided.\n */\nexport function fixBearings(tokens: Tokens, format?: Format): PipeResult {\n const [left, right] = [\n tokens.slice(0, tokens.indexOf(SYMBOLS.DIVIDER)),\n tokens.slice(1 + tokens.indexOf(SYMBOLS.DIVIDER)),\n ].map(moveBearingsToHead) as [Tokens, Tokens];\n\n if (bearingConflictsWithNumber(left)) {\n return [[], conflict(left)];\n }\n\n if (bearingConflictsWithNumber(right)) {\n return [[], conflict(right)];\n }\n\n const [leftHasBearing, rightHasBearing] = [left, right].map(\n (list) => !!(list?.[0] && SYMBOL_PATTERNS.NSEW.test(list[0])),\n );\n\n let leftBearing = '';\n let rightBearing = '';\n\n if (leftHasBearing && rightHasBearing) {\n leftBearing = left.shift() ?? '';\n rightBearing = right.shift() ?? '';\n } else if (leftHasBearing) {\n leftBearing = left.shift() ?? '';\n rightBearing =\n orthogonal[leftBearing as keyof typeof orthogonal][\n +SYMBOL_PATTERNS.NEGATIVE_SIGN.test(right[0] ?? '') as 0 | 1\n ];\n } else if (rightHasBearing) {\n rightBearing = right.shift() ?? '';\n leftBearing =\n orthogonal[rightBearing as keyof typeof orthogonal][\n +SYMBOL_PATTERNS.NEGATIVE_SIGN.test(right[0] ?? '') as 0 | 1\n ];\n } else if (format) {\n leftBearing = `${BEARINGS[format][0][+SYMBOL_PATTERNS.NEGATIVE_SIGN.test(`${left[0]}`)]}`;\n rightBearing = `${BEARINGS[format][1][+SYMBOL_PATTERNS.NEGATIVE_SIGN.test(`${right[0]}`)]}`;\n } else {\n // neither exist\n return [[...left, SYMBOLS.DIVIDER, ...right], false];\n }\n\n return [\n [\n ...left.map(bePositive),\n leftBearing,\n SYMBOLS.DIVIDER,\n ...right.map(bePositive),\n rightBearing,\n ],\n false,\n ];\n}\n\n/**\n * Move the bearings indicators to the first element in the list - in this\n * module only - so that it is easier to work with; moving a bearing to the\n * \"head\" allows for `push()` of subsequent number processing will keep the\n * order of the numeric values intact.\n */\nfunction moveBearingsToHead(coord: Tokens) {\n return coord.reduce((acc, t) => {\n if (/\\d/.test(t)) {\n acc.push(t);\n } else {\n acc.unshift(t);\n }\n\n return acc;\n }, [] as Tokens);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,aAAa;CACjB,GAAG,SAAS;CACZ,GAAG,SAAS;CACZ,GAAG,SAAS;CACZ,GAAG,SAAS;CACb;AAED,MAAM,8BAA8B,WAClC,OAAO,MACP,OAAO,MACP,gBAAgB,cAAc,KAAK,OAAO,GAAG,IAC7C,gBAAgB,KAAK,KAAK,OAAO,GAAG,IACpC,CAAC,gBAAgB,kBAAkB,KAAK,OAAO,GAAG;AAEpD,MAAM,cAAc,MAAc,EAAE,QAAQ,gBAAgB,eAAe,GAAG;AAE9E,MAAM,YAAY,CAAC,GAAG,OACpB,YAAY,EAAE,oCAAoC,EAAE
|
|
1
|
+
{"version":3,"file":"fix-bearings.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/fix-bearings.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { BEARINGS, type Format, SYMBOL_PATTERNS, SYMBOLS } from '..';\nimport type { Tokens } from '../lexer';\nimport type { PipeResult } from '../pipes';\n\nconst orthogonal = {\n N: BEARINGS.LON,\n S: BEARINGS.LON,\n E: BEARINGS.LAT,\n W: BEARINGS.LAT,\n};\n\nconst bearingConflictsWithNumber = (tokens: Tokens) =>\n tokens[0] &&\n tokens[1] &&\n SYMBOL_PATTERNS.NEGATIVE_SIGN.test(tokens[1]) &&\n SYMBOL_PATTERNS.NSEW.test(tokens[0]) &&\n !SYMBOL_PATTERNS.NEGATIVE_BEARINGS.test(tokens[0]);\n\nconst bePositive = (n: string) => n.replace(SYMBOL_PATTERNS.NEGATIVE_SIGN, '');\n\nconst conflict = ([a, b]: Tokens) =>\n `Bearing (${a}) conflicts with negative number (${b}).`;\n\n/**\n * Normalize bearings - negative and positive numeric values to NSEW - and\n * positioning of bearings - after the numeric values - and fill in any missing\n * bearings if only one is provided.\n *\n * @param tokens - Array of parsed coordinate tokens containing a divider.\n * @param format - Optional coordinate format (LATLON or LONLAT) to infer missing bearings.\n * @returns Pipe result with normalized tokens and error status.\n *\n * @example\n * ```typescript\n * fixBearings(['45', 'N', '/', '122', 'W'], 'LATLON');\n * // Returns ['45', 'N', '/', '122', 'W'] with error=false\n * ```\n *\n * @example\n * ```typescript\n * fixBearings(['-45', '/', '122'], 'LATLON');\n * // Returns ['45', 'S', '/', '122', 'E'] with error=false\n * ```\n */\nexport function fixBearings(tokens: Tokens, format?: Format): PipeResult {\n const [left, right] = [\n tokens.slice(0, tokens.indexOf(SYMBOLS.DIVIDER)),\n tokens.slice(1 + tokens.indexOf(SYMBOLS.DIVIDER)),\n ].map(moveBearingsToHead) as [Tokens, Tokens];\n\n if (bearingConflictsWithNumber(left)) {\n return [[], conflict(left)];\n }\n\n if (bearingConflictsWithNumber(right)) {\n return [[], conflict(right)];\n }\n\n const [leftHasBearing, rightHasBearing] = [left, right].map(\n (list) => !!(list?.[0] && SYMBOL_PATTERNS.NSEW.test(list[0])),\n );\n\n let leftBearing = '';\n let rightBearing = '';\n\n if (leftHasBearing && rightHasBearing) {\n leftBearing = left.shift() ?? '';\n rightBearing = right.shift() ?? '';\n } else if (leftHasBearing) {\n leftBearing = left.shift() ?? '';\n rightBearing =\n orthogonal[leftBearing as keyof typeof orthogonal][\n +SYMBOL_PATTERNS.NEGATIVE_SIGN.test(right[0] ?? '') as 0 | 1\n ];\n } else if (rightHasBearing) {\n rightBearing = right.shift() ?? '';\n leftBearing =\n orthogonal[rightBearing as keyof typeof orthogonal][\n +SYMBOL_PATTERNS.NEGATIVE_SIGN.test(right[0] ?? '') as 0 | 1\n ];\n } else if (format) {\n leftBearing = `${BEARINGS[format][0][+SYMBOL_PATTERNS.NEGATIVE_SIGN.test(`${left[0]}`)]}`;\n rightBearing = `${BEARINGS[format][1][+SYMBOL_PATTERNS.NEGATIVE_SIGN.test(`${right[0]}`)]}`;\n } else {\n // neither exist\n return [[...left, SYMBOLS.DIVIDER, ...right], false];\n }\n\n return [\n [\n ...left.map(bePositive),\n leftBearing,\n SYMBOLS.DIVIDER,\n ...right.map(bePositive),\n rightBearing,\n ],\n false,\n ];\n}\n\n/**\n * Move the bearings indicators to the first element in the list - in this\n * module only - so that it is easier to work with; moving a bearing to the\n * \"head\" allows for `push()` of subsequent number processing will keep the\n * order of the numeric values intact.\n *\n * @param coord - Array of tokens for one coordinate half (before or after divider).\n * @returns New array with bearing moved to first position.\n *\n * @example\n * ```typescript\n * moveBearingsToHead(['45', '30', 'N']);\n * // ['N', '45', '30']\n * ```\n *\n * @example\n * ```typescript\n * moveBearingsToHead(['122', '15']);\n * // ['122', '15']\n * ```\n */\nfunction moveBearingsToHead(coord: Tokens) {\n return coord.reduce((acc, t) => {\n if (/\\d/.test(t)) {\n acc.push(t);\n } else {\n acc.unshift(t);\n }\n\n return acc;\n }, [] as Tokens);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,aAAa;CACjB,GAAG,SAAS;CACZ,GAAG,SAAS;CACZ,GAAG,SAAS;CACZ,GAAG,SAAS;CACb;AAED,MAAM,8BAA8B,WAClC,OAAO,MACP,OAAO,MACP,gBAAgB,cAAc,KAAK,OAAO,GAAG,IAC7C,gBAAgB,KAAK,KAAK,OAAO,GAAG,IACpC,CAAC,gBAAgB,kBAAkB,KAAK,OAAO,GAAG;AAEpD,MAAM,cAAc,MAAc,EAAE,QAAQ,gBAAgB,eAAe,GAAG;AAE9E,MAAM,YAAY,CAAC,GAAG,OACpB,YAAY,EAAE,oCAAoC,EAAE;;;;;;;;;;;;;;;;;;;;;;AAuBtD,SAAgB,YAAY,QAAgB,QAA6B;CACvE,MAAM,CAAC,MAAM,SAAS,CACpB,OAAO,MAAM,GAAG,OAAO,QAAQ,QAAQ,QAAQ,CAAC,EAChD,OAAO,MAAM,IAAI,OAAO,QAAQ,QAAQ,QAAQ,CAAC,CAClD,CAAC,IAAI,mBAAmB;AAEzB,KAAI,2BAA2B,KAAK,CAClC,QAAO,CAAC,EAAE,EAAE,SAAS,KAAK,CAAC;AAG7B,KAAI,2BAA2B,MAAM,CACnC,QAAO,CAAC,EAAE,EAAE,SAAS,MAAM,CAAC;CAG9B,MAAM,CAAC,gBAAgB,mBAAmB,CAAC,MAAM,MAAM,CAAC,KACrD,SAAS,CAAC,EAAE,OAAO,MAAM,gBAAgB,KAAK,KAAK,KAAK,GAAG,EAC7D;CAED,IAAI,cAAc;CAClB,IAAI,eAAe;AAEnB,KAAI,kBAAkB,iBAAiB;AACrC,gBAAc,KAAK,OAAO,IAAI;AAC9B,iBAAe,MAAM,OAAO,IAAI;YACvB,gBAAgB;AACzB,gBAAc,KAAK,OAAO,IAAI;AAC9B,iBACE,WAAW,aACT,CAAC,gBAAgB,cAAc,KAAK,MAAM,MAAM,GAAG;YAE9C,iBAAiB;AAC1B,iBAAe,MAAM,OAAO,IAAI;AAChC,gBACE,WAAW,cACT,CAAC,gBAAgB,cAAc,KAAK,MAAM,MAAM,GAAG;YAE9C,QAAQ;AACjB,gBAAc,GAAG,SAAS,QAAQ,GAAG,CAAC,gBAAgB,cAAc,KAAK,GAAG,KAAK,KAAK;AACtF,iBAAe,GAAG,SAAS,QAAQ,GAAG,CAAC,gBAAgB,cAAc,KAAK,GAAG,MAAM,KAAK;OAGxF,QAAO,CAAC;EAAC,GAAG;EAAM,QAAQ;EAAS,GAAG;EAAM,EAAE,MAAM;AAGtD,QAAO,CACL;EACE,GAAG,KAAK,IAAI,WAAW;EACvB;EACA,QAAQ;EACR,GAAG,MAAM,IAAI,WAAW;EACxB;EACD,EACD,MACD;;;;;;;;;;;;;;;;;;;;;;;AAwBH,SAAS,mBAAmB,OAAe;AACzC,QAAO,MAAM,QAAQ,KAAK,MAAM;AAC9B,MAAI,KAAK,KAAK,EAAE,CACd,KAAI,KAAK,EAAE;MAEX,KAAI,QAAQ,EAAE;AAGhB,SAAO;IACN,EAAE,CAAW"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -15,11 +15,28 @@ import { Tokens } from "../lexer.js";
|
|
|
15
15
|
import { PipeResult } from "./index.js";
|
|
16
16
|
|
|
17
17
|
//#region src/coordinates/latlon/internal/pipes/fix-dividers.d.ts
|
|
18
|
+
|
|
18
19
|
/**
|
|
19
20
|
* For tokens lists without a divider, `fixDivider` attempts to determine the
|
|
20
21
|
* __safe__ location to add a divider based on the existing formatting of the
|
|
21
22
|
* coordinate: numbers, number positions, and number indicators.
|
|
22
23
|
*
|
|
24
|
+
* @param original - Array of coordinate tokens without a divider.
|
|
25
|
+
* @param _format - Optional coordinate format (LATLON or LONLAT), currently unused.
|
|
26
|
+
* @returns Pipe result with divider inserted, or error=true if no safe location found.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* fixDivider(['45°', '30'', 'N', '122°', '15'', 'W']);
|
|
31
|
+
* // Returns tokens with divider inserted between latitude and longitude
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* fixDivider(['45', '30', 'N']);
|
|
37
|
+
* // Returns error=true (cannot safely determine divider position)
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
23
40
|
* @remarks
|
|
24
41
|
* pure function
|
|
25
42
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -22,6 +22,19 @@ const SIMPLER_PATTERNS = {
|
|
|
22
22
|
BNNB: 2,
|
|
23
23
|
BNN: 2
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Inserts a divider token at the specified index in the tokens array.
|
|
27
|
+
*
|
|
28
|
+
* @param tokens - Array of coordinate tokens without a divider.
|
|
29
|
+
* @param index - Position where the divider should be inserted.
|
|
30
|
+
* @returns Pipe result with divider inserted and error=false.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* insertDivider(['45', '30', 'N', '122', '15', 'W'], 3);
|
|
35
|
+
* // [['45', '30', 'N', '/', '122', '15', 'W'], false]
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
25
38
|
const insertDivider = (tokens, index) => [[
|
|
26
39
|
...tokens.slice(0, index),
|
|
27
40
|
SYMBOLS.DIVIDER,
|
|
@@ -32,6 +45,22 @@ const insertDivider = (tokens, index) => [[
|
|
|
32
45
|
* __safe__ location to add a divider based on the existing formatting of the
|
|
33
46
|
* coordinate: numbers, number positions, and number indicators.
|
|
34
47
|
*
|
|
48
|
+
* @param original - Array of coordinate tokens without a divider.
|
|
49
|
+
* @param _format - Optional coordinate format (LATLON or LONLAT), currently unused.
|
|
50
|
+
* @returns Pipe result with divider inserted, or error=true if no safe location found.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* fixDivider(['45°', '30'', 'N', '122°', '15'', 'W']);
|
|
55
|
+
* // Returns tokens with divider inserted between latitude and longitude
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* fixDivider(['45', '30', 'N']);
|
|
61
|
+
* // Returns error=true (cannot safely determine divider position)
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
35
64
|
* @remarks
|
|
36
65
|
* pure function
|
|
37
66
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix-dividers.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/fix-dividers.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { type Format, SYMBOLS } from '..';\nimport { getGenomeIndex } from './genome';\nimport { simpler } from './simpler';\nimport type { Tokens } from '../lexer';\nimport type { PipeResult } from '../pipes';\n\n// N = number\n// B = bearing\nconst SIMPLER_PATTERNS = {\n NN: 1,\n NNB: 1,\n BNNB: 2,\n BNN: 2,\n};\n\nconst insertDivider = (tokens: Tokens, index: number): PipeResult => [\n [...tokens.slice(0, index), SYMBOLS.DIVIDER, ...tokens.slice(index)],\n false,\n];\n\n/**\n * For tokens lists without a divider, `fixDivider` attempts to determine the\n * __safe__ location to add a divider based on the existing formatting of the\n * coordinate: numbers, number positions, and number indicators.\n *\n * @remarks\n * pure function\n */\nexport function fixDivider(original: Tokens, _format?: Format): PipeResult {\n // if there is already a divider then there is nothing to do\n if (original.includes(SYMBOLS.DIVIDER)) {\n return [original, false];\n }\n\n // disconnect from argument memory space so we aren't working on shared memory\n const tokens = original.slice(0);\n\n const genomeIndex = getGenomeIndex(tokens);\n\n if (genomeIndex) {\n return insertDivider(tokens, genomeIndex);\n }\n\n const simple = simpler(tokens) as keyof typeof SIMPLER_PATTERNS;\n\n if (SIMPLER_PATTERNS[simple]) {\n return insertDivider(tokens, SIMPLER_PATTERNS[simple]);\n }\n\n // no position is found to be a safe location to insert a divider; any placement\n // would be a guess and therefor only has a 50% chance of being wrong or right\n return [[], true];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,mBAAmB;CACvB,IAAI;CACJ,KAAK;CACL,MAAM;CACN,KAAK;CACN
|
|
1
|
+
{"version":3,"file":"fix-dividers.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/fix-dividers.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { type Format, SYMBOLS } from '..';\nimport { getGenomeIndex } from './genome';\nimport { simpler } from './simpler';\nimport type { Tokens } from '../lexer';\nimport type { PipeResult } from '../pipes';\n\n// N = number\n// B = bearing\nconst SIMPLER_PATTERNS = {\n NN: 1,\n NNB: 1,\n BNNB: 2,\n BNN: 2,\n};\n\n/**\n * Inserts a divider token at the specified index in the tokens array.\n *\n * @param tokens - Array of coordinate tokens without a divider.\n * @param index - Position where the divider should be inserted.\n * @returns Pipe result with divider inserted and error=false.\n *\n * @example\n * ```typescript\n * insertDivider(['45', '30', 'N', '122', '15', 'W'], 3);\n * // [['45', '30', 'N', '/', '122', '15', 'W'], false]\n * ```\n */\nconst insertDivider = (tokens: Tokens, index: number): PipeResult => [\n [...tokens.slice(0, index), SYMBOLS.DIVIDER, ...tokens.slice(index)],\n false,\n];\n\n/**\n * For tokens lists without a divider, `fixDivider` attempts to determine the\n * __safe__ location to add a divider based on the existing formatting of the\n * coordinate: numbers, number positions, and number indicators.\n *\n * @param original - Array of coordinate tokens without a divider.\n * @param _format - Optional coordinate format (LATLON or LONLAT), currently unused.\n * @returns Pipe result with divider inserted, or error=true if no safe location found.\n *\n * @example\n * ```typescript\n * fixDivider(['45°', '30'', 'N', '122°', '15'', 'W']);\n * // Returns tokens with divider inserted between latitude and longitude\n * ```\n *\n * @example\n * ```typescript\n * fixDivider(['45', '30', 'N']);\n * // Returns error=true (cannot safely determine divider position)\n * ```\n *\n * @remarks\n * pure function\n */\nexport function fixDivider(original: Tokens, _format?: Format): PipeResult {\n // if there is already a divider then there is nothing to do\n if (original.includes(SYMBOLS.DIVIDER)) {\n return [original, false];\n }\n\n // disconnect from argument memory space so we aren't working on shared memory\n const tokens = original.slice(0);\n\n const genomeIndex = getGenomeIndex(tokens);\n\n if (genomeIndex) {\n return insertDivider(tokens, genomeIndex);\n }\n\n const simple = simpler(tokens) as keyof typeof SIMPLER_PATTERNS;\n\n if (SIMPLER_PATTERNS[simple]) {\n return insertDivider(tokens, SIMPLER_PATTERNS[simple]);\n }\n\n // no position is found to be a safe location to insert a divider; any placement\n // would be a guess and therefor only has a 50% chance of being wrong or right\n return [[], true];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,mBAAmB;CACvB,IAAI;CACJ,KAAK;CACL,MAAM;CACN,KAAK;CACN;;;;;;;;;;;;;;AAeD,MAAM,iBAAiB,QAAgB,UAA8B,CACnE;CAAC,GAAG,OAAO,MAAM,GAAG,MAAM;CAAE,QAAQ;CAAS,GAAG,OAAO,MAAM,MAAM;CAAC,EACpE,MACD;;;;;;;;;;;;;;;;;;;;;;;;;AA0BD,SAAgB,WAAW,UAAkB,SAA8B;AAEzE,KAAI,SAAS,SAAS,QAAQ,QAAQ,CACpC,QAAO,CAAC,UAAU,MAAM;CAI1B,MAAM,SAAS,SAAS,MAAM,EAAE;CAEhC,MAAM,cAAc,eAAe,OAAO;AAE1C,KAAI,YACF,QAAO,cAAc,QAAQ,YAAY;CAG3C,MAAM,SAAS,QAAQ,OAAO;AAE9B,KAAI,iBAAiB,QACnB,QAAO,cAAc,QAAQ,iBAAiB,QAAQ;AAKxD,QAAO,CAAC,EAAE,EAAE,KAAK"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -13,9 +13,25 @@
|
|
|
13
13
|
import { Tokens } from "../lexer.js";
|
|
14
14
|
|
|
15
15
|
//#region src/coordinates/latlon/internal/pipes/genome.d.ts
|
|
16
|
+
|
|
16
17
|
/**
|
|
17
18
|
* Use the "genome" sequence of the token list to find the index for inserting
|
|
18
19
|
* a missing divider token.
|
|
20
|
+
*
|
|
21
|
+
* @param tokens - Array of coordinate tokens to analyze.
|
|
22
|
+
* @returns Index position where divider should be inserted, or 0 if pattern doesn't match.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* getGenomeIndex(['45°', '30'', 'N', '122°', '15'', 'W']);
|
|
27
|
+
* // 3 (insert divider after latitude components)
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* getGenomeIndex(['45', '30', '15']);
|
|
33
|
+
* // 0 (pattern doesn't match genome sequence)
|
|
34
|
+
* ```
|
|
19
35
|
*/
|
|
20
36
|
declare function getGenomeIndex(tokens: Tokens): number;
|
|
21
37
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -19,6 +19,16 @@ const GENOME_PATTERN = /^(B?)([DN]?[MN]?[SN]?)(B?)(?:B?)([DN]?[MN]?[SN]?)(?:B?)$
|
|
|
19
19
|
* Get the position (index) of where to insert a divider into the token list;
|
|
20
20
|
* basically, the count of numeric components (left-of-divider position) plus
|
|
21
21
|
* 1 if there is a bearing identifier (left-of-divider).
|
|
22
|
+
*
|
|
23
|
+
* @param _full - Full regex match string (unused).
|
|
24
|
+
* @param args - Regex capture groups: [bearing1, number1, bearing2, number2].
|
|
25
|
+
* @returns String representation of the divider index position.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* dividerIndexer('BDNBDNB', 'B', 'DN', 'B', 'DN');
|
|
30
|
+
* // '3' (bearing + 2 numeric components)
|
|
31
|
+
* ```
|
|
22
32
|
*/
|
|
23
33
|
function dividerIndexer(_full, ...args) {
|
|
24
34
|
const [bearing1 = "", number1, bearing2 = "", number2] = args;
|
|
@@ -34,6 +44,22 @@ function dividerIndexer(_full, ...args) {
|
|
|
34
44
|
* - S = seconds (number with seconds character following)
|
|
35
45
|
* - N = number (no identifying character following)
|
|
36
46
|
* - X = for unmatched token types
|
|
47
|
+
*
|
|
48
|
+
* @param acc - Accumulated genome sequence string.
|
|
49
|
+
* @param t - Current token to classify.
|
|
50
|
+
* @returns Updated genome sequence with new character appended.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* genomeSequencer('', '45°');
|
|
55
|
+
* // 'D'
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* genomeSequencer('D', 'N');
|
|
61
|
+
* // 'DB'
|
|
62
|
+
* ```
|
|
37
63
|
*/
|
|
38
64
|
function genomeSequencer(acc, t) {
|
|
39
65
|
if (t.includes(SYMBOLS.DEGREES)) return `${acc}D`;
|
|
@@ -46,6 +72,21 @@ function genomeSequencer(acc, t) {
|
|
|
46
72
|
/**
|
|
47
73
|
* Use the "genome" sequence of the token list to find the index for inserting
|
|
48
74
|
* a missing divider token.
|
|
75
|
+
*
|
|
76
|
+
* @param tokens - Array of coordinate tokens to analyze.
|
|
77
|
+
* @returns Index position where divider should be inserted, or 0 if pattern doesn't match.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* getGenomeIndex(['45°', '30'', 'N', '122°', '15'', 'W']);
|
|
82
|
+
* // 3 (insert divider after latitude components)
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* getGenomeIndex(['45', '30', '15']);
|
|
88
|
+
* // 0 (pattern doesn't match genome sequence)
|
|
89
|
+
* ```
|
|
49
90
|
*/
|
|
50
91
|
function getGenomeIndex(tokens) {
|
|
51
92
|
const seq = tokens.reduce(genomeSequencer, "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genome.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/genome.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { SYMBOL_PATTERNS, SYMBOLS } from '..';\nimport type { Tokens } from '../lexer';\n\nconst GENOME_PATTERN =\n /^(B?)([DN]?[MN]?[SN]?)(B?)(?:B?)([DN]?[MN]?[SN]?)(?:B?)$/;\n\n/**\n * Get the position (index) of where to insert a divider into the token list;\n * basically, the count of numeric components (left-of-divider position) plus\n * 1 if there is a bearing identifier (left-of-divider).\n */\nfunction dividerIndexer(_full: string, ...args: string[]) {\n const [bearing1 = '', number1, bearing2 = '', number2] = args;\n\n // if no numeric values exist there no way to infer a location to insert a divider\n if (!(number1?.length && number2?.length)) {\n return '0';\n }\n\n return `${number1.length + (bearing1.length || bearing2.length)}`;\n}\n\n/**\n * The genome sequence is a simplification of the tokens list:\n *\n * - B = bearings (NSEW)\n * - D = degrees (number with degree character following)\n * - M = minutes (number with minutes character following)\n * - S = seconds (number with seconds character following)\n * - N = number (no identifying character following)\n * - X = for unmatched token types\n */\nfunction genomeSequencer(acc: string, t: string) {\n if (t.includes(SYMBOLS.DEGREES)) {\n return `${acc}D`;\n }\n\n if (t.includes(SYMBOLS.MINUTES)) {\n return `${acc}M`;\n }\n\n if (t.includes(SYMBOLS.SECONDS)) {\n return `${acc}S`;\n }\n\n if (SYMBOL_PATTERNS.NSEW.test(t)) {\n return `${acc}B`;\n }\n\n if (/\\d/.test(t)) {\n return `${acc}N`;\n }\n\n return `${acc}X`;\n}\n\n/**\n * Use the \"genome\" sequence of the token list to find the index for inserting\n * a missing divider token.\n */\nexport function getGenomeIndex(tokens: Tokens) {\n const seq = tokens.reduce(genomeSequencer, '');\n\n return GENOME_PATTERN.test(seq)\n ? Number.parseInt(seq.replace(GENOME_PATTERN, dividerIndexer), 10)\n : 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAM,iBACJ
|
|
1
|
+
{"version":3,"file":"genome.js","names":[],"sources":["../../../../../src/coordinates/latlon/internal/pipes/genome.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { SYMBOL_PATTERNS, SYMBOLS } from '..';\nimport type { Tokens } from '../lexer';\n\nconst GENOME_PATTERN =\n /^(B?)([DN]?[MN]?[SN]?)(B?)(?:B?)([DN]?[MN]?[SN]?)(?:B?)$/;\n\n/**\n * Get the position (index) of where to insert a divider into the token list;\n * basically, the count of numeric components (left-of-divider position) plus\n * 1 if there is a bearing identifier (left-of-divider).\n *\n * @param _full - Full regex match string (unused).\n * @param args - Regex capture groups: [bearing1, number1, bearing2, number2].\n * @returns String representation of the divider index position.\n *\n * @example\n * ```typescript\n * dividerIndexer('BDNBDNB', 'B', 'DN', 'B', 'DN');\n * // '3' (bearing + 2 numeric components)\n * ```\n */\nfunction dividerIndexer(_full: string, ...args: string[]) {\n const [bearing1 = '', number1, bearing2 = '', number2] = args;\n\n // if no numeric values exist there no way to infer a location to insert a divider\n if (!(number1?.length && number2?.length)) {\n return '0';\n }\n\n return `${number1.length + (bearing1.length || bearing2.length)}`;\n}\n\n/**\n * The genome sequence is a simplification of the tokens list:\n *\n * - B = bearings (NSEW)\n * - D = degrees (number with degree character following)\n * - M = minutes (number with minutes character following)\n * - S = seconds (number with seconds character following)\n * - N = number (no identifying character following)\n * - X = for unmatched token types\n *\n * @param acc - Accumulated genome sequence string.\n * @param t - Current token to classify.\n * @returns Updated genome sequence with new character appended.\n *\n * @example\n * ```typescript\n * genomeSequencer('', '45°');\n * // 'D'\n * ```\n *\n * @example\n * ```typescript\n * genomeSequencer('D', 'N');\n * // 'DB'\n * ```\n */\nfunction genomeSequencer(acc: string, t: string) {\n if (t.includes(SYMBOLS.DEGREES)) {\n return `${acc}D`;\n }\n\n if (t.includes(SYMBOLS.MINUTES)) {\n return `${acc}M`;\n }\n\n if (t.includes(SYMBOLS.SECONDS)) {\n return `${acc}S`;\n }\n\n if (SYMBOL_PATTERNS.NSEW.test(t)) {\n return `${acc}B`;\n }\n\n if (/\\d/.test(t)) {\n return `${acc}N`;\n }\n\n return `${acc}X`;\n}\n\n/**\n * Use the \"genome\" sequence of the token list to find the index for inserting\n * a missing divider token.\n *\n * @param tokens - Array of coordinate tokens to analyze.\n * @returns Index position where divider should be inserted, or 0 if pattern doesn't match.\n *\n * @example\n * ```typescript\n * getGenomeIndex(['45°', '30'', 'N', '122°', '15'', 'W']);\n * // 3 (insert divider after latitude components)\n * ```\n *\n * @example\n * ```typescript\n * getGenomeIndex(['45', '30', '15']);\n * // 0 (pattern doesn't match genome sequence)\n * ```\n */\nexport function getGenomeIndex(tokens: Tokens) {\n const seq = tokens.reduce(genomeSequencer, '');\n\n return GENOME_PATTERN.test(seq)\n ? Number.parseInt(seq.replace(GENOME_PATTERN, dividerIndexer), 10)\n : 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAM,iBACJ;;;;;;;;;;;;;;;;AAiBF,SAAS,eAAe,OAAe,GAAG,MAAgB;CACxD,MAAM,CAAC,WAAW,IAAI,SAAS,WAAW,IAAI,WAAW;AAGzD,KAAI,EAAE,SAAS,UAAU,SAAS,QAChC,QAAO;AAGT,QAAO,GAAG,QAAQ,UAAU,SAAS,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B1D,SAAS,gBAAgB,KAAa,GAAW;AAC/C,KAAI,EAAE,SAAS,QAAQ,QAAQ,CAC7B,QAAO,GAAG,IAAI;AAGhB,KAAI,EAAE,SAAS,QAAQ,QAAQ,CAC7B,QAAO,GAAG,IAAI;AAGhB,KAAI,EAAE,SAAS,QAAQ,QAAQ,CAC7B,QAAO,GAAG,IAAI;AAGhB,KAAI,gBAAgB,KAAK,KAAK,EAAE,CAC9B,QAAO,GAAG,IAAI;AAGhB,KAAI,KAAK,KAAK,EAAE,CACd,QAAO,GAAG,IAAI;AAGhB,QAAO,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;AAsBhB,SAAgB,eAAe,QAAgB;CAC7C,MAAM,MAAM,OAAO,OAAO,iBAAiB,GAAG;AAE9C,QAAO,eAAe,KAAK,IAAI,GAC3B,OAAO,SAAS,IAAI,QAAQ,gBAAgB,eAAe,EAAE,GAAG,GAChE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -20,7 +20,21 @@ type PipeResult = ReturnType<Pipe>;
|
|
|
20
20
|
* Consistently create a PipesResult array to return. Use this instead of
|
|
21
21
|
* casting to PipesResult everywhere.
|
|
22
22
|
*
|
|
23
|
-
* @param
|
|
23
|
+
* @param t - Array of coordinate tokens.
|
|
24
|
+
* @param e - Error status: true = has error, false = no error, or error message string.
|
|
25
|
+
* @returns Pipe result tuple with tokens (empty if error) and error status.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* pipesResult(['45', 'N', '/', '122', 'W'], false);
|
|
30
|
+
* // [['45', 'N', '/', '122', 'W'], false]
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* pipesResult(['45'], 'Too few numbers.');
|
|
36
|
+
* // [[], 'Too few numbers.']
|
|
37
|
+
* ```
|
|
24
38
|
*
|
|
25
39
|
* @remarks
|
|
26
40
|
* pure function
|
|
@@ -30,7 +44,23 @@ declare const pipesResult: (t: Tokens, e: boolean | string) => PipeResult;
|
|
|
30
44
|
* Run the tokens through a preset pipeline of violations checks exiting the
|
|
31
45
|
* process as early as possible when violations are found because violations
|
|
32
46
|
* will make further violations checks less accurate and could return inaccurate
|
|
33
|
-
* violations that could be misleading or hide the most important violation
|
|
47
|
+
* violations that could be misleading or hide the most important violation.
|
|
48
|
+
*
|
|
49
|
+
* @param tokens - Array of parsed coordinate tokens to validate and normalize.
|
|
50
|
+
* @param format - Optional coordinate format (LATLON or LONLAT) for inference.
|
|
51
|
+
* @returns Tuple of [processed tokens, array of error messages].
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* pipesRunner(['45', 'N', '/', '122', 'W'], 'LATLON');
|
|
56
|
+
* // [['45', 'N', '/', '122', 'W'], []]
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* pipesRunner(['45'], 'LATLON');
|
|
62
|
+
* // [[], ['Too few numbers.']]
|
|
63
|
+
* ```
|
|
34
64
|
*/
|
|
35
65
|
declare function pipesRunner(tokens: Tokens, format?: Format): [Tokens, string[]];
|
|
36
66
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
3
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
5
|
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -18,19 +18,56 @@ import { fixBearings } from "./fix-bearings.js";
|
|
|
18
18
|
import { fixDivider } from "./fix-dividers.js";
|
|
19
19
|
|
|
20
20
|
//#region src/coordinates/latlon/internal/pipes/index.ts
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Make a RegExp global.
|
|
23
|
+
*
|
|
24
|
+
* @param k - Key of the SYMBOL_PATTERNS object.
|
|
25
|
+
* @returns New global RegExp based on the pattern.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* makeGlobal('NSEW');
|
|
30
|
+
* // /[NSEW]/g
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
22
33
|
const makeGlobal = (k) => new RegExp(SYMBOL_PATTERNS[k], "g");
|
|
23
34
|
/**
|
|
24
35
|
* Consistently create a PipesResult array to return. Use this instead of
|
|
25
36
|
* casting to PipesResult everywhere.
|
|
26
37
|
*
|
|
27
|
-
* @param
|
|
38
|
+
* @param t - Array of coordinate tokens.
|
|
39
|
+
* @param e - Error status: true = has error, false = no error, or error message string.
|
|
40
|
+
* @returns Pipe result tuple with tokens (empty if error) and error status.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* pipesResult(['45', 'N', '/', '122', 'W'], false);
|
|
45
|
+
* // [['45', 'N', '/', '122', 'W'], false]
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* pipesResult(['45'], 'Too few numbers.');
|
|
51
|
+
* // [[], 'Too few numbers.']
|
|
52
|
+
* ```
|
|
28
53
|
*
|
|
29
54
|
* @remarks
|
|
30
55
|
* pure function
|
|
31
56
|
*/
|
|
32
57
|
const pipesResult = (t, e) => [e ? [] : t, e];
|
|
33
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Check if there are more than 2 of something.
|
|
60
|
+
*
|
|
61
|
+
* @param p - Regular expression pattern to match.
|
|
62
|
+
* @returns Function that takes tokens and returns pipe result with error if >2 matches found.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const checkBearings = tooMany(/[NSEW]/g);
|
|
67
|
+
* checkBearings(['N', 'S', 'E', 'W']);
|
|
68
|
+
* // Returns error=true (more than 2 bearings)
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
34
71
|
const tooMany = (p) => (t) => pipesResult(t, (t.join("").match(p) ?? []).length > 2);
|
|
35
72
|
const pipes = [
|
|
36
73
|
["Too many bearings.", tooMany(makeGlobal("NSEW"))],
|
|
@@ -47,7 +84,23 @@ const pipes = [
|
|
|
47
84
|
* Run the tokens through a preset pipeline of violations checks exiting the
|
|
48
85
|
* process as early as possible when violations are found because violations
|
|
49
86
|
* will make further violations checks less accurate and could return inaccurate
|
|
50
|
-
* violations that could be misleading or hide the most important violation
|
|
87
|
+
* violations that could be misleading or hide the most important violation.
|
|
88
|
+
*
|
|
89
|
+
* @param tokens - Array of parsed coordinate tokens to validate and normalize.
|
|
90
|
+
* @param format - Optional coordinate format (LATLON or LONLAT) for inference.
|
|
91
|
+
* @returns Tuple of [processed tokens, array of error messages].
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* pipesRunner(['45', 'N', '/', '122', 'W'], 'LATLON');
|
|
96
|
+
* // [['45', 'N', '/', '122', 'W'], []]
|
|
97
|
+
* ```
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* pipesRunner(['45'], 'LATLON');
|
|
102
|
+
* // [[], ['Too few numbers.']]
|
|
103
|
+
* ```
|
|
51
104
|
*/
|
|
52
105
|
function pipesRunner(tokens, format) {
|
|
53
106
|
let copy = tokens.slice(0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["pipes: [string, Pipe][]","error: PipeResult[1]"],"sources":["../../../../../src/coordinates/latlon/internal/pipes/index.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { type Format, SYMBOL_PATTERNS } from '..';\nimport { checkAmbiguousGrouping } from './check-ambiguous';\nimport { checkNumberValues } from './check-numbers';\nimport { fixBearings } from './fix-bearings';\nimport { fixDivider } from './fix-dividers';\nimport type { Tokens } from '../lexer';\n\ntype Pipe = (t: Tokens, f?: Format) => [Tokens, boolean | string];\n\nexport type PipeResult = ReturnType<Pipe>;\n\n
|
|
1
|
+
{"version":3,"file":"index.js","names":["pipes: [string, Pipe][]","error: PipeResult[1]"],"sources":["../../../../../src/coordinates/latlon/internal/pipes/index.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2024 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { type Format, SYMBOL_PATTERNS } from '..';\nimport { checkAmbiguousGrouping } from './check-ambiguous';\nimport { checkNumberValues } from './check-numbers';\nimport { fixBearings } from './fix-bearings';\nimport { fixDivider } from './fix-dividers';\nimport type { Tokens } from '../lexer';\n\ntype Pipe = (t: Tokens, f?: Format) => [Tokens, boolean | string];\n\nexport type PipeResult = ReturnType<Pipe>;\n\n/**\n * Make a RegExp global.\n *\n * @param k - Key of the SYMBOL_PATTERNS object.\n * @returns New global RegExp based on the pattern.\n *\n * @example\n * ```typescript\n * makeGlobal('NSEW');\n * // /[NSEW]/g\n * ```\n */\nconst makeGlobal = (k: keyof typeof SYMBOL_PATTERNS) =>\n new RegExp(SYMBOL_PATTERNS[k], 'g');\n\n/**\n * Consistently create a PipesResult array to return. Use this instead of\n * casting to PipesResult everywhere.\n *\n * @param t - Array of coordinate tokens.\n * @param e - Error status: true = has error, false = no error, or error message string.\n * @returns Pipe result tuple with tokens (empty if error) and error status.\n *\n * @example\n * ```typescript\n * pipesResult(['45', 'N', '/', '122', 'W'], false);\n * // [['45', 'N', '/', '122', 'W'], false]\n * ```\n *\n * @example\n * ```typescript\n * pipesResult(['45'], 'Too few numbers.');\n * // [[], 'Too few numbers.']\n * ```\n *\n * @remarks\n * pure function\n */\nexport const pipesResult = (t: Tokens, e: boolean | string): PipeResult => [\n // if there are errors do NOT return the tokens\n e ? [] : t,\n e,\n];\n\n/**\n * Check if there are more than 2 of something.\n *\n * @param p - Regular expression pattern to match.\n * @returns Function that takes tokens and returns pipe result with error if >2 matches found.\n *\n * @example\n * ```typescript\n * const checkBearings = tooMany(/[NSEW]/g);\n * checkBearings(['N', 'S', 'E', 'W']);\n * // Returns error=true (more than 2 bearings)\n * ```\n */\nconst tooMany = (p: RegExp) => (t: Tokens) =>\n pipesResult(t, (t.join('').match(p) ?? []).length > 2);\n\nconst pipes: [string, Pipe][] = [\n // Unrecoverable violations\n ['Too many bearings.', tooMany(makeGlobal('NSEW'))],\n ['Too many numeric signs.', tooMany(/[-+]/g)],\n ['Too many degrees indicators.', tooMany(makeGlobal('DEGREES'))],\n ['Too many minutes indicators.', tooMany(makeGlobal('MINUTES'))],\n ['Too many seconds indicators.', tooMany(makeGlobal('SECONDS'))],\n ['Number values checks.', checkNumberValues],\n ['Ambiguous grouping of numbers with no divider.', checkAmbiguousGrouping],\n\n // fix values and formatting to be consistent\n ['Unable to identify latitude from longitude.', fixDivider],\n ['Unable to identify bearings.', fixBearings],\n];\n\n/**\n * Run the tokens through a preset pipeline of violations checks exiting the\n * process as early as possible when violations are found because violations\n * will make further violations checks less accurate and could return inaccurate\n * violations that could be misleading or hide the most important violation.\n *\n * @param tokens - Array of parsed coordinate tokens to validate and normalize.\n * @param format - Optional coordinate format (LATLON or LONLAT) for inference.\n * @returns Tuple of [processed tokens, array of error messages].\n *\n * @example\n * ```typescript\n * pipesRunner(['45', 'N', '/', '122', 'W'], 'LATLON');\n * // [['45', 'N', '/', '122', 'W'], []]\n * ```\n *\n * @example\n * ```typescript\n * pipesRunner(['45'], 'LATLON');\n * // [[], ['Too few numbers.']]\n * ```\n */\nexport function pipesRunner(\n tokens: Tokens,\n format?: Format,\n): [Tokens, string[]] {\n let copy = tokens.slice(0);\n let error: PipeResult[1] = false;\n const errors = [] as string[];\n\n for (const [message, op] of pipes) {\n [copy, error] = op(copy, format);\n\n if (error) {\n // accumulate the \"errors\" because if tokens are returned\n // the errors are only warnings and are recoverable\n errors.push(error === true ? message : error);\n\n if (!copy.length) {\n return [copy, [error === true ? message : error]];\n }\n }\n }\n\n return [copy, errors];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,MAAM,cAAc,MAClB,IAAI,OAAO,gBAAgB,IAAI,IAAI;;;;;;;;;;;;;;;;;;;;;;;;AAyBrC,MAAa,eAAe,GAAW,MAAoC,CAEzE,IAAI,EAAE,GAAG,GACT,EACD;;;;;;;;;;;;;;AAeD,MAAM,WAAW,OAAe,MAC9B,YAAY,IAAI,EAAE,KAAK,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE;AAExD,MAAMA,QAA0B;CAE9B,CAAC,sBAAsB,QAAQ,WAAW,OAAO,CAAC,CAAC;CACnD,CAAC,2BAA2B,QAAQ,QAAQ,CAAC;CAC7C,CAAC,gCAAgC,QAAQ,WAAW,UAAU,CAAC,CAAC;CAChE,CAAC,gCAAgC,QAAQ,WAAW,UAAU,CAAC,CAAC;CAChE,CAAC,gCAAgC,QAAQ,WAAW,UAAU,CAAC,CAAC;CAChE,CAAC,yBAAyB,kBAAkB;CAC5C,CAAC,kDAAkD,uBAAuB;CAG1E,CAAC,+CAA+C,WAAW;CAC3D,CAAC,gCAAgC,YAAY;CAC9C;;;;;;;;;;;;;;;;;;;;;;;AAwBD,SAAgB,YACd,QACA,QACoB;CACpB,IAAI,OAAO,OAAO,MAAM,EAAE;CAC1B,IAAIC,QAAuB;CAC3B,MAAM,SAAS,EAAE;AAEjB,MAAK,MAAM,CAAC,SAAS,OAAO,OAAO;AACjC,GAAC,MAAM,SAAS,GAAG,MAAM,OAAO;AAEhC,MAAI,OAAO;AAGT,UAAO,KAAK,UAAU,OAAO,UAAU,MAAM;AAE7C,OAAI,CAAC,KAAK,OACR,QAAO,CAAC,MAAM,CAAC,UAAU,OAAO,UAAU,MAAM,CAAC;;;AAKvD,QAAO,CAAC,MAAM,OAAO"}
|