@accelint/geo 0.5.1 → 0.6.0

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +233 -1
  3. package/catalog-info.yaml +1 -1
  4. package/dist/cartesian.d.ts +2 -0
  5. package/dist/cartesian.js +2 -0
  6. package/dist/cartesian.js.map +1 -1
  7. package/dist/coordinates/coordinate.d.ts +41 -7
  8. package/dist/coordinates/coordinate.js +102 -12
  9. package/dist/coordinates/coordinate.js.map +1 -1
  10. package/dist/coordinates/latlon/decimal-degrees/formatter.d.ts +20 -0
  11. package/dist/coordinates/latlon/decimal-degrees/formatter.js +38 -0
  12. package/dist/coordinates/latlon/decimal-degrees/formatter.js.map +1 -1
  13. package/dist/coordinates/latlon/decimal-degrees/parser.d.ts +68 -2
  14. package/dist/coordinates/latlon/decimal-degrees/parser.js +66 -5
  15. package/dist/coordinates/latlon/decimal-degrees/parser.js.map +1 -1
  16. package/dist/coordinates/latlon/decimal-degrees/system.d.ts +32 -0
  17. package/dist/coordinates/latlon/decimal-degrees/system.js +31 -0
  18. package/dist/coordinates/latlon/decimal-degrees/system.js.map +1 -1
  19. package/dist/coordinates/latlon/degrees-decimal-minutes/formatter.d.ts +20 -0
  20. package/dist/coordinates/latlon/degrees-decimal-minutes/formatter.js +37 -0
  21. package/dist/coordinates/latlon/degrees-decimal-minutes/formatter.js.map +1 -1
  22. package/dist/coordinates/latlon/degrees-decimal-minutes/parser.d.ts +72 -2
  23. package/dist/coordinates/latlon/degrees-decimal-minutes/parser.js +66 -3
  24. package/dist/coordinates/latlon/degrees-decimal-minutes/parser.js.map +1 -1
  25. package/dist/coordinates/latlon/degrees-decimal-minutes/system.d.ts +32 -0
  26. package/dist/coordinates/latlon/degrees-decimal-minutes/system.js +31 -0
  27. package/dist/coordinates/latlon/degrees-decimal-minutes/system.js.map +1 -1
  28. package/dist/coordinates/latlon/degrees-minutes-seconds/formatter.d.ts +20 -0
  29. package/dist/coordinates/latlon/degrees-minutes-seconds/formatter.js +37 -0
  30. package/dist/coordinates/latlon/degrees-minutes-seconds/formatter.js.map +1 -1
  31. package/dist/coordinates/latlon/degrees-minutes-seconds/parser.d.ts +74 -2
  32. package/dist/coordinates/latlon/degrees-minutes-seconds/parser.js +66 -3
  33. package/dist/coordinates/latlon/degrees-minutes-seconds/parser.js.map +1 -1
  34. package/dist/coordinates/latlon/degrees-minutes-seconds/system.d.ts +32 -0
  35. package/dist/coordinates/latlon/degrees-minutes-seconds/system.js +31 -0
  36. package/dist/coordinates/latlon/degrees-minutes-seconds/system.js.map +1 -1
  37. package/dist/coordinates/latlon/internal/coordinate-system.d.ts +22 -0
  38. package/dist/coordinates/latlon/internal/create-cache.d.ts +17 -1
  39. package/dist/coordinates/latlon/internal/create-cache.js +19 -3
  40. package/dist/coordinates/latlon/internal/create-cache.js.map +1 -1
  41. package/dist/coordinates/latlon/internal/exhaustive-errors.d.ts +15 -0
  42. package/dist/coordinates/latlon/internal/exhaustive-errors.js +28 -0
  43. package/dist/coordinates/latlon/internal/exhaustive-errors.js.map +1 -1
  44. package/dist/coordinates/latlon/internal/format.d.ts +20 -0
  45. package/dist/coordinates/latlon/internal/format.js +20 -0
  46. package/dist/coordinates/latlon/internal/format.js.map +1 -1
  47. package/dist/coordinates/latlon/internal/in-range.d.ts +23 -0
  48. package/dist/coordinates/latlon/internal/in-range.js +24 -0
  49. package/dist/coordinates/latlon/internal/in-range.js.map +1 -1
  50. package/dist/coordinates/latlon/internal/index.d.ts +16 -1
  51. package/dist/coordinates/latlon/internal/index.js +25 -1
  52. package/dist/coordinates/latlon/internal/index.js.map +1 -1
  53. package/dist/coordinates/latlon/internal/lexer.d.ts +2 -0
  54. package/dist/coordinates/latlon/internal/lexer.js +26 -0
  55. package/dist/coordinates/latlon/internal/lexer.js.map +1 -1
  56. package/dist/coordinates/latlon/internal/normalize.d.ts +67 -0
  57. package/dist/coordinates/latlon/internal/normalize.js +87 -0
  58. package/dist/coordinates/latlon/internal/normalize.js.map +1 -0
  59. package/dist/coordinates/latlon/internal/ordinal.d.ts +25 -0
  60. package/dist/coordinates/latlon/internal/ordinal.js +25 -0
  61. package/dist/coordinates/latlon/internal/ordinal.js.map +1 -1
  62. package/dist/coordinates/latlon/internal/parse-format.d.ts +22 -0
  63. package/dist/coordinates/latlon/internal/parse-format.js +43 -1
  64. package/dist/coordinates/latlon/internal/parse-format.js.map +1 -1
  65. package/dist/coordinates/latlon/internal/parse.d.ts +2 -0
  66. package/dist/coordinates/latlon/internal/parse.js +4 -1
  67. package/dist/coordinates/latlon/internal/parse.js.map +1 -1
  68. package/dist/coordinates/latlon/internal/pipes/check-ambiguous.d.ts +17 -0
  69. package/dist/coordinates/latlon/internal/pipes/check-ambiguous.js +16 -0
  70. package/dist/coordinates/latlon/internal/pipes/check-ambiguous.js.map +1 -1
  71. package/dist/coordinates/latlon/internal/pipes/check-numbers.d.ts +25 -0
  72. package/dist/coordinates/latlon/internal/pipes/check-numbers.js +33 -0
  73. package/dist/coordinates/latlon/internal/pipes/check-numbers.js.map +1 -1
  74. package/dist/coordinates/latlon/internal/pipes/fix-bearings.d.ts +17 -0
  75. package/dist/coordinates/latlon/internal/pipes/fix-bearings.js +31 -0
  76. package/dist/coordinates/latlon/internal/pipes/fix-bearings.js.map +1 -1
  77. package/dist/coordinates/latlon/internal/pipes/fix-dividers.d.ts +17 -0
  78. package/dist/coordinates/latlon/internal/pipes/fix-dividers.js +29 -0
  79. package/dist/coordinates/latlon/internal/pipes/fix-dividers.js.map +1 -1
  80. package/dist/coordinates/latlon/internal/pipes/genome.d.ts +16 -0
  81. package/dist/coordinates/latlon/internal/pipes/genome.js +41 -0
  82. package/dist/coordinates/latlon/internal/pipes/genome.js.map +1 -1
  83. package/dist/coordinates/latlon/internal/pipes/index.d.ts +32 -2
  84. package/dist/coordinates/latlon/internal/pipes/index.js +57 -4
  85. package/dist/coordinates/latlon/internal/pipes/index.js.map +1 -1
  86. package/dist/coordinates/latlon/internal/pipes/simpler.d.ts +16 -3
  87. package/dist/coordinates/latlon/internal/pipes/simpler.js +15 -3
  88. package/dist/coordinates/latlon/internal/pipes/simpler.js.map +1 -1
  89. package/dist/coordinates/latlon/internal/validate.d.ts +75 -0
  90. package/dist/coordinates/latlon/internal/validate.js +105 -0
  91. package/dist/coordinates/latlon/internal/validate.js.map +1 -0
  92. package/dist/coordinates/latlon/internal/violation.d.ts +18 -0
  93. package/dist/coordinates/latlon/internal/violation.js +18 -0
  94. package/dist/coordinates/latlon/internal/violation.js.map +1 -1
  95. package/dist/coordinates/mgrs/parser.d.ts +24 -0
  96. package/dist/coordinates/mgrs/parser.js +56 -0
  97. package/dist/coordinates/mgrs/parser.js.map +1 -1
  98. package/dist/coordinates/mgrs/system.d.ts +31 -0
  99. package/dist/coordinates/mgrs/system.js +30 -0
  100. package/dist/coordinates/mgrs/system.js.map +1 -1
  101. package/dist/coordinates/utm/parser.d.ts +24 -0
  102. package/dist/coordinates/utm/parser.js +56 -0
  103. package/dist/coordinates/utm/parser.js.map +1 -1
  104. package/dist/coordinates/utm/system.d.ts +21 -0
  105. package/dist/coordinates/utm/system.js +20 -0
  106. package/dist/coordinates/utm/system.js.map +1 -1
  107. package/dist/index.d.ts +3 -1
  108. package/dist/index.js +3 -1
  109. package/dist/patterning.d.ts +12 -2
  110. package/dist/patterning.js +12 -2
  111. package/dist/patterning.js.map +1 -1
  112. package/package.json +3 -1
@@ -13,6 +13,38 @@
13
13
  import { CoordinateSystem } from "../internal/coordinate-system.js";
14
14
 
15
15
  //#region src/coordinates/latlon/degrees-decimal-minutes/system.d.ts
16
+
17
+ /**
18
+ * Degrees Decimal Minutes coordinate system implementation.
19
+ *
20
+ * Provides parsing, conversion, and formatting for coordinates in degrees decimal minutes notation.
21
+ * Coordinates are expressed as integer degrees and decimal minutes (e.g., 37° 46.4940' N).
22
+ *
23
+ * @property name - Human-readable name of the coordinate system.
24
+ * @property parse - Parses degrees decimal minutes coordinate strings.
25
+ * @property toFloat - Converts parsed coordinate components to floating point numbers.
26
+ * @property toFormat - Formats numeric coordinates back to degrees decimal minutes string.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Parse a coordinate string
31
+ * const [coords, errors] = systemDegreesDecimalMinutes.parse('37° 46.4940' N / 122° 25.1640' W', 'LATLON');
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Convert to float
37
+ * const lat = systemDegreesDecimalMinutes.toFloat(['37', '46.4940', 'N']);
38
+ * // 37.7749
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Format to string
44
+ * const formatted = systemDegreesDecimalMinutes.toFormat('LATLON', [37.7749, -122.4194]);
45
+ * // '37 46.494 N / 122 25.164 W'
46
+ * ```
47
+ */
16
48
  declare const systemDegreesDecimalMinutes: CoordinateSystem;
17
49
  //#endregion
18
50
  export { systemDegreesDecimalMinutes };
@@ -15,6 +15,37 @@ import { BEARINGS, SYMBOLS, SYMBOL_PATTERNS } from "../internal/index.js";
15
15
  import { parseDegreesDecimalMinutes } from "./parser.js";
16
16
 
17
17
  //#region src/coordinates/latlon/degrees-decimal-minutes/system.ts
18
+ /**
19
+ * Degrees Decimal Minutes coordinate system implementation.
20
+ *
21
+ * Provides parsing, conversion, and formatting for coordinates in degrees decimal minutes notation.
22
+ * Coordinates are expressed as integer degrees and decimal minutes (e.g., 37° 46.4940' N).
23
+ *
24
+ * @property name - Human-readable name of the coordinate system.
25
+ * @property parse - Parses degrees decimal minutes coordinate strings.
26
+ * @property toFloat - Converts parsed coordinate components to floating point numbers.
27
+ * @property toFormat - Formats numeric coordinates back to degrees decimal minutes string.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Parse a coordinate string
32
+ * const [coords, errors] = systemDegreesDecimalMinutes.parse('37° 46.4940' N / 122° 25.1640' W', 'LATLON');
33
+ * ```
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Convert to float
38
+ * const lat = systemDegreesDecimalMinutes.toFloat(['37', '46.4940', 'N']);
39
+ * // 37.7749
40
+ * ```
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * // Format to string
45
+ * const formatted = systemDegreesDecimalMinutes.toFormat('LATLON', [37.7749, -122.4194]);
46
+ * // '37 46.494 N / 122 25.164 W'
47
+ * ```
48
+ */
18
49
  const systemDegreesDecimalMinutes = {
19
50
  name: "Degrees Decimal Minutes",
20
51
  parse: parseDegreesDecimalMinutes,
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","names":["systemDegreesDecimalMinutes: CoordinateSystem"],"sources":["../../../../src/coordinates/latlon/degrees-decimal-minutes/system.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 {\n BEARINGS,\n type Compass,\n type Format,\n SYMBOL_PATTERNS,\n SYMBOLS,\n} from '../internal';\nimport { parseDegreesDecimalMinutes } from './parser';\nimport type { CoordinateSystem } from '../internal/coordinate-system';\n\nexport const systemDegreesDecimalMinutes: CoordinateSystem = {\n name: 'Degrees Decimal Minutes',\n\n parse: parseDegreesDecimalMinutes,\n\n toFloat(arg) {\n const [degrees, minutes, bear] = arg as [string, string, Compass];\n\n return Number.parseFloat(\n (\n (Number.parseFloat(degrees) + Number.parseFloat(minutes) / 60) *\n (SYMBOL_PATTERNS.NEGATIVE_BEARINGS.test(bear) ? -1 : 1)\n ).toFixed(9),\n );\n },\n\n toFormat(format: Format, [left, right]: [number, number]) {\n return [left, right]\n .map((num, index) => {\n const abs = Math.abs(num);\n const deg = Math.floor(abs);\n const min = Number.parseFloat(((abs - deg) * 60).toFixed(10));\n\n return `${deg} ${min} ${BEARINGS[format][index as 0 | 1][+(num < 0)]}`;\n })\n .join(` ${SYMBOLS.DIVIDER} `);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAuBA,MAAaA,8BAAgD;CAC3D,MAAM;CAEN,OAAO;CAEP,QAAQ,KAAK;EACX,MAAM,CAAC,SAAS,SAAS,QAAQ;AAEjC,SAAO,OAAO,aAET,OAAO,WAAW,QAAQ,GAAG,OAAO,WAAW,QAAQ,GAAG,OAC1D,gBAAgB,kBAAkB,KAAK,KAAK,GAAG,KAAK,IACrD,QAAQ,EAAE,CACb;;CAGH,SAAS,QAAgB,CAAC,MAAM,QAA0B;AACxD,SAAO,CAAC,MAAM,MAAM,CACjB,KAAK,KAAK,UAAU;GACnB,MAAM,MAAM,KAAK,IAAI,IAAI;GACzB,MAAM,MAAM,KAAK,MAAM,IAAI;AAG3B,UAAO,GAAG,IAAI,GAFF,OAAO,aAAa,MAAM,OAAO,IAAI,QAAQ,GAAG,CAAC,CAExC,GAAG,SAAS,QAAQ,OAAgB,EAAE,MAAM;IACjE,CACD,KAAK,IAAI,QAAQ,QAAQ,GAAG;;CAElC"}
1
+ {"version":3,"file":"system.js","names":["systemDegreesDecimalMinutes: CoordinateSystem"],"sources":["../../../../src/coordinates/latlon/degrees-decimal-minutes/system.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 {\n BEARINGS,\n type Compass,\n type Format,\n SYMBOL_PATTERNS,\n SYMBOLS,\n} from '../internal';\nimport { parseDegreesDecimalMinutes } from './parser';\nimport type { CoordinateSystem } from '../internal/coordinate-system';\n\n/**\n * Degrees Decimal Minutes coordinate system implementation.\n *\n * Provides parsing, conversion, and formatting for coordinates in degrees decimal minutes notation.\n * Coordinates are expressed as integer degrees and decimal minutes (e.g., 37° 46.4940' N).\n *\n * @property name - Human-readable name of the coordinate system.\n * @property parse - Parses degrees decimal minutes coordinate strings.\n * @property toFloat - Converts parsed coordinate components to floating point numbers.\n * @property toFormat - Formats numeric coordinates back to degrees decimal minutes string.\n *\n * @example\n * ```typescript\n * // Parse a coordinate string\n * const [coords, errors] = systemDegreesDecimalMinutes.parse('37° 46.4940' N / 122° 25.1640' W', 'LATLON');\n * ```\n *\n * @example\n * ```typescript\n * // Convert to float\n * const lat = systemDegreesDecimalMinutes.toFloat(['37', '46.4940', 'N']);\n * // 37.7749\n * ```\n *\n * @example\n * ```typescript\n * // Format to string\n * const formatted = systemDegreesDecimalMinutes.toFormat('LATLON', [37.7749, -122.4194]);\n * // '37 46.494 N / 122 25.164 W'\n * ```\n */\nexport const systemDegreesDecimalMinutes: CoordinateSystem = {\n name: 'Degrees Decimal Minutes',\n\n parse: parseDegreesDecimalMinutes,\n\n toFloat(arg) {\n const [degrees, minutes, bear] = arg as [string, string, Compass];\n\n return Number.parseFloat(\n (\n (Number.parseFloat(degrees) + Number.parseFloat(minutes) / 60) *\n (SYMBOL_PATTERNS.NEGATIVE_BEARINGS.test(bear) ? -1 : 1)\n ).toFixed(9),\n );\n },\n\n toFormat(format: Format, [left, right]: [number, number]) {\n return [left, right]\n .map((num, index) => {\n const abs = Math.abs(num);\n const deg = Math.floor(abs);\n const min = Number.parseFloat(((abs - deg) * 60).toFixed(10));\n\n return `${deg} ${min} ${BEARINGS[format][index as 0 | 1][+(num < 0)]}`;\n })\n .join(` ${SYMBOLS.DIVIDER} `);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,MAAaA,8BAAgD;CAC3D,MAAM;CAEN,OAAO;CAEP,QAAQ,KAAK;EACX,MAAM,CAAC,SAAS,SAAS,QAAQ;AAEjC,SAAO,OAAO,aAET,OAAO,WAAW,QAAQ,GAAG,OAAO,WAAW,QAAQ,GAAG,OAC1D,gBAAgB,kBAAkB,KAAK,KAAK,GAAG,KAAK,IACrD,QAAQ,EAAE,CACb;;CAGH,SAAS,QAAgB,CAAC,MAAM,QAA0B;AACxD,SAAO,CAAC,MAAM,MAAM,CACjB,KAAK,KAAK,UAAU;GACnB,MAAM,MAAM,KAAK,IAAI,IAAI;GACzB,MAAM,MAAM,KAAK,MAAM,IAAI;AAG3B,UAAO,GAAG,IAAI,GAFF,OAAO,aAAa,MAAM,OAAO,IAAI,QAAQ,GAAG,CAAC,CAExC,GAAG,SAAS,QAAQ,OAAgB,EAAE,MAAM;IACjE,CACD,KAAK,IAAI,QAAQ,QAAQ,GAAG;;CAElC"}
@@ -13,6 +13,26 @@
13
13
  import { FormatOptions } from "../internal/format.js";
14
14
 
15
15
  //#region src/coordinates/latlon/degrees-minutes-seconds/formatter.d.ts
16
+
17
+ /**
18
+ * Formats latitude/longitude coordinates in degrees minutes seconds notation.
19
+ *
20
+ * @param coordinates - Tuple of [latitude, longitude] values.
21
+ * @param config - Optional formatting configuration.
22
+ * @returns Formatted coordinate string in degrees minutes seconds format.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * formatDegreesMinutesSeconds([37.7749, -122.4194]);
27
+ * // '37° 46' 29.64″ N, 122° 25' 9.84″ W'
28
+ * ```
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * formatDegreesMinutesSeconds([37.7749, -122.4194], { separator: ' / ' });
33
+ * // '37° 46' 29.64″ N / 122° 25' 9.84″ W'
34
+ * ```
35
+ */
16
36
  declare const formatDegreesMinutesSeconds: (coordinates: [number, number], config?: FormatOptions) => string;
17
37
  //#endregion
18
38
  export { formatDegreesMinutesSeconds };
@@ -14,12 +14,49 @@
14
14
  import { createFormatter } from "../internal/format.js";
15
15
 
16
16
  //#region src/coordinates/latlon/degrees-minutes-seconds/formatter.ts
17
+ /**
18
+ * Converts a coordinate value to degrees minutes seconds format.
19
+ *
20
+ * @param num - The coordinate value to format.
21
+ * @returns Formatted coordinate string with degrees, minutes, and seconds (e.g., "45° 30' 15.23″").
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * toDegreesMinutesSeconds(45.5042);
26
+ * // '45° 30' 15.12″'
27
+ * ```
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * toDegreesMinutesSeconds(-122.4194);
32
+ * // '122° 25' 9.84″'
33
+ * ```
34
+ */
17
35
  const toDegreesMinutesSeconds = (num) => {
18
36
  const degrees = Math.floor(Math.abs(num));
19
37
  const minutesFull = (Math.abs(num) - degrees) * 60;
20
38
  const minutes = Math.floor(minutesFull);
21
39
  return `${degrees}° ${minutes}' ${((minutesFull - minutes) * 60).toFixed(2)}″`;
22
40
  };
41
+ /**
42
+ * Formats latitude/longitude coordinates in degrees minutes seconds notation.
43
+ *
44
+ * @param coordinates - Tuple of [latitude, longitude] values.
45
+ * @param config - Optional formatting configuration.
46
+ * @returns Formatted coordinate string in degrees minutes seconds format.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * formatDegreesMinutesSeconds([37.7749, -122.4194]);
51
+ * // '37° 46' 29.64″ N, 122° 25' 9.84″ W'
52
+ * ```
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * formatDegreesMinutesSeconds([37.7749, -122.4194], { separator: ' / ' });
57
+ * // '37° 46' 29.64″ N / 122° 25' 9.84″ W'
58
+ * ```
59
+ */
23
60
  const formatDegreesMinutesSeconds = createFormatter(toDegreesMinutesSeconds);
24
61
 
25
62
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.js","names":[],"sources":["../../../../src/coordinates/latlon/degrees-minutes-seconds/formatter.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { createFormatter } from '../internal/format';\n\nconst toDegreesMinutesSeconds = (num: number): string => {\n const degrees = Math.floor(Math.abs(num));\n const minutesFull = (Math.abs(num) - degrees) * 60;\n const minutes = Math.floor(minutesFull);\n const seconds = ((minutesFull - minutes) * 60).toFixed(2);\n\n return `${degrees}° ${minutes}' ${seconds}″`;\n};\n\nexport const formatDegreesMinutesSeconds = createFormatter(\n toDegreesMinutesSeconds,\n);\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,MAAM,2BAA2B,QAAwB;CACvD,MAAM,UAAU,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC;CACzC,MAAM,eAAe,KAAK,IAAI,IAAI,GAAG,WAAW;CAChD,MAAM,UAAU,KAAK,MAAM,YAAY;AAGvC,QAAO,GAAG,QAAQ,IAAI,QAAQ,MAFZ,cAAc,WAAW,IAAI,QAAQ,EAAE,CAEf;;AAG5C,MAAa,8BAA8B,gBACzC,wBACD"}
1
+ {"version":3,"file":"formatter.js","names":[],"sources":["../../../../src/coordinates/latlon/degrees-minutes-seconds/formatter.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { createFormatter } from '../internal/format';\n\n/**\n * Converts a coordinate value to degrees minutes seconds format.\n *\n * @param num - The coordinate value to format.\n * @returns Formatted coordinate string with degrees, minutes, and seconds (e.g., \"45° 30' 15.23″\").\n *\n * @example\n * ```typescript\n * toDegreesMinutesSeconds(45.5042);\n * // '45° 30' 15.12″'\n * ```\n *\n * @example\n * ```typescript\n * toDegreesMinutesSeconds(-122.4194);\n * // '122° 25' 9.84″'\n * ```\n */\nconst toDegreesMinutesSeconds = (num: number): string => {\n const degrees = Math.floor(Math.abs(num));\n const minutesFull = (Math.abs(num) - degrees) * 60;\n const minutes = Math.floor(minutesFull);\n const seconds = ((minutesFull - minutes) * 60).toFixed(2);\n\n return `${degrees}° ${minutes}' ${seconds}″`;\n};\n\n/**\n * Formats latitude/longitude coordinates in degrees minutes seconds notation.\n *\n * @param coordinates - Tuple of [latitude, longitude] values.\n * @param config - Optional formatting configuration.\n * @returns Formatted coordinate string in degrees minutes seconds format.\n *\n * @example\n * ```typescript\n * formatDegreesMinutesSeconds([37.7749, -122.4194]);\n * // '37° 46' 29.64″ N, 122° 25' 9.84″ W'\n * ```\n *\n * @example\n * ```typescript\n * formatDegreesMinutesSeconds([37.7749, -122.4194], { separator: ' / ' });\n * // '37° 46' 29.64″ N / 122° 25' 9.84″ W'\n * ```\n */\nexport const formatDegreesMinutesSeconds = createFormatter(\n toDegreesMinutesSeconds,\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAM,2BAA2B,QAAwB;CACvD,MAAM,UAAU,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC;CACzC,MAAM,eAAe,KAAK,IAAI,IAAI,GAAG,WAAW;CAChD,MAAM,UAAU,KAAK,MAAM,YAAY;AAGvC,QAAO,GAAG,QAAQ,IAAI,QAAQ,MAFZ,cAAc,WAAW,IAAI,QAAQ,EAAE,CAEf;;;;;;;;;;;;;;;;;;;;;AAsB5C,MAAa,8BAA8B,gBACzC,wBACD"}
@@ -14,8 +14,80 @@ import { Format } from "../internal/index.js";
14
14
  import { ParseResults } from "../internal/parse.js";
15
15
 
16
16
  //#region src/coordinates/latlon/degrees-minutes-seconds/parser.d.ts
17
- /** Parse a Degrees Minutes Seconds coordinate. */
17
+ type DegreesMinutesSeconds = {
18
+ bear: string;
19
+ deg: string;
20
+ min: string;
21
+ sec: string;
22
+ };
23
+ /**
24
+ * Creates an error identification function for degrees minutes seconds coordinates.
25
+ *
26
+ * Validates that degree values are integers, minutes are in range 0-59,
27
+ * seconds are in range 0-59.999..., and all components are properly formatted.
28
+ *
29
+ * @param format - The coordinate format (LATLON or LONLAT).
30
+ * @returns Function that validates coordinate components and returns parse results.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const validator = identifyErrors('LATLON');
35
+ * const result = validator({ deg: '91', min: '0', sec: '0', bear: 'N' }, 0);
36
+ * // [[], ['Degrees value (91) exceeds max value (90).']]
37
+ * ```
38
+ */
39
+ declare function identifyErrors(format: Format): (arg: DegreesMinutesSeconds | undefined, i: number) => ParseResults;
40
+ /**
41
+ * Identifies and organizes coordinate components from parsed tokens.
42
+ *
43
+ * Separates bearing indicators (N/S/E/W), degree values, minute values, and second values from tokens.
44
+ * Uses symbol patterns to identify component types and positional logic as fallback.
45
+ *
46
+ * @param half - Array of tokens representing one coordinate component.
47
+ * @returns Object with `bear`, `deg`, `min`, and `sec` properties, or undefined if invalid.
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * identifyPieces(['45', '30', '15.23', 'N']);
52
+ * // { bear: 'N', deg: '45', min: '30', sec: '15.23' }
53
+ * ```
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * identifyPieces(['122°', '25'', '9.84″', 'W']);
58
+ * // { bear: 'W', deg: '122', min: '25', sec: '9.84' }
59
+ * ```
60
+ */
61
+ declare function identifyPieces(half: string[]): {
62
+ bear: string;
63
+ deg: string;
64
+ min: string;
65
+ sec: string;
66
+ } | undefined;
67
+ /**
68
+ * Parses a Degrees Minutes Seconds coordinate string.
69
+ *
70
+ * Accepts coordinates in degrees minutes seconds format with bearing indicators.
71
+ * Validates that degrees are integers, minutes are in range 0-59,
72
+ * seconds are in range 0-59.999..., and all components are properly formatted.
73
+ *
74
+ * @param input - Raw coordinate string to parse.
75
+ * @param format - Expected format (LATLON or LONLAT).
76
+ * @returns Parsed coordinate values or errors.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * parseDegreesMinutesSeconds('37° 46' 29.64″ N / 122° 25' 9.84″ W', 'LATLON');
81
+ * // [[37.7749, -122.4194], []]
82
+ * ```
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * parseDegreesMinutesSeconds('45 30 15.23 N, 122 25 9.84 W');
87
+ * // [[45.504231, -122.419400], []]
88
+ * ```
89
+ */
18
90
  declare const parseDegreesMinutesSeconds: (format: Format, input: string) => ParseResults;
19
91
  //#endregion
20
- export { parseDegreesMinutesSeconds };
92
+ export { identifyErrors as _identifyErrors, identifyPieces as _identifyPieces, parseDegreesMinutesSeconds };
21
93
  //# sourceMappingURL=parser.d.ts.map
@@ -19,7 +19,9 @@ import { inRange } from "../internal/in-range.js";
19
19
  //#region src/coordinates/latlon/degrees-minutes-seconds/parser.ts
20
20
  const checks = {
21
21
  deg: (deg, limit) => {
22
- if (Number.parseFloat(deg) > limit) return `Degrees value (${deg}) exceeds max value (${limit}).`;
22
+ const num = Number.parseFloat(deg);
23
+ if (Number.isNaN(num)) return `Degrees value (${deg}) is not a valid number.`;
24
+ if (num > limit) return `Degrees value (${deg}) exceeds max value (${limit}).`;
23
25
  if (/\./.test(deg)) return `Degrees value (${deg}) must not include decimal value.`;
24
26
  },
25
27
  min: (min) => inRange("Minutes", min, 59),
@@ -29,6 +31,22 @@ const formats = {
29
31
  LATLON: fromTemplate(PARTIAL_PATTERNS, `degLat min secDec NS ${SYMBOLS.DIVIDER} degLon min secDec EW`),
30
32
  LONLAT: fromTemplate(PARTIAL_PATTERNS, `degLon min secDec EW ${SYMBOLS.DIVIDER} degLat min secDec NS`)
31
33
  };
34
+ /**
35
+ * Creates an error identification function for degrees minutes seconds coordinates.
36
+ *
37
+ * Validates that degree values are integers, minutes are in range 0-59,
38
+ * seconds are in range 0-59.999..., and all components are properly formatted.
39
+ *
40
+ * @param format - The coordinate format (LATLON or LONLAT).
41
+ * @returns Function that validates coordinate components and returns parse results.
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const validator = identifyErrors('LATLON');
46
+ * const result = validator({ deg: '91', min: '0', sec: '0', bear: 'N' }, 0);
47
+ * // [[], ['Degrees value (91) exceeds max value (90).']]
48
+ * ```
49
+ */
32
50
  function identifyErrors(format) {
33
51
  return (arg, i) => {
34
52
  if (!arg) return [[], ["Invalid coordinate value."]];
@@ -56,6 +74,27 @@ function identifyErrors(format) {
56
74
  ], []];
57
75
  };
58
76
  }
77
+ /**
78
+ * Identifies and organizes coordinate components from parsed tokens.
79
+ *
80
+ * Separates bearing indicators (N/S/E/W), degree values, minute values, and second values from tokens.
81
+ * Uses symbol patterns to identify component types and positional logic as fallback.
82
+ *
83
+ * @param half - Array of tokens representing one coordinate component.
84
+ * @returns Object with `bear`, `deg`, `min`, and `sec` properties, or undefined if invalid.
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * identifyPieces(['45', '30', '15.23', 'N']);
89
+ * // { bear: 'N', deg: '45', min: '30', sec: '15.23' }
90
+ * ```
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * identifyPieces(['122°', '25'', '9.84″', 'W']);
95
+ * // { bear: 'W', deg: '122', min: '25', sec: '9.84' }
96
+ * ```
97
+ */
59
98
  function identifyPieces(half) {
60
99
  if (half.length < 1 || half.length > 4) return;
61
100
  const asString = half.join(" ");
@@ -72,18 +111,42 @@ function identifyPieces(half) {
72
111
  ];
73
112
  const test = (r, b, v) => r.test(v) || r.test(asString) && b;
74
113
  return half.reduce((acc, token, i, { length }) => {
114
+ if (!acc) return;
75
115
  if (test(SYMBOL_PATTERNS.NSEW, i === length - 1, token)) acc.bear ||= token;
76
116
  else if (test(SYMBOL_PATTERNS.DEGREES, i === 0, token)) acc.deg ||= token;
77
117
  else if (test(SYMBOL_PATTERNS.MINUTES, i === 1, token)) acc.min ||= token;
78
118
  else if (test(SYMBOL_PATTERNS.SECONDS, i === 2, token)) acc.sec ||= token;
79
119
  else {
80
120
  const key = keys.find((k) => !acc[k]);
121
+ if (!key) return;
81
122
  acc[key] = token;
82
123
  }
83
124
  return acc;
84
125
  }, places);
85
126
  }
86
- /** Parse a Degrees Minutes Seconds coordinate. */
127
+ /**
128
+ * Parses a Degrees Minutes Seconds coordinate string.
129
+ *
130
+ * Accepts coordinates in degrees minutes seconds format with bearing indicators.
131
+ * Validates that degrees are integers, minutes are in range 0-59,
132
+ * seconds are in range 0-59.999..., and all components are properly formatted.
133
+ *
134
+ * @param input - Raw coordinate string to parse.
135
+ * @param format - Expected format (LATLON or LONLAT).
136
+ * @returns Parsed coordinate values or errors.
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * parseDegreesMinutesSeconds('37° 46' 29.64″ N / 122° 25' 9.84″ W', 'LATLON');
141
+ * // [[37.7749, -122.4194], []]
142
+ * ```
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * parseDegreesMinutesSeconds('45 30 15.23 N, 122 25 9.84 W');
147
+ * // [[45.504231, -122.419400], []]
148
+ * ```
149
+ */
87
150
  const parseDegreesMinutesSeconds = createParser({
88
151
  formats,
89
152
  identifyErrors,
@@ -91,5 +154,5 @@ const parseDegreesMinutesSeconds = createParser({
91
154
  });
92
155
 
93
156
  //#endregion
94
- export { parseDegreesMinutesSeconds };
157
+ export { identifyErrors as _identifyErrors, identifyPieces as _identifyPieces, parseDegreesMinutesSeconds };
95
158
  //# sourceMappingURL=parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","names":["Patterning.fromTemplate","isNegative: 0 | 1"],"sources":["../../../../src/coordinates/latlon/degrees-minutes-seconds/parser.ts"],"sourcesContent":["/*\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 * as Patterning from '@/patterning';\nimport {\n BEARINGS,\n type Format,\n LIMITS,\n PARTIAL_PATTERNS,\n SYMBOL_PATTERNS,\n SYMBOLS,\n} from '../internal';\nimport { inRange } from '../internal/in-range';\nimport { createParser } from '../internal/parse-format';\nimport type { ParseResults } from '../internal/parse';\n\ntype DegreesMinutesSeconds = {\n bear: string;\n deg: string;\n min: string;\n sec: string;\n};\n\nconst checks = {\n deg: (deg: string, limit: number) => {\n if (Number.parseFloat(deg) > limit) {\n return `Degrees value (${deg}) exceeds max value (${limit}).`;\n }\n\n if (/\\./.test(deg)) {\n return `Degrees value (${deg}) must not include decimal value.`;\n }\n },\n min: (min: string) => inRange('Minutes', min, 59),\n sec: (sec: string) => inRange('Seconds', sec, 59.999999999),\n};\n\nconst formats = {\n LATLON: Patterning.fromTemplate(\n PARTIAL_PATTERNS,\n `degLat min secDec NS ${SYMBOLS.DIVIDER} degLon min secDec EW`,\n ),\n LONLAT: Patterning.fromTemplate(\n PARTIAL_PATTERNS,\n `degLon min secDec EW ${SYMBOLS.DIVIDER} degLat min secDec NS`,\n ),\n};\n\nfunction identifyErrors(format: Format) {\n return (arg: DegreesMinutesSeconds | undefined, i: number) => {\n if (!arg) {\n return [[], ['Invalid coordinate value.']] as ParseResults;\n }\n\n let { bear, deg, min, sec } = arg;\n\n deg ??= '0';\n // NOTE: need `||=` not `??=` because empty-string is not nullish\n min ||= '0';\n sec ||= '0';\n\n let isNegative: 0 | 1 = SYMBOL_PATTERNS.NEGATIVE_SIGN.test(deg) ? 1 : 0;\n const bearingOptions = BEARINGS[format][i] as [string, string];\n\n if (!bear || isNegative) {\n bear = bearingOptions[isNegative];\n deg = Math.abs(Number.parseFloat(deg)).toString();\n isNegative = 0;\n }\n\n const errors = [\n ...[checks.deg(deg, LIMITS[format][i] ?? 0)],\n ...[checks.min(min)],\n ...[checks.sec(sec)],\n ].filter(Boolean);\n\n return (\n errors.length ? [[], errors] : [[deg, min, sec, bear], []]\n ) as ParseResults;\n };\n}\n\nfunction identifyPieces(half: string[]) {\n if (half.length < 1 || half.length > 4) {\n return;\n }\n\n const asString = half.join(' ');\n const places = { bear: '', deg: '', min: '', sec: '' };\n const keys = ['deg', 'min', 'sec'] as (keyof typeof places)[];\n const test = (r: RegExp, b: boolean, v: string) =>\n r.test(v) || (r.test(asString) && b);\n\n return half.reduce((acc, token, i, { length }) => {\n if (test(SYMBOL_PATTERNS.NSEW, i === length - 1, token)) {\n acc.bear ||= token;\n } else if (test(SYMBOL_PATTERNS.DEGREES, i === 0, token)) {\n acc.deg ||= token;\n } else if (test(SYMBOL_PATTERNS.MINUTES, i === 1, token)) {\n acc.min ||= token;\n } else if (test(SYMBOL_PATTERNS.SECONDS, i === 2, token)) {\n acc.sec ||= token;\n } else {\n const key = keys.find((k) => !acc[k]);\n\n acc[key as keyof typeof acc] = token;\n }\n\n return acc;\n }, places);\n}\n\n/** Parse a Degrees Minutes Seconds coordinate. */\nexport const parseDegreesMinutesSeconds = createParser<DegreesMinutesSeconds>({\n formats,\n identifyErrors,\n identifyPieces,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgCA,MAAM,SAAS;CACb,MAAM,KAAa,UAAkB;AACnC,MAAI,OAAO,WAAW,IAAI,GAAG,MAC3B,QAAO,kBAAkB,IAAI,uBAAuB,MAAM;AAG5D,MAAI,KAAK,KAAK,IAAI,CAChB,QAAO,kBAAkB,IAAI;;CAGjC,MAAM,QAAgB,QAAQ,WAAW,KAAK,GAAG;CACjD,MAAM,QAAgB,QAAQ,WAAW,KAAK,aAAa;CAC5D;AAED,MAAM,UAAU;CACd,QAAQA,aACN,kBACA,wBAAwB,QAAQ,QAAQ,uBACzC;CACD,QAAQA,aACN,kBACA,wBAAwB,QAAQ,QAAQ,uBACzC;CACF;AAED,SAAS,eAAe,QAAgB;AACtC,SAAQ,KAAwC,MAAc;AAC5D,MAAI,CAAC,IACH,QAAO,CAAC,EAAE,EAAE,CAAC,4BAA4B,CAAC;EAG5C,IAAI,EAAE,MAAM,KAAK,KAAK,QAAQ;AAE9B,UAAQ;AAER,UAAQ;AACR,UAAQ;EAER,IAAIC,aAAoB,gBAAgB,cAAc,KAAK,IAAI,GAAG,IAAI;EACtE,MAAM,iBAAiB,SAAS,QAAQ;AAExC,MAAI,CAAC,QAAQ,YAAY;AACvB,UAAO,eAAe;AACtB,SAAM,KAAK,IAAI,OAAO,WAAW,IAAI,CAAC,CAAC,UAAU;AACjD,gBAAa;;EAGf,MAAM,SAAS;GACb,GAAG,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,MAAM,EAAE,CAAC;GAC5C,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;GACpB,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;GACrB,CAAC,OAAO,QAAQ;AAEjB,SACE,OAAO,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,CAAC;GAAC;GAAK;GAAK;GAAK;GAAK,EAAE,EAAE,CAAC;;;AAKhE,SAAS,eAAe,MAAgB;AACtC,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,EACnC;CAGF,MAAM,WAAW,KAAK,KAAK,IAAI;CAC/B,MAAM,SAAS;EAAE,MAAM;EAAI,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI;CACtD,MAAM,OAAO;EAAC;EAAO;EAAO;EAAM;CAClC,MAAM,QAAQ,GAAW,GAAY,MACnC,EAAE,KAAK,EAAE,IAAK,EAAE,KAAK,SAAS,IAAI;AAEpC,QAAO,KAAK,QAAQ,KAAK,OAAO,GAAG,EAAE,aAAa;AAChD,MAAI,KAAK,gBAAgB,MAAM,MAAM,SAAS,GAAG,MAAM,CACrD,KAAI,SAAS;WACJ,KAAK,gBAAgB,SAAS,MAAM,GAAG,MAAM,CACtD,KAAI,QAAQ;WACH,KAAK,gBAAgB,SAAS,MAAM,GAAG,MAAM,CACtD,KAAI,QAAQ;WACH,KAAK,gBAAgB,SAAS,MAAM,GAAG,MAAM,CACtD,KAAI,QAAQ;OACP;GACL,MAAM,MAAM,KAAK,MAAM,MAAM,CAAC,IAAI,GAAG;AAErC,OAAI,OAA2B;;AAGjC,SAAO;IACN,OAAO;;;AAIZ,MAAa,6BAA6B,aAAoC;CAC5E;CACA;CACA;CACD,CAAC"}
1
+ {"version":3,"file":"parser.js","names":["Patterning.fromTemplate","isNegative: 0 | 1"],"sources":["../../../../src/coordinates/latlon/degrees-minutes-seconds/parser.ts"],"sourcesContent":["/*\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 * as Patterning from '@/patterning';\nimport {\n BEARINGS,\n type Format,\n LIMITS,\n PARTIAL_PATTERNS,\n SYMBOL_PATTERNS,\n SYMBOLS,\n} from '../internal';\nimport { inRange } from '../internal/in-range';\nimport { createParser } from '../internal/parse-format';\nimport type { ParseResults } from '../internal/parse';\n\ntype DegreesMinutesSeconds = {\n bear: string;\n deg: string;\n min: string;\n sec: string;\n};\n\nconst checks = {\n deg: (deg: string, limit: number) => {\n const num = Number.parseFloat(deg);\n if (Number.isNaN(num)) {\n return `Degrees value (${deg}) is not a valid number.`;\n }\n if (num > limit) {\n return `Degrees value (${deg}) exceeds max value (${limit}).`;\n }\n\n if (/\\./.test(deg)) {\n return `Degrees value (${deg}) must not include decimal value.`;\n }\n },\n min: (min: string) => inRange('Minutes', min, 59),\n sec: (sec: string) => inRange('Seconds', sec, 59.999999999),\n};\n\nconst formats = {\n LATLON: Patterning.fromTemplate(\n PARTIAL_PATTERNS,\n `degLat min secDec NS ${SYMBOLS.DIVIDER} degLon min secDec EW`,\n ),\n LONLAT: Patterning.fromTemplate(\n PARTIAL_PATTERNS,\n `degLon min secDec EW ${SYMBOLS.DIVIDER} degLat min secDec NS`,\n ),\n};\n\n/**\n * Creates an error identification function for degrees minutes seconds coordinates.\n *\n * Validates that degree values are integers, minutes are in range 0-59,\n * seconds are in range 0-59.999..., and all components are properly formatted.\n *\n * @param format - The coordinate format (LATLON or LONLAT).\n * @returns Function that validates coordinate components and returns parse results.\n *\n * @example\n * ```typescript\n * const validator = identifyErrors('LATLON');\n * const result = validator({ deg: '91', min: '0', sec: '0', bear: 'N' }, 0);\n * // [[], ['Degrees value (91) exceeds max value (90).']]\n * ```\n */\nfunction identifyErrors(format: Format) {\n return (arg: DegreesMinutesSeconds | undefined, i: number) => {\n if (!arg) {\n return [[], ['Invalid coordinate value.']] as ParseResults;\n }\n\n let { bear, deg, min, sec } = arg;\n\n deg ??= '0';\n // NOTE: need `||=` not `??=` because empty-string is not nullish\n min ||= '0';\n sec ||= '0';\n\n let isNegative: 0 | 1 = SYMBOL_PATTERNS.NEGATIVE_SIGN.test(deg) ? 1 : 0;\n const bearingOptions = BEARINGS[format][i] as [string, string];\n\n if (!bear || isNegative) {\n bear = bearingOptions[isNegative];\n deg = Math.abs(Number.parseFloat(deg)).toString();\n isNegative = 0;\n }\n\n const errors = [\n ...[checks.deg(deg, LIMITS[format][i] ?? 0)],\n ...[checks.min(min)],\n ...[checks.sec(sec)],\n ].filter(Boolean);\n\n return (\n errors.length ? [[], errors] : [[deg, min, sec, bear], []]\n ) as ParseResults;\n };\n}\n\n/**\n * Identifies and organizes coordinate components from parsed tokens.\n *\n * Separates bearing indicators (N/S/E/W), degree values, minute values, and second values from tokens.\n * Uses symbol patterns to identify component types and positional logic as fallback.\n *\n * @param half - Array of tokens representing one coordinate component.\n * @returns Object with `bear`, `deg`, `min`, and `sec` properties, or undefined if invalid.\n *\n * @example\n * ```typescript\n * identifyPieces(['45', '30', '15.23', 'N']);\n * // { bear: 'N', deg: '45', min: '30', sec: '15.23' }\n * ```\n *\n * @example\n * ```typescript\n * identifyPieces(['122°', '25'', '9.84″', 'W']);\n * // { bear: 'W', deg: '122', min: '25', sec: '9.84' }\n * ```\n */\nfunction identifyPieces(half: string[]) {\n if (half.length < 1 || half.length > 4) {\n return;\n }\n\n const asString = half.join(' ');\n const places = { bear: '', deg: '', min: '', sec: '' };\n const keys = ['deg', 'min', 'sec'] as (keyof typeof places)[];\n const test = (r: RegExp, b: boolean, v: string) =>\n r.test(v) || (r.test(asString) && b);\n\n return half.reduce<typeof places | undefined>((acc, token, i, { length }) => {\n if (!acc) {\n return undefined;\n }\n if (test(SYMBOL_PATTERNS.NSEW, i === length - 1, token)) {\n acc.bear ||= token;\n } else if (test(SYMBOL_PATTERNS.DEGREES, i === 0, token)) {\n acc.deg ||= token;\n } else if (test(SYMBOL_PATTERNS.MINUTES, i === 1, token)) {\n acc.min ||= token;\n } else if (test(SYMBOL_PATTERNS.SECONDS, i === 2, token)) {\n acc.sec ||= token;\n } else {\n const key = keys.find((k) => !acc[k]);\n if (!key) {\n return undefined;\n }\n acc[key] = token;\n }\n\n return acc;\n }, places);\n}\n\n/**\n * Parses a Degrees Minutes Seconds coordinate string.\n *\n * Accepts coordinates in degrees minutes seconds format with bearing indicators.\n * Validates that degrees are integers, minutes are in range 0-59,\n * seconds are in range 0-59.999..., and all components are properly formatted.\n *\n * @param input - Raw coordinate string to parse.\n * @param format - Expected format (LATLON or LONLAT).\n * @returns Parsed coordinate values or errors.\n *\n * @example\n * ```typescript\n * parseDegreesMinutesSeconds('37° 46' 29.64″ N / 122° 25' 9.84″ W', 'LATLON');\n * // [[37.7749, -122.4194], []]\n * ```\n *\n * @example\n * ```typescript\n * parseDegreesMinutesSeconds('45 30 15.23 N, 122 25 9.84 W');\n * // [[45.504231, -122.419400], []]\n * ```\n */\nexport const parseDegreesMinutesSeconds = createParser<DegreesMinutesSeconds>({\n formats,\n identifyErrors,\n identifyPieces,\n});\n\nexport { identifyErrors as _identifyErrors, identifyPieces as _identifyPieces };\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgCA,MAAM,SAAS;CACb,MAAM,KAAa,UAAkB;EACnC,MAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,OAAO,MAAM,IAAI,CACnB,QAAO,kBAAkB,IAAI;AAE/B,MAAI,MAAM,MACR,QAAO,kBAAkB,IAAI,uBAAuB,MAAM;AAG5D,MAAI,KAAK,KAAK,IAAI,CAChB,QAAO,kBAAkB,IAAI;;CAGjC,MAAM,QAAgB,QAAQ,WAAW,KAAK,GAAG;CACjD,MAAM,QAAgB,QAAQ,WAAW,KAAK,aAAa;CAC5D;AAED,MAAM,UAAU;CACd,QAAQA,aACN,kBACA,wBAAwB,QAAQ,QAAQ,uBACzC;CACD,QAAQA,aACN,kBACA,wBAAwB,QAAQ,QAAQ,uBACzC;CACF;;;;;;;;;;;;;;;;;AAkBD,SAAS,eAAe,QAAgB;AACtC,SAAQ,KAAwC,MAAc;AAC5D,MAAI,CAAC,IACH,QAAO,CAAC,EAAE,EAAE,CAAC,4BAA4B,CAAC;EAG5C,IAAI,EAAE,MAAM,KAAK,KAAK,QAAQ;AAE9B,UAAQ;AAER,UAAQ;AACR,UAAQ;EAER,IAAIC,aAAoB,gBAAgB,cAAc,KAAK,IAAI,GAAG,IAAI;EACtE,MAAM,iBAAiB,SAAS,QAAQ;AAExC,MAAI,CAAC,QAAQ,YAAY;AACvB,UAAO,eAAe;AACtB,SAAM,KAAK,IAAI,OAAO,WAAW,IAAI,CAAC,CAAC,UAAU;AACjD,gBAAa;;EAGf,MAAM,SAAS;GACb,GAAG,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,MAAM,EAAE,CAAC;GAC5C,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;GACpB,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;GACrB,CAAC,OAAO,QAAQ;AAEjB,SACE,OAAO,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,CAAC;GAAC;GAAK;GAAK;GAAK;GAAK,EAAE,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;AA0BhE,SAAS,eAAe,MAAgB;AACtC,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,EACnC;CAGF,MAAM,WAAW,KAAK,KAAK,IAAI;CAC/B,MAAM,SAAS;EAAE,MAAM;EAAI,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI;CACtD,MAAM,OAAO;EAAC;EAAO;EAAO;EAAM;CAClC,MAAM,QAAQ,GAAW,GAAY,MACnC,EAAE,KAAK,EAAE,IAAK,EAAE,KAAK,SAAS,IAAI;AAEpC,QAAO,KAAK,QAAmC,KAAK,OAAO,GAAG,EAAE,aAAa;AAC3E,MAAI,CAAC,IACH;AAEF,MAAI,KAAK,gBAAgB,MAAM,MAAM,SAAS,GAAG,MAAM,CACrD,KAAI,SAAS;WACJ,KAAK,gBAAgB,SAAS,MAAM,GAAG,MAAM,CACtD,KAAI,QAAQ;WACH,KAAK,gBAAgB,SAAS,MAAM,GAAG,MAAM,CACtD,KAAI,QAAQ;WACH,KAAK,gBAAgB,SAAS,MAAM,GAAG,MAAM,CACtD,KAAI,QAAQ;OACP;GACL,MAAM,MAAM,KAAK,MAAM,MAAM,CAAC,IAAI,GAAG;AACrC,OAAI,CAAC,IACH;AAEF,OAAI,OAAO;;AAGb,SAAO;IACN,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;AA0BZ,MAAa,6BAA6B,aAAoC;CAC5E;CACA;CACA;CACD,CAAC"}
@@ -13,6 +13,38 @@
13
13
  import { CoordinateSystem } from "../internal/coordinate-system.js";
14
14
 
15
15
  //#region src/coordinates/latlon/degrees-minutes-seconds/system.d.ts
16
+
17
+ /**
18
+ * Degrees Minutes Seconds coordinate system implementation.
19
+ *
20
+ * Provides parsing, conversion, and formatting for coordinates in degrees minutes seconds notation.
21
+ * Coordinates are expressed as integer degrees, integer minutes, and decimal seconds (e.g., 37° 46' 29.64″ N).
22
+ *
23
+ * @property name - Human-readable name of the coordinate system.
24
+ * @property parse - Parses degrees minutes seconds coordinate strings.
25
+ * @property toFloat - Converts parsed coordinate components to floating point numbers.
26
+ * @property toFormat - Formats numeric coordinates back to degrees minutes seconds string.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Parse a coordinate string
31
+ * const [coords, errors] = systemDegreesMinutesSeconds.parse('37° 46' 29.64″ N / 122° 25' 9.84″ W', 'LATLON');
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Convert to float
37
+ * const lat = systemDegreesMinutesSeconds.toFloat(['37', '46', '29.64', 'N']);
38
+ * // 37.7749
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Format to string
44
+ * const formatted = systemDegreesMinutesSeconds.toFormat('LATLON', [37.7749, -122.4194]);
45
+ * // '37 46 29.64 N / 122 25 9.84 W'
46
+ * ```
47
+ */
16
48
  declare const systemDegreesMinutesSeconds: CoordinateSystem;
17
49
  //#endregion
18
50
  export { systemDegreesMinutesSeconds };
@@ -15,6 +15,37 @@ import { BEARINGS, SYMBOLS, SYMBOL_PATTERNS } from "../internal/index.js";
15
15
  import { parseDegreesMinutesSeconds } from "./parser.js";
16
16
 
17
17
  //#region src/coordinates/latlon/degrees-minutes-seconds/system.ts
18
+ /**
19
+ * Degrees Minutes Seconds coordinate system implementation.
20
+ *
21
+ * Provides parsing, conversion, and formatting for coordinates in degrees minutes seconds notation.
22
+ * Coordinates are expressed as integer degrees, integer minutes, and decimal seconds (e.g., 37° 46' 29.64″ N).
23
+ *
24
+ * @property name - Human-readable name of the coordinate system.
25
+ * @property parse - Parses degrees minutes seconds coordinate strings.
26
+ * @property toFloat - Converts parsed coordinate components to floating point numbers.
27
+ * @property toFormat - Formats numeric coordinates back to degrees minutes seconds string.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Parse a coordinate string
32
+ * const [coords, errors] = systemDegreesMinutesSeconds.parse('37° 46' 29.64″ N / 122° 25' 9.84″ W', 'LATLON');
33
+ * ```
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Convert to float
38
+ * const lat = systemDegreesMinutesSeconds.toFloat(['37', '46', '29.64', 'N']);
39
+ * // 37.7749
40
+ * ```
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * // Format to string
45
+ * const formatted = systemDegreesMinutesSeconds.toFormat('LATLON', [37.7749, -122.4194]);
46
+ * // '37 46 29.64 N / 122 25 9.84 W'
47
+ * ```
48
+ */
18
49
  const systemDegreesMinutesSeconds = {
19
50
  name: "Degrees Minutes Seconds",
20
51
  parse: parseDegreesMinutesSeconds,
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","names":["systemDegreesMinutesSeconds: CoordinateSystem"],"sources":["../../../../src/coordinates/latlon/degrees-minutes-seconds/system.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 {\n BEARINGS,\n type Compass,\n type Format,\n SYMBOL_PATTERNS,\n SYMBOLS,\n} from '../internal';\nimport { parseDegreesMinutesSeconds } from './parser';\nimport type { CoordinateSystem } from '../internal/coordinate-system';\n\nexport const systemDegreesMinutesSeconds: CoordinateSystem = {\n name: 'Degrees Minutes Seconds',\n\n parse: parseDegreesMinutesSeconds,\n\n toFloat(arg) {\n const [degrees, minutes, seconds, bear] = arg as [\n string,\n string,\n string,\n Compass,\n ];\n\n return Number.parseFloat(\n (\n (Number.parseFloat(degrees) +\n Number.parseFloat(minutes) / 60 +\n Number.parseFloat(seconds) / 3600) *\n (SYMBOL_PATTERNS.NEGATIVE_BEARINGS.test(bear) ? -1 : 1)\n ).toFixed(9),\n );\n },\n\n toFormat(format: Format, [left, right]: [number, number]) {\n return [left, right]\n .map((num, index) => {\n const abs = Math.abs(num);\n const deg = Math.floor(abs);\n const rem = (abs - deg) * 60;\n const min = Math.floor(rem);\n const sec = Number.parseFloat(((rem - min) * 60).toFixed(10));\n\n return `${deg} ${min} ${sec} ${BEARINGS[format][index as 0 | 1][+(num < 0)]}`;\n })\n .join(` ${SYMBOLS.DIVIDER} `);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAuBA,MAAaA,8BAAgD;CAC3D,MAAM;CAEN,OAAO;CAEP,QAAQ,KAAK;EACX,MAAM,CAAC,SAAS,SAAS,SAAS,QAAQ;AAO1C,SAAO,OAAO,aAET,OAAO,WAAW,QAAQ,GACzB,OAAO,WAAW,QAAQ,GAAG,KAC7B,OAAO,WAAW,QAAQ,GAAG,SAC9B,gBAAgB,kBAAkB,KAAK,KAAK,GAAG,KAAK,IACrD,QAAQ,EAAE,CACb;;CAGH,SAAS,QAAgB,CAAC,MAAM,QAA0B;AACxD,SAAO,CAAC,MAAM,MAAM,CACjB,KAAK,KAAK,UAAU;GACnB,MAAM,MAAM,KAAK,IAAI,IAAI;GACzB,MAAM,MAAM,KAAK,MAAM,IAAI;GAC3B,MAAM,OAAO,MAAM,OAAO;GAC1B,MAAM,MAAM,KAAK,MAAM,IAAI;AAG3B,UAAO,GAAG,IAAI,GAAG,IAAI,GAFT,OAAO,aAAa,MAAM,OAAO,IAAI,QAAQ,GAAG,CAAC,CAEjC,GAAG,SAAS,QAAQ,OAAgB,EAAE,MAAM;IACxE,CACD,KAAK,IAAI,QAAQ,QAAQ,GAAG;;CAElC"}
1
+ {"version":3,"file":"system.js","names":["systemDegreesMinutesSeconds: CoordinateSystem"],"sources":["../../../../src/coordinates/latlon/degrees-minutes-seconds/system.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 {\n BEARINGS,\n type Compass,\n type Format,\n SYMBOL_PATTERNS,\n SYMBOLS,\n} from '../internal';\nimport { parseDegreesMinutesSeconds } from './parser';\nimport type { CoordinateSystem } from '../internal/coordinate-system';\n\n/**\n * Degrees Minutes Seconds coordinate system implementation.\n *\n * Provides parsing, conversion, and formatting for coordinates in degrees minutes seconds notation.\n * Coordinates are expressed as integer degrees, integer minutes, and decimal seconds (e.g., 37° 46' 29.64″ N).\n *\n * @property name - Human-readable name of the coordinate system.\n * @property parse - Parses degrees minutes seconds coordinate strings.\n * @property toFloat - Converts parsed coordinate components to floating point numbers.\n * @property toFormat - Formats numeric coordinates back to degrees minutes seconds string.\n *\n * @example\n * ```typescript\n * // Parse a coordinate string\n * const [coords, errors] = systemDegreesMinutesSeconds.parse('37° 46' 29.64″ N / 122° 25' 9.84″ W', 'LATLON');\n * ```\n *\n * @example\n * ```typescript\n * // Convert to float\n * const lat = systemDegreesMinutesSeconds.toFloat(['37', '46', '29.64', 'N']);\n * // 37.7749\n * ```\n *\n * @example\n * ```typescript\n * // Format to string\n * const formatted = systemDegreesMinutesSeconds.toFormat('LATLON', [37.7749, -122.4194]);\n * // '37 46 29.64 N / 122 25 9.84 W'\n * ```\n */\nexport const systemDegreesMinutesSeconds: CoordinateSystem = {\n name: 'Degrees Minutes Seconds',\n\n parse: parseDegreesMinutesSeconds,\n\n toFloat(arg) {\n const [degrees, minutes, seconds, bear] = arg as [\n string,\n string,\n string,\n Compass,\n ];\n\n return Number.parseFloat(\n (\n (Number.parseFloat(degrees) +\n Number.parseFloat(minutes) / 60 +\n Number.parseFloat(seconds) / 3600) *\n (SYMBOL_PATTERNS.NEGATIVE_BEARINGS.test(bear) ? -1 : 1)\n ).toFixed(9),\n );\n },\n\n toFormat(format: Format, [left, right]: [number, number]) {\n return [left, right]\n .map((num, index) => {\n const abs = Math.abs(num);\n const deg = Math.floor(abs);\n const rem = (abs - deg) * 60;\n const min = Math.floor(rem);\n const sec = Number.parseFloat(((rem - min) * 60).toFixed(10));\n\n return `${deg} ${min} ${sec} ${BEARINGS[format][index as 0 | 1][+(num < 0)]}`;\n })\n .join(` ${SYMBOLS.DIVIDER} `);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,MAAaA,8BAAgD;CAC3D,MAAM;CAEN,OAAO;CAEP,QAAQ,KAAK;EACX,MAAM,CAAC,SAAS,SAAS,SAAS,QAAQ;AAO1C,SAAO,OAAO,aAET,OAAO,WAAW,QAAQ,GACzB,OAAO,WAAW,QAAQ,GAAG,KAC7B,OAAO,WAAW,QAAQ,GAAG,SAC9B,gBAAgB,kBAAkB,KAAK,KAAK,GAAG,KAAK,IACrD,QAAQ,EAAE,CACb;;CAGH,SAAS,QAAgB,CAAC,MAAM,QAA0B;AACxD,SAAO,CAAC,MAAM,MAAM,CACjB,KAAK,KAAK,UAAU;GACnB,MAAM,MAAM,KAAK,IAAI,IAAI;GACzB,MAAM,MAAM,KAAK,MAAM,IAAI;GAC3B,MAAM,OAAO,MAAM,OAAO;GAC1B,MAAM,MAAM,KAAK,MAAM,IAAI;AAG3B,UAAO,GAAG,IAAI,GAAG,IAAI,GAFT,OAAO,aAAa,MAAM,OAAO,IAAI,QAAQ,GAAG,CAAC,CAEjC,GAAG,SAAS,QAAQ,OAAgB,EAAE,MAAM;IACxE,CACD,KAAK,IAAI,QAAQ,QAAQ,GAAG;;CAElC"}
@@ -14,6 +14,28 @@ import { Compass, Format } from "./index.js";
14
14
  import { ParseResults } from "./parse.js";
15
15
 
16
16
  //#region src/coordinates/latlon/internal/coordinate-system.d.ts
17
+
18
+ /**
19
+ * Coordinate system interface for parsing, converting, and formatting geographic coordinates.
20
+ *
21
+ * Defines the contract for coordinate notation systems (Decimal Degrees, Degrees Decimal Minutes,
22
+ * Degrees Minutes Seconds) to parse, convert to float, and format coordinate values.
23
+ *
24
+ * @property name - Human-readable name of the coordinate system.
25
+ * @property parse - Parses a coordinate string into validated tokens or error messages.
26
+ * @property toFloat - Converts parsed coordinate components (degrees, minutes, seconds, bearing) to a float.
27
+ * @property toFormat - Formats numeric coordinate pair back to string representation.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const system: CoordinateSystem = {
32
+ * name: 'Decimal Degrees',
33
+ * parse: (format, input) => parseDecimalDegrees(input, format),
34
+ * toFloat: ([deg, bear]) => Number.parseFloat(deg) * (bear === 'S' || bear === 'W' ? -1 : 1),
35
+ * toFormat: (format, [lat, lon]) => `${Math.abs(lat)}° ${lat >= 0 ? 'N' : 'S'} / ${Math.abs(lon)}° ${lon >= 0 ? 'E' : 'W'}`
36
+ * };
37
+ * ```
38
+ */
17
39
  type CoordinateSystem = {
18
40
  name: string;
19
41
  parse: (format: Format, input: string) => ParseResults;
@@ -19,7 +19,23 @@ type CoordinateCache = Record<Format, string>;
19
19
  * conversions are only ever done once and only "one-direction-ally". The
20
20
  * "one-direction" concept is to avoid the problem of encountering rounding
21
21
  * errors when converting between multiple formats.
22
- * */
22
+ *
23
+ * @param format - The coordinate format (LATLON or LONLAT) for the provided value.
24
+ * @param value - The formatted coordinate string to cache.
25
+ * @returns Cache object with both LATLON and LONLAT format strings.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * createCache('LATLON', '37.7749 N / 122.4194 W');
30
+ * // { LATLON: '37.7749 N / 122.4194 W', LONLAT: '122.4194 W / 37.7749 N' }
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * createCache('LONLAT', '122° W / 37° N');
36
+ * // { LONLAT: '122° W / 37° N', LATLON: '37° N / 122° W' }
37
+ * ```
38
+ */
23
39
  declare function createCache(format: Format, value: string): CoordinateCache;
24
40
  //#endregion
25
41
  export { CoordinateCache, createCache };
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
 
14
- import { FORMATS, SYMBOLS } from "./index.js";
14
+ import { SYMBOLS } from "./index.js";
15
15
 
16
16
  //#region src/coordinates/latlon/internal/create-cache.ts
17
17
  const DIVIDER = ` ${SYMBOLS.DIVIDER} `;
@@ -20,9 +20,25 @@ const DIVIDER = ` ${SYMBOLS.DIVIDER} `;
20
20
  * conversions are only ever done once and only "one-direction-ally". The
21
21
  * "one-direction" concept is to avoid the problem of encountering rounding
22
22
  * errors when converting between multiple formats.
23
- * */
23
+ *
24
+ * @param format - The coordinate format (LATLON or LONLAT) for the provided value.
25
+ * @param value - The formatted coordinate string to cache.
26
+ * @returns Cache object with both LATLON and LONLAT format strings.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * createCache('LATLON', '37.7749 N / 122.4194 W');
31
+ * // { LATLON: '37.7749 N / 122.4194 W', LONLAT: '122.4194 W / 37.7749 N' }
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * createCache('LONLAT', '122° W / 37° N');
37
+ * // { LONLAT: '122° W / 37° N', LATLON: '37° N / 122° W' }
38
+ * ```
39
+ */
24
40
  function createCache(format, value) {
25
- const [alternate] = FORMATS.filter((o) => o !== format);
41
+ const alternate = format === "LATLON" ? "LONLAT" : "LATLON";
26
42
  return {
27
43
  [format]: value,
28
44
  [alternate]: value.includes(SYMBOLS.DIVIDER) ? value.split(DIVIDER).reverse().join(DIVIDER).trim() : value
@@ -1 +1 @@
1
- {"version":3,"file":"create-cache.js","names":[],"sources":["../../../../src/coordinates/latlon/internal/create-cache.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 { FORMATS, type Format, SYMBOLS } from '.';\n\nexport type CoordinateCache = Record<Format, string>;\n\nconst DIVIDER = ` ${SYMBOLS.DIVIDER} `;\n\n/**\n * Create, and initialize, a cache object for coordinate conversions so that\n * conversions are only ever done once and only \"one-direction-ally\". The\n * \"one-direction\" concept is to avoid the problem of encountering rounding\n * errors when converting between multiple formats.\n * */\nexport function createCache(format: Format, value: string) {\n const [alternate] = FORMATS.filter((o) => o !== format) as [Format];\n\n return {\n [format]: value,\n [alternate]: value.includes(SYMBOLS.DIVIDER)\n ? value.split(DIVIDER).reverse().join(DIVIDER).trim()\n : value,\n } as CoordinateCache;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,UAAU,IAAI,QAAQ,QAAQ;;;;;;;AAQpC,SAAgB,YAAY,QAAgB,OAAe;CACzD,MAAM,CAAC,aAAa,QAAQ,QAAQ,MAAM,MAAM,OAAO;AAEvD,QAAO;GACJ,SAAS;GACT,YAAY,MAAM,SAAS,QAAQ,QAAQ,GACxC,MAAM,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,MAAM,GACnD;EACL"}
1
+ {"version":3,"file":"create-cache.js","names":["alternate: Format"],"sources":["../../../../src/coordinates/latlon/internal/create-cache.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 '.';\n\nexport type CoordinateCache = Record<Format, string>;\n\nconst DIVIDER = ` ${SYMBOLS.DIVIDER} `;\n\n/**\n * Create, and initialize, a cache object for coordinate conversions so that\n * conversions are only ever done once and only \"one-direction-ally\". The\n * \"one-direction\" concept is to avoid the problem of encountering rounding\n * errors when converting between multiple formats.\n *\n * @param format - The coordinate format (LATLON or LONLAT) for the provided value.\n * @param value - The formatted coordinate string to cache.\n * @returns Cache object with both LATLON and LONLAT format strings.\n *\n * @example\n * ```typescript\n * createCache('LATLON', '37.7749 N / 122.4194 W');\n * // { LATLON: '37.7749 N / 122.4194 W', LONLAT: '122.4194 W / 37.7749 N' }\n * ```\n *\n * @example\n * ```typescript\n * createCache('LONLAT', '122° W / 37° N');\n * // { LONLAT: '122° W / 37° N', LATLON: '37° N / 122° W' }\n * ```\n */\nexport function createCache(format: Format, value: string) {\n const alternate: Format = format === 'LATLON' ? 'LONLAT' : 'LATLON';\n\n return {\n [format]: value,\n [alternate]: value.includes(SYMBOLS.DIVIDER)\n ? value.split(DIVIDER).reverse().join(DIVIDER).trim()\n : value,\n } as CoordinateCache;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,UAAU,IAAI,QAAQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;AAwBpC,SAAgB,YAAY,QAAgB,OAAe;CACzD,MAAMA,YAAoB,WAAW,WAAW,WAAW;AAE3D,QAAO;GACJ,SAAS;GACT,YAAY,MAAM,SAAS,QAAQ,QAAQ,GACxC,MAAM,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,MAAM,GACnD;EACL"}
@@ -2,6 +2,21 @@
2
2
  /**
3
3
  * A collection of input strings each with exactly one error in a unique
4
4
  * position for each format (LATLON and LONLAT) in each system (DD, DDM, DMS).
5
+ *
6
+ * Used for comprehensive error validation testing. Each entry contains coordinate
7
+ * strings with systematic errors across different notation systems.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * EXHAUSTIVE_ERRORS.DD.LATLON;
12
+ * // Array of decimal degrees strings with errors like '91 N / 179 E'
13
+ * ```
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * EXHAUSTIVE_ERRORS.DMS.LONLAT;
18
+ * // Array of degrees-minutes-seconds strings with errors
19
+ * ```
5
20
  */
6
21
  declare const EXHAUSTIVE_ERRORS: {
7
22
  [k: string]: any;