@zukall/zap 0.0.0-stage → 0.2.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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/PROTOCOL-V1.md +117 -0
  3. package/PROTOCOL.md +176 -0
  4. package/README.md +418 -2
  5. package/THIRD-PARTY-NOTICES.md +19 -0
  6. package/dist/cjs/address.d.ts +3 -0
  7. package/dist/cjs/address.js +38 -0
  8. package/dist/cjs/address_bounty.d.ts +26 -0
  9. package/dist/cjs/address_bounty.js +2334 -0
  10. package/dist/cjs/address_province_bounty.d.ts +56 -0
  11. package/dist/cjs/address_province_bounty.js +5563 -0
  12. package/dist/cjs/country.d.ts +6 -0
  13. package/dist/cjs/country.js +27 -0
  14. package/dist/cjs/data.d.ts +3 -0
  15. package/dist/cjs/data.js +33 -0
  16. package/dist/cjs/directions.d.ts +5 -0
  17. package/dist/cjs/directions.js +13 -0
  18. package/dist/cjs/encoding.d.ts +3 -0
  19. package/dist/cjs/encoding.js +20 -0
  20. package/dist/cjs/grid.d.ts +23 -0
  21. package/dist/cjs/grid.js +152 -0
  22. package/dist/cjs/index.d.ts +27 -0
  23. package/dist/cjs/index.js +26 -0
  24. package/dist/cjs/internal.d.ts +3 -0
  25. package/dist/cjs/internal.js +19 -0
  26. package/dist/cjs/legacy-address.d.ts +3 -0
  27. package/dist/cjs/legacy-address.js +44 -0
  28. package/dist/cjs/package.json +1 -0
  29. package/dist/cjs/protocol.d.ts +22 -0
  30. package/dist/cjs/protocol.js +25 -0
  31. package/dist/cjs/types.d.ts +114 -0
  32. package/dist/cjs/types.js +2 -0
  33. package/dist/esm/address.d.ts +3 -0
  34. package/dist/esm/address.js +35 -0
  35. package/dist/esm/address_bounty.d.ts +26 -0
  36. package/dist/esm/address_bounty.js +2331 -0
  37. package/dist/esm/address_province_bounty.d.ts +56 -0
  38. package/dist/esm/address_province_bounty.js +5560 -0
  39. package/dist/esm/country.d.ts +6 -0
  40. package/dist/esm/country.js +22 -0
  41. package/dist/esm/data.d.ts +3 -0
  42. package/dist/esm/data.js +2 -0
  43. package/dist/esm/directions.d.ts +5 -0
  44. package/dist/esm/directions.js +10 -0
  45. package/dist/esm/encoding.d.ts +3 -0
  46. package/dist/esm/encoding.js +17 -0
  47. package/dist/esm/grid.d.ts +23 -0
  48. package/dist/esm/grid.js +148 -0
  49. package/dist/esm/index.d.ts +27 -0
  50. package/dist/esm/index.js +16 -0
  51. package/dist/esm/internal.d.ts +3 -0
  52. package/dist/esm/internal.js +15 -0
  53. package/dist/esm/legacy-address.d.ts +3 -0
  54. package/dist/esm/legacy-address.js +41 -0
  55. package/dist/esm/package.json +1 -0
  56. package/dist/esm/protocol.d.ts +22 -0
  57. package/dist/esm/protocol.js +22 -0
  58. package/dist/esm/types.d.ts +114 -0
  59. package/dist/esm/types.js +1 -0
  60. package/package.json +67 -4
package/README.md CHANGED
@@ -1,3 +1,419 @@
1
- # Temporary Holding Version
1
+ # ZAP — Zukall Addressing Protocol
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **`@zukall/zap`** generates addresses directly from latitude and longitude using
4
+ fixed country/province grids. Protocol **2** encodes **100-meter blocks** and
5
+ separate **whole-meter remainders**. It needs no Google Places API, geocoding
6
+ service, network request, or runtime dependency. Generation works offline.
7
+
8
+ ```text
9
+ 1194 S 382 E #16-20, Kampala, UG ZAP
10
+ 2106 S 3614 E #22-64, Miami, FL US ZAP
11
+ 580 S 770 E #43-46, HT ZAP
12
+ ```
13
+
14
+ These illustrate the display format. Actual numbers depend on the original GPS
15
+ point and selected grid; a city label never changes the origin or verifies
16
+ administrative membership.
17
+
18
+ ## Installation and local verification
19
+
20
+ After publication:
21
+
22
+ ```sh
23
+ npm install @zukall/zap
24
+ ```
25
+
26
+ Before publication, install the verified local package:
27
+
28
+ ```sh
29
+ npm install /absolute/path/to/your-address-protocol/.artifacts/zukall-zap-0.2.0.tgz
30
+ ```
31
+
32
+ Build and verify the source:
33
+
34
+ ```sh
35
+ cd /absolute/path/to/your-address-protocol
36
+ npm ci
37
+ npm run check
38
+ npm run pack:check
39
+ ```
40
+
41
+ Node.js 20 or newer is required for development and Node consumers. Browser
42
+ bundlers can use the same generator; runtime code has no Node-specific APIs.
43
+ ESM, CommonJS and TypeScript declarations are included. `pack:check` installs the
44
+ tarball into a temporary consumer and verifies both module formats and types.
45
+
46
+ ## Quick start: ESM
47
+
48
+ ```js
49
+ import { generateAddress } from "@zukall/zap";
50
+
51
+ const result = generateAddress({
52
+ countryCode: "UG",
53
+ city: "Kampala",
54
+ latitude: 0.3476,
55
+ longitude: 32.5825,
56
+ });
57
+
58
+ console.log(result.address); // 1139 S 339 E #33-19, Kampala, UG ZAP
59
+ console.log(result.protocolVersion); // 2 (string)
60
+ console.log(result.northSouthBlock); // 1139
61
+ console.log(result.eastWestBlock); // 339
62
+ console.log(result.northSouthRemainder); // 33
63
+ console.log(result.eastWestRemainder); // 19
64
+ console.log(result.coordinateSuffix); // #33-19
65
+ ```
66
+
67
+ The complete result is:
68
+
69
+ ```json
70
+ {
71
+ "protocol": "ZAP",
72
+ "protocolVersion": "2",
73
+ "address": "1139 S 339 E #33-19, Kampala, UG ZAP",
74
+ "countryCode": "UG",
75
+ "gridName": "Uganda",
76
+ "countryVersion": "ne-admin0-239eec57ac17-v1",
77
+ "gridVersion": "ne-admin0-239eec57ac17-v1",
78
+ "coordinates": {
79
+ "latitude": 0.3476,
80
+ "longitude": 32.5825
81
+ },
82
+ "center": {
83
+ "latitude": 1.372243,
84
+ "longitude": 32.277466499999946
85
+ },
86
+ "widthMeters": 606730,
87
+ "heightMeters": 633245,
88
+ "northingMeters": -113933.63641380174,
89
+ "eastingMeters": 33919.40824532269,
90
+ "city": "Kampala",
91
+ "northSouthBlock": 1139,
92
+ "eastWestBlock": 339,
93
+ "northSouthDirection": "S",
94
+ "eastWestDirection": "E",
95
+ "northSouthRemainder": 33,
96
+ "eastWestRemainder": 19,
97
+ "coordinateSuffix": "#33-19",
98
+ "blockSizeMeters": 100,
99
+ "detailSizeMeters": 1,
100
+ "encoding": "blocks-100m-detail-1m-floor-absolute-dashed-suffix-2x2-v1",
101
+ "gridId": "ZAP:2:UG:ne-admin0-239eec57ac17-v1:ne-admin0-239eec57ac17-v1:AEQD-SPHERE-v1:6371008.8:1.372243:32.277466499999946:blocks-100m-detail-1m-floor-absolute-dashed-suffix-2x2-v1"
102
+ }
103
+ ```
104
+
105
+ `coordinates` retains the original GPS point. `northingMeters` and `eastingMeters`
106
+ are signed, **unrounded** projected offsets. Remainders are numbers for application
107
+ use; `coordinateSuffix` and `address` always format them with two digits.
108
+ `widthMeters` and `heightMeters` are approximate rectangle dimensions rounded to
109
+ whole meters.
110
+
111
+ You may also pass an optional `street` label. It is returned as separate metadata
112
+ and does not enter the formatted coordinate address or affect the grid. City and
113
+ street labels are trimmed, whitespace is normalized, and blank labels are omitted.
114
+
115
+ ## CommonJS and selected provinces
116
+
117
+ ```js
118
+ const { generateAddress, ZAP_PROTOCOL } = require("@zukall/zap");
119
+
120
+ const result = generateAddress({
121
+ countryCode: "US",
122
+ provinceCode: "FL",
123
+ city: "Miami",
124
+ latitude: 25.7617,
125
+ longitude: -80.1918,
126
+ });
127
+
128
+ console.log(ZAP_PROTOCOL.name); // Zukall Addressing Protocol
129
+ console.log(result.address); // 2181 S 3643 E #89-31, Miami, FL US ZAP
130
+ ```
131
+
132
+ Countries with province/state grids require the caller to choose one. Countries
133
+ with country-wide grids require only the country code and reject province codes.
134
+ Existing corners, origins, snapshot versions and overlapping rectangles are
135
+ unchanged. Rectangle containment does not establish actual administrative
136
+ membership. City and street labels do not determine the selected grid.
137
+
138
+ ## TypeScript and the named namespace
139
+
140
+ ```ts
141
+ import {
142
+ generateAddress,
143
+ zap,
144
+ type AddressInput,
145
+ type AddressResult,
146
+ } from "@zukall/zap";
147
+
148
+ const input: AddressInput = {
149
+ countryCode: "US",
150
+ provinceCode: "AK",
151
+ latitude: 61.2181,
152
+ longitude: -149.9003,
153
+ };
154
+
155
+ const result: AddressResult = generateAddress(input);
156
+ console.log(result.address); // 214 N 4726 E #44-94, AK US ZAP
157
+ console.log(zap.generateAddress(input).address); // Same address
158
+ console.log(zap.protocol.version); // 2
159
+ ```
160
+
161
+ Public types include `AddressInput`, `AddressResult`, `AddressEncoding`,
162
+ `LegacyAddressInput`, `LegacyAddressResult`, `GridInput`, `Coordinates`, `Corners`,
163
+ `Country`, `Province`, `ProvinceCountry`, `CountryOption`, and `ProvinceOption`.
164
+ ESM and CommonJS consumers receive matching declarations.
165
+
166
+ ## Display formatting and the encoding
167
+
168
+ The format is:
169
+
170
+ ```text
171
+ {northSouthBlock} {N|S} {eastWestBlock} {E|W} #{northSouthRemainder}-{eastWestRemainder}, {city}, {provinceCode} {countryCode} ZAP
172
+ ```
173
+
174
+ Missing city/province components are omitted cleanly. The final province,
175
+ country and `ZAP` labels are separated by spaces:
176
+
177
+ ```js
178
+ const withoutCity = generateAddress({
179
+ countryCode: "UG", latitude: 0.3476, longitude: 32.5825,
180
+ });
181
+ console.log(withoutCity.address); // 1139 S 339 E #33-19, UG ZAP
182
+
183
+ const withoutCityInProvince = generateAddress({
184
+ countryCode: "US", provinceCode: "CA", latitude: 34.0522, longitude: -118.2437,
185
+ });
186
+ console.log(withoutCityInProvince.address); // 3568 S 940 E #20-58, CA US ZAP
187
+ ```
188
+
189
+ For each signed projected axis:
190
+
191
+ 1. Choose direction from its sign: negative northing is S, negative easting is W.
192
+ 2. Take `wholeMeters = Math.floor(Math.abs(offset))`.
193
+ 3. Calculate `block = Math.floor(wholeMeters / 100)`.
194
+ 4. Calculate `remainder = wholeMeters % 100`.
195
+ 5. Pad both remainders to two digits and join north/south first: `#03-06`.
196
+
197
+ Northing `-119416.594` and easting `38220.747` produce
198
+ `1194 S 382 E #16-20`. Magnitude `99.999` remains block 0, remainder 99;
199
+ magnitude 100 becomes block 1, remainder 00. Exact zero and negative zero use
200
+ N/E, but `-0.3` meters keeps S/W even though its whole-meter magnitude is zero.
201
+ Blocks may have any number of digits. Neither nearest-meter rounding nor old
202
+ 5-meter snapping is applied.
203
+
204
+ The spherical azimuthal equidistant projection and Earth radius 6,371,008.8 meters
205
+ are unchanged. The grid axes remain fixed. A diagonal or curved street can change
206
+ both blocks; each address is independently derived from its GPS point. Roads
207
+ do not rotate the grid or introduce sequential house numbers. Moving 100
208
+ projected meters away from the origin along one axis increments that block while
209
+ preserving the other axis and both remainders.
210
+
211
+ ## Country and province selectors
212
+
213
+ ```js
214
+ import { getCountries, getCountry, getProvinces } from "@zukall/zap";
215
+
216
+ console.log(getCountries().length); // 239
217
+ console.log(getCountries().find(item => item.code === "US"));
218
+ // { code: "US", name: "United States", requiresProvince: true }
219
+ console.log(getProvinces("US").length); // 51
220
+ console.log(getProvinces("US").find(item => item.code === "FL"));
221
+ // { code: "FL", name: "Florida" }
222
+ console.log(getProvinces("UG")); // []
223
+ console.log(getCountry("UG").name); // Uganda
224
+ ```
225
+
226
+ Options are sorted by name, and each call returns a fresh array. Country/province
227
+ codes are trimmed and uppercased. Keep province codes as strings, preserving
228
+ leading zeros and source-specific codes returned by `getProvinces`.
229
+
230
+ These 22 countries require a configured province:
231
+
232
+ ```text
233
+ DZ CD SD LY TD NE AO ML ZA ET MR RU CA US CN BR AU IN AR KZ SA ID
234
+ ```
235
+
236
+ They contain 530 province grids. The remaining 217 country/territory entries use
237
+ country-wide grids. Select the country/province explicitly; the generator does
238
+ not infer membership from intersecting rectangles.
239
+
240
+ ## Save the full record and keep unit details separate
241
+
242
+ ```js
243
+ import { generateAddress } from "@zukall/zap";
244
+
245
+ const result = generateAddress({
246
+ countryCode: "UG", city: "Kampala", latitude: 0.3476, longitude: 32.5825,
247
+ });
248
+
249
+ const record = {
250
+ ...result, // Address, blocks, original GPS, versions, center, encoding, gridId
251
+ street: "Example Road",
252
+ apartment: "12B",
253
+ floor: "3",
254
+ unit: "Office 4",
255
+ };
256
+ const saved = JSON.parse(JSON.stringify(record));
257
+ console.log(saved.address); // 1139 S 339 E #33-19, Kampala, UG ZAP
258
+ console.log(saved.unit); // Office 4 (separate from #33-19)
259
+ ```
260
+
261
+ Persist the original address text and complete result, especially `coordinates`,
262
+ `protocolVersion`, `countryVersion`, `gridVersion`, and `gridId`. Treat `gridId` as
263
+ opaque. Cell identity uses that ID with the structured blocks, directions and
264
+ remainders; city/street/unit labels are independent display metadata. The package
265
+ does not include a reverse decoder or change your stored records.
266
+
267
+ ## Open directions from saved GPS
268
+
269
+ ```js
270
+ import { getDirectionsUrl } from "@zukall/zap";
271
+
272
+ // Use the stored record, including when it contains a protocol-1 address.
273
+ const url = getDirectionsUrl(saved);
274
+ console.log(url);
275
+ // https://www.google.com/maps/dir/?api=1&destination=0.3476%2C32.5825
276
+
277
+ // In a browser, open this from the user's Directions button:
278
+ window.open(url, "_blank", "noopener,noreferrer");
279
+ ```
280
+
281
+ The optional helper builds a [Google Maps directions URL](https://developers.google.com/maps/documentation/urls/get-started#directions)
282
+ from the original coordinates. It performs no API request and does not need an
283
+ API key. You can also pass `saved.coordinates` to your own map provider. Never
284
+ use the formatted ZAP string, grid center, city name, or coordinate suffix as the
285
+ routing destination.
286
+
287
+ ## Upgrade from protocol 1 without changing issued addresses
288
+
289
+ Package `0.2.0` introduces protocol 2. `generateAddress` no longer accepts
290
+ `gridSizeMeters`; remove that option when intentionally issuing a new protocol-2
291
+ address. Passing it is rejected in TypeScript and at runtime, including when a
292
+ JavaScript caller passes `undefined`.
293
+
294
+ Previously issued records retain their original address, GPS point,
295
+ `protocolVersion: "1"`, grid interval and original `gridId`. Continue displaying
296
+ those saved values. Do not regenerate or overwrite them merely on package upgrade.
297
+
298
+ To explicitly reproduce a version-1 address, use its original GPS and interval:
299
+
300
+ ```ts
301
+ import {
302
+ generateLegacyAddress,
303
+ type LegacyAddressInput,
304
+ type LegacyAddressResult,
305
+ } from "@zukall/zap";
306
+
307
+ const legacyInput: LegacyAddressInput = {
308
+ countryCode: "UG",
309
+ latitude: 0.3476,
310
+ longitude: 32.5825,
311
+ gridSizeMeters: 5,
312
+ };
313
+ const original: LegacyAddressResult = generateLegacyAddress(legacyInput);
314
+ console.log(original.address); // 113935 S 33920 E, UG, ZAP
315
+ console.log(original.protocolVersion); // 1
316
+ console.log(original.gridSizeMeters); // 5
317
+ ```
318
+
319
+ `generateLegacyAddress` retains the original result schema, nearest-interval
320
+ snapping and grid identity. Its default is 5 meters; supported original intervals
321
+ are integers 1–1000. `LEGACY_ZAP_PROTOCOL` exposes the frozen version-1 rules.
322
+ See [PROTOCOL-V1.md](PROTOCOL-V1.md).
323
+
324
+ If a user requests a new protocol-2 address for a saved location, explicitly
325
+ select its original country/province and GPS coordinates, omit the legacy grid
326
+ option, generate a **new record**, and retain the old record as history. Changing
327
+ the text of an old record without changing its protocol metadata is incorrect.
328
+
329
+ ## Handle invalid input
330
+
331
+ ```js
332
+ function tryAddress(input) {
333
+ try {
334
+ return { ok: true, result: generateAddress(input) };
335
+ } catch (error) {
336
+ return { ok: false, error: error instanceof Error ? error.message : String(error) };
337
+ }
338
+ }
339
+
340
+ console.log(tryAddress({ countryCode: "US", latitude: 34, longitude: -118 }));
341
+ // { ok: false, error: "Please select your province or state." }
342
+ ```
343
+
344
+ Validation rejects missing/non-string codes, unknown countries/provinces,
345
+ non-numeric or non-finite coordinates, latitude outside ±90, longitude outside
346
+ ±180, coordinates outside the selected inclusive rectangle, non-string cities,
347
+ non-string street labels, and the obsolete `gridSizeMeters` option. Numeric strings must be converted before
348
+ calling. Empty city labels are omitted. Zero coordinates, date-line rectangles,
349
+ and Antarctica's full 360-degree rectangle remain supported.
350
+
351
+ ## Inspect immutable source data
352
+
353
+ ```js
354
+ import {
355
+ countries, provinceCountries, provinceGrids,
356
+ provinceCounts, provinceDataNotes, additionalSourceAreas,
357
+ } from "@zukall/zap/data";
358
+
359
+ console.log(countries.UG.corners); // Original four country corners
360
+ console.log(provinceCounts.US); // 51
361
+ console.log(provinceCounts.DZ); // 48 in this frozen snapshot
362
+ console.log(provinceDataNotes.DZ); // Historical coverage notes
363
+ console.log(provinceCountries.US.province.CA.name); // California
364
+ console.log(provinceGrids.US.provinces.CA.name); // California
365
+ console.log(Object.keys(additionalSourceAreas).length); // 13
366
+ ```
367
+
368
+ The data is the unchanged Natural Earth snapshot, with historical divisions,
369
+ source-specific keys, and some territorial groupings. It supplies fixed grid
370
+ origins rather than a current postal/administrative directory. The 13 additional
371
+ source areas remain outside address generation. Bounds and versions are frozen at
372
+ runtime; future changes require new snapshots and preservation of older versions.
373
+ See [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md) and [PROTOCOL.md](PROTOCOL.md).
374
+
375
+ ## Public API
376
+
377
+ | Export | Purpose |
378
+ | --- | --- |
379
+ | `generateAddress(input)` | Generate a protocol-2 address with fixed 100-meter blocks and 1-meter detail. |
380
+ | `generateLegacyAddress(input)` | Explicitly reproduce the original protocol-1 address and grid ID. |
381
+ | `getDirectionsUrl(savedRecord)` | Build directions using original saved GPS coordinates, for either version. |
382
+ | `getCountries()` / `getCountry(code)` | Select or inspect immutable country configurations. |
383
+ | `getProvinces(code)` | List configured provinces; country-wide grids return `[]`. |
384
+ | `ZAP_PROTOCOL` / `LEGACY_ZAP_PROTOCOL` | Read current or original protocol constants. |
385
+ | `zap` | Access the same functions through a named namespace. |
386
+ | `@zukall/zap/data` | Inspect frozen snapshots, counts, notes and additional source areas. |
387
+
388
+ ## Tests, packaging, and publication
389
+
390
+ ```sh
391
+ npm run typecheck
392
+ npm test
393
+ npm run pack:check
394
+ ```
395
+
396
+ Tests cover the requested formats, all directions, zero and sub-meter negatives,
397
+ 99/100-meter boundaries, two-digit suffixes, country/province selection, unchanged
398
+ grid identity components, date-line rectangles, diagonal sequences, 100-meter
399
+ axis movements, old-address compatibility, saved GPS directions, and all centers
400
+ and corners of 747 configured grids. Package verification checks ESM/CommonJS
401
+ runtime exports and compiles both TypeScript consumer formats, including the
402
+ removed-option error.
403
+
404
+ `npm pack` also runs the checks through `prepack`. Publishing is a separate action:
405
+
406
+ ```sh
407
+ npm login
408
+ npm run pack:check
409
+ npm publish .artifacts/zukall-zap-0.2.0.tgz --access public
410
+ ```
411
+
412
+ An npm account with permission to publish `@zukall/zap` is required. Building and
413
+ packing do not publish the package. Package version is `0.2.0`; current protocol
414
+ version is `2`, while preserved legacy results remain version `1`.
415
+
416
+ ## License
417
+
418
+ Code: [MIT](LICENSE). Natural Earth data: public domain, documented in
419
+ [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).
@@ -0,0 +1,19 @@
1
+ # Bundled map data
2
+
3
+ The country and province grid rectangles derive from Natural Earth at 1:10 million
4
+ scale, using WGS84 coordinates. Natural Earth places its vector and raster data in
5
+ the public domain: https://www.naturalearthdata.com/about/terms-of-use/.
6
+
7
+ - Countries: https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-admin-0-countries/
8
+ - Provinces: https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-admin-1-states-provinces/
9
+ - Province snapshot SHA256 recorded by the source files:
10
+ `22d0e3ad85eb3e27f17cabf8ba2d50e554fbc27a87796ff891d958185da62fb5`.
11
+ - Retrieval date recorded by the supplied files: 2026-10-10.
12
+
13
+ The source files preserve their original bounds and snapshot versions. Province
14
+ counts and historical coverage notes are available from `@zukall/zap/data`.
15
+ The recorded retrieval date does not establish the current validity of administrative
16
+ divisions. Bounding rectangles can overlap and do not establish administrative membership.
17
+
18
+ The MIT license covers this package's code. Natural Earth's public-domain terms
19
+ apply to the underlying map data.
@@ -0,0 +1,3 @@
1
+ import type { AddressInput, AddressResult } from "./types.js";
2
+ /** Generate a protocol-2 address directly from the original GPS coordinates. */
3
+ export declare function generateAddress(input: AddressInput): AddressResult;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAddress = generateAddress;
4
+ const encoding_js_1 = require("./encoding.js");
5
+ const grid_js_1 = require("./grid.js");
6
+ const protocol_js_1 = require("./protocol.js");
7
+ function displayLabel(value, name) {
8
+ if (value !== undefined && typeof value !== "string") {
9
+ throw new TypeError(`${name} must be a string when supplied.`);
10
+ }
11
+ return value?.trim().replace(/\s+/g, " ") || undefined;
12
+ }
13
+ /** Generate a protocol-2 address directly from the original GPS coordinates. */
14
+ function generateAddress(input) {
15
+ if (input && typeof input === "object" && "gridSizeMeters" in input) {
16
+ throw new TypeError("gridSizeMeters is a protocol-1 option. Remove it for ZAP 2, or use generateLegacyAddress to reproduce an original address.");
17
+ }
18
+ const { identityComponents, ...grid } = (0, grid_js_1.projectAddress)(input);
19
+ const city = displayLabel(input.city, "city");
20
+ const street = displayLabel(input.street, "street");
21
+ const encoded = (0, encoding_js_1.encodeOffsets)(grid.northingMeters, grid.eastingMeters);
22
+ const location = [grid.provinceCode, grid.countryCode, protocol_js_1.ZAP_PROTOCOL.addressSuffix]
23
+ .filter(Boolean).join(" ");
24
+ const position = `${encoded.northSouthBlock} ${encoded.northSouthDirection} ${encoded.eastWestBlock} ${encoded.eastWestDirection} ${encoded.coordinateSuffix}`;
25
+ return {
26
+ protocol: protocol_js_1.ZAP_PROTOCOL.id,
27
+ protocolVersion: protocol_js_1.ZAP_PROTOCOL.version,
28
+ address: [position, ...(city ? [city] : []), location].join(", "),
29
+ ...grid,
30
+ ...(city ? { city } : {}),
31
+ ...(street ? { street } : {}),
32
+ ...encoded,
33
+ blockSizeMeters: protocol_js_1.ZAP_PROTOCOL.blockSizeMeters,
34
+ detailSizeMeters: protocol_js_1.ZAP_PROTOCOL.detailSizeMeters,
35
+ encoding: protocol_js_1.ZAP_PROTOCOL.encoding,
36
+ gridId: [protocol_js_1.ZAP_PROTOCOL.id, protocol_js_1.ZAP_PROTOCOL.version, ...identityComponents, protocol_js_1.ZAP_PROTOCOL.encoding].join(":"),
37
+ };
38
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Direct country/province configuration for generateAddress.
3
+ * Natural Earth 1:10 million, WGS84 degrees, public-domain map data.
4
+ * Sources retrieved 2026-10-10:
5
+ * https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-admin-0-countries/
6
+ * https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-admin-1-states-provinces/
7
+ *
8
+ * 239 country/territory keys; 22 countries use province grids, including US states.
9
+ * The remaining 217 entries use country-wide rectangles. No invented province codes.
10
+ * Source units without ISO/EH codes are exported separately under NE_ keys.
11
+ * Some territories are grouped under a parent: this is not ISO-249 coverage.
12
+ * XK is the source's Kosovo code, not an officially assigned ISO code.
13
+ * Source de facto territorial grouping is retained.
14
+ *
15
+ * Corner order: topLeft, topRight, bottomRight, bottomLeft.
16
+ * Numbers are rounded outward to six decimals to contain source geometry.
17
+ * Six decimals are representation precision, not centimeter boundary accuracy.
18
+ * Rectangles can overlap; administrative membership must be verified separately.
19
+ * For date-line crossings west > east. ZAP supports these rectangles.
20
+ * AQ (Antarctica) spans all longitudes. ZAP handles its explicit 360-degree span.
21
+ * US territories such as PR and GU have separate country/territory entries.
22
+ * These versions and corners are frozen at runtime. Updates require a new snapshot.
23
+ */
24
+ import type { Country } from "./types.js";
25
+ export declare const countries: Readonly<Record<string, Country>>;
26
+ export declare const additionalSourceAreas: Readonly<Record<string, Country>>;