text-to-map 1.1.45 → 1.1.47

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 (97) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +69 -69
  3. package/dist/bin/address-points.d.ts +1 -1
  4. package/dist/bin/address-points.js +16 -16
  5. package/dist/bin/cities.d.ts +1 -1
  6. package/dist/bin/cities.js +10 -10
  7. package/dist/bin/clear-all.d.ts +1 -1
  8. package/dist/bin/clear-all.js +13 -13
  9. package/dist/bin/constants.d.ts +2 -2
  10. package/dist/bin/constants.js +4 -4
  11. package/dist/bin/generate-syntax-diagrams.d.ts +1 -1
  12. package/dist/bin/generate-syntax-diagrams.js +20 -20
  13. package/dist/bin/init-db.d.ts +1 -1
  14. package/dist/bin/init-db.js +8 -8
  15. package/dist/bin/knex.d.ts +1 -1
  16. package/dist/bin/knex.js +10 -10
  17. package/dist/bin/parse-ordinance.d.ts +1 -1
  18. package/dist/bin/parse-ordinance.js +74 -74
  19. package/dist/bin/polygons.d.ts +1 -1
  20. package/dist/bin/polygons.js +27 -27
  21. package/dist/bin/regions.d.ts +1 -1
  22. package/dist/bin/regions.js +10 -10
  23. package/dist/bin/schools.d.ts +1 -1
  24. package/dist/bin/schools.js +10 -10
  25. package/dist/bin/streets.d.ts +1 -1
  26. package/dist/bin/streets.js +19 -19
  27. package/dist/bin/sync-all.d.ts +1 -1
  28. package/dist/bin/sync-all.js +4 -4
  29. package/dist/db/address-points.d.ts +59 -59
  30. package/dist/db/address-points.js +401 -399
  31. package/dist/db/cities.d.ts +7 -7
  32. package/dist/db/cities.js +95 -95
  33. package/dist/db/db.d.ts +37 -37
  34. package/dist/db/db.js +191 -191
  35. package/dist/db/founders.d.ts +14 -14
  36. package/dist/db/founders.js +461 -461
  37. package/dist/db/meta.d.ts +4 -4
  38. package/dist/db/meta.js +26 -26
  39. package/dist/db/migrations/20230704125715_initial.js +304 -304
  40. package/dist/db/migrations/20230731232915_city_positions.js +13 -13
  41. package/dist/db/migrations/20240106224603_city_polygon.js +11 -11
  42. package/dist/db/migrations/20240320200534_district_polygon.js +11 -11
  43. package/dist/db/migrations/20250316162700_kindergartens.js +12 -12
  44. package/dist/db/regions.d.ts +31 -31
  45. package/dist/db/regions.js +81 -81
  46. package/dist/db/schools.d.ts +7 -7
  47. package/dist/db/schools.js +95 -95
  48. package/dist/db/street-sync.d.ts +6 -6
  49. package/dist/db/street-sync.js +22 -22
  50. package/dist/db/sync-log.d.ts +9 -9
  51. package/dist/db/sync-log.js +66 -66
  52. package/dist/db/types.d.ts +59 -59
  53. package/dist/db/types.js +26 -26
  54. package/dist/index.d.ts +23 -23
  55. package/dist/index.js +32 -32
  56. package/dist/open-data-sync/address-points.d.ts +2 -2
  57. package/dist/open-data-sync/address-points.js +68 -68
  58. package/dist/open-data-sync/cities.d.ts +2 -2
  59. package/dist/open-data-sync/cities.js +32 -32
  60. package/dist/open-data-sync/common.d.ts +2 -2
  61. package/dist/open-data-sync/common.js +22 -22
  62. package/dist/open-data-sync/regions.d.ts +2 -2
  63. package/dist/open-data-sync/regions.js +37 -37
  64. package/dist/open-data-sync/schools.d.ts +3 -3
  65. package/dist/open-data-sync/schools.js +207 -207
  66. package/dist/open-data-sync/streets.d.ts +2 -2
  67. package/dist/open-data-sync/streets.js +132 -132
  68. package/dist/smd-to-csv/json-to-csv.d.ts +1 -1
  69. package/dist/smd-to-csv/json-to-csv.js +154 -154
  70. package/dist/smd-to-csv/ordinance-to-csv-rules.d.ts +1 -1
  71. package/dist/smd-to-csv/ordinance-to-csv-rules.js +23 -23
  72. package/dist/smd-to-csv/txt-to-json.d.ts +1 -1
  73. package/dist/smd-to-csv/txt-to-json.js +92 -92
  74. package/dist/souradnice.csv +6260 -6260
  75. package/dist/street-markdown/municipality.d.ts +11 -11
  76. package/dist/street-markdown/municipality.js +116 -116
  77. package/dist/street-markdown/polygons.d.ts +7 -7
  78. package/dist/street-markdown/polygons.js +261 -261
  79. package/dist/street-markdown/roman-numerals.d.ts +1 -1
  80. package/dist/street-markdown/roman-numerals.js +68 -68
  81. package/dist/street-markdown/smd-line-parser.d.ts +4 -4
  82. package/dist/street-markdown/smd-line-parser.js +40 -40
  83. package/dist/street-markdown/smd-parser.d.ts +23 -23
  84. package/dist/street-markdown/smd-parser.js +393 -393
  85. package/dist/street-markdown/smd.d.ts +24 -24
  86. package/dist/street-markdown/smd.js +440 -440
  87. package/dist/street-markdown/token-definition.d.ts +25 -25
  88. package/dist/street-markdown/token-definition.js +168 -168
  89. package/dist/street-markdown/types.d.ts +148 -148
  90. package/dist/street-markdown/types.js +13 -13
  91. package/dist/utils/atom.d.ts +2 -2
  92. package/dist/utils/atom.js +57 -57
  93. package/dist/utils/helpers.d.ts +28 -28
  94. package/dist/utils/helpers.js +176 -176
  95. package/dist/utils/jtsk2wgs84.d.ts +17 -17
  96. package/dist/utils/jtsk2wgs84.js +82 -82
  97. package/package.json +109 -109
@@ -1,207 +1,207 @@
1
- import { createReadStream, createWriteStream, existsSync, rmSync } from "fs";
2
- import fetch from "node-fetch";
3
- import { join } from "path";
4
- import parser from "stream-json";
5
- import Pick from "stream-json/filters/Pick";
6
- import StreamArray from "stream-json/streamers/StreamArray";
7
- import { pipeline } from "stream/promises";
8
- import { insertFounders } from "../db/founders";
9
- import { insertSchools } from "../db/schools";
10
- import { getKnexDb } from "../db/db";
11
- import { MunicipalityType, SchoolType, SyncPart, } from "../db/types";
12
- import { prepareOptions, } from "../utils/helpers";
13
- import { runSyncPart } from "./common";
14
- const downloadJsonld = async (options) => {
15
- if (existsSync(getJsonldFilePath(options))) {
16
- return;
17
- }
18
- console.log("Downloading a large JSON-LD file with school data...");
19
- const response = await fetch(options.schoolsJsonldUrl);
20
- if (response.status !== 200) {
21
- throw new Error(`The JSON-LD file could not be downloaded. HTTP Code: ${response.status}`);
22
- }
23
- await pipeline(response.body, createWriteStream(getJsonldFilePath(options)));
24
- console.log("Finished downloading.");
25
- };
26
- const SCHOOL_TYPE_KINDERGARTEN = "A00";
27
- const SCHOOL_TYPE_ELEMENTARY = "B00";
28
- const getCorrectFounderType = (founderType) => {
29
- return founderType === "" ? "101" : founderType;
30
- };
31
- const getMunicipalityType = (founderType) => {
32
- return founderType === "261"
33
- ? MunicipalityType.City
34
- : founderType === "263"
35
- ? MunicipalityType.District
36
- : MunicipalityType.Other;
37
- };
38
- const processSchoolRegisterJsonld = async (options) => {
39
- const founders = new Map();
40
- const schools = [];
41
- const schoolsWithoutRuian = [];
42
- const stream = createReadStream(getJsonldFilePath(options))
43
- .pipe(parser())
44
- .pipe(new Pick({ filter: "list" }))
45
- .pipe(new StreamArray());
46
- for await (const { value: entity } of stream) {
47
- const redizo = entity.redIzo ?? "";
48
- const ico = entity.ico ?? "";
49
- const entityName = entity.uplnyNazev ?? "";
50
- const currentSchools = [];
51
- for (const school of entity.skolyAZarizeni ?? []) {
52
- const type = school.druh === SCHOOL_TYPE_KINDERGARTEN
53
- ? SchoolType.Kindergarten
54
- : school.druh === SCHOOL_TYPE_ELEMENTARY
55
- ? SchoolType.Elementary
56
- : null;
57
- if (type === null)
58
- continue;
59
- const capacityEntry = school.kapacity?.find((k) => k.mernaJednotka === "01") ??
60
- school.kapacity?.[0];
61
- const capacity = capacityEntry?.nejvyssiPovolenyPocet ?? 0;
62
- const allPlaces = school.mistaVyuky ?? [];
63
- const locationsWithRuian = allPlaces.filter((p) => p.adresa?.kodRUIAN != null);
64
- // Prefer the main building (IDmista matches school IZO), fall back to first available
65
- const mainPlace = locationsWithRuian.find((p) => p.IDmista === school.izo) ??
66
- locationsWithRuian[0];
67
- const locations = mainPlace
68
- ? [{ addressPointId: mainPlace.adresa.kodRUIAN }]
69
- : [];
70
- if (!mainPlace && allPlaces.length > 0) {
71
- const addr = allPlaces[0].adresa ?? {};
72
- const addressParts = [
73
- addr.ulice,
74
- addr.cisloDomovni?.toString(),
75
- addr.obec,
76
- ].filter(Boolean);
77
- schoolsWithoutRuian.push({ izo: school.izo, address: addressParts, type });
78
- }
79
- currentSchools.push({
80
- izo: school.izo,
81
- name: entityName || school.uplnyNazev || "",
82
- redizo,
83
- capacity,
84
- type,
85
- locations,
86
- });
87
- }
88
- schools.push(...currentSchools);
89
- for (const z of entity.zrizovatele ?? []) {
90
- let founderIco;
91
- let founderName;
92
- let founderType;
93
- if (z.druhOsoby === "PO") {
94
- founderIco = z.Ico ?? "";
95
- founderName = z.nazevOsoby ?? "";
96
- founderType = getCorrectFounderType(z.pravniForma ?? "");
97
- }
98
- else {
99
- founderIco = z.datumNarozeni ?? "";
100
- founderName = z.nazevOsoby ?? "";
101
- founderType = getCorrectFounderType("");
102
- }
103
- if (founderIco === "" || founderName === "") {
104
- founderIco = ico;
105
- founderName = entityName;
106
- founderType = "224";
107
- }
108
- if (currentSchools.length > 0) {
109
- const key = founderName + founderIco;
110
- if (founders.has(key)) {
111
- founders.get(key).schools.push(...currentSchools);
112
- }
113
- else {
114
- founders.set(key, {
115
- name: founderName,
116
- ico: founderIco,
117
- originalType: parseInt(founderType),
118
- municipalityType: getMunicipalityType(founderType),
119
- schools: [...currentSchools],
120
- });
121
- }
122
- }
123
- }
124
- }
125
- return { schools, founders, schoolsWithoutRuian };
126
- };
127
- const importDataToDb = async (options, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => {
128
- const { schools, founders, schoolsWithoutRuian } = await processSchoolRegisterJsonld(options);
129
- if (saveFoundersToCsv) {
130
- const csvFile = "founders.csv";
131
- if (existsSync(csvFile)) {
132
- rmSync(csvFile);
133
- }
134
- var csv = createWriteStream(csvFile, {
135
- flags: "a",
136
- });
137
- csv.write("IČO;Zřizovatel;Právní forma;Počet škol;Školy\n");
138
- founders.forEach((founder) => {
139
- csv.write(`#${founder.ico};${founder.name};${founder.originalType};${founder.schools.length};${founder.schools.map((school) => school.name).join("---")}\n`);
140
- });
141
- csv.end();
142
- }
143
- if (saveSchoolsWithoutRuianToCsv) {
144
- const csvFile = "schoolsWithoutRuian.csv";
145
- if (existsSync(csvFile)) {
146
- rmSync(csvFile);
147
- }
148
- var csv = createWriteStream(csvFile, {
149
- flags: "a",
150
- });
151
- csv.write("IZO;Je mateřská;Je základní;adresa1;adresa2;adresa3\n");
152
- schoolsWithoutRuian.forEach((schoolAddress) => {
153
- csv.write(`#${schoolAddress.izo};${schoolAddress.type === SchoolType.Kindergarten ? "TRUE" : "FALSE"};${schoolAddress.type === SchoolType.Elementary ? "TRUE" : "FALSE"};${schoolAddress.address.join(";")}\n`);
154
- });
155
- csv.end();
156
- }
157
- const knex = getKnexDb();
158
- const schoolsBefore = (await knex("school").count("izo as count").first()).count;
159
- const foundersBefore = (await knex("founder").count("id as count").first()).count;
160
- // Compute change stats before inserting (uses same logic as insertSchools)
161
- const existingSnap = await knex("school")
162
- .leftJoin("school_location", "school.izo", "school_location.school_izo")
163
- .select("school.izo", "school.name", "school.capacity", "school_location.address_point_id");
164
- const existingSnapMap = new Map(existingSnap.map((r) => [r.izo, r]));
165
- const statsFieldUpdates = schools.filter((s) => {
166
- const row = existingSnapMap.get(s.izo);
167
- return row && (row.name !== s.name || row.capacity !== s.capacity);
168
- }).length;
169
- const statsLocationUpdates = schools.filter((s) => {
170
- const row = existingSnapMap.get(s.izo);
171
- const newRuians = s.locations.map((l) => l.addressPointId);
172
- return row && row.address_point_id !== null && newRuians.length > 0 && !newRuians.includes(row.address_point_id);
173
- }).length;
174
- await insertSchools(schools);
175
- await insertFounders(Array.from(founders.values()));
176
- const schoolsAfter = (await knex("school").count("izo as count").first()).count;
177
- const foundersAfter = (await knex("founder").count("id as count").first()).count;
178
- const kindergartens = schools.filter((s) => s.type === SchoolType.Kindergarten).length;
179
- const elementary = schools.filter((s) => s.type === SchoolType.Elementary).length;
180
- console.log(`\n=== School sync statistics ===`);
181
- console.log(`Schools parsed: ${schools.length} (${kindergartens} kindergartens, ${elementary} elementary)`);
182
- console.log(`Founders parsed: ${founders.size}`);
183
- console.log(`New schools inserted: ${schoolsAfter - schoolsBefore}`);
184
- console.log(`New founders inserted: ${foundersAfter - foundersBefore}`);
185
- console.log(`Field updates: ${statsFieldUpdates} (name/capacity changed)`);
186
- console.log(`Location updates: ${statsLocationUpdates} (first location changed)`);
187
- console.log(`Total schools in DB: ${schoolsAfter}`);
188
- console.log(`Total founders in DB: ${foundersAfter}`);
189
- };
190
- const getJsonldFilePath = (options) => {
191
- return join(options.tmpDir, options.schoolsJsonldFileName);
192
- };
193
- export const downloadAndImportSchools = async (options = {}, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => {
194
- await runSyncPart(SyncPart.Schools, [SyncPart.AddressPoints], async () => {
195
- const runOptions = prepareOptions(options);
196
- await downloadJsonld(runOptions);
197
- await importDataToDb(runOptions, saveFoundersToCsv, saveSchoolsWithoutRuianToCsv);
198
- deleteSchoolsJsonldFile(runOptions);
199
- });
200
- };
201
- export const deleteSchoolsJsonldFile = (options = {}) => {
202
- const runOptions = prepareOptions(options);
203
- if (existsSync(getJsonldFilePath(runOptions))) {
204
- rmSync(getJsonldFilePath(runOptions));
205
- }
206
- };
207
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nob29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVuLWRhdGEtc3luYy9zY2hvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQzdFLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVCLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUNqQyxPQUFPLElBQUksTUFBTSwwQkFBMEIsQ0FBQztBQUM1QyxPQUFPLFdBQVcsTUFBTSxtQ0FBbUMsQ0FBQztBQUU1RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNyQyxPQUFPLEVBRUwsZ0JBQWdCLEVBR2hCLFVBQVUsRUFDVixRQUFRLEdBQ1QsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkMsTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLE9BQTRCLEVBQWlCLEVBQUU7SUFDM0UsSUFBSSxVQUFVLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRTtRQUMxQyxPQUFPO0tBQ1I7SUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDcEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENB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QixFQUNqQiw0QkFBNEIsQ0FDN0IsQ0FBQztRQUNGLHVCQUF1QixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FDckMsVUFBc0MsRUFBRSxFQUN4QyxFQUFFO0lBQ0YsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRTNDLElBQUksVUFBVSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUU7UUFDN0MsTUFBTSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7S0FDdkM7QUFDSCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVSZWFkU3RyZWFtLCBjcmVhdGVXcml0ZVN0cmVhbSwgZXhpc3RzU3luYywgcm1TeW5jIH0gZnJvbSBcImZzXCI7XHJcbmltcG9ydCBmZXRjaCBmcm9tIFwibm9kZS1mZXRjaFwiO1xyXG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0IHBhcnNlciBmcm9tIFwic3RyZWFtLWpzb25cIjtcclxuaW1wb3J0IFBpY2sgZnJvbSBcInN0cmVhbS1qc29uL2ZpbHRlcnMvUGlja1wiO1xyXG5pbXBvcnQgU3RyZWFtQXJyYXkgZnJvbSBcInN0cmVhbS1qc29uL3N0cmVhbWVycy9TdHJlYW1BcnJheVwiO1xyXG5cclxuaW1wb3J0IHsgcGlwZWxpbmUgfSBmcm9tIFwic3RyZWFtL3Byb21pc2VzXCI7XHJcbmltcG9ydCB7IGluc2VydEZvdW5kZXJzIH0gZnJvbSBcIi4uL2RiL2ZvdW5kZXJzXCI7XHJcbmltcG9ydCB7IGluc2VydFNjaG9vbHMgfSBmcm9tIFwiLi4vZGIvc2Nob29sc1wiO1xyXG5pbXBvcnQgeyBnZXRLbmV4RGIgfSBmcm9tIFwiLi4vZGIvZGJcIjtcclxuaW1wb3J0IHtcclxuICBGb3VuZGVyLFxyXG4gIE11bmljaXBhbGl0eVR5cGUsXHJcbiAgU2Nob29sLFxyXG4gIFNjaG9vbExvY2F0aW9uLFxyXG4gIFNjaG9vbFR5cGUsXHJcbiAgU3luY1BhcnQsXHJcbn0gZnJvbSBcIi4uL2RiL3R5cGVzXCI7XHJcbmltcG9ydCB7XHJcbiAgT3BlbkRhdGFTeW5jT3B0aW9ucyxcclxuICBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCxcclxuICBwcmVwYXJlT3B0aW9ucyxcclxufSBmcm9tIFwiLi4vdXRpbHMvaGVscGVyc1wiO1xyXG5pbXBvcnQgeyBydW5TeW5jUGFydCB9IGZyb20gXCIuL2NvbW1vblwiO1xyXG5cclxuY29uc3QgZG93bmxvYWRKc29ubGQgPSBhc3luYyAob3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xyXG4gIGlmIChleGlzdHNTeW5jKGdldEpzb25sZEZpbGVQYXRoKG9wdGlvbnMpKSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgY29uc29sZS5sb2coXCJEb3dubG9hZGluZyBhIGxhcmdlIEpTT04tTEQgZmlsZSB3aXRoIHNjaG9vbCBkYXRhLi4uXCIpO1xyXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gob3B0aW9ucy5zY2hvb2xzSnNvbmxkVXJsKTtcclxuICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgYFRoZSBKU09OLUxEIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQuIEhUVFAgQ29kZTogJHtyZXNwb25zZS5zdGF0dXN9YFxyXG4gICAgKTtcclxuICB9XHJcbiAgYXdhaXQgcGlwZWxpbmUocmVzcG9uc2UuYm9keSwgY3JlYXRlV3JpdGVTdHJlYW0oZ2V0SnNvbmxkRmlsZVBhdGgob3B0aW9ucykpKTtcclxuICBjb25zb2xlLmxvZyhcIkZpbmlzaGVkIGRvd25sb2FkaW5nLlwiKTtcclxufTtcclxuXHJcbmNvbnN0IFNDSE9PTF9UWVBFX0tJTkRFUkdBUlRFTiA9IFwiQTAwXCI7XHJcbmNvbnN0IFNDSE9PTF9UWVBFX0VMRU1FTlRBUlkgPSBcIkIwMFwiO1xyXG5cclxuY29uc3QgZ2V0Q29ycmVjdEZvdW5kZXJUeXBlID0gKGZvdW5kZXJUeXBlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xyXG4gIHJldHVybiBmb3VuZGVyVHlwZSA9PT0gXCJcIiA/IFwiMTAxXCIgOiBmb3VuZGVyVHlwZTtcclxufTtcclxuXHJcbmNvbnN0IGdldE11bmljaXBhbGl0eVR5cGUgPSAoZm91bmRlclR5cGU6IHN0cmluZyk6IE11bmljaXBhbGl0eVR5cGUgPT4ge1xyXG4gIHJldHVybiBmb3VuZGVyVHlwZSA9PT0gXCIyNjFcIlxyXG4gICAgPyBNdW5pY2lwYWxpdHlUeXBlLkNpdHlcclxuICAgIDogZm91bmRlclR5cGUgPT09IFwiMjYzXCJcclxuICAgID8gTXVuaWNpcGFsaXR5VHlwZS5EaXN0cmljdFxyXG4gICAgOiBNdW5pY2lwYWxpdHlUeXBlLk90aGVyO1xyXG59O1xyXG5cclxudHlwZSBTY2hvb2xBZGRyZXNzID0ge1xyXG4gIGl6bzogc3RyaW5nO1xyXG4gIGFkZHJlc3M6IHN0cmluZ1tdO1xyXG4gIHR5cGU6IFNjaG9vbFR5cGU7XHJcbn07XHJcblxyXG5jb25zdCBwcm9jZXNzU2Nob29sUmVnaXN0ZXJKc29ubGQgPSBhc3luYyAoXHJcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1xyXG4pOiBQcm9taXNlPHtcclxuICBzY2hvb2xzOiBTY2hvb2xbXTtcclxuICBmb3VuZGVyczogTWFwPHN0cmluZywgRm91bmRlcj47XHJcbiAgc2Nob29sc1dpdGhvdXRSdWlhbjogU2Nob29sQWRkcmVzc1tdO1xyXG59PiA9PiB7XHJcbiAgY29uc3QgZm91bmRlcnMgPSBuZXcgTWFwPHN0cmluZywgRm91bmRlcj4oKTtcclxuICBjb25zdCBzY2hvb2xzOiBTY2hvb2xbXSA9IFtdO1xyXG4gIGNvbnN0IHNjaG9vbHNXaXRob3V0UnVpYW46IFNjaG9vbEFkZHJlc3NbXSA9IFtdO1xyXG5cclxuICBjb25zdCBzdHJlYW0gPSBjcmVhdGVSZWFkU3RyZWFtKGdldEpzb25sZEZpbGVQYXRoKG9wdGlvbnMpKVxyXG4gICAgLnBpcGUocGFyc2VyKCkpXHJcbiAgICAucGlwZShuZXcgUGljayh7IGZpbHRlcjogXCJsaXN0XCIgfSkpXHJcbiAgICAucGlwZShuZXcgU3RyZWFtQXJyYXkoKSk7XHJcblxyXG4gIGZvciBhd2FpdCAoY29uc3QgeyB2YWx1ZTogZW50aXR5IH0gb2Ygc3RyZWFtKSB7XHJcbiAgICBjb25zdCByZWRpem86IHN0cmluZyA9IGVudGl0eS5yZWRJem8gPz8gXCJcIjtcclxuICAgIGNvbnN0IGljbzogc3RyaW5nID0gZW50aXR5LmljbyA/PyBcIlwiO1xyXG4gICAgY29uc3QgZW50aXR5TmFtZTogc3RyaW5nID0gZW50aXR5LnVwbG55TmF6ZXYgPz8gXCJcIjtcclxuICAgIGNvbnN0IGN1cnJlbnRTY2hvb2xzOiBTY2hvb2xbXSA9IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3Qgc2Nob29sIG9mIGVudGl0eS5za29seUFaYXJpemVuaSA/PyBbXSkge1xyXG4gICAgICBjb25zdCB0eXBlID1cclxuICAgICAgICBzY2hvb2wuZHJ1aCA9PT0gU0NIT09MX1RZUEVfS0lOREVSR0FSVEVOXHJcbiAgICAgICAgICA/IFNjaG9vbFR5cGUuS2luZGVyZ2FydGVuXHJcbiAgICAgICAgICA6IHNjaG9vbC5kcnVoID09PSBTQ0hPT0xfVFlQRV9FTEVNRU5UQVJZXHJcbiAgICAgICAgICA/IFNjaG9vbFR5cGUuRWxlbWVudGFyeVxyXG4gICAgICAgICAgOiBudWxsO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09IG51bGwpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgY29uc3QgY2FwYWNpdHlFbnRyeSA9XHJcbiAgICAgICAgc2Nob29sLmthcGFjaXR5Py5maW5kKChrKSA9PiBrLm1lcm5hSmVkbm90a2EgPT09IFwiMDFcIikgPz9cclxuICAgICAgICBzY2hvb2wua2FwYWNpdHk/LlswXTtcclxuICAgICAgY29uc3QgY2FwYWNpdHk6IG51bWJlciA9IGNhcGFjaXR5RW50cnk/Lm5lanZ5c3NpUG92b2xlbnlQb2NldCA/PyAwO1xyXG4gICAgICBjb25zdCBhbGxQbGFjZXMgPSBzY2hvb2wubWlzdGFWeXVreSA/PyBbXTtcclxuICAgICAgY29uc3QgbG9jYXRpb25zV2l0aFJ1aWFuID0gYWxsUGxhY2VzLmZpbHRlcihcclxuICAgICAgICAocCkgPT4gcC5hZHJlc2E/LmtvZFJVSUFOICE9IG51bGxcclxuICAgICAgKTtcclxuICAgICAgLy8gUHJlZmVyIHRoZSBtYWluIGJ1aWxkaW5nIChJRG1pc3RhIG1hdGNoZXMgc2Nob29sIElaTyksIGZhbGwgYmFjayB0byBmaXJzdCBhdmFpbGFibGVcclxuICAgICAgY29uc3QgbWFpblBsYWNlID1cclxuICAgICAgICBsb2NhdGlvbnNXaXRoUnVpYW4uZmluZCgocCkgPT4gcC5JRG1pc3RhID09PSBzY2hvb2wuaXpvKSA/P1xyXG4gICAgICAgIGxvY2F0aW9uc1dpdGhSdWlhblswXTtcclxuXHJcbiAgICAgIGNvbnN0IGxvY2F0aW9uczogU2Nob29sTG9jYXRpb25bXSA9IG1haW5QbGFjZVxyXG4gICAgICAgID8gW3sgYWRkcmVzc1BvaW50SWQ6IG1haW5QbGFjZS5hZHJlc2Eua29kUlVJQU4gfV1cclxuICAgICAgICA6IFtdO1xyXG5cclxuICAgICAgaWYgKCFtYWluUGxhY2UgJiYgYWxsUGxhY2VzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBjb25zdCBhZGRyID0gYWxsUGxhY2VzWzBdLmFkcmVzYSA/PyB7fTtcclxuICAgICAgICBjb25zdCBhZGRyZXNzUGFydHMgPSBbXHJcbiAgICAgICAgICBhZGRyLnVsaWNlLFxyXG4gICAgICAgICAgYWRkci5jaXNsb0RvbW92bmk/LnRvU3RyaW5nKCksXHJcbiAgICAgICAgICBhZGRyLm9iZWMsXHJcbiAgICAgICAgXS5maWx0ZXIoQm9vbGVhbik7XHJcbiAgICAgICAgc2Nob29sc1dpdGhvdXRSdWlhbi5wdXNoKHsgaXpvOiBzY2hvb2wuaXpvLCBhZGRyZXNzOiBhZGRyZXNzUGFydHMsIHR5cGUgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGN1cnJlbnRTY2hvb2xzLnB1c2goe1xyXG4gICAgICAgIGl6bzogc2Nob29sLml6byxcclxuICAgICAgICBuYW1lOiBlbnRpdHlOYW1lIHx8IHNjaG9vbC51cGxueU5hemV2IHx8IFwiXCIsXHJcbiAgICAgICAgcmVkaXpvLFxyXG4gICAgICAgIGNhcGFjaXR5LFxyXG4gICAgICAgIHR5cGUsXHJcbiAgICAgICAgbG9jYXRpb25zLFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzY2hvb2xzLnB1c2goLi4uY3VycmVudFNjaG9vbHMpO1xyXG5cclxuICAgIGZvciAoY29uc3QgeiBvZiBlbnRpdHkuenJpem92YXRlbGUgPz8gW10pIHtcclxuICAgICAgbGV0IGZvdW5kZXJJY286IHN0cmluZztcclxuICAgICAgbGV0IGZvdW5kZXJOYW1lOiBzdHJpbmc7XHJcbiAgICAgIGxldCBmb3VuZGVyVHlwZTogc3RyaW5nO1xyXG5cclxuICAgICAgaWYgKHouZHJ1aE9zb2J5ID09PSBcIlBPXCIpIHtcclxuICAgICAgICBmb3VuZGVySWNvID0gei5JY28gPz8gXCJcIjtcclxuICAgICAgICBmb3VuZGVyTmFtZSA9IHoubmF6ZXZPc29ieSA/PyBcIlwiO1xyXG4gICAgICAgIGZvdW5kZXJUeXBlID0gZ2V0Q29ycmVjdEZvdW5kZXJUeXBlKHoucHJhdm5pRm9ybWEgPz8gXCJcIik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZm91bmRlckljbyA9IHouZGF0dW1OYXJvemVuaSA/PyBcIlwiO1xyXG4gICAgICAgIGZvdW5kZXJOYW1lID0gei5uYXpldk9zb2J5ID8/IFwiXCI7XHJcbiAgICAgICAgZm91bmRlclR5cGUgPSBnZXRDb3JyZWN0Rm91bmRlclR5cGUoXCJcIik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChmb3VuZGVySWNvID09PSBcIlwiIHx8IGZvdW5kZXJOYW1lID09PSBcIlwiKSB7XHJcbiAgICAgICAgZm91bmRlckljbyA9IGljbztcclxuICAgICAgICBmb3VuZGVyTmFtZSA9IGVudGl0eU5hbWU7XHJcbiAgICAgICAgZm91bmRlclR5cGUgPSBcIjIyNFwiO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoY3VycmVudFNjaG9vbHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IGtleSA9IGZvdW5kZXJOYW1lICsgZm91bmRlckljbztcclxuICAgICAgICBpZiAoZm91bmRlcnMuaGFzKGtleSkpIHtcclxuICAgICAgICAgIGZvdW5kZXJzLmdldChrZXkpLnNjaG9vbHMucHVzaCguLi5jdXJyZW50U2Nob29scyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGZvdW5kZXJzLnNldChrZXksIHtcclxuICAgICAgICAgICAgbmFtZTogZm91bmRlck5hbWUsXHJcbiAgICAgICAgICAgIGljbzogZm91bmRlckljbyxcclxuICAgICAgICAgICAgb3JpZ2luYWxUeXBlOiBwYXJzZUludChmb3VuZGVyVHlwZSksXHJcbiAgICAgICAgICAgIG11bmljaXBhbGl0eVR5cGU6IGdldE11bmljaXBhbGl0eVR5cGUoZm91bmRlclR5cGUpLFxyXG4gICAgICAgICAgICBzY2hvb2xzOiBbLi4uY3VycmVudFNjaG9vbHNdLFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4geyBzY2hvb2xzLCBmb3VuZGVycywgc2Nob29sc1dpdGhvdXRSdWlhbiB9O1xyXG59O1xyXG5cclxuY29uc3QgaW1wb3J0RGF0YVRvRGIgPSBhc3luYyAoXHJcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9ucyxcclxuICBzYXZlRm91bmRlcnNUb0NzdjogYm9vbGVhbiA9IGZhbHNlLFxyXG4gIHNhdmVTY2hvb2xzV2l0aG91dFJ1aWFuVG9Dc3Y6IGJvb2xlYW4gPSBmYWxzZVxyXG4pID0+IHtcclxuICBjb25zdCB7IHNjaG9vbHMsIGZvdW5kZXJzLCBzY2hvb2xzV2l0aG91dFJ1aWFuIH0gPVxyXG4gICAgYXdhaXQgcHJvY2Vzc1NjaG9vbFJlZ2lzdGVySnNvbmxkKG9wdGlvbnMpO1xyXG5cclxuICBpZiAoc2F2ZUZvdW5kZXJzVG9Dc3YpIHtcclxuICAgIGNvbnN0IGNzdkZpbGUgPSBcImZvdW5kZXJzLmNzdlwiO1xyXG5cclxuICAgIGlmIChleGlzdHNTeW5jKGNzdkZpbGUpKSB7XHJcbiAgICAgIHJtU3luYyhjc3ZGaWxlKTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgY3N2ID0gY3JlYXRlV3JpdGVTdHJlYW0oY3N2RmlsZSwge1xyXG4gICAgICBmbGFnczogXCJhXCIsXHJcbiAgICB9KTtcclxuICAgIGNzdi53cml0ZShcIknEjE87WsWZaXpvdmF0ZWw7UHLDoXZuw60gZm9ybWE7UG/EjWV0IMWha29sO8Wga29seVxcblwiKTtcclxuICAgIGZvdW5kZXJzLmZvckVhY2goKGZvdW5kZXIpID0+IHtcclxuICAgICAgY3N2LndyaXRlKFxyXG4gICAgICAgIGAjJHtmb3VuZGVyLmljb307JHtmb3VuZGVyLm5hbWV9OyR7Zm91bmRlci5vcmlnaW5hbFR5cGV9OyR7XHJcbiAgICAgICAgICBmb3VuZGVyLnNjaG9vbHMubGVuZ3RoXHJcbiAgICAgICAgfTske2ZvdW5kZXIuc2Nob29scy5tYXAoKHNjaG9vbCkgPT4gc2Nob29sLm5hbWUpLmpvaW4oXCItLS1cIil9XFxuYFxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcbiAgICBjc3YuZW5kKCk7XHJcbiAgfVxyXG5cclxuICBpZiAoc2F2ZVNjaG9vbHNXaXRob3V0UnVpYW5Ub0Nzdikge1xyXG4gICAgY29uc3QgY3N2RmlsZSA9IFwic2Nob29sc1dpdGhvdXRSdWlhbi5jc3ZcIjtcclxuXHJcbiAgICBpZiAoZXhpc3RzU3luYyhjc3ZGaWxlKSkge1xyXG4gICAgICBybVN5bmMoY3N2RmlsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNzdiA9IGNyZWF0ZVdyaXRlU3RyZWFtKGNzdkZpbGUsIHtcclxuICAgICAgZmxhZ3M6IFwiYVwiLFxyXG4gICAgfSk7XHJcbiAgICBjc3Yud3JpdGUoXCJJWk87SmUgbWF0ZcWZc2vDoTtKZSB6w6FrbGFkbsOtO2FkcmVzYTE7YWRyZXNhMjthZHJlc2EzXFxuXCIpO1xyXG4gICAgc2Nob29sc1dpdGhvdXRSdWlhbi5mb3JFYWNoKChzY2hvb2xBZGRyZXNzKSA9PiB7XHJcbiAgICAgIGNzdi53cml0ZShcclxuICAgICAgICBgIyR7c2Nob29sQWRkcmVzcy5pem99OyR7XHJcbiAgICAgICAgICBzY2hvb2xBZGRyZXNzLnR5cGUgPT09IFNjaG9vbFR5cGUuS2luZGVyZ2FydGVuID8gXCJUUlVFXCIgOiBcIkZBTFNFXCJcclxuICAgICAgICB9OyR7XHJcbiAgICAgICAgICBzY2hvb2xBZGRyZXNzLnR5cGUgPT09IFNjaG9vbFR5cGUuRWxlbWVudGFyeSA/IFwiVFJVRVwiIDogXCJGQUxTRVwiXHJcbiAgICAgICAgfTske3NjaG9vbEFkZHJlc3MuYWRkcmVzcy5qb2luKFwiO1wiKX1cXG5gXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuICAgIGNzdi5lbmQoKTtcclxuICB9XHJcblxyXG4gIGNvbnN0IGtuZXggPSBnZXRLbmV4RGIoKTtcclxuICBjb25zdCBzY2hvb2xzQmVmb3JlID0gKGF3YWl0IGtuZXgoXCJzY2hvb2xcIikuY291bnQoXCJpem8gYXMgY291bnRcIikuZmlyc3QoKSkuY291bnQgYXMgbnVtYmVyO1xyXG4gIGNvbnN0IGZvdW5kZXJzQmVmb3JlID0gKGF3YWl0IGtuZXgoXCJmb3VuZGVyXCIpLmNvdW50KFwiaWQgYXMgY291bnRcIikuZmlyc3QoKSkuY291bnQgYXMgbnVtYmVyO1xyXG5cclxuICAvLyBDb21wdXRlIGNoYW5nZSBzdGF0cyBiZWZvcmUgaW5zZXJ0aW5nICh1c2VzIHNhbWUgbG9naWMgYXMgaW5zZXJ0U2Nob29scylcclxuICBjb25zdCBleGlzdGluZ1NuYXA6IHsgaXpvOiBzdHJpbmc7IG5hbWU6IHN0cmluZzsgY2FwYWNpdHk6IG51bWJlcjsgYWRkcmVzc19wb2ludF9pZDogbnVtYmVyIHwgbnVsbCB9W10gPVxyXG4gICAgYXdhaXQga25leChcInNjaG9vbFwiKVxyXG4gICAgICAubGVmdEpvaW4oXCJzY2hvb2xfbG9jYXRpb25cIiwgXCJzY2hvb2wuaXpvXCIsIFwic2Nob29sX2xvY2F0aW9uLnNjaG9vbF9pem9cIilcclxuICAgICAgLnNlbGVjdChcInNjaG9vbC5pem9cIiwgXCJzY2hvb2wubmFtZVwiLCBcInNjaG9vbC5jYXBhY2l0eVwiLCBcInNjaG9vbF9sb2NhdGlvbi5hZGRyZXNzX3BvaW50X2lkXCIpO1xyXG4gIGNvbnN0IGV4aXN0aW5nU25hcE1hcCA9IG5ldyBNYXAoZXhpc3RpbmdTbmFwLm1hcCgocikgPT4gW3IuaXpvLCByXSkpO1xyXG4gIGNvbnN0IHN0YXRzRmllbGRVcGRhdGVzID0gc2Nob29scy5maWx0ZXIoKHMpID0+IHtcclxuICAgIGNvbnN0IHJvdyA9IGV4aXN0aW5nU25hcE1hcC5nZXQocy5pem8pO1xyXG4gICAgcmV0dXJuIHJvdyAmJiAocm93Lm5hbWUgIT09IHMubmFtZSB8fCByb3cuY2FwYWNpdHkgIT09IHMuY2FwYWNpdHkpO1xyXG4gIH0pLmxlbmd0aDtcclxuICBjb25zdCBzdGF0c0xvY2F0aW9uVXBkYXRlcyA9IHNjaG9vbHMuZmlsdGVyKChzKSA9PiB7XHJcbiAgICBjb25zdCByb3cgPSBleGlzdGluZ1NuYXBNYXAuZ2V0KHMuaXpvKTtcclxuICAgIGNvbnN0IG5ld1J1aWFucyA9IHMubG9jYXRpb25zLm1hcCgobCkgPT4gbC5hZGRyZXNzUG9pbnRJZCk7XHJcbiAgICByZXR1cm4gcm93ICYmIHJvdy5hZGRyZXNzX3BvaW50X2lkICE9PSBudWxsICYmIG5ld1J1aWFucy5sZW5ndGggPiAwICYmICFuZXdSdWlhbnMuaW5jbHVkZXMocm93LmFkZHJlc3NfcG9pbnRfaWQpO1xyXG4gIH0pLmxlbmd0aDtcclxuXHJcbiAgYXdhaXQgaW5zZXJ0U2Nob29scyhzY2hvb2xzKTtcclxuICBhd2FpdCBpbnNlcnRGb3VuZGVycyhBcnJheS5mcm9tKGZvdW5kZXJzLnZhbHVlcygpKSk7XHJcblxyXG4gIGNvbnN0IHNjaG9vbHNBZnRlciA9IChhd2FpdCBrbmV4KFwic2Nob29sXCIpLmNvdW50KFwiaXpvIGFzIGNvdW50XCIpLmZpcnN0KCkpLmNvdW50IGFzIG51bWJlcjtcclxuICBjb25zdCBmb3VuZGVyc0FmdGVyID0gKGF3YWl0IGtuZXgoXCJmb3VuZGVyXCIpLmNvdW50KFwiaWQgYXMgY291bnRcIikuZmlyc3QoKSkuY291bnQgYXMgbnVtYmVyO1xyXG5cclxuICBjb25zdCBraW5kZXJnYXJ0ZW5zID0gc2Nob29scy5maWx0ZXIoKHMpID0+IHMudHlwZSA9PT0gU2Nob29sVHlwZS5LaW5kZXJnYXJ0ZW4pLmxlbmd0aDtcclxuICBjb25zdCBlbGVtZW50YXJ5ID0gc2Nob29scy5maWx0ZXIoKHMpID0+IHMudHlwZSA9PT0gU2Nob29sVHlwZS5FbGVtZW50YXJ5KS5sZW5ndGg7XHJcblxyXG4gIGNvbnNvbGUubG9nKGBcXG49PT0gU2Nob29sIHN5bmMgc3RhdGlzdGljcyA9PT1gKTtcclxuICBjb25zb2xlLmxvZyhgU2Nob29scyBwYXJzZWQ6ICAgICAgICAgJHtzY2hvb2xzLmxlbmd0aH0gKCR7a2luZGVyZ2FydGVuc30ga2luZGVyZ2FydGVucywgJHtlbGVtZW50YXJ5fSBlbGVtZW50YXJ5KWApO1xyXG4gIGNvbnNvbGUubG9nKGBGb3VuZGVycyBwYXJzZWQ6ICAgICAgICAke2ZvdW5kZXJzLnNpemV9YCk7XHJcbiAgY29uc29sZS5sb2coYE5ldyBzY2hvb2xzIGluc2VydGVkOiAgICR7c2Nob29sc0FmdGVyIC0gc2Nob29sc0JlZm9yZX1gKTtcclxuICBjb25zb2xlLmxvZyhgTmV3IGZvdW5kZXJzIGluc2VydGVkOiAgJHtmb3VuZGVyc0FmdGVyIC0gZm91bmRlcnNCZWZvcmV9YCk7XHJcbiAgY29uc29sZS5sb2coYEZpZWxkIHVwZGF0ZXM6ICAgICAgICAgICR7c3RhdHNGaWVsZFVwZGF0ZXN9IChuYW1lL2NhcGFjaXR5IGNoYW5nZWQpYCk7XHJcbiAgY29uc29sZS5sb2coYExvY2F0aW9uIHVwZGF0ZXM6ICAgICAgICR7c3RhdHNMb2NhdGlvblVwZGF0ZXN9IChmaXJzdCBsb2NhdGlvbiBjaGFuZ2VkKWApO1xyXG4gIGNvbnNvbGUubG9nKGBUb3RhbCBzY2hvb2xzIGluIERCOiAgICAke3NjaG9vbHNBZnRlcn1gKTtcclxuICBjb25zb2xlLmxvZyhgVG90YWwgZm91bmRlcnMgaW4gREI6ICAgJHtmb3VuZGVyc0FmdGVyfWApO1xyXG59O1xyXG5cclxuY29uc3QgZ2V0SnNvbmxkRmlsZVBhdGggPSAob3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwpOiBzdHJpbmcgPT4ge1xyXG4gIHJldHVybiBqb2luKG9wdGlvbnMudG1wRGlyLCBvcHRpb25zLnNjaG9vbHNKc29ubGRGaWxlTmFtZSk7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZG93bmxvYWRBbmRJbXBvcnRTY2hvb2xzID0gYXN5bmMgKFxyXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNQYXJ0aWFsID0ge30sXHJcbiAgc2F2ZUZvdW5kZXJzVG9Dc3Y6IGJvb2xlYW4gPSBmYWxzZSxcclxuICBzYXZlU2Nob29sc1dpdGhvdXRSdWlhblRvQ3N2OiBib29sZWFuID0gZmFsc2VcclxuKSA9PiB7XHJcbiAgYXdhaXQgcnVuU3luY1BhcnQoU3luY1BhcnQuU2Nob29scywgW1N5bmNQYXJ0LkFkZHJlc3NQb2ludHNdLCBhc3luYyAoKSA9PiB7XHJcbiAgICBjb25zdCBydW5PcHRpb25zID0gcHJlcGFyZU9wdGlvbnMob3B0aW9ucyk7XHJcblxyXG4gICAgYXdhaXQgZG93bmxvYWRKc29ubGQocnVuT3B0aW9ucyk7XHJcbiAgICBhd2FpdCBpbXBvcnREYXRhVG9EYihcclxuICAgICAgcnVuT3B0aW9ucyxcclxuICAgICAgc2F2ZUZvdW5kZXJzVG9Dc3YsXHJcbiAgICAgIHNhdmVTY2hvb2xzV2l0aG91dFJ1aWFuVG9Dc3ZcclxuICAgICk7XHJcbiAgICBkZWxldGVTY2hvb2xzSnNvbmxkRmlsZShydW5PcHRpb25zKTtcclxuICB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBkZWxldGVTY2hvb2xzSnNvbmxkRmlsZSA9IChcclxuICBvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCA9IHt9XHJcbikgPT4ge1xyXG4gIGNvbnN0IHJ1bk9wdGlvbnMgPSBwcmVwYXJlT3B0aW9ucyhvcHRpb25zKTtcclxuXHJcbiAgaWYgKGV4aXN0c1N5bmMoZ2V0SnNvbmxkRmlsZVBhdGgocnVuT3B0aW9ucykpKSB7XHJcbiAgICBybVN5bmMoZ2V0SnNvbmxkRmlsZVBhdGgocnVuT3B0aW9ucykpO1xyXG4gIH1cclxufTtcclxuIl19
1
+ import { createReadStream, createWriteStream, existsSync, rmSync } from "fs";
2
+ import fetch from "node-fetch";
3
+ import { join } from "path";
4
+ import parser from "stream-json";
5
+ import Pick from "stream-json/filters/Pick";
6
+ import StreamArray from "stream-json/streamers/StreamArray";
7
+ import { pipeline } from "stream/promises";
8
+ import { insertFounders } from "../db/founders";
9
+ import { insertSchools } from "../db/schools";
10
+ import { getKnexDb } from "../db/db";
11
+ import { MunicipalityType, SchoolType, SyncPart, } from "../db/types";
12
+ import { prepareOptions, } from "../utils/helpers";
13
+ import { runSyncPart } from "./common";
14
+ const downloadJsonld = async (options) => {
15
+ if (existsSync(getJsonldFilePath(options))) {
16
+ return;
17
+ }
18
+ console.log("Downloading a large JSON-LD file with school data...");
19
+ const response = await fetch(options.schoolsJsonldUrl);
20
+ if (response.status !== 200) {
21
+ throw new Error(`The JSON-LD file could not be downloaded. HTTP Code: ${response.status}`);
22
+ }
23
+ await pipeline(response.body, createWriteStream(getJsonldFilePath(options)));
24
+ console.log("Finished downloading.");
25
+ };
26
+ const SCHOOL_TYPE_KINDERGARTEN = "A00";
27
+ const SCHOOL_TYPE_ELEMENTARY = "B00";
28
+ const getCorrectFounderType = (founderType) => {
29
+ return founderType === "" ? "101" : founderType;
30
+ };
31
+ const getMunicipalityType = (founderType) => {
32
+ return founderType === "261"
33
+ ? MunicipalityType.City
34
+ : founderType === "263"
35
+ ? MunicipalityType.District
36
+ : MunicipalityType.Other;
37
+ };
38
+ const processSchoolRegisterJsonld = async (options) => {
39
+ const founders = new Map();
40
+ const schools = [];
41
+ const schoolsWithoutRuian = [];
42
+ const stream = createReadStream(getJsonldFilePath(options))
43
+ .pipe(parser())
44
+ .pipe(new Pick({ filter: "list" }))
45
+ .pipe(new StreamArray());
46
+ for await (const { value: entity } of stream) {
47
+ const redizo = entity.redIzo ?? "";
48
+ const ico = entity.ico ?? "";
49
+ const entityName = entity.uplnyNazev ?? "";
50
+ const currentSchools = [];
51
+ for (const school of entity.skolyAZarizeni ?? []) {
52
+ const type = school.druh === SCHOOL_TYPE_KINDERGARTEN
53
+ ? SchoolType.Kindergarten
54
+ : school.druh === SCHOOL_TYPE_ELEMENTARY
55
+ ? SchoolType.Elementary
56
+ : null;
57
+ if (type === null)
58
+ continue;
59
+ const capacityEntry = school.kapacity?.find((k) => k.mernaJednotka === "01") ??
60
+ school.kapacity?.[0];
61
+ const capacity = capacityEntry?.nejvyssiPovolenyPocet ?? 0;
62
+ const allPlaces = school.mistaVyuky ?? [];
63
+ const locationsWithRuian = allPlaces.filter((p) => p.adresa?.kodRUIAN != null);
64
+ // Prefer the main building (IDmista matches school IZO), fall back to first available
65
+ const mainPlace = locationsWithRuian.find((p) => p.IDmista === school.izo) ??
66
+ locationsWithRuian[0];
67
+ const locations = mainPlace
68
+ ? [{ addressPointId: mainPlace.adresa.kodRUIAN }]
69
+ : [];
70
+ if (!mainPlace && allPlaces.length > 0) {
71
+ const addr = allPlaces[0].adresa ?? {};
72
+ const addressParts = [
73
+ addr.ulice,
74
+ addr.cisloDomovni?.toString(),
75
+ addr.obec,
76
+ ].filter(Boolean);
77
+ schoolsWithoutRuian.push({ izo: school.izo, address: addressParts, type });
78
+ }
79
+ currentSchools.push({
80
+ izo: school.izo,
81
+ name: entityName || school.uplnyNazev || "",
82
+ redizo,
83
+ capacity,
84
+ type,
85
+ locations,
86
+ });
87
+ }
88
+ schools.push(...currentSchools);
89
+ for (const z of entity.zrizovatele ?? []) {
90
+ let founderIco;
91
+ let founderName;
92
+ let founderType;
93
+ if (z.druhOsoby === "PO") {
94
+ founderIco = z.Ico ?? "";
95
+ founderName = z.nazevOsoby ?? "";
96
+ founderType = getCorrectFounderType(z.pravniForma ?? "");
97
+ }
98
+ else {
99
+ founderIco = z.datumNarozeni ?? "";
100
+ founderName = z.nazevOsoby ?? "";
101
+ founderType = getCorrectFounderType("");
102
+ }
103
+ if (founderIco === "" || founderName === "") {
104
+ founderIco = ico;
105
+ founderName = entityName;
106
+ founderType = "224";
107
+ }
108
+ if (currentSchools.length > 0) {
109
+ const key = founderName + founderIco;
110
+ if (founders.has(key)) {
111
+ founders.get(key).schools.push(...currentSchools);
112
+ }
113
+ else {
114
+ founders.set(key, {
115
+ name: founderName,
116
+ ico: founderIco,
117
+ originalType: parseInt(founderType),
118
+ municipalityType: getMunicipalityType(founderType),
119
+ schools: [...currentSchools],
120
+ });
121
+ }
122
+ }
123
+ }
124
+ }
125
+ return { schools, founders, schoolsWithoutRuian };
126
+ };
127
+ const importDataToDb = async (options, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => {
128
+ const { schools, founders, schoolsWithoutRuian } = await processSchoolRegisterJsonld(options);
129
+ if (saveFoundersToCsv) {
130
+ const csvFile = "founders.csv";
131
+ if (existsSync(csvFile)) {
132
+ rmSync(csvFile);
133
+ }
134
+ var csv = createWriteStream(csvFile, {
135
+ flags: "a",
136
+ });
137
+ csv.write("IČO;Zřizovatel;Právní forma;Počet škol;Školy\n");
138
+ founders.forEach((founder) => {
139
+ csv.write(`#${founder.ico};${founder.name};${founder.originalType};${founder.schools.length};${founder.schools.map((school) => school.name).join("---")}\n`);
140
+ });
141
+ csv.end();
142
+ }
143
+ if (saveSchoolsWithoutRuianToCsv) {
144
+ const csvFile = "schoolsWithoutRuian.csv";
145
+ if (existsSync(csvFile)) {
146
+ rmSync(csvFile);
147
+ }
148
+ var csv = createWriteStream(csvFile, {
149
+ flags: "a",
150
+ });
151
+ csv.write("IZO;Je mateřská;Je základní;adresa1;adresa2;adresa3\n");
152
+ schoolsWithoutRuian.forEach((schoolAddress) => {
153
+ csv.write(`#${schoolAddress.izo};${schoolAddress.type === SchoolType.Kindergarten ? "TRUE" : "FALSE"};${schoolAddress.type === SchoolType.Elementary ? "TRUE" : "FALSE"};${schoolAddress.address.join(";")}\n`);
154
+ });
155
+ csv.end();
156
+ }
157
+ const knex = getKnexDb();
158
+ const schoolsBefore = (await knex("school").count("izo as count").first()).count;
159
+ const foundersBefore = (await knex("founder").count("id as count").first()).count;
160
+ // Compute change stats before inserting (uses same logic as insertSchools)
161
+ const existingSnap = await knex("school")
162
+ .leftJoin("school_location", "school.izo", "school_location.school_izo")
163
+ .select("school.izo", "school.name", "school.capacity", "school_location.address_point_id");
164
+ const existingSnapMap = new Map(existingSnap.map((r) => [r.izo, r]));
165
+ const statsFieldUpdates = schools.filter((s) => {
166
+ const row = existingSnapMap.get(s.izo);
167
+ return row && (row.name !== s.name || row.capacity !== s.capacity);
168
+ }).length;
169
+ const statsLocationUpdates = schools.filter((s) => {
170
+ const row = existingSnapMap.get(s.izo);
171
+ const newRuians = s.locations.map((l) => l.addressPointId);
172
+ return row && row.address_point_id !== null && newRuians.length > 0 && !newRuians.includes(row.address_point_id);
173
+ }).length;
174
+ await insertSchools(schools);
175
+ await insertFounders(Array.from(founders.values()));
176
+ const schoolsAfter = (await knex("school").count("izo as count").first()).count;
177
+ const foundersAfter = (await knex("founder").count("id as count").first()).count;
178
+ const kindergartens = schools.filter((s) => s.type === SchoolType.Kindergarten).length;
179
+ const elementary = schools.filter((s) => s.type === SchoolType.Elementary).length;
180
+ console.log(`\n=== School sync statistics ===`);
181
+ console.log(`Schools parsed: ${schools.length} (${kindergartens} kindergartens, ${elementary} elementary)`);
182
+ console.log(`Founders parsed: ${founders.size}`);
183
+ console.log(`New schools inserted: ${schoolsAfter - schoolsBefore}`);
184
+ console.log(`New founders inserted: ${foundersAfter - foundersBefore}`);
185
+ console.log(`Field updates: ${statsFieldUpdates} (name/capacity changed)`);
186
+ console.log(`Location updates: ${statsLocationUpdates} (first location changed)`);
187
+ console.log(`Total schools in DB: ${schoolsAfter}`);
188
+ console.log(`Total founders in DB: ${foundersAfter}`);
189
+ };
190
+ const getJsonldFilePath = (options) => {
191
+ return join(options.tmpDir, options.schoolsJsonldFileName);
192
+ };
193
+ export const downloadAndImportSchools = async (options = {}, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => {
194
+ await runSyncPart(SyncPart.Schools, [SyncPart.AddressPoints], async () => {
195
+ const runOptions = prepareOptions(options);
196
+ await downloadJsonld(runOptions);
197
+ await importDataToDb(runOptions, saveFoundersToCsv, saveSchoolsWithoutRuianToCsv);
198
+ deleteSchoolsJsonldFile(runOptions);
199
+ });
200
+ };
201
+ export const deleteSchoolsJsonldFile = (options = {}) => {
202
+ const runOptions = prepareOptions(options);
203
+ if (existsSync(getJsonldFilePath(runOptions))) {
204
+ rmSync(getJsonldFilePath(runOptions));
205
+ }
206
+ };
207
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nob29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVuLWRhdGEtc3luYy9zY2hvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQzdFLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVCLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUNqQyxPQUFPLElBQUksTUFBTSwwQkFBMEIsQ0FBQztBQUM1QyxPQUFPLFdBQVcsTUFBTSxtQ0FBbUMsQ0FBQztBQUU1RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNyQyxPQUFPLEVBRUwsZ0JBQWdCLEVBR2hCLFVBQVUsRUFDVixRQUFRLEdBQ1QsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkMsTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLE9BQTRCLEVBQWlCLEVBQUU7SUFDM0UsSUFBSSxVQUFVLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRTtRQUMxQyxPQUFPO0tBQ1I7SUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDcEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENB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QixFQUNqQiw0QkFBNEIsQ0FDN0IsQ0FBQztRQUNGLHVCQUF1QixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FDckMsVUFBc0MsRUFBRSxFQUN4QyxFQUFFO0lBQ0YsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRTNDLElBQUksVUFBVSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUU7UUFDN0MsTUFBTSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7S0FDdkM7QUFDSCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVSZWFkU3RyZWFtLCBjcmVhdGVXcml0ZVN0cmVhbSwgZXhpc3RzU3luYywgcm1TeW5jIH0gZnJvbSBcImZzXCI7XG5pbXBvcnQgZmV0Y2ggZnJvbSBcIm5vZGUtZmV0Y2hcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHBhcnNlciBmcm9tIFwic3RyZWFtLWpzb25cIjtcbmltcG9ydCBQaWNrIGZyb20gXCJzdHJlYW0tanNvbi9maWx0ZXJzL1BpY2tcIjtcbmltcG9ydCBTdHJlYW1BcnJheSBmcm9tIFwic3RyZWFtLWpzb24vc3RyZWFtZXJzL1N0cmVhbUFycmF5XCI7XG5cbmltcG9ydCB7IHBpcGVsaW5lIH0gZnJvbSBcInN0cmVhbS9wcm9taXNlc1wiO1xuaW1wb3J0IHsgaW5zZXJ0Rm91bmRlcnMgfSBmcm9tIFwiLi4vZGIvZm91bmRlcnNcIjtcbmltcG9ydCB7IGluc2VydFNjaG9vbHMgfSBmcm9tIFwiLi4vZGIvc2Nob29sc1wiO1xuaW1wb3J0IHsgZ2V0S25leERiIH0gZnJvbSBcIi4uL2RiL2RiXCI7XG5pbXBvcnQge1xuICBGb3VuZGVyLFxuICBNdW5pY2lwYWxpdHlUeXBlLFxuICBTY2hvb2wsXG4gIFNjaG9vbExvY2F0aW9uLFxuICBTY2hvb2xUeXBlLFxuICBTeW5jUGFydCxcbn0gZnJvbSBcIi4uL2RiL3R5cGVzXCI7XG5pbXBvcnQge1xuICBPcGVuRGF0YVN5bmNPcHRpb25zLFxuICBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCxcbiAgcHJlcGFyZU9wdGlvbnMsXG59IGZyb20gXCIuLi91dGlscy9oZWxwZXJzXCI7XG5pbXBvcnQgeyBydW5TeW5jUGFydCB9IGZyb20gXCIuL2NvbW1vblwiO1xuXG5jb25zdCBkb3dubG9hZEpzb25sZCA9IGFzeW5jIChvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmIChleGlzdHNTeW5jKGdldEpzb25sZEZpbGVQYXRoKG9wdGlvbnMpKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKFwiRG93bmxvYWRpbmcgYSBsYXJnZSBKU09OLUxEIGZpbGUgd2l0aCBzY2hvb2wgZGF0YS4uLlwiKTtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChvcHRpb25zLnNjaG9vbHNKc29ubGRVcmwpO1xuICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVGhlIEpTT04tTEQgZmlsZSBjb3VsZCBub3QgYmUgZG93bmxvYWRlZC4gSFRUUCBDb2RlOiAke3Jlc3BvbnNlLnN0YXR1c31gXG4gICAgKTtcbiAgfVxuICBhd2FpdCBwaXBlbGluZShyZXNwb25zZS5ib2R5LCBjcmVhdGVXcml0ZVN0cmVhbShnZXRKc29ubGRGaWxlUGF0aChvcHRpb25zKSkpO1xuICBjb25zb2xlLmxvZyhcIkZpbmlzaGVkIGRvd25sb2FkaW5nLlwiKTtcbn07XG5cbmNvbnN0IFNDSE9PTF9UWVBFX0tJTkRFUkdBUlRFTiA9IFwiQTAwXCI7XG5jb25zdCBTQ0hPT0xfVFlQRV9FTEVNRU5UQVJZID0gXCJCMDBcIjtcblxuY29uc3QgZ2V0Q29ycmVjdEZvdW5kZXJUeXBlID0gKGZvdW5kZXJUeXBlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gZm91bmRlclR5cGUgPT09IFwiXCIgPyBcIjEwMVwiIDogZm91bmRlclR5cGU7XG59O1xuXG5jb25zdCBnZXRNdW5pY2lwYWxpdHlUeXBlID0gKGZvdW5kZXJUeXBlOiBzdHJpbmcpOiBNdW5pY2lwYWxpdHlUeXBlID0+IHtcbiAgcmV0dXJuIGZvdW5kZXJUeXBlID09PSBcIjI2MVwiXG4gICAgPyBNdW5pY2lwYWxpdHlUeXBlLkNpdHlcbiAgICA6IGZvdW5kZXJUeXBlID09PSBcIjI2M1wiXG4gICAgPyBNdW5pY2lwYWxpdHlUeXBlLkRpc3RyaWN0XG4gICAgOiBNdW5pY2lwYWxpdHlUeXBlLk90aGVyO1xufTtcblxudHlwZSBTY2hvb2xBZGRyZXNzID0ge1xuICBpem86IHN0cmluZztcbiAgYWRkcmVzczogc3RyaW5nW107XG4gIHR5cGU6IFNjaG9vbFR5cGU7XG59O1xuXG5jb25zdCBwcm9jZXNzU2Nob29sUmVnaXN0ZXJKc29ubGQgPSBhc3luYyAoXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNcbik6IFByb21pc2U8e1xuICBzY2hvb2xzOiBTY2hvb2xbXTtcbiAgZm91bmRlcnM6IE1hcDxzdHJpbmcsIEZvdW5kZXI+O1xuICBzY2hvb2xzV2l0aG91dFJ1aWFuOiBTY2hvb2xBZGRyZXNzW107XG59PiA9PiB7XG4gIGNvbnN0IGZvdW5kZXJzID0gbmV3IE1hcDxzdHJpbmcsIEZvdW5kZXI+KCk7XG4gIGNvbnN0IHNjaG9vbHM6IFNjaG9vbFtdID0gW107XG4gIGNvbnN0IHNjaG9vbHNXaXRob3V0UnVpYW46IFNjaG9vbEFkZHJlc3NbXSA9IFtdO1xuXG4gIGNvbnN0IHN0cmVhbSA9IGNyZWF0ZVJlYWRTdHJlYW0oZ2V0SnNvbmxkRmlsZVBhdGgob3B0aW9ucykpXG4gICAgLnBpcGUocGFyc2VyKCkpXG4gICAgLnBpcGUobmV3IFBpY2soeyBmaWx0ZXI6IFwibGlzdFwiIH0pKVxuICAgIC5waXBlKG5ldyBTdHJlYW1BcnJheSgpKTtcblxuICBmb3IgYXdhaXQgKGNvbnN0IHsgdmFsdWU6IGVudGl0eSB9IG9mIHN0cmVhbSkge1xuICAgIGNvbnN0IHJlZGl6bzogc3RyaW5nID0gZW50aXR5LnJlZEl6byA/PyBcIlwiO1xuICAgIGNvbnN0IGljbzogc3RyaW5nID0gZW50aXR5LmljbyA/PyBcIlwiO1xuICAgIGNvbnN0IGVudGl0eU5hbWU6IHN0cmluZyA9IGVudGl0eS51cGxueU5hemV2ID8/IFwiXCI7XG4gICAgY29uc3QgY3VycmVudFNjaG9vbHM6IFNjaG9vbFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHNjaG9vbCBvZiBlbnRpdHkuc2tvbHlBWmFyaXplbmkgPz8gW10pIHtcbiAgICAgIGNvbnN0IHR5cGUgPVxuICAgICAgICBzY2hvb2wuZHJ1aCA9PT0gU0NIT09MX1RZUEVfS0lOREVSR0FSVEVOXG4gICAgICAgICAgPyBTY2hvb2xUeXBlLktpbmRlcmdhcnRlblxuICAgICAgICAgIDogc2Nob29sLmRydWggPT09IFNDSE9PTF9UWVBFX0VMRU1FTlRBUllcbiAgICAgICAgICA/IFNjaG9vbFR5cGUuRWxlbWVudGFyeVxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgaWYgKHR5cGUgPT09IG51bGwpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBjYXBhY2l0eUVudHJ5ID1cbiAgICAgICAgc2Nob29sLmthcGFjaXR5Py5maW5kKChrKSA9PiBrLm1lcm5hSmVkbm90a2EgPT09IFwiMDFcIikgPz9cbiAgICAgICAgc2Nob29sLmthcGFjaXR5Py5bMF07XG4gICAgICBjb25zdCBjYXBhY2l0eTogbnVtYmVyID0gY2FwYWNpdHlFbnRyeT8ubmVqdnlzc2lQb3ZvbGVueVBvY2V0ID8/IDA7XG4gICAgICBjb25zdCBhbGxQbGFjZXMgPSBzY2hvb2wubWlzdGFWeXVreSA/PyBbXTtcbiAgICAgIGNvbnN0IGxvY2F0aW9uc1dpdGhSdWlhbiA9IGFsbFBsYWNlcy5maWx0ZXIoXG4gICAgICAgIChwKSA9PiBwLmFkcmVzYT8ua29kUlVJQU4gIT0gbnVsbFxuICAgICAgKTtcbiAgICAgIC8vIFByZWZlciB0aGUgbWFpbiBidWlsZGluZyAoSURtaXN0YSBtYXRjaGVzIHNjaG9vbCBJWk8pLCBmYWxsIGJhY2sgdG8gZmlyc3QgYXZhaWxhYmxlXG4gICAgICBjb25zdCBtYWluUGxhY2UgPVxuICAgICAgICBsb2NhdGlvbnNXaXRoUnVpYW4uZmluZCgocCkgPT4gcC5JRG1pc3RhID09PSBzY2hvb2wuaXpvKSA/P1xuICAgICAgICBsb2NhdGlvbnNXaXRoUnVpYW5bMF07XG5cbiAgICAgIGNvbnN0IGxvY2F0aW9uczogU2Nob29sTG9jYXRpb25bXSA9IG1haW5QbGFjZVxuICAgICAgICA/IFt7IGFkZHJlc3NQb2ludElkOiBtYWluUGxhY2UuYWRyZXNhLmtvZFJVSUFOIH1dXG4gICAgICAgIDogW107XG5cbiAgICAgIGlmICghbWFpblBsYWNlICYmIGFsbFBsYWNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBhbGxQbGFjZXNbMF0uYWRyZXNhID8/IHt9O1xuICAgICAgICBjb25zdCBhZGRyZXNzUGFydHMgPSBbXG4gICAgICAgICAgYWRkci51bGljZSxcbiAgICAgICAgICBhZGRyLmNpc2xvRG9tb3ZuaT8udG9TdHJpbmcoKSxcbiAgICAgICAgICBhZGRyLm9iZWMsXG4gICAgICAgIF0uZmlsdGVyKEJvb2xlYW4pO1xuICAgICAgICBzY2hvb2xzV2l0aG91dFJ1aWFuLnB1c2goeyBpem86IHNjaG9vbC5pem8sIGFkZHJlc3M6IGFkZHJlc3NQYXJ0cywgdHlwZSB9KTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudFNjaG9vbHMucHVzaCh7XG4gICAgICAgIGl6bzogc2Nob29sLml6byxcbiAgICAgICAgbmFtZTogZW50aXR5TmFtZSB8fCBzY2hvb2wudXBsbnlOYXpldiB8fCBcIlwiLFxuICAgICAgICByZWRpem8sXG4gICAgICAgIGNhcGFjaXR5LFxuICAgICAgICB0eXBlLFxuICAgICAgICBsb2NhdGlvbnMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBzY2hvb2xzLnB1c2goLi4uY3VycmVudFNjaG9vbHMpO1xuXG4gICAgZm9yIChjb25zdCB6IG9mIGVudGl0eS56cml6b3ZhdGVsZSA/PyBbXSkge1xuICAgICAgbGV0IGZvdW5kZXJJY286IHN0cmluZztcbiAgICAgIGxldCBmb3VuZGVyTmFtZTogc3RyaW5nO1xuICAgICAgbGV0IGZvdW5kZXJUeXBlOiBzdHJpbmc7XG5cbiAgICAgIGlmICh6LmRydWhPc29ieSA9PT0gXCJQT1wiKSB7XG4gICAgICAgIGZvdW5kZXJJY28gPSB6LkljbyA/PyBcIlwiO1xuICAgICAgICBmb3VuZGVyTmFtZSA9IHoubmF6ZXZPc29ieSA/PyBcIlwiO1xuICAgICAgICBmb3VuZGVyVHlwZSA9IGdldENvcnJlY3RGb3VuZGVyVHlwZSh6LnByYXZuaUZvcm1hID8/IFwiXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRlckljbyA9IHouZGF0dW1OYXJvemVuaSA/PyBcIlwiO1xuICAgICAgICBmb3VuZGVyTmFtZSA9IHoubmF6ZXZPc29ieSA/PyBcIlwiO1xuICAgICAgICBmb3VuZGVyVHlwZSA9IGdldENvcnJlY3RGb3VuZGVyVHlwZShcIlwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZvdW5kZXJJY28gPT09IFwiXCIgfHwgZm91bmRlck5hbWUgPT09IFwiXCIpIHtcbiAgICAgICAgZm91bmRlckljbyA9IGljbztcbiAgICAgICAgZm91bmRlck5hbWUgPSBlbnRpdHlOYW1lO1xuICAgICAgICBmb3VuZGVyVHlwZSA9IFwiMjI0XCI7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50U2Nob29scy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGZvdW5kZXJOYW1lICsgZm91bmRlckljbztcbiAgICAgICAgaWYgKGZvdW5kZXJzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgZm91bmRlcnMuZ2V0KGtleSkuc2Nob29scy5wdXNoKC4uLmN1cnJlbnRTY2hvb2xzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3VuZGVycy5zZXQoa2V5LCB7XG4gICAgICAgICAgICBuYW1lOiBmb3VuZGVyTmFtZSxcbiAgICAgICAgICAgIGljbzogZm91bmRlckljbyxcbiAgICAgICAgICAgIG9yaWdpbmFsVHlwZTogcGFyc2VJbnQoZm91bmRlclR5cGUpLFxuICAgICAgICAgICAgbXVuaWNpcGFsaXR5VHlwZTogZ2V0TXVuaWNpcGFsaXR5VHlwZShmb3VuZGVyVHlwZSksXG4gICAgICAgICAgICBzY2hvb2xzOiBbLi4uY3VycmVudFNjaG9vbHNdLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgc2Nob29scywgZm91bmRlcnMsIHNjaG9vbHNXaXRob3V0UnVpYW4gfTtcbn07XG5cbmNvbnN0IGltcG9ydERhdGFUb0RiID0gYXN5bmMgKFxuICBvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zLFxuICBzYXZlRm91bmRlcnNUb0NzdjogYm9vbGVhbiA9IGZhbHNlLFxuICBzYXZlU2Nob29sc1dpdGhvdXRSdWlhblRvQ3N2OiBib29sZWFuID0gZmFsc2VcbikgPT4ge1xuICBjb25zdCB7IHNjaG9vbHMsIGZvdW5kZXJzLCBzY2hvb2xzV2l0aG91dFJ1aWFuIH0gPVxuICAgIGF3YWl0IHByb2Nlc3NTY2hvb2xSZWdpc3Rlckpzb25sZChvcHRpb25zKTtcblxuICBpZiAoc2F2ZUZvdW5kZXJzVG9Dc3YpIHtcbiAgICBjb25zdCBjc3ZGaWxlID0gXCJmb3VuZGVycy5jc3ZcIjtcblxuICAgIGlmIChleGlzdHNTeW5jKGNzdkZpbGUpKSB7XG4gICAgICBybVN5bmMoY3N2RmlsZSk7XG4gICAgfVxuXG4gICAgdmFyIGNzdiA9IGNyZWF0ZVdyaXRlU3RyZWFtKGNzdkZpbGUsIHtcbiAgICAgIGZsYWdzOiBcImFcIixcbiAgICB9KTtcbiAgICBjc3Yud3JpdGUoXCJJxIxPO1rFmWl6b3ZhdGVsO1Byw6F2bsOtIGZvcm1hO1BvxI1ldCDFoWtvbDvFoGtvbHlcXG5cIik7XG4gICAgZm91bmRlcnMuZm9yRWFjaCgoZm91bmRlcikgPT4ge1xuICAgICAgY3N2LndyaXRlKFxuICAgICAgICBgIyR7Zm91bmRlci5pY299OyR7Zm91bmRlci5uYW1lfTske2ZvdW5kZXIub3JpZ2luYWxUeXBlfTske1xuICAgICAgICAgIGZvdW5kZXIuc2Nob29scy5sZW5ndGhcbiAgICAgICAgfTske2ZvdW5kZXIuc2Nob29scy5tYXAoKHNjaG9vbCkgPT4gc2Nob29sLm5hbWUpLmpvaW4oXCItLS1cIil9XFxuYFxuICAgICAgKTtcbiAgICB9KTtcbiAgICBjc3YuZW5kKCk7XG4gIH1cblxuICBpZiAoc2F2ZVNjaG9vbHNXaXRob3V0UnVpYW5Ub0Nzdikge1xuICAgIGNvbnN0IGNzdkZpbGUgPSBcInNjaG9vbHNXaXRob3V0UnVpYW4uY3N2XCI7XG5cbiAgICBpZiAoZXhpc3RzU3luYyhjc3ZGaWxlKSkge1xuICAgICAgcm1TeW5jKGNzdkZpbGUpO1xuICAgIH1cblxuICAgIHZhciBjc3YgPSBjcmVhdGVXcml0ZVN0cmVhbShjc3ZGaWxlLCB7XG4gICAgICBmbGFnczogXCJhXCIsXG4gICAgfSk7XG4gICAgY3N2LndyaXRlKFwiSVpPO0plIG1hdGXFmXNrw6E7SmUgesOha2xhZG7DrTthZHJlc2ExO2FkcmVzYTI7YWRyZXNhM1xcblwiKTtcbiAgICBzY2hvb2xzV2l0aG91dFJ1aWFuLmZvckVhY2goKHNjaG9vbEFkZHJlc3MpID0+IHtcbiAgICAgIGNzdi53cml0ZShcbiAgICAgICAgYCMke3NjaG9vbEFkZHJlc3MuaXpvfTske1xuICAgICAgICAgIHNjaG9vbEFkZHJlc3MudHlwZSA9PT0gU2Nob29sVHlwZS5LaW5kZXJnYXJ0ZW4gPyBcIlRSVUVcIiA6IFwiRkFMU0VcIlxuICAgICAgICB9OyR7XG4gICAgICAgICAgc2Nob29sQWRkcmVzcy50eXBlID09PSBTY2hvb2xUeXBlLkVsZW1lbnRhcnkgPyBcIlRSVUVcIiA6IFwiRkFMU0VcIlxuICAgICAgICB9OyR7c2Nob29sQWRkcmVzcy5hZGRyZXNzLmpvaW4oXCI7XCIpfVxcbmBcbiAgICAgICk7XG4gICAgfSk7XG4gICAgY3N2LmVuZCgpO1xuICB9XG5cbiAgY29uc3Qga25leCA9IGdldEtuZXhEYigpO1xuICBjb25zdCBzY2hvb2xzQmVmb3JlID0gKGF3YWl0IGtuZXgoXCJzY2hvb2xcIikuY291bnQoXCJpem8gYXMgY291bnRcIikuZmlyc3QoKSkuY291bnQgYXMgbnVtYmVyO1xuICBjb25zdCBmb3VuZGVyc0JlZm9yZSA9IChhd2FpdCBrbmV4KFwiZm91bmRlclwiKS5jb3VudChcImlkIGFzIGNvdW50XCIpLmZpcnN0KCkpLmNvdW50IGFzIG51bWJlcjtcblxuICAvLyBDb21wdXRlIGNoYW5nZSBzdGF0cyBiZWZvcmUgaW5zZXJ0aW5nICh1c2VzIHNhbWUgbG9naWMgYXMgaW5zZXJ0U2Nob29scylcbiAgY29uc3QgZXhpc3RpbmdTbmFwOiB7IGl6bzogc3RyaW5nOyBuYW1lOiBzdHJpbmc7IGNhcGFjaXR5OiBudW1iZXI7IGFkZHJlc3NfcG9pbnRfaWQ6IG51bWJlciB8IG51bGwgfVtdID1cbiAgICBhd2FpdCBrbmV4KFwic2Nob29sXCIpXG4gICAgICAubGVmdEpvaW4oXCJzY2hvb2xfbG9jYXRpb25cIiwgXCJzY2hvb2wuaXpvXCIsIFwic2Nob29sX2xvY2F0aW9uLnNjaG9vbF9pem9cIilcbiAgICAgIC5zZWxlY3QoXCJzY2hvb2wuaXpvXCIsIFwic2Nob29sLm5hbWVcIiwgXCJzY2hvb2wuY2FwYWNpdHlcIiwgXCJzY2hvb2xfbG9jYXRpb24uYWRkcmVzc19wb2ludF9pZFwiKTtcbiAgY29uc3QgZXhpc3RpbmdTbmFwTWFwID0gbmV3IE1hcChleGlzdGluZ1NuYXAubWFwKChyKSA9PiBbci5pem8sIHJdKSk7XG4gIGNvbnN0IHN0YXRzRmllbGRVcGRhdGVzID0gc2Nob29scy5maWx0ZXIoKHMpID0+IHtcbiAgICBjb25zdCByb3cgPSBleGlzdGluZ1NuYXBNYXAuZ2V0KHMuaXpvKTtcbiAgICByZXR1cm4gcm93ICYmIChyb3cubmFtZSAhPT0gcy5uYW1lIHx8IHJvdy5jYXBhY2l0eSAhPT0gcy5jYXBhY2l0eSk7XG4gIH0pLmxlbmd0aDtcbiAgY29uc3Qgc3RhdHNMb2NhdGlvblVwZGF0ZXMgPSBzY2hvb2xzLmZpbHRlcigocykgPT4ge1xuICAgIGNvbnN0IHJvdyA9IGV4aXN0aW5nU25hcE1hcC5nZXQocy5pem8pO1xuICAgIGNvbnN0IG5ld1J1aWFucyA9IHMubG9jYXRpb25zLm1hcCgobCkgPT4gbC5hZGRyZXNzUG9pbnRJZCk7XG4gICAgcmV0dXJuIHJvdyAmJiByb3cuYWRkcmVzc19wb2ludF9pZCAhPT0gbnVsbCAmJiBuZXdSdWlhbnMubGVuZ3RoID4gMCAmJiAhbmV3UnVpYW5zLmluY2x1ZGVzKHJvdy5hZGRyZXNzX3BvaW50X2lkKTtcbiAgfSkubGVuZ3RoO1xuXG4gIGF3YWl0IGluc2VydFNjaG9vbHMoc2Nob29scyk7XG4gIGF3YWl0IGluc2VydEZvdW5kZXJzKEFycmF5LmZyb20oZm91bmRlcnMudmFsdWVzKCkpKTtcblxuICBjb25zdCBzY2hvb2xzQWZ0ZXIgPSAoYXdhaXQga25leChcInNjaG9vbFwiKS5jb3VudChcIml6byBhcyBjb3VudFwiKS5maXJzdCgpKS5jb3VudCBhcyBudW1iZXI7XG4gIGNvbnN0IGZvdW5kZXJzQWZ0ZXIgPSAoYXdhaXQga25leChcImZvdW5kZXJcIikuY291bnQoXCJpZCBhcyBjb3VudFwiKS5maXJzdCgpKS5jb3VudCBhcyBudW1iZXI7XG5cbiAgY29uc3Qga2luZGVyZ2FydGVucyA9IHNjaG9vbHMuZmlsdGVyKChzKSA9PiBzLnR5cGUgPT09IFNjaG9vbFR5cGUuS2luZGVyZ2FydGVuKS5sZW5ndGg7XG4gIGNvbnN0IGVsZW1lbnRhcnkgPSBzY2hvb2xzLmZpbHRlcigocykgPT4gcy50eXBlID09PSBTY2hvb2xUeXBlLkVsZW1lbnRhcnkpLmxlbmd0aDtcblxuICBjb25zb2xlLmxvZyhgXFxuPT09IFNjaG9vbCBzeW5jIHN0YXRpc3RpY3MgPT09YCk7XG4gIGNvbnNvbGUubG9nKGBTY2hvb2xzIHBhcnNlZDogICAgICAgICAke3NjaG9vbHMubGVuZ3RofSAoJHtraW5kZXJnYXJ0ZW5zfSBraW5kZXJnYXJ0ZW5zLCAke2VsZW1lbnRhcnl9IGVsZW1lbnRhcnkpYCk7XG4gIGNvbnNvbGUubG9nKGBGb3VuZGVycyBwYXJzZWQ6ICAgICAgICAke2ZvdW5kZXJzLnNpemV9YCk7XG4gIGNvbnNvbGUubG9nKGBOZXcgc2Nob29scyBpbnNlcnRlZDogICAke3NjaG9vbHNBZnRlciAtIHNjaG9vbHNCZWZvcmV9YCk7XG4gIGNvbnNvbGUubG9nKGBOZXcgZm91bmRlcnMgaW5zZXJ0ZWQ6ICAke2ZvdW5kZXJzQWZ0ZXIgLSBmb3VuZGVyc0JlZm9yZX1gKTtcbiAgY29uc29sZS5sb2coYEZpZWxkIHVwZGF0ZXM6ICAgICAgICAgICR7c3RhdHNGaWVsZFVwZGF0ZXN9IChuYW1lL2NhcGFjaXR5IGNoYW5nZWQpYCk7XG4gIGNvbnNvbGUubG9nKGBMb2NhdGlvbiB1cGRhdGVzOiAgICAgICAke3N0YXRzTG9jYXRpb25VcGRhdGVzfSAoZmlyc3QgbG9jYXRpb24gY2hhbmdlZClgKTtcbiAgY29uc29sZS5sb2coYFRvdGFsIHNjaG9vbHMgaW4gREI6ICAgICR7c2Nob29sc0FmdGVyfWApO1xuICBjb25zb2xlLmxvZyhgVG90YWwgZm91bmRlcnMgaW4gREI6ICAgJHtmb3VuZGVyc0FmdGVyfWApO1xufTtcblxuY29uc3QgZ2V0SnNvbmxkRmlsZVBhdGggPSAob3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gam9pbihvcHRpb25zLnRtcERpciwgb3B0aW9ucy5zY2hvb2xzSnNvbmxkRmlsZU5hbWUpO1xufTtcblxuZXhwb3J0IGNvbnN0IGRvd25sb2FkQW5kSW1wb3J0U2Nob29scyA9IGFzeW5jIChcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwgPSB7fSxcbiAgc2F2ZUZvdW5kZXJzVG9Dc3Y6IGJvb2xlYW4gPSBmYWxzZSxcbiAgc2F2ZVNjaG9vbHNXaXRob3V0UnVpYW5Ub0NzdjogYm9vbGVhbiA9IGZhbHNlXG4pID0+IHtcbiAgYXdhaXQgcnVuU3luY1BhcnQoU3luY1BhcnQuU2Nob29scywgW1N5bmNQYXJ0LkFkZHJlc3NQb2ludHNdLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcnVuT3B0aW9ucyA9IHByZXBhcmVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgYXdhaXQgZG93bmxvYWRKc29ubGQocnVuT3B0aW9ucyk7XG4gICAgYXdhaXQgaW1wb3J0RGF0YVRvRGIoXG4gICAgICBydW5PcHRpb25zLFxuICAgICAgc2F2ZUZvdW5kZXJzVG9Dc3YsXG4gICAgICBzYXZlU2Nob29sc1dpdGhvdXRSdWlhblRvQ3N2XG4gICAgKTtcbiAgICBkZWxldGVTY2hvb2xzSnNvbmxkRmlsZShydW5PcHRpb25zKTtcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZGVsZXRlU2Nob29sc0pzb25sZEZpbGUgPSAoXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNQYXJ0aWFsID0ge31cbikgPT4ge1xuICBjb25zdCBydW5PcHRpb25zID0gcHJlcGFyZU9wdGlvbnMob3B0aW9ucyk7XG5cbiAgaWYgKGV4aXN0c1N5bmMoZ2V0SnNvbmxkRmlsZVBhdGgocnVuT3B0aW9ucykpKSB7XG4gICAgcm1TeW5jKGdldEpzb25sZEZpbGVQYXRoKHJ1bk9wdGlvbnMpKTtcbiAgfVxufTtcbiJdfQ==
@@ -1,2 +1,2 @@
1
- import { OpenDataSyncOptionsPartial } from "../utils/helpers";
2
- export declare const downloadAndImportStreets: (options?: OpenDataSyncOptionsPartial, noCache?: boolean) => Promise<void>;
1
+ import { OpenDataSyncOptionsPartial } from "../utils/helpers";
2
+ export declare const downloadAndImportStreets: (options?: OpenDataSyncOptionsPartial, noCache?: boolean) => Promise<void>;