text-to-map 1.1.28 → 1.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/address-points.js +1 -0
- package/dist/bin/cities.js +1 -0
- package/dist/bin/clear-all.js +8 -18
- package/dist/bin/constants.js +1 -0
- package/dist/bin/generate-syntax-diagrams.js +1 -0
- package/dist/bin/init-db.js +5 -15
- package/dist/bin/knex.js +6 -16
- package/dist/bin/parse-ordinance.js +60 -71
- package/dist/bin/polygons.js +23 -32
- package/dist/bin/regions.js +1 -0
- package/dist/bin/schools.js +1 -0
- package/dist/bin/streets.js +1 -0
- package/dist/bin/sync-all.js +1 -0
- package/dist/db/address-points.js +43 -54
- package/dist/db/cities.d.ts +5 -3
- package/dist/db/cities.js +56 -25
- package/dist/db/db.js +24 -32
- package/dist/db/founders.js +104 -91
- package/dist/db/meta.js +12 -20
- package/dist/db/migrations/20230704125715_initial.js +291 -303
- package/dist/db/migrations/20230731232915_city_positions.js +9 -21
- package/dist/db/migrations/20240106224603_city_polygon.js +7 -19
- package/dist/db/migrations/20240320200534_district_polygon.js +11 -0
- package/dist/db/migrations/20240729211323_ordinance_city.js +11 -0
- package/dist/db/regions.js +20 -28
- package/dist/db/schools.d.ts +1 -1
- package/dist/db/schools.js +18 -23
- package/dist/db/street-sync.js +13 -21
- package/dist/db/sync-log.js +25 -33
- package/dist/db/types.d.ts +3 -1
- package/dist/db/types.js +2 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -22
- package/dist/open-data-sync/address-points.js +21 -29
- package/dist/open-data-sync/cities.js +10 -18
- package/dist/open-data-sync/common.js +8 -16
- package/dist/open-data-sync/regions.js +13 -21
- package/dist/open-data-sync/schools.js +20 -28
- package/dist/open-data-sync/streets.js +40 -39
- package/dist/smd-to-csv/json-to-csv.js +1 -0
- package/dist/smd-to-csv/ordinance-to-csv-rules.js +4 -12
- package/dist/smd-to-csv/txt-to-json.js +59 -69
- package/dist/street-markdown/municipality.js +26 -28
- package/dist/street-markdown/polygons.d.ts +7 -4
- package/dist/street-markdown/polygons.js +190 -44
- package/dist/street-markdown/roman-numerals.js +1 -0
- package/dist/street-markdown/smd-line-parser.js +6 -8
- package/dist/street-markdown/smd-parser.js +2 -2
- package/dist/street-markdown/smd.d.ts +7 -1
- package/dist/street-markdown/smd.js +190 -164
- package/dist/street-markdown/token-definition.js +1 -0
- package/dist/street-markdown/types.d.ts +21 -11
- package/dist/street-markdown/types.js +3 -2
- package/dist/utils/atom.js +9 -17
- package/dist/utils/helpers.d.ts +3 -1
- package/dist/utils/helpers.js +12 -4
- package/dist/utils/jtsk2wgs84.js +1 -0
- package/package.json +5 -1
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import AdmZip from "adm-zip";
|
|
11
2
|
import { parse } from "csv-parse";
|
|
12
3
|
import { createReadStream, createWriteStream, readdirSync, rmSync } from "fs";
|
|
@@ -21,14 +12,14 @@ import { getLatestUrlFromAtomFeed } from "../utils/atom";
|
|
|
21
12
|
import { prepareOptions, } from "../utils/helpers";
|
|
22
13
|
import { runSyncPart } from "./common";
|
|
23
14
|
const maxBufferSize = 1000;
|
|
24
|
-
const downloadAndUnzip = (url, options) =>
|
|
15
|
+
const downloadAndUnzip = async (url, options) => {
|
|
25
16
|
const zipFilePath = join(options.tmpDir, options.addressPointsZipFileName);
|
|
26
17
|
console.log("Downloading a large ZIP file with RUIAN data (~65 MB)...");
|
|
27
|
-
const response =
|
|
18
|
+
const response = await fetch(url);
|
|
28
19
|
if (response.status !== 200) {
|
|
29
20
|
throw new Error(`The ZIP file could not be downloaded. HTTP Code: ${response.status}`);
|
|
30
21
|
}
|
|
31
|
-
|
|
22
|
+
await pipeline(response.body, createWriteStream(zipFilePath));
|
|
32
23
|
console.log("Finished downloading.");
|
|
33
24
|
const zip = new AdmZip(zipFilePath);
|
|
34
25
|
console.log(`Starting to unzip CSV files to '${options.tmpDir}'`);
|
|
@@ -36,8 +27,8 @@ const downloadAndUnzip = (url, options) => __awaiter(void 0, void 0, void 0, fun
|
|
|
36
27
|
console.log("Unzip completed.");
|
|
37
28
|
rmSync(zipFilePath);
|
|
38
29
|
console.log("Removed the ZIP file.");
|
|
39
|
-
}
|
|
40
|
-
const importDataToDb = (options) =>
|
|
30
|
+
};
|
|
31
|
+
const importDataToDb = async (options) => {
|
|
41
32
|
const extractionFolder = getExtractionFolder(options);
|
|
42
33
|
const files = readdirSync(extractionFolder);
|
|
43
34
|
let total = 0;
|
|
@@ -45,28 +36,29 @@ const importDataToDb = (options) => __awaiter(void 0, void 0, void 0, function*
|
|
|
45
36
|
console.log("Initiating import of RUIAN data to search DB (~3 million rows to be imported).");
|
|
46
37
|
for (const file of files) {
|
|
47
38
|
const rows = [];
|
|
48
|
-
const parseStream = parse({ delimiter: ";", fromLine: 2 }).on("data", (data) =>
|
|
39
|
+
const parseStream = parse({ delimiter: ";", fromLine: 2 }).on("data", async (data) => {
|
|
49
40
|
rows.push(data);
|
|
50
|
-
})
|
|
51
|
-
|
|
41
|
+
});
|
|
42
|
+
await pipeline(createReadStream(join(extractionFolder, file)), iconv.decodeStream("win1250"), parseStream);
|
|
52
43
|
const chunks = chunk(rows, maxBufferSize);
|
|
53
|
-
|
|
54
|
-
total +=
|
|
44
|
+
await Promise.all(chunks.map(async (chunk) => {
|
|
45
|
+
total += await commitAddressPoints(chunk);
|
|
55
46
|
if (total - next >= 100000) {
|
|
56
47
|
next += 100000;
|
|
57
48
|
console.log(`Total imported rows: ${next}`);
|
|
58
49
|
}
|
|
59
|
-
}))
|
|
50
|
+
}));
|
|
60
51
|
}
|
|
61
52
|
console.log(`Import completed. Total imported rows: ${total}`);
|
|
62
|
-
}
|
|
53
|
+
};
|
|
63
54
|
const getExtractionFolder = (options) => join(options.tmpDir, options.addressPointsCsvFolderName);
|
|
64
|
-
export const downloadAndImportAddressPoints = (options = {}) =>
|
|
65
|
-
|
|
55
|
+
export const downloadAndImportAddressPoints = async (options = {}) => {
|
|
56
|
+
await runSyncPart(SyncPart.AddressPoints, [], async () => {
|
|
66
57
|
const completeOptions = prepareOptions(options);
|
|
67
|
-
const datasetFeedLink =
|
|
68
|
-
const zipUrl =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
})
|
|
72
|
-
}
|
|
58
|
+
const datasetFeedLink = await getLatestUrlFromAtomFeed(completeOptions.addressPointsAtomUrl);
|
|
59
|
+
const zipUrl = await getLatestUrlFromAtomFeed(datasetFeedLink);
|
|
60
|
+
await downloadAndUnzip(zipUrl, completeOptions);
|
|
61
|
+
await importDataToDb(completeOptions);
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkcmVzcy1wb2ludHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3Blbi1kYXRhLXN5bmMvYWRkcmVzcy1wb2ludHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sU0FBUyxDQUFDO0FBQzdCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDOUUsT0FBTyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEtBQUssTUFBTSxjQUFjLENBQUM7QUFDakMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBRTNCLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxFQUM1QixHQUFXLEVBQ1gsT0FBNEIsRUFDYixFQUFFO0lBQ2pCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBRTNFLE9BQU8sQ0FBQyxHQUFHLENBQUMsMERBQTBELENBQUMsQ0FBQztJQUN4RSxNQUFNLFFBQVEs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QVEsQ0FBQyxhQUFhLEVBQUUsRUFBRSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZELE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRCxNQUFNLGVBQWUsR0FBRyxNQUFNLHdCQUF3QixDQUNwRCxlQUFlLENBQUMsb0JBQW9CLENBQ3JDLENBQUM7UUFDRixNQUFNLE1BQU0sR0FBRyxNQUFNLHdCQUF3QixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sZ0JBQWdCLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3hDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFkbVppcCBmcm9tIFwiYWRtLXppcFwiO1xyXG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gXCJjc3YtcGFyc2VcIjtcclxuaW1wb3J0IHsgY3JlYXRlUmVhZFN0cmVhbSwgY3JlYXRlV3JpdGVTdHJlYW0sIHJlYWRkaXJTeW5jLCBybVN5bmMgfSBmcm9tIFwiZnNcIjtcclxuaW1wb3J0IGljb252IGZyb20gXCJpY29udi1saXRlXCI7XHJcbmltcG9ydCBmZXRjaCBmcm9tIFwibm9kZS1mZXRjaFwiO1xyXG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0IHsgcGlwZWxpbmUgfSBmcm9tIFwic3RyZWFtL3Byb21pc2VzXCI7XHJcbmltcG9ydCBjaHVuayBmcm9tIFwibG9kYXNoL2NodW5rXCI7XHJcbmltcG9ydCB7IGNvbW1pdEFkZHJlc3NQb2ludHMgfSBmcm9tIFwiLi4vZGIvYWRkcmVzcy1wb2ludHNcIjtcclxuaW1wb3J0IHsgU3luY1BhcnQgfSBmcm9tIFwiLi4vZGIvdHlwZXNcIjtcclxuaW1wb3J0IHsgZ2V0TGF0ZXN0VXJsRnJvbUF0b21GZWVkIH0gZnJvbSBcIi4uL3V0aWxzL2F0b21cIjtcclxuaW1wb3J0IHtcclxuICBPcGVuRGF0YVN5bmNPcHRpb25zLFxyXG4gIE9wZW5EYXRhU3luY09wdGlvbnNQYXJ0aWFsLFxyXG4gIHByZXBhcmVPcHRpb25zLFxyXG59IGZyb20gXCIuLi91dGlscy9oZWxwZXJzXCI7XHJcbmltcG9ydCB7IHJ1blN5bmNQYXJ0IH0gZnJvbSBcIi4vY29tbW9uXCI7XHJcblxyXG5jb25zdCBtYXhCdWZmZXJTaXplID0gMTAwMDtcclxuXHJcbmNvbnN0IGRvd25sb2FkQW5kVW56aXAgPSBhc3luYyAoXHJcbiAgdXJsOiBzdHJpbmcsXHJcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1xyXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcclxuICBjb25zdCB6aXBGaWxlUGF0aCA9IGpvaW4ob3B0aW9ucy50bXBEaXIsIG9wdGlvbnMuYWRkcmVzc1BvaW50c1ppcEZpbGVOYW1lKTtcclxuXHJcbiAgY29uc29sZS5sb2coXCJEb3dubG9hZGluZyBhIGxhcmdlIFpJUCBmaWxlIHdpdGggUlVJQU4gZGF0YSAofjY1IE1CKS4uLlwiKTtcclxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XHJcbiAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgIGBUaGUgWklQIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQuIEhUVFAgQ29kZTogJHtyZXNwb25zZS5zdGF0dXN9YFxyXG4gICAgKTtcclxuICB9XHJcbiAgYXdhaXQgcGlwZWxpbmUocmVzcG9uc2UuYm9keSwgY3JlYXRlV3JpdGVTdHJlYW0oemlwRmlsZVBhdGgpKTtcclxuXHJcbiAgY29uc29sZS5sb2coXCJGaW5pc2hlZCBkb3dubG9hZGluZy5cIik7XHJcbiAgY29uc3QgemlwID0gbmV3IEFkbVppcCh6aXBGaWxlUGF0aCk7XHJcblxyXG4gIGNvbnNvbGUubG9nKGBTdGFydGluZyB0byB1bnppcCBDU1YgZmlsZXMgdG8gJyR7b3B0aW9ucy50bXBEaXJ9J2ApO1xyXG4gIHppcC5leHRyYWN0QWxsVG8ob3B0aW9ucy50bXBEaXIsIHRydWUpO1xyXG4gIGNvbnNvbGUubG9nKFwiVW56aXAgY29tcGxldGVkLlwiKTtcclxuXHJcbiAgcm1TeW5jKHppcEZpbGVQYXRoKTtcclxuICBjb25zb2xlLmxvZyhcIlJlbW92ZWQgdGhlIFpJUCBmaWxlLlwiKTtcclxufTtcclxuXHJcbmNvbnN0IGltcG9ydERhdGFUb0RiID0gYXN5bmMgKG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnMpID0+IHtcclxuICBjb25zdCBleHRyYWN0aW9uRm9sZGVyID0gZ2V0RXh0cmFjdGlvbkZvbGRlcihvcHRpb25zKTtcclxuXHJcbiAgY29uc3QgZmlsZXMgPSByZWFkZGlyU3luYyhleHRyYWN0aW9uRm9sZGVyKTtcclxuXHJcbiAgbGV0IHRvdGFsID0gMDtcclxuICBsZXQgbmV4dCA9IDA7XHJcblxyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgXCJJbml0aWF0aW5nIGltcG9ydCBvZiBSVUlBTiBkYXRhIHRvIHNlYXJjaCBEQiAofjMgbWlsbGlvbiByb3dzIHRvIGJlIGltcG9ydGVkKS5cIlxyXG4gICk7XHJcblxyXG4gIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xyXG4gICAgY29uc3Qgcm93czogc3RyaW5nW11bXSA9IFtdO1xyXG4gICAgY29uc3QgcGFyc2VTdHJlYW0gPSBwYXJzZSh7IGRlbGltaXRlcjogXCI7XCIsIGZyb21MaW5lOiAyIH0pLm9uKFxyXG4gICAgICBcImRhdGFcIixcclxuICAgICAgYXN5bmMgKGRhdGEpID0+IHtcclxuICAgICAgICByb3dzLnB1c2goZGF0YSk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcblxyXG4gICAgYXdhaXQgcGlwZWxpbmUoXHJcbiAgICAgIGNyZWF0ZVJlYWRTdHJlYW0oam9pbihleHRyYWN0aW9uRm9sZGVyLCBmaWxlKSksXHJcbiAgICAgIGljb252LmRlY29kZVN0cmVhbShcIndpbjEyNTBcIiksXHJcbiAgICAgIHBhcnNlU3RyZWFtXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGNodW5rcyA9IGNodW5rKHJvd3MsIG1heEJ1ZmZlclNpemUpO1xyXG5cclxuICAgIGF3YWl0IFByb21pc2UuYWxsKFxyXG4gICAgICBjaHVua3MubWFwKGFzeW5jIChjaHVuaykgPT4ge1xyXG4gICAgICAgIHRvdGFsICs9IGF3YWl0IGNvbW1pdEFkZHJlc3NQb2ludHMoY2h1bmspO1xyXG5cclxuICAgICAgICBpZiAodG90YWwgLSBuZXh0ID49IDEwMDAwMCkge1xyXG4gICAgICAgICAgbmV4dCArPSAxMDAwMDA7XHJcbiAgICAgICAgICBjb25zb2xlLmxvZyhgVG90YWwgaW1wb3J0ZWQgcm93czogJHtuZXh0fWApO1xyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBjb25zb2xlLmxvZyhgSW1wb3J0IGNvbXBsZXRlZC4gVG90YWwgaW1wb3J0ZWQgcm93czogJHt0b3RhbH1gKTtcclxufTtcclxuXHJcbmNvbnN0IGdldEV4dHJhY3Rpb25Gb2xkZXIgPSAob3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9ucykgPT5cclxuICBqb2luKG9wdGlvbnMudG1wRGlyLCBvcHRpb25zLmFkZHJlc3NQb2ludHNDc3ZGb2xkZXJOYW1lKTtcclxuXHJcbmV4cG9ydCBjb25zdCBkb3dubG9hZEFuZEltcG9ydEFkZHJlc3NQb2ludHMgPSBhc3luYyAoXHJcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwgPSB7fVxyXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcclxuICBhd2FpdCBydW5TeW5jUGFydChTeW5jUGFydC5BZGRyZXNzUG9pbnRzLCBbXSwgYXN5bmMgKCkgPT4ge1xyXG4gICAgY29uc3QgY29tcGxldGVPcHRpb25zID0gcHJlcGFyZU9wdGlvbnMob3B0aW9ucyk7XHJcbiAgICBjb25zdCBkYXRhc2V0RmVlZExpbmsgPSBhd2FpdCBnZXRMYXRlc3RVcmxGcm9tQXRvbUZlZWQoXHJcbiAgICAgIGNvbXBsZXRlT3B0aW9ucy5hZGRyZXNzUG9pbnRzQXRvbVVybFxyXG4gICAgKTtcclxuICAgIGNvbnN0IHppcFVybCA9IGF3YWl0IGdldExhdGVzdFVybEZyb21BdG9tRmVlZChkYXRhc2V0RmVlZExpbmspO1xyXG4gICAgYXdhaXQgZG93bmxvYWRBbmRVbnppcCh6aXBVcmwsIGNvbXBsZXRlT3B0aW9ucyk7XHJcbiAgICBhd2FpdCBpbXBvcnREYXRhVG9EYihjb21wbGV0ZU9wdGlvbnMpO1xyXG4gIH0pO1xyXG59O1xyXG4iXX0=
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { parse } from "csv-parse";
|
|
11
2
|
import iconv from "iconv-lite";
|
|
12
3
|
import { pipeline } from "stream/promises";
|
|
@@ -17,7 +8,7 @@ import { insertCityPositions } from "../db/cities";
|
|
|
17
8
|
import { SyncPart } from "../db/types";
|
|
18
9
|
import { prepareOptions, } from "../utils/helpers";
|
|
19
10
|
import { runSyncPart } from "./common";
|
|
20
|
-
const importDataToDb = (options) =>
|
|
11
|
+
const importDataToDb = async (options) => {
|
|
21
12
|
console.log("Starting to parse CSV file...");
|
|
22
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
23
14
|
const __dirname = dirname(__filename);
|
|
@@ -27,14 +18,15 @@ const importDataToDb = (options) => __awaiter(void 0, void 0, void 0, function*
|
|
|
27
18
|
const parseStream = parse({ delimiter: ",", fromLine: 2 }).on("data", (data) => {
|
|
28
19
|
rows.push(data);
|
|
29
20
|
});
|
|
30
|
-
|
|
21
|
+
await pipeline(csvStream, iconv.decodeStream("utf-8"), parseStream);
|
|
31
22
|
console.log("Parsing completed. Starting to import data to DB...");
|
|
32
|
-
|
|
23
|
+
await insertCityPositions(rows);
|
|
33
24
|
console.log(`Import completed. Total imported rows: ${rows.length}`);
|
|
34
|
-
}
|
|
35
|
-
export const importCities = (options = {}) =>
|
|
36
|
-
|
|
25
|
+
};
|
|
26
|
+
export const importCities = async (options = {}) => {
|
|
27
|
+
await runSyncPart(SyncPart.Regions, [], async () => {
|
|
37
28
|
const completeOptions = prepareOptions(options);
|
|
38
|
-
|
|
39
|
-
})
|
|
40
|
-
}
|
|
29
|
+
await importDataToDb(completeOptions);
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2l0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29wZW4tZGF0YS1zeW5jL2NpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkMsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkMsTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLE9BQTRCLEVBQUUsRUFBRTtJQUM1RCxPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixDQUFDLENBQUM7SUFFN0MsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbEQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXRDLCtFQUErRTtJQUMvRSxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7SUFFNUUsTUFBTSxJQUFJLEdBQWUsRUFBRSxDQUFDO0lBQzVCLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUMzRCxNQUFNLEVBQ04sQ0FBQyxJQUFjLEVBQUUsRUFBRTtRQUNqQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xCLENBQUMsQ0FDRixDQUFDO0lBRUYsTUFBTSxRQUFRLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFFcEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO0lBRW5FLE1BQU0sbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFDL0IsVUFBc0MsRUFBRSxFQUN6QixFQUFFO0lBQ2pCLE1BQU0sV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2pELE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRCxNQUFNLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN4QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHBhcnNlIH0gZnJvbSBcImNzdi1wYXJzZVwiO1xyXG5pbXBvcnQgaWNvbnYgZnJvbSBcImljb252LWxpdGVcIjtcclxuaW1wb3J0IHsgcGlwZWxpbmUgfSBmcm9tIFwic3RyZWFtL3Byb21pc2VzXCI7XHJcblxyXG5pbXBvcnQgeyBjcmVhdGVSZWFkU3RyZWFtIH0gZnJvbSBcImZzXCI7XHJcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwicGF0aFwiO1xyXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcInVybFwiO1xyXG5pbXBvcnQgeyBpbnNlcnRDaXR5UG9zaXRpb25zIH0gZnJvbSBcIi4uL2RiL2NpdGllc1wiO1xyXG5pbXBvcnQgeyBTeW5jUGFydCB9IGZyb20gXCIuLi9kYi90eXBlc1wiO1xyXG5pbXBvcnQge1xyXG4gIE9wZW5EYXRhU3luY09wdGlvbnMsXHJcbiAgT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwsXHJcbiAgcHJlcGFyZU9wdGlvbnMsXHJcbn0gZnJvbSBcIi4uL3V0aWxzL2hlbHBlcnNcIjtcclxuaW1wb3J0IHsgcnVuU3luY1BhcnQgfSBmcm9tIFwiLi9jb21tb25cIjtcclxuXHJcbmNvbnN0IGltcG9ydERhdGFUb0RiID0gYXN5bmMgKG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnMpID0+IHtcclxuICBjb25zb2xlLmxvZyhcIlN0YXJ0aW5nIHRvIHBhcnNlIENTViBmaWxlLi4uXCIpO1xyXG5cclxuICBjb25zdCBfX2ZpbGVuYW1lID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpO1xyXG4gIGNvbnN0IF9fZGlybmFtZSA9IGRpcm5hbWUoX19maWxlbmFtZSk7XHJcblxyXG4gIC8vIHNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tLzMzYmNkZC9zb3VyYWRuaWNlLW1lc3QvYmxvYi9tYXN0ZXIvc291cmFkbmljZS5jc3ZcclxuICBjb25zdCBjc3ZTdHJlYW0gPSBjcmVhdGVSZWFkU3RyZWFtKGpvaW4oX19kaXJuYW1lLCBcIi4uXCIsIFwic291cmFkbmljZS5jc3ZcIikpO1xyXG5cclxuICBjb25zdCByb3dzOiBzdHJpbmdbXVtdID0gW107XHJcbiAgY29uc3QgcGFyc2VTdHJlYW0gPSBwYXJzZSh7IGRlbGltaXRlcjogXCIsXCIsIGZyb21MaW5lOiAyIH0pLm9uKFxyXG4gICAgXCJkYXRhXCIsXHJcbiAgICAoZGF0YTogc3RyaW5nW10pID0+IHtcclxuICAgICAgcm93cy5wdXNoKGRhdGEpO1xyXG4gICAgfVxyXG4gICk7XHJcblxyXG4gIGF3YWl0IHBpcGVsaW5lKGNzdlN0cmVhbSwgaWNvbnYuZGVjb2RlU3RyZWFtKFwidXRmLThcIiksIHBhcnNlU3RyZWFtKTtcclxuXHJcbiAgY29uc29sZS5sb2coXCJQYXJzaW5nIGNvbXBsZXRlZC4gU3RhcnRpbmcgdG8gaW1wb3J0IGRhdGEgdG8gREIuLi5cIik7XHJcblxyXG4gIGF3YWl0IGluc2VydENpdHlQb3NpdGlvbnMocm93cyk7XHJcblxyXG4gIGNvbnNvbGUubG9nKGBJbXBvcnQgY29tcGxldGVkLiBUb3RhbCBpbXBvcnRlZCByb3dzOiAke3Jvd3MubGVuZ3RofWApO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGltcG9ydENpdGllcyA9IGFzeW5jIChcclxuICBvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCA9IHt9XHJcbik6IFByb21pc2U8dm9pZD4gPT4ge1xyXG4gIGF3YWl0IHJ1blN5bmNQYXJ0KFN5bmNQYXJ0LlJlZ2lvbnMsIFtdLCBhc3luYyAoKSA9PiB7XHJcbiAgICBjb25zdCBjb21wbGV0ZU9wdGlvbnMgPSBwcmVwYXJlT3B0aW9ucyhvcHRpb25zKTtcclxuICAgIGF3YWl0IGltcG9ydERhdGFUb0RiKGNvbXBsZXRlT3B0aW9ucyk7XHJcbiAgfSk7XHJcbn07XHJcbiJdfQ==
|
|
@@ -1,30 +1,22 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { disconnectKnex } from "../db/db";
|
|
11
2
|
import { isSyncPartCompleted, setSyncPartAsCompleted, startSyncPart } from "../db/sync-log";
|
|
12
|
-
export const runSyncPart = (part, dependencies, partFunction) =>
|
|
3
|
+
export const runSyncPart = async (part, dependencies, partFunction) => {
|
|
13
4
|
try {
|
|
14
|
-
const logId =
|
|
5
|
+
const logId = await startSyncPart(part);
|
|
15
6
|
for (const dependency of dependencies) {
|
|
16
|
-
const isCompleted =
|
|
7
|
+
const isCompleted = await isSyncPartCompleted(dependency);
|
|
17
8
|
if (!isCompleted) {
|
|
18
9
|
throw new Error(`Sync part ${part} cannot be started because dependency ${dependency} is not completed. Run 'npm run ${dependency}' first.`);
|
|
19
10
|
}
|
|
20
11
|
}
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
await partFunction();
|
|
13
|
+
await setSyncPartAsCompleted(logId);
|
|
23
14
|
}
|
|
24
15
|
catch (error) {
|
|
25
16
|
console.log(error);
|
|
26
17
|
}
|
|
27
18
|
finally {
|
|
28
|
-
|
|
19
|
+
await disconnectKnex();
|
|
29
20
|
}
|
|
30
|
-
}
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29wZW4tZGF0YS1zeW5jL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxzQkFBc0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUc1RixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsS0FBSyxFQUM5QixJQUFjLEVBQ2QsWUFBd0IsRUFDeEIsWUFBaUMsRUFDbEIsRUFBRTtJQUNqQixJQUFJO1FBQ0YsTUFBTSxLQUFLLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEMsS0FBSyxNQUFNLFVBQVUsSUFBSSxZQUFZLEVBQUU7WUFDckMsTUFBTSxXQUFXLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMxRCxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLGFBQWEsSUFBSSx5Q0FBeUMsVUFBVSxtQ0FBbUMsVUFBVSxVQUFVLENBQzVILENBQUM7YUFDSDtTQUNGO1FBQ0QsTUFBTSxZQUFZLEVBQUUsQ0FBQztRQUVyQixNQUFNLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3JDO0lBQUMsT0FBTyxLQUFLLEVBQUU7UUFDZCxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3BCO1lBQVM7UUFDUixNQUFNLGNBQWMsRUFBRSxDQUFDO0tBQ3hCO0FBQ0gsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGlzY29ubmVjdEtuZXggfSBmcm9tIFwiLi4vZGIvZGJcIjtcclxuaW1wb3J0IHsgaXNTeW5jUGFydENvbXBsZXRlZCwgc2V0U3luY1BhcnRBc0NvbXBsZXRlZCwgc3RhcnRTeW5jUGFydCB9IGZyb20gXCIuLi9kYi9zeW5jLWxvZ1wiO1xyXG5pbXBvcnQgeyBTeW5jUGFydCB9IGZyb20gXCIuLi9kYi90eXBlc1wiO1xyXG5cclxuZXhwb3J0IGNvbnN0IHJ1blN5bmNQYXJ0ID0gYXN5bmMgKFxyXG4gIHBhcnQ6IFN5bmNQYXJ0LFxyXG4gIGRlcGVuZGVuY2llczogU3luY1BhcnRbXSxcclxuICBwYXJ0RnVuY3Rpb246ICgpID0+IFByb21pc2U8dm9pZD5cclxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XHJcbiAgdHJ5IHtcclxuICAgIGNvbnN0IGxvZ0lkID0gYXdhaXQgc3RhcnRTeW5jUGFydChwYXJ0KTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3kgb2YgZGVwZW5kZW5jaWVzKSB7XHJcbiAgICAgIGNvbnN0IGlzQ29tcGxldGVkID0gYXdhaXQgaXNTeW5jUGFydENvbXBsZXRlZChkZXBlbmRlbmN5KTtcclxuICAgICAgaWYgKCFpc0NvbXBsZXRlZCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgICAgIGBTeW5jIHBhcnQgJHtwYXJ0fSBjYW5ub3QgYmUgc3RhcnRlZCBiZWNhdXNlIGRlcGVuZGVuY3kgJHtkZXBlbmRlbmN5fSBpcyBub3QgY29tcGxldGVkLiBSdW4gJ25wbSBydW4gJHtkZXBlbmRlbmN5fScgZmlyc3QuYFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGF3YWl0IHBhcnRGdW5jdGlvbigpO1xyXG5cclxuICAgIGF3YWl0IHNldFN5bmNQYXJ0QXNDb21wbGV0ZWQobG9nSWQpO1xyXG4gIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICBjb25zb2xlLmxvZyhlcnJvcik7XHJcbiAgfSBmaW5hbGx5IHtcclxuICAgIGF3YWl0IGRpc2Nvbm5lY3RLbmV4KCk7XHJcbiAgfVxyXG59O1xyXG4iXX0=
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { parse } from "csv-parse";
|
|
11
2
|
import iconv from "iconv-lite";
|
|
12
3
|
import fetch from "node-fetch";
|
|
@@ -15,9 +6,9 @@ import { insertRegionsAndOrps } from "../db/regions";
|
|
|
15
6
|
import { SyncPart } from "../db/types";
|
|
16
7
|
import { prepareOptions } from "../utils/helpers";
|
|
17
8
|
import { runSyncPart } from "./common";
|
|
18
|
-
const downloadAndImportDataToDb = (options) =>
|
|
9
|
+
const downloadAndImportDataToDb = async (options) => {
|
|
19
10
|
console.log("Downloading regions and ORP data...");
|
|
20
|
-
const response =
|
|
11
|
+
const response = await fetch(options.regionsCsvUrl);
|
|
21
12
|
if (response.status !== 200) {
|
|
22
13
|
throw new Error(`The file could not be downloaded. HTTP Code: ${response.status}`);
|
|
23
14
|
}
|
|
@@ -26,20 +17,21 @@ const downloadAndImportDataToDb = (options) => __awaiter(void 0, void 0, void 0,
|
|
|
26
17
|
const parseStream = parse({ delimiter: ",", fromLine: 2 }).on("data", (data) => {
|
|
27
18
|
rows.push(data);
|
|
28
19
|
});
|
|
29
|
-
|
|
30
|
-
const schemaResponse =
|
|
20
|
+
await pipeline(response.body, iconv.decodeStream("utf-8"), parseStream);
|
|
21
|
+
const schemaResponse = await fetch(options.regionsSchemaUrl);
|
|
31
22
|
if (schemaResponse.status !== 200) {
|
|
32
23
|
throw new Error(`The file could not be downloaded. HTTP Code: ${schemaResponse.status}`);
|
|
33
24
|
}
|
|
34
25
|
// @ts-ignore
|
|
35
|
-
const schema =
|
|
26
|
+
const schema = await schemaResponse.json();
|
|
36
27
|
console.log("Parsing completed. Starting to import data to DB...");
|
|
37
|
-
|
|
28
|
+
await insertRegionsAndOrps(rows, schema);
|
|
38
29
|
console.log(`Import completed. Total imported rows: ${rows.length}`);
|
|
39
|
-
}
|
|
40
|
-
export const downloadAndImportRegions = (options = {}) =>
|
|
41
|
-
|
|
30
|
+
};
|
|
31
|
+
export const downloadAndImportRegions = async (options = {}) => {
|
|
32
|
+
await runSyncPart(SyncPart.Regions, [], async () => {
|
|
42
33
|
const completeOptions = prepareOptions(options);
|
|
43
|
-
|
|
44
|
-
})
|
|
45
|
-
}
|
|
34
|
+
await downloadAndImportDataToDb(completeOptions);
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVuLWRhdGEtc3luYy9yZWdpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0MsT0FBTyxFQUFzQixvQkFBb0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFHTCxjQUFjLEVBQ2YsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXZDLE1BQU0seUJBQXlCLEdBQUcsS0FBSyxFQUNyQyxPQUE0QixFQUM1QixFQUFFO0lBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ25ELE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNwRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0RBQWdELFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FDbEUsQ0FBQztLQUNIO0lBR0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO0lBRWpFLE1BQU0sSUFBSSxHQUFlLEVBQUUsQ0FBQztJQUM1QixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FDM0QsTUFBTSxFQUNOLENBQUMsSUFBYyxFQUFFLEVBQUU7UUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQ0YsQ0FBQztJQUVGLE1BQU0sUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUV4RSxNQUFNLGNBQWMsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM3RCxJQUFJLGNBQWMsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFO1FBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0RBQWdELGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FDeEUsQ0FBQztLQUNIO0lBQ0QsYUFBYTtJQUNiLE1BQU0sTUFBTSxHQUF1QixNQUFNLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUUvRCxPQUFPLENBQUMsR0FBRyxDQUFDLHFEQUFxRCxDQUFDLENBQUM7SUFFbkUsTUFBTSxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFekMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxFQUMzQyxVQUFzQyxFQUFFLEVBQ3pCLEVBQUU7SUFDakIsTUFBTSxXQUFXLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDakQsTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hELE1BQU0seUJBQXlCLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbkQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwYXJzZSB9IGZyb20gXCJjc3YtcGFyc2VcIjtcclxuaW1wb3J0IGljb252IGZyb20gXCJpY29udi1saXRlXCI7XHJcbmltcG9ydCBmZXRjaCBmcm9tIFwibm9kZS1mZXRjaFwiO1xyXG5pbXBvcnQgeyBwaXBlbGluZSB9IGZyb20gXCJzdHJlYW0vcHJvbWlzZXNcIjtcclxuXHJcbmltcG9ydCB7IFJlZ2lvbnNUYWJsZVNjaGVtYSwgaW5zZXJ0UmVnaW9uc0FuZE9ycHMgfSBmcm9tIFwiLi4vZGIvcmVnaW9uc1wiO1xyXG5pbXBvcnQgeyBTeW5jUGFydCB9IGZyb20gXCIuLi9kYi90eXBlc1wiO1xyXG5pbXBvcnQge1xyXG4gIE9wZW5EYXRhU3luY09wdGlvbnMsXHJcbiAgT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwsXHJcbiAgcHJlcGFyZU9wdGlvbnNcclxufSBmcm9tIFwiLi4vdXRpbHMvaGVscGVyc1wiO1xyXG5pbXBvcnQgeyBydW5TeW5jUGFydCB9IGZyb20gXCIuL2NvbW1vblwiO1xyXG5cclxuY29uc3QgZG93bmxvYWRBbmRJbXBvcnREYXRhVG9EYiA9IGFzeW5jIChcclxuICBvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zXHJcbikgPT4ge1xyXG4gIGNvbnNvbGUubG9nKFwiRG93bmxvYWRpbmcgcmVnaW9ucyBhbmQgT1JQIGRhdGEuLi5cIik7XHJcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChvcHRpb25zLnJlZ2lvbnNDc3ZVcmwpO1xyXG4gIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICBgVGhlIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQuIEhUVFAgQ29kZTogJHtyZXNwb25zZS5zdGF0dXN9YFxyXG4gICAgKTtcclxuICB9XHJcblxyXG5cclxuICBjb25zb2xlLmxvZyhcIkRvd25sb2FkIGNvbXBsZXRlZC4gU3RhcnRpbmcgdG8gcGFyc2UgQ1NWIGZpbGUuLi5cIik7XHJcblxyXG4gIGNvbnN0IHJvd3M6IHN0cmluZ1tdW10gPSBbXTtcclxuICBjb25zdCBwYXJzZVN0cmVhbSA9IHBhcnNlKHsgZGVsaW1pdGVyOiBcIixcIiwgZnJvbUxpbmU6IDIgfSkub24oXHJcbiAgICBcImRhdGFcIixcclxuICAgIChkYXRhOiBzdHJpbmdbXSkgPT4ge1xyXG4gICAgICByb3dzLnB1c2goZGF0YSk7XHJcbiAgICB9XHJcbiAgKTtcclxuXHJcbiAgYXdhaXQgcGlwZWxpbmUocmVzcG9uc2UuYm9keSwgaWNvbnYuZGVjb2RlU3RyZWFtKFwidXRmLThcIiksIHBhcnNlU3RyZWFtKTtcclxuICBcclxuICBjb25zdCBzY2hlbWFSZXNwb25zZSA9IGF3YWl0IGZldGNoKG9wdGlvbnMucmVnaW9uc1NjaGVtYVVybCk7XHJcbiAgaWYgKHNjaGVtYVJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgIGBUaGUgZmlsZSBjb3VsZCBub3QgYmUgZG93bmxvYWRlZC4gSFRUUCBDb2RlOiAke3NjaGVtYVJlc3BvbnNlLnN0YXR1c31gXHJcbiAgICApO1xyXG4gIH1cclxuICAvLyBAdHMtaWdub3JlXHJcbiAgY29uc3Qgc2NoZW1hOiBSZWdpb25zVGFibGVTY2hlbWEgPSBhd2FpdCBzY2hlbWFSZXNwb25zZS5qc29uKCk7XHJcblxyXG4gIGNvbnNvbGUubG9nKFwiUGFyc2luZyBjb21wbGV0ZWQuIFN0YXJ0aW5nIHRvIGltcG9ydCBkYXRhIHRvIERCLi4uXCIpO1xyXG5cclxuICBhd2FpdCBpbnNlcnRSZWdpb25zQW5kT3Jwcyhyb3dzLCBzY2hlbWEpO1xyXG5cclxuICBjb25zb2xlLmxvZyhgSW1wb3J0IGNvbXBsZXRlZC4gVG90YWwgaW1wb3J0ZWQgcm93czogJHtyb3dzLmxlbmd0aH1gKTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBkb3dubG9hZEFuZEltcG9ydFJlZ2lvbnMgPSBhc3luYyAoXHJcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwgPSB7fVxyXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcclxuICBhd2FpdCBydW5TeW5jUGFydChTeW5jUGFydC5SZWdpb25zLCBbXSwgYXN5bmMgKCkgPT4ge1xyXG4gICAgY29uc3QgY29tcGxldGVPcHRpb25zID0gcHJlcGFyZU9wdGlvbnMob3B0aW9ucyk7XHJcbiAgICBhd2FpdCBkb3dubG9hZEFuZEltcG9ydERhdGFUb0RiKGNvbXBsZXRlT3B0aW9ucyk7XHJcbiAgfSk7XHJcbn07XHJcbiJdfQ==
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { createReadStream, createWriteStream, existsSync, rmSync } from "fs";
|
|
11
2
|
import fetch from "node-fetch";
|
|
12
3
|
import { join } from "path";
|
|
@@ -14,21 +5,21 @@ import sax from "sax";
|
|
|
14
5
|
import { pipeline } from "stream/promises";
|
|
15
6
|
import { insertFounders } from "../db/founders";
|
|
16
7
|
import { insertSchools } from "../db/schools";
|
|
17
|
-
import { MunicipalityType, SyncPart } from "../db/types";
|
|
8
|
+
import { MunicipalityType, SyncPart, } from "../db/types";
|
|
18
9
|
import { prepareOptions, } from "../utils/helpers";
|
|
19
10
|
import { runSyncPart } from "./common";
|
|
20
|
-
const downloadXml = (options) =>
|
|
11
|
+
const downloadXml = async (options) => {
|
|
21
12
|
if (existsSync(getXmlFilePath(options))) {
|
|
22
13
|
return;
|
|
23
14
|
}
|
|
24
15
|
console.log("Downloading a large XML file with school data...");
|
|
25
|
-
const response =
|
|
16
|
+
const response = await fetch(options.schoolsXmlUrl);
|
|
26
17
|
if (response.status !== 200) {
|
|
27
18
|
throw new Error(`The XML file could not be downloaded. HTTP Code: ${response.status}`);
|
|
28
19
|
}
|
|
29
|
-
|
|
20
|
+
await pipeline(response.body, createWriteStream(getXmlFilePath(options)));
|
|
30
21
|
console.log("Finished downloading.");
|
|
31
|
-
}
|
|
22
|
+
};
|
|
32
23
|
var XMLState;
|
|
33
24
|
(function (XMLState) {
|
|
34
25
|
XMLState[XMLState["None"] = 0] = "None";
|
|
@@ -64,7 +55,7 @@ const getMunicipalityType = (founderType) => {
|
|
|
64
55
|
? MunicipalityType.District
|
|
65
56
|
: MunicipalityType.Other;
|
|
66
57
|
};
|
|
67
|
-
const processSchoolRegisterXml = (options) =>
|
|
58
|
+
const processSchoolRegisterXml = async (options) => {
|
|
68
59
|
let currentSchool;
|
|
69
60
|
let isCurrentSchoolPrimary;
|
|
70
61
|
let currentIzo;
|
|
@@ -260,11 +251,11 @@ const processSchoolRegisterXml = (options) => __awaiter(void 0, void 0, void 0,
|
|
|
260
251
|
// but the program would quit spontaneously after finishing stream - using Promise instead.
|
|
261
252
|
createReadStream(getXmlFilePath(options)).pipe(saxStream);
|
|
262
253
|
});
|
|
263
|
-
|
|
254
|
+
await streamPromise;
|
|
264
255
|
return { schools, founders, schoolsWithoutRuian };
|
|
265
|
-
}
|
|
266
|
-
const importDataToDb = (options, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) =>
|
|
267
|
-
const { schools, founders, schoolsWithoutRuian } =
|
|
256
|
+
};
|
|
257
|
+
const importDataToDb = async (options, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => {
|
|
258
|
+
const { schools, founders, schoolsWithoutRuian } = await processSchoolRegisterXml(options);
|
|
268
259
|
if (saveFoundersToCsv) {
|
|
269
260
|
const csvFile = "founders.csv";
|
|
270
261
|
if (existsSync(csvFile)) {
|
|
@@ -293,23 +284,24 @@ const importDataToDb = (options, saveFoundersToCsv = false, saveSchoolsWithoutRu
|
|
|
293
284
|
});
|
|
294
285
|
csv.end();
|
|
295
286
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
287
|
+
await insertSchools(schools);
|
|
288
|
+
await insertFounders(Array.from(founders.values()));
|
|
289
|
+
};
|
|
299
290
|
const getXmlFilePath = (options) => {
|
|
300
291
|
return join(options.tmpDir, options.schoolsXmlFileName);
|
|
301
292
|
};
|
|
302
|
-
export const downloadAndImportSchools = (options = {}, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) =>
|
|
303
|
-
|
|
293
|
+
export const downloadAndImportSchools = async (options = {}, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => {
|
|
294
|
+
await runSyncPart(SyncPart.Schools, [SyncPart.AddressPoints], async () => {
|
|
304
295
|
const runOptions = prepareOptions(options);
|
|
305
|
-
|
|
306
|
-
|
|
296
|
+
await downloadXml(runOptions);
|
|
297
|
+
await importDataToDb(runOptions, saveFoundersToCsv, saveSchoolsWithoutRuianToCsv);
|
|
307
298
|
deleteSchoolsXmlFile(runOptions);
|
|
308
|
-
})
|
|
309
|
-
}
|
|
299
|
+
});
|
|
300
|
+
};
|
|
310
301
|
export const deleteSchoolsXmlFile = (options = {}) => {
|
|
311
302
|
const runOptions = prepareOptions(options);
|
|
312
303
|
if (existsSync(getXmlFilePath(runOptions))) {
|
|
313
304
|
rmSync(getXmlFilePath(runOptions));
|
|
314
305
|
}
|
|
315
306
|
};
|
|
307
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nob29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVuLWRhdGEtc3luYy9zY2hvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQzdFLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVCLE9BQU8sR0FBWSxNQUFNLEtBQUssQ0FBQztBQUUvQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxFQUVMLGdCQUFnQixFQUdoQixRQUFRLEdBQ1QsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkMsTUFBTSxXQUFXLEdBQUcsS0FBSyxFQUFFLE9BQTRCLEVBQWlCLEVBQUU7SUFDeEUsSUFBSSxVQUFVLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUU7UUFDdkMsT0FBTztLQUNSO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0lBQ2hFLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNwRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQ2Isb0RBQW9ELFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FDdEUsQ0FBQztLQUNIO0lBQ0QsTUFB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YXRlUmVhZFN0cmVhbSwgY3JlYXRlV3JpdGVTdHJlYW0sIGV4aXN0c1N5bmMsIHJtU3luYyB9IGZyb20gXCJmc1wiO1xyXG5pbXBvcnQgZmV0Y2ggZnJvbSBcIm5vZGUtZmV0Y2hcIjtcclxuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCBzYXgsIHsgVGFnIH0gZnJvbSBcInNheFwiO1xyXG5cclxuaW1wb3J0IHsgcGlwZWxpbmUgfSBmcm9tIFwic3RyZWFtL3Byb21pc2VzXCI7XHJcbmltcG9ydCB7IGluc2VydEZvdW5kZXJzIH0gZnJvbSBcIi4uL2RiL2ZvdW5kZXJzXCI7XHJcbmltcG9ydCB7IGluc2VydFNjaG9vbHMgfSBmcm9tIFwiLi4vZGIvc2Nob29sc1wiO1xyXG5pbXBvcnQge1xyXG4gIEZvdW5kZXIsXHJcbiAgTXVuaWNpcGFsaXR5VHlwZSxcclxuICBTY2hvb2wsXHJcbiAgU2Nob29sTG9jYXRpb24sXHJcbiAgU3luY1BhcnQsXHJcbn0gZnJvbSBcIi4uL2RiL3R5cGVzXCI7XHJcbmltcG9ydCB7XHJcbiAgT3BlbkRhdGFTeW5jT3B0aW9ucyxcclxuICBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCxcclxuICBwcmVwYXJlT3B0aW9ucyxcclxufSBmcm9tIFwiLi4vdXRpbHMvaGVscGVyc1wiO1xyXG5pbXBvcnQgeyBydW5TeW5jUGFydCB9IGZyb20gXCIuL2NvbW1vblwiO1xyXG5cclxuY29uc3QgZG93bmxvYWRYbWwgPSBhc3luYyAob3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xyXG4gIGlmIChleGlzdHNTeW5jKGdldFhtbEZpbGVQYXRoKG9wdGlvbnMpKSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgY29uc29sZS5sb2coXCJEb3dubG9hZGluZyBhIGxhcmdlIFhNTCBmaWxlIHdpdGggc2Nob29sIGRhdGEuLi5cIik7XHJcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChvcHRpb25zLnNjaG9vbHNYbWxVcmwpO1xyXG4gIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICBgVGhlIFhNTCBmaWxlIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkLiBIVFRQIENvZGU6ICR7cmVzcG9uc2Uuc3RhdHVzfWBcclxuICAgICk7XHJcbiAgfVxyXG4gIGF3YWl0IHBpcGVsaW5lKHJlc3BvbnNlLmJvZHksIGNyZWF0ZVdyaXRlU3RyZWFtKGdldFhtbEZpbGVQYXRoKG9wdGlvbnMpKSk7XHJcbiAgY29uc29sZS5sb2coXCJGaW5pc2hlZCBkb3dubG9hZGluZy5cIik7XHJcbn07XHJcblxyXG5lbnVtIFhNTFN0YXRlIHtcclxuICBOb25lLFxyXG4gIFJlZEl6byxcclxuICBTY2hvb2xOYW1lLFxyXG4gIEl6byxcclxuICBJY28sXHJcbiAgU2Nob29sVHlwZSxcclxuICBDYXBhY2l0eSxcclxuICBSdWlhbkNvZGUsXHJcbiAgQWRkcmVzcyxcclxuICBGb3VuZGVyTmFtZSxcclxuICBGb3VuZGVyVHlwZSxcclxuICBGb3VuZGVySWNvLFxyXG59XHJcblxyXG5jb25zdCBTQ0hPT0xfVFlQRV9QUklNQVJZID0gXCJCMDBcIjtcclxuXHJcbmNvbnN0IGNyZWF0ZU5ld1NjaG9vbCA9ICgpOiBTY2hvb2wgPT4ge1xyXG4gIHJldHVybiB7XHJcbiAgICBuYW1lOiBcIlwiLFxyXG4gICAgcmVkaXpvOiBcIlwiLFxyXG4gICAgaXpvOiBcIlwiLFxyXG4gICAgY2FwYWNpdHk6IDAsXHJcbiAgICBsb2NhdGlvbnM6IFtdLFxyXG4gIH07XHJcbn07XHJcblxyXG5jb25zdCBnZXRDb3JyZWN0Rm91bmRlclR5cGUgPSAoZm91bmRlclR5cGU6IHN0cmluZyk6IHN0cmluZyA9PiB7XHJcbiAgcmV0dXJuIGZvdW5kZXJUeXBlID09PSBcIlwiID8gXCIxMDFcIiA6IGZvdW5kZXJUeXBlO1xyXG59O1xyXG5cclxuY29uc3QgZ2V0TXVuaWNpcGFsaXR5VHlwZSA9IChmb3VuZGVyVHlwZTogc3RyaW5nKTogTXVuaWNpcGFsaXR5VHlwZSA9PiB7XHJcbiAgcmV0dXJuIGZvdW5kZXJUeXBlID09PSBcIjI2MVwiXHJcbiAgICA/IE11bmljaXBhbGl0eVR5cGUuQ2l0eVxyXG4gICAgOiBmb3VuZGVyVHlwZSA9PT0gXCIyNjNcIlxyXG4gICAgPyBNdW5pY2lwYWxpdHlUeXBlLkRpc3RyaWN0XHJcbiAgICA6IE11bmljaXBhbGl0eVR5cGUuT3RoZXI7XHJcbn07XHJcblxyXG50eXBlIFNjaG9vbEFkZHJlc3MgPSB7IGl6bzogc3RyaW5nOyBhZGRyZXNzOiBzdHJpbmdbXTsgaXNQcmltYXJ5OiBib29sZWFuIH07XHJcblxyXG5jb25zdCBwcm9jZXNzU2Nob29sUmVnaXN0ZXJYbWwgPSBhc3luYyAoXHJcbiAgb3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1xyXG4pOiBQcm9taXNlPHtcclxuICBzY2hvb2xzOiBTY2hvb2xbXTtcclxuICBmb3VuZGVyczogTWFwPHN0cmluZywgRm91bmRlcj47XHJcbiAgc2Nob29sc1dpdGhvdXRSdWlhbjogU2Nob29sQWRkcmVzc1tdO1xyXG59PiA9PiB7XHJcbiAgbGV0IGN1cnJlbnRTY2hvb2w6IFNjaG9vbDtcclxuICBsZXQgaXNDdXJyZW50U2Nob29sUHJpbWFyeTogYm9vbGVhbjtcclxuICBsZXQgY3VycmVudEl6bzogc3RyaW5nO1xyXG4gIGxldCBjdXJyZW50SWNvOiBzdHJpbmc7XHJcbiAgbGV0IGN1cnJlbnRUeXBlOiBzdHJpbmc7XHJcbiAgbGV0IGN1cnJlbnRDYXBhY2l0eTogbnVtYmVyO1xyXG4gIGxldCBjdXJyZW50TG9jYXRpb25zOiBTY2hvb2xMb2NhdGlvbltdID0gW107XHJcbiAgbGV0IHN0YXRlOiBYTUxTdGF0ZSA9IFhNTFN0YXRlLk5vbmU7XHJcbiAgbGV0IGN1cnJlbnRGb3VuZGVycyA9IFtdO1xyXG4gIGxldCBjdXJyZW50Rm91bmRlckljbzogc3RyaW5nO1xyXG4gIGxldCBjdXJyZW50Rm91bmRlck5hbWU6IHN0cmluZztcclxuICBsZXQgY3VycmVudEZvdW5kZXJUeXBlOiBzdHJpbmc7XHJcbiAgbGV0IGlzUnVpYW5Db2RlU2V0ID0gZmFsc2U7XHJcbiAgbGV0IGlzUnVpYW5Db2RlTWlzc2luZyA9IGZhbHNlO1xyXG4gIGxldCBjdXJyZW50QWRkcmVzcyA9IFtdO1xyXG4gIGNvbnN0IGZvdW5kZXJzID0gbmV3IE1hcDxzdHJpbmcsIEZvdW5kZXI+KCk7XHJcbiAgY29uc3Qgc2Nob29sczogU2Nob29sW10gPSBbXTtcclxuICBjb25zdCBzY2hvb2xzV2l0aG91dFJ1aWFuOiBTY2hvb2xBZGRyZXNzW10gPSBbXTtcclxuXHJcbiAgY29uc3Qgc3RyZWFtUHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgIGNvbnN0IHNheFN0cmVhbSA9IHNheFxyXG4gICAgICAuY3JlYXRlU3RyZWFtKHRydWUpXHJcbiAgICAgIC5vbihcIm9wZW50YWdcIiwgKHRhZzogVGFnKSA9PiB7XHJcbiAgICAgICAgc3dpdGNoICh0YWcubmFtZSkge1xyXG4gICAgICAgICAgY2FzZSBcIlByYXZuaVN1Ympla3RcIjpcclxuICAgICAgICAgICAgY3VycmVudFNjaG9vbCA9IGNyZWF0ZU5ld1NjaG9vbCgpO1xyXG4gICAgICAgICAgICBpc0N1cnJlbnRTY2hvb2xQcmltYXJ5ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlzUnVpYW5Db2RlTWlzc2luZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJSZWRJem9cIjpcclxuICAgICAgICAgICAgc3RhdGUgPSBYTUxTdGF0ZS5SZWRJem87XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIlJlZFBsbnlOYXpldlwiOlxyXG4gICAgICAgICAgICBzdGF0ZSA9IFhNTFN0YXRlLlNjaG9vbE5hbWU7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIklaT1wiOlxyXG4gICAgICAgICAgICBzdGF0ZSA9IFhNTFN0YXRlLkl6bztcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiSUNPXCI6XHJcbiAgICAgICAgICAgIHN0YXRlID0gWE1MU3RhdGUuSWNvO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJTa29sYURydWhUeXBcIjpcclxuICAgICAgICAgICAgc3RhdGUgPSBYTUxTdGF0ZS5TY2hvb2xUeXBlO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJTa29sYUthcGFjaXRhXCI6XHJcbiAgICAgICAgICAgIHN0YXRlID0gWE1MU3RhdGUuQ2FwYWNpdHk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIk1pc3RvUlVBSU5Lb2RcIjpcclxuICAgICAgICAgICAgaXNSdWlhbkNvZGVTZXQgPSBmYWxzZTtcclxuICAgICAgICAgICAgY3VycmVudEFkZHJlc3MgPSBbXTtcclxuICAgICAgICAgICAgc3RhdGUgPSBYTUxTdGF0ZS5SdWlhbkNvZGU7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIlpyaXpOYXpldlwiOlxyXG4gICAgICAgICAgICBzdGF0ZSA9IFhNTFN0YXRlLkZvdW5kZXJOYW1lO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJacml6UHJhdm5pRm9ybWFcIjpcclxuICAgICAgICAgICAgc3RhdGUgPSBYTUxTdGF0ZS5Gb3VuZGVyVHlwZTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiTWlzdG9BZHJlc2ExXCI6XHJcbiAgICAgICAgICBjYXNlIFwiTWlzdG9BZHJlc2EyXCI6XHJcbiAgICAgICAgICBjYXNlIFwiTWlzdG9BZHJlc2EzXCI6XHJcbiAgICAgICAgICAgIHN0YXRlID0gWE1MU3RhdGUuQWRkcmVzcztcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiWnJpekRhdHVtTmFyb3plbmlcIjpcclxuICAgICAgICAgIGNhc2UgXCJacml6SUNPXCI6XHJcbiAgICAgICAgICAgIHN0YXRlID0gWE1MU3RhdGUuRm91bmRlckljbztcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAub24oXCJjbG9zZXRhZ1wiLCAodGFnTmFtZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgc3dpdGNoICh0YWdOYW1lKSB7XHJcbiAgICAgICAgICBjYXNlIFwiUHJhdm5pU3ViamVrdFwiOlxyXG4gICAgICAgICAgICBpZiAoaXNDdXJyZW50U2Nob29sUHJpbWFyeSkge1xyXG4gICAgICAgICAgICAgIHNjaG9vbHMucHVzaChjdXJyZW50U2Nob29sKTtcclxuICAgICAgICAgICAgICBjdXJyZW50Rm91bmRlcnMuZm9yRWFjaCgoZm91bmRlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gZm91bmRlci5uYW1lICsgZm91bmRlci5pY287XHJcbiAgICAgICAgICAgICAgICBpZiAoZm91bmRlcnMuaGFzKGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgZm91bmRlcnMuZ2V0KGtleSkuc2Nob29scy5wdXNoKGN1cnJlbnRTY2hvb2wpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgZm91bmRlcnMuc2V0KGtleSwge1xyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGZvdW5kZXIubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBpY286IGZvdW5kZXIuaWNvLFxyXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsVHlwZTogZm91bmRlci50eXBlLFxyXG4gICAgICAgICAgICAgICAgICAgIG11bmljaXBhbGl0eVR5cGU6IGdldE11bmljaXBhbGl0eVR5cGUoZm91bmRlci50eXBlKSxcclxuICAgICAgICAgICAgICAgICAgICBzY2hvb2xzOiBbY3VycmVudFNjaG9vbF0sXHJcbiAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGN1cnJlbnRJY28gPSBcIlwiO1xyXG4gICAgICAgICAgICBjdXJyZW50Rm91bmRlcnMgPSBbXTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgY2FzZSBcIlpyaXpvdmF0ZWxcIjpcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRGb3VuZGVySWNvID09PSBcIlwiIHx8IGN1cnJlbnRGb3VuZGVyTmFtZSA9PT0gXCJcIikge1xyXG4gICAgICAgICAgICAgIGN1cnJlbnRGb3VuZGVycy5wdXNoKHtcclxuICAgICAgICAgICAgICAgIGljbzogY3VycmVudEljbyxcclxuICAgICAgICAgICAgICAgIG5hbWU6IGN1cnJlbnRTY2hvb2wubmFtZSxcclxuICAgICAgICAgICAgICAgIHR5cGU6IFwiMjI0XCIsIC8vIHMuci5vIChub3QgYWxsIGFyZSB0aG9zZSwgYnV0IHdlIGRvbid0IG5lZWQgdG8gZGlmZmVyZW50aWF0ZSBoZXJlKVxyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGN1cnJlbnRGb3VuZGVycy5wdXNoKHtcclxuICAgICAgICAgICAgICAgIGljbzogY3VycmVudEZvdW5kZXJJY28sXHJcbiAgICAgICAgICAgICAgICBuYW1lOiBjdXJyZW50Rm91bmRlck5hbWUsXHJcbiAgICAgICAgICAgICAgICB0eXBlOiBnZXRDb3JyZWN0Rm91bmRlclR5cGUoY3VycmVudEZvdW5kZXJUeXBlKSxcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjdXJyZW50Rm91bmRlckljbyA9IFwiXCI7XHJcbiAgICAgICAgICAgIGN1cnJlbnRGb3VuZGVyTmFtZSA9IFwiXCI7XHJcbiAgICAgICAgICAgIGN1cnJlbnRGb3VuZGVyVHlwZSA9IFwiXCI7XHJcblxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJTa29sYVphcml6ZW5pXCI6XHJcbiAgICAgICAgICAgIGlmIChjdXJyZW50VHlwZSA9PT0gU0NIT09MX1RZUEVfUFJJTUFSWSkge1xyXG4gICAgICAgICAgICAgIGN1cnJlbnRTY2hvb2wuaXpvID0gY3VycmVudEl6bztcclxuICAgICAgICAgICAgICBjdXJyZW50U2Nob29sLmxvY2F0aW9ucyA9IGN1cnJlbnRMb2NhdGlvbnM7XHJcbiAgICAgICAgICAgICAgY3VycmVudFNjaG9vbC5jYXBhY2l0eSA9IGN1cnJlbnRDYXBhY2l0eTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjdXJyZW50TG9jYXRpb25zID0gW107XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIlNrb2xhTWlzdG9WeWtvbnVDaW5ub3N0aVwiOlxyXG4gICAgICAgICAgICBpZiAoaXNSdWlhbkNvZGVNaXNzaW5nKSB7XHJcbiAgICAgICAgICAgICAgc2Nob29sc1dpdGhvdXRSdWlhbi5wdXNoKHtcclxuICAgICAgICAgICAgICAgIGl6bzogY3VycmVudEl6byxcclxuICAgICAgICAgICAgICAgIGFkZHJlc3M6IGN1cnJlbnRBZGRyZXNzLFxyXG4gICAgICAgICAgICAgICAgaXNQcmltYXJ5OiBjdXJyZW50VHlwZSA9PT0gU0NIT09MX1RZUEVfUFJJTUFSWSxcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJNaXN0b1JVQUlOS29kXCI6XHJcbiAgICAgICAgICAgIGlzUnVpYW5Db2RlTWlzc2luZyA9ICFpc1J1aWFuQ29kZVNldDtcclxuICAgICAgICAgIGNhc2UgXCJSZWRQbG55TmF6ZXZcIjpcclxuICAgICAgICAgIGNhc2UgXCJSZWRJem9cIjpcclxuICAgICAgICAgIGNhc2UgXCJJQ09cIjpcclxuICAgICAgICAgIGNhc2UgXCJJWk9cIjpcclxuICAgICAgICAgIGNhc2UgXCJTa29sYURydWhUeXBcIjpcclxuICAgICAgICAgIGNhc2UgXCJTa29sYUthcGFjaXRhXCI6XHJcbiAgICAgICAgICBjYXNlIFwiWnJpek5hemV2XCI6XHJcbiAgICAgICAgICBjYXNlIFwiWnJpeklDT1wiOlxyXG4gICAgICAgICAgY2FzZSBcIlpyaXpEYXR1bU5hcm96ZW5pXCI6XHJcbiAgICAgICAgICBjYXNlIFwiWnJpelByYXZuaUZvcm1hXCI6XHJcbiAgICAgICAgICBjYXNlIFwiTWlzdG9BZHJlc2ExXCI6XHJcbiAgICAgICAgICBjYXNlIFwiTWlzdG9BZHJlc2EyXCI6XHJcbiAgICAgICAgICBjYXNlIFwiTWlzdG9BZHJlc2EzXCI6XHJcbiAgICAgICAgICAgIHN0YXRlID0gWE1MU3RhdGUuTm9uZTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAub24oXCJ0ZXh0XCIsICh0ZXh0OiBzdHJpbmcpID0+IHtcclxuICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7XHJcbiAgICAgICAgICBjYXNlIFhNTFN0YXRlLlJlZEl6bzpcclxuICAgICAgICAgICAgY3VycmVudFNjaG9vbC5yZWRpem8gPSB0ZXh0O1xyXG4gICAgICAgICAgY2FzZSBYTUxTdGF0ZS5TY2hvb2xOYW1lOlxyXG4gICAgICAgICAgICBjdXJyZW50U2Nob29sLm5hbWUgPSB0ZXh0O1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgWE1MU3RhdGUuSXpvOlxyXG4gICAgICAgICAgICBjdXJyZW50SXpvID0gdGV4dDtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFhNTFN0YXRlLkljbzpcclxuICAgICAgICAgICAgY3VycmVudEljbyA9IHRleHQ7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBYTUxTdGF0ZS5TY2hvb2xUeXBlOlxyXG4gICAgICAgICAgICBjdXJyZW50VHlwZSA9IHRleHQ7XHJcbiAgICAgICAgICAgIGlmICh0ZXh0ID09PSBTQ0hPT0xfVFlQRV9QUklNQVJZKSB7XHJcbiAgICAgICAgICAgICAgaXNDdXJyZW50U2Nob29sUHJpbWFyeSA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFhNTFN0YXRlLlJ1aWFuQ29kZTpcclxuICAgICAgICAgICAgaXNSdWlhbkNvZGVTZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICBjdXJyZW50TG9jYXRpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgIGFkZHJlc3NQb2ludElkOiBwYXJzZUludCh0ZXh0KSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBYTUxTdGF0ZS5BZGRyZXNzOlxyXG4gICAgICAgICAgICBjdXJyZW50QWRkcmVzcy5wdXNoKHRleHQpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgWE1MU3RhdGUuRm91bmRlck5hbWU6XHJcbiAgICAgICAgICAgIGN1cnJlbnRGb3VuZGVyTmFtZSA9IHRleHQ7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBYTUxTdGF0ZS5Gb3VuZGVySWNvOlxyXG4gICAgICAgICAgICBjdXJyZW50Rm91bmRlckljbyA9IHRleHQ7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBYTUxTdGF0ZS5Gb3VuZGVyVHlwZTpcclxuICAgICAgICAgICAgY3VycmVudEZvdW5kZXJUeXBlID0gdGV4dDtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFhNTFN0YXRlLkNhcGFjaXR5OlxyXG4gICAgICAgICAgICBjdXJyZW50Q2FwYWNpdHkgPSBwYXJzZUludCh0ZXh0KTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAub24oXCJlcnJvclwiLCByZWplY3QpXHJcbiAgICAgIC5vbihcImVuZFwiLCByZXNvbHZlKTtcclxuXHJcbiAgICAvLyB3YW50ZWQgdG8gdXNlICdhd2FpdCBwaXBlbGluZShjcmVhdGVSZWFkU3RyZWFtKGdldFhtbEZpbGVQYXRoKG9wdGlvbnMpKSwgc2F4U3RyZWFtKSdcclxuICAgIC8vIGJ1dCB0aGUgcHJvZ3JhbSB3b3VsZCBxdWl0IHNwb250YW5lb3VzbHkgYWZ0ZXIgZmluaXNoaW5nIHN0cmVhbSAtIHVzaW5nIFByb21pc2UgaW5zdGVhZC5cclxuICAgIGNyZWF0ZVJlYWRTdHJlYW0oZ2V0WG1sRmlsZVBhdGgob3B0aW9ucykpLnBpcGUoc2F4U3RyZWFtKTtcclxuICB9KTtcclxuXHJcbiAgYXdhaXQgc3RyZWFtUHJvbWlzZTtcclxuXHJcbiAgcmV0dXJuIHsgc2Nob29scywgZm91bmRlcnMsIHNjaG9vbHNXaXRob3V0UnVpYW4gfTtcclxufTtcclxuXHJcbmNvbnN0IGltcG9ydERhdGFUb0RiID0gYXN5bmMgKFxyXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnMsXHJcbiAgc2F2ZUZvdW5kZXJzVG9Dc3Y6IGJvb2xlYW4gPSBmYWxzZSxcclxuICBzYXZlU2Nob29sc1dpdGhvdXRSdWlhblRvQ3N2OiBib29sZWFuID0gZmFsc2VcclxuKSA9PiB7XHJcbiAgY29uc3QgeyBzY2hvb2xzLCBmb3VuZGVycywgc2Nob29sc1dpdGhvdXRSdWlhbiB9ID1cclxuICAgIGF3YWl0IHByb2Nlc3NTY2hvb2xSZWdpc3RlclhtbChvcHRpb25zKTtcclxuXHJcbiAgaWYgKHNhdmVGb3VuZGVyc1RvQ3N2KSB7XHJcbiAgICBjb25zdCBjc3ZGaWxlID0gXCJmb3VuZGVycy5jc3ZcIjtcclxuXHJcbiAgICBpZiAoZXhpc3RzU3luYyhjc3ZGaWxlKSkge1xyXG4gICAgICBybVN5bmMoY3N2RmlsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNzdiA9IGNyZWF0ZVdyaXRlU3RyZWFtKGNzdkZpbGUsIHtcclxuICAgICAgZmxhZ3M6IFwiYVwiLFxyXG4gICAgfSk7XHJcbiAgICBjc3Yud3JpdGUoXCJJxIxPO1rFmWl6b3ZhdGVsO1Byw6F2bsOtIGZvcm1hO1BvxI1ldCDFoWtvbDvFoGtvbHlcXG5cIik7XHJcbiAgICBmb3VuZGVycy5mb3JFYWNoKChmb3VuZGVyKSA9PiB7XHJcbiAgICAgIGNzdi53cml0ZShcclxuICAgICAgICBgIyR7Zm91bmRlci5pY299OyR7Zm91bmRlci5uYW1lfTske2ZvdW5kZXIub3JpZ2luYWxUeXBlfTske1xyXG4gICAgICAgICAgZm91bmRlci5zY2hvb2xzLmxlbmd0aFxyXG4gICAgICAgIH07JHtmb3VuZGVyLnNjaG9vbHMubWFwKChzY2hvb2wpID0+IHNjaG9vbC5uYW1lKS5qb2luKFwiLS0tXCIpfVxcbmBcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gICAgY3N2LmVuZCgpO1xyXG4gIH1cclxuXHJcbiAgaWYgKHNhdmVTY2hvb2xzV2l0aG91dFJ1aWFuVG9Dc3YpIHtcclxuICAgIGNvbnN0IGNzdkZpbGUgPSBcInNjaG9vbHNXaXRob3V0UnVpYW4uY3N2XCI7XHJcblxyXG4gICAgaWYgKGV4aXN0c1N5bmMoY3N2RmlsZSkpIHtcclxuICAgICAgcm1TeW5jKGNzdkZpbGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBjc3YgPSBjcmVhdGVXcml0ZVN0cmVhbShjc3ZGaWxlLCB7XHJcbiAgICAgIGZsYWdzOiBcImFcIixcclxuICAgIH0pO1xyXG4gICAgY3N2LndyaXRlKFwiSVpPO0plIHrDoWtsYWRuw607YWRyZXNhMTthZHJlc2EyO2FkcmVzYTNcXG5cIik7XHJcbiAgICBzY2hvb2xzV2l0aG91dFJ1aWFuLmZvckVhY2goKHNjaG9vbEFkZHJlc3MpID0+IHtcclxuICAgICAgY3N2LndyaXRlKFxyXG4gICAgICAgIGAjJHtzY2hvb2xBZGRyZXNzLml6b307JHtcclxuICAgICAgICAgIHNjaG9vbEFkZHJlc3MuaXNQcmltYXJ5ID8gXCJUUlVFXCIgOiBcIkZBTFNFXCJcclxuICAgICAgICB9OyR7c2Nob29sQWRkcmVzcy5hZGRyZXNzLmpvaW4oXCI7XCIpfVxcbmBcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gICAgY3N2LmVuZCgpO1xyXG4gIH1cclxuXHJcbiAgYXdhaXQgaW5zZXJ0U2Nob29scyhzY2hvb2xzKTtcclxuXHJcbiAgYXdhaXQgaW5zZXJ0Rm91bmRlcnMoQXJyYXkuZnJvbShmb3VuZGVycy52YWx1ZXMoKSkpO1xyXG59O1xyXG5cclxuY29uc3QgZ2V0WG1sRmlsZVBhdGggPSAob3B0aW9uczogT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwpOiBzdHJpbmcgPT4ge1xyXG4gIHJldHVybiBqb2luKG9wdGlvbnMudG1wRGlyLCBvcHRpb25zLnNjaG9vbHNYbWxGaWxlTmFtZSk7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZG93bmxvYWRBbmRJbXBvcnRTY2hvb2xzID0gYXN5bmMgKFxyXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNQYXJ0aWFsID0ge30sXHJcbiAgc2F2ZUZvdW5kZXJzVG9Dc3Y6IGJvb2xlYW4gPSBmYWxzZSxcclxuICBzYXZlU2Nob29sc1dpdGhvdXRSdWlhblRvQ3N2OiBib29sZWFuID0gZmFsc2VcclxuKSA9PiB7XHJcbiAgYXdhaXQgcnVuU3luY1BhcnQoU3luY1BhcnQuU2Nob29scywgW1N5bmNQYXJ0LkFkZHJlc3NQb2ludHNdLCBhc3luYyAoKSA9PiB7XHJcbiAgICBjb25zdCBydW5PcHRpb25zID0gcHJlcGFyZU9wdGlvbnMob3B0aW9ucyk7XHJcblxyXG4gICAgYXdhaXQgZG93bmxvYWRYbWwocnVuT3B0aW9ucyk7XHJcbiAgICBhd2FpdCBpbXBvcnREYXRhVG9EYihcclxuICAgICAgcnVuT3B0aW9ucyxcclxuICAgICAgc2F2ZUZvdW5kZXJzVG9Dc3YsXHJcbiAgICAgIHNhdmVTY2hvb2xzV2l0aG91dFJ1aWFuVG9Dc3ZcclxuICAgICk7XHJcbiAgICBkZWxldGVTY2hvb2xzWG1sRmlsZShydW5PcHRpb25zKTtcclxuICB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBkZWxldGVTY2hvb2xzWG1sRmlsZSA9IChcclxuICBvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCA9IHt9XHJcbikgPT4ge1xyXG4gIGNvbnN0IHJ1bk9wdGlvbnMgPSBwcmVwYXJlT3B0aW9ucyhvcHRpb25zKTtcclxuXHJcbiAgaWYgKGV4aXN0c1N5bmMoZ2V0WG1sRmlsZVBhdGgocnVuT3B0aW9ucykpKSB7XHJcbiAgICBybVN5bmMoZ2V0WG1sRmlsZVBhdGgocnVuT3B0aW9ucykpO1xyXG4gIH1cclxufTtcclxuIl19
|
|
@@ -1,27 +1,18 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import AdmZip from "adm-zip";
|
|
11
2
|
import { createWriteStream, existsSync, mkdirSync, rmSync } from "fs";
|
|
12
3
|
import fetch from "node-fetch";
|
|
13
4
|
import parseDBF from "parsedbf";
|
|
14
|
-
import ShpToGeoJson from "shp-to-geojson";
|
|
15
5
|
import { join } from "path";
|
|
6
|
+
import ShpToGeoJson from "shp-to-geojson";
|
|
16
7
|
import { pipeline } from "stream/promises";
|
|
8
|
+
import { coordEach } from "@turf/meta";
|
|
9
|
+
import { setCityPolygonGeojson } from "../db/cities";
|
|
17
10
|
import { deleteStreets, getAllSyncedStreets, insertStreetsFromDbf, setStreetAsSynced, } from "../db/street-sync";
|
|
18
11
|
import { SyncPart } from "../db/types";
|
|
19
12
|
import { getAllUrlsFromAtomFeed, getLatestUrlFromAtomFeed, } from "../utils/atom";
|
|
20
13
|
import { prepareOptions, } from "../utils/helpers";
|
|
21
|
-
import { runSyncPart } from "./common";
|
|
22
|
-
import { coordEach } from "@turf/meta";
|
|
23
14
|
import jtsk2wgs84 from "../utils/jtsk2wgs84";
|
|
24
|
-
import {
|
|
15
|
+
import { runSyncPart } from "./common";
|
|
25
16
|
const prepareFolders = (options) => {
|
|
26
17
|
const tempFolder = getTempFolder(options);
|
|
27
18
|
if (!existsSync(tempFolder)) {
|
|
@@ -31,13 +22,13 @@ const prepareFolders = (options) => {
|
|
|
31
22
|
const getTempFolder = (options) => {
|
|
32
23
|
return join(options.tmpDir, options.streetZipFolderName);
|
|
33
24
|
};
|
|
34
|
-
const downloadZipAndParseFiles = (url, index, options) =>
|
|
35
|
-
const response =
|
|
25
|
+
const downloadZipAndParseFiles = async (url, index, options) => {
|
|
26
|
+
const response = await fetch(url);
|
|
36
27
|
if (response.status !== 200) {
|
|
37
28
|
throw new Error(`The ZIP file from '${url}' could not be downloaded. HTTP Code: ${response.status}`);
|
|
38
29
|
}
|
|
39
30
|
const zipFilePath = join(getTempFolder(options), `street${index}.zip`);
|
|
40
|
-
|
|
31
|
+
await pipeline(response.body, createWriteStream(zipFilePath));
|
|
41
32
|
const zip = new AdmZip(zipFilePath);
|
|
42
33
|
const folderName = zip.getEntries()[0].entryName;
|
|
43
34
|
const cityCode = folderName.substring(0, 6);
|
|
@@ -45,13 +36,21 @@ const downloadZipAndParseFiles = (url, index, options) => __awaiter(void 0, void
|
|
|
45
36
|
const streetData = parseDBF(zip.getEntry(dbfEntryName).getData(), "win1250");
|
|
46
37
|
const shpEntryName = `${folderName}${options.polygonShpFileName}`;
|
|
47
38
|
const polygonData = convertShpToGeoJson(zip.getEntry(shpEntryName).getData());
|
|
39
|
+
const districtShpEntryName = `${folderName}${options.districtPolygonShpFileName}`;
|
|
40
|
+
const districtShpEntry = zip.getEntry(districtShpEntryName);
|
|
41
|
+
let districtsPolygonData = undefined;
|
|
42
|
+
if (districtShpEntry !== null) {
|
|
43
|
+
const districtDbfEntryName = `${folderName}${options.districtPolygonDbfFileName}`;
|
|
44
|
+
districtsPolygonData = convertShpToGeoJson(districtShpEntry.getData(), zip.getEntry(districtDbfEntryName).getData());
|
|
45
|
+
}
|
|
48
46
|
rmSync(zipFilePath);
|
|
49
|
-
return { streetData, polygonData, cityCode };
|
|
50
|
-
}
|
|
51
|
-
const convertShpToGeoJson = (shpBuffer) => {
|
|
47
|
+
return { streetData, polygonData, districtsPolygonData, cityCode };
|
|
48
|
+
};
|
|
49
|
+
const convertShpToGeoJson = (shpBuffer, dbfBuffer) => {
|
|
52
50
|
const shp = new ShpToGeoJson({
|
|
53
51
|
arraybuffers: {
|
|
54
52
|
shpBuffer,
|
|
53
|
+
...(dbfBuffer ? { dbfBuffer } : {}),
|
|
55
54
|
},
|
|
56
55
|
});
|
|
57
56
|
const geoJson = shp.getGeoJson();
|
|
@@ -64,21 +63,21 @@ const convertShpToGeoJson = (shpBuffer) => {
|
|
|
64
63
|
});
|
|
65
64
|
return geoJson;
|
|
66
65
|
};
|
|
67
|
-
const importDataToDb = ({ streetData, polygonData,
|
|
66
|
+
const importDataToDb = async ({ streetData, cityCode, polygonData, districtsPolygonData, }) => {
|
|
68
67
|
if (streetData.length > 0) {
|
|
69
|
-
|
|
68
|
+
await insertStreetsFromDbf(streetData);
|
|
70
69
|
}
|
|
71
|
-
|
|
72
|
-
}
|
|
70
|
+
await setCityPolygonGeojson(cityCode, polygonData, districtsPolygonData);
|
|
71
|
+
};
|
|
73
72
|
const attempts = 5;
|
|
74
|
-
export const downloadAndImportStreets = (options = {}) =>
|
|
75
|
-
|
|
73
|
+
export const downloadAndImportStreets = async (options = {}) => {
|
|
74
|
+
await runSyncPart(SyncPart.Streets, [SyncPart.AddressPoints], async () => {
|
|
76
75
|
console.log("Starting to download and import streets. This takes up to 1 hour.");
|
|
77
76
|
const completeOptions = prepareOptions(options);
|
|
78
77
|
prepareFolders(completeOptions);
|
|
79
|
-
const allDatasetFeedLinks =
|
|
78
|
+
const allDatasetFeedLinks = await getAllUrlsFromAtomFeed(completeOptions.streetsAtomUrl);
|
|
80
79
|
console.log(`Total of ${allDatasetFeedLinks.length} links to ZIP files.`);
|
|
81
|
-
const syncedStreetLinks =
|
|
80
|
+
const syncedStreetLinks = await getAllSyncedStreets();
|
|
82
81
|
const toDelete = [];
|
|
83
82
|
// remove all deprecated links (not in the new list)
|
|
84
83
|
syncedStreetLinks.forEach((link) => {
|
|
@@ -87,7 +86,7 @@ export const downloadAndImportStreets = (options = {}) => __awaiter(void 0, void
|
|
|
87
86
|
delete syncedStreetLinks[link];
|
|
88
87
|
}
|
|
89
88
|
});
|
|
90
|
-
|
|
89
|
+
await deleteStreets(toDelete);
|
|
91
90
|
let done = syncedStreetLinks.size;
|
|
92
91
|
console.log(`Total of ${done} links to ZIP files already stored.`);
|
|
93
92
|
// get all links not yet stored
|
|
@@ -97,13 +96,13 @@ export const downloadAndImportStreets = (options = {}) => __awaiter(void 0, void
|
|
|
97
96
|
for (const link of newLinks) {
|
|
98
97
|
for (let i = 0; i < attempts; i++) {
|
|
99
98
|
try {
|
|
100
|
-
const zipLink =
|
|
101
|
-
const data =
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
const zipLink = await getLatestUrlFromAtomFeed(link);
|
|
100
|
+
const data = await downloadZipAndParseFiles(zipLink, done, completeOptions);
|
|
101
|
+
await importDataToDb(data);
|
|
102
|
+
await setStreetAsSynced(link);
|
|
104
103
|
done++;
|
|
105
104
|
console.log(`Loaded links: ${done}/${allDatasetFeedLinks.length}`);
|
|
106
|
-
|
|
105
|
+
await wait(delay);
|
|
107
106
|
break;
|
|
108
107
|
}
|
|
109
108
|
catch (error) {
|
|
@@ -111,7 +110,8 @@ export const downloadAndImportStreets = (options = {}) => __awaiter(void 0, void
|
|
|
111
110
|
delay += 100; // if error occured, it is likely to repeat so we wait a bit longer
|
|
112
111
|
const waitTime = (i + 1) * 3;
|
|
113
112
|
console.error(`Error connecting to CUZK servers, retrying in ${waitTime} seconds...`);
|
|
114
|
-
|
|
113
|
+
console.log(error);
|
|
114
|
+
await wait(waitTime * 1000);
|
|
115
115
|
}
|
|
116
116
|
else {
|
|
117
117
|
throw error;
|
|
@@ -119,8 +119,9 @@ export const downloadAndImportStreets = (options = {}) => __awaiter(void 0, void
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
const wait = (ms) =>
|
|
125
|
-
|
|
126
|
-
}
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
const wait = async (ms) => {
|
|
125
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVuLWRhdGEtc3luYy9zdHJlZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sTUFBTSxNQUFNLFNBQVMsQ0FBQztBQUU3QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDdEUsT0FBTyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQy9CLE9BQU8sUUFBUSxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVCLE9BQU8sWUFBWSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUczQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsYUFBYSxFQUNiLG1CQUFtQixFQUNuQixvQkFBb0IsRUFDcEIsaUJBQWlCLEdBQ2xCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFhLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHdCQUF3QixHQUN6QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBR0wsY0FBYyxHQUNmLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxVQUFVLE1BQU0scUJBQXFCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUV2QyxNQUFNLGNBQWMsR0FBRyxDQUFDLE9BQTRCLEVBQUUsRUFBRTtJQUN0RCxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxV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QUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDMUQsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFkbVppcCBmcm9tIFwiYWRtLXppcFwiO1xyXG5pbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiYnVmZmVyXCI7XHJcbmltcG9ydCB7IGNyZWF0ZVdyaXRlU3RyZWFtLCBleGlzdHNTeW5jLCBta2RpclN5bmMsIHJtU3luYyB9IGZyb20gXCJmc1wiO1xyXG5pbXBvcnQgZmV0Y2ggZnJvbSBcIm5vZGUtZmV0Y2hcIjtcclxuaW1wb3J0IHBhcnNlREJGIGZyb20gXCJwYXJzZWRiZlwiO1xyXG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0IFNocFRvR2VvSnNvbiBmcm9tIFwic2hwLXRvLWdlb2pzb25cIjtcclxuaW1wb3J0IHsgcGlwZWxpbmUgfSBmcm9tIFwic3RyZWFtL3Byb21pc2VzXCI7XHJcblxyXG5pbXBvcnQgeyBGZWF0dXJlQ29sbGVjdGlvbiB9IGZyb20gXCJAdHVyZi9oZWxwZXJzXCI7XHJcbmltcG9ydCB7IGNvb3JkRWFjaCB9IGZyb20gXCJAdHVyZi9tZXRhXCI7XHJcbmltcG9ydCB7IHNldENpdHlQb2x5Z29uR2VvanNvbiB9IGZyb20gXCIuLi9kYi9jaXRpZXNcIjtcclxuaW1wb3J0IHtcclxuICBkZWxldGVTdHJlZXRzLFxyXG4gIGdldEFsbFN5bmNlZFN0cmVldHMsXHJcbiAgaW5zZXJ0U3RyZWV0c0Zyb21EYmYsXHJcbiAgc2V0U3RyZWV0QXNTeW5jZWQsXHJcbn0gZnJvbSBcIi4uL2RiL3N0cmVldC1zeW5jXCI7XHJcbmltcG9ydCB7IERiZlN0cmVldCwgU3luY1BhcnQgfSBmcm9tIFwiLi4vZGIvdHlwZXNcIjtcclxuaW1wb3J0IHtcclxuICBnZXRBbGxVcmxzRnJvbUF0b21GZWVkLFxyXG4gIGdldExhdGVzdFVybEZyb21BdG9tRmVlZCxcclxufSBmcm9tIFwiLi4vdXRpbHMvYXRvbVwiO1xyXG5pbXBvcnQge1xyXG4gIE9wZW5EYXRhU3luY09wdGlvbnMsXHJcbiAgT3BlbkRhdGFTeW5jT3B0aW9uc1BhcnRpYWwsXHJcbiAgcHJlcGFyZU9wdGlvbnMsXHJcbn0gZnJvbSBcIi4uL3V0aWxzL2hlbHBlcnNcIjtcclxuaW1wb3J0IGp0c2syd2dzODQgZnJvbSBcIi4uL3V0aWxzL2p0c2syd2dzODRcIjtcclxuaW1wb3J0IHsgcnVuU3luY1BhcnQgfSBmcm9tIFwiLi9jb21tb25cIjtcclxuXHJcbmNvbnN0IHByZXBhcmVGb2xkZXJzID0gKG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnMpID0+IHtcclxuICBjb25zdCB0ZW1wRm9sZGVyID0gZ2V0VGVtcEZvbGRlcihvcHRpb25zKTtcclxuICBpZiAoIWV4aXN0c1N5bmModGVtcEZvbGRlcikpIHtcclxuICAgIG1rZGlyU3luYyh0ZW1wRm9sZGVyKTtcclxuICB9XHJcbn07XHJcblxyXG5jb25zdCBnZXRUZW1wRm9sZGVyID0gKG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnMpID0+IHtcclxuICByZXR1cm4gam9pbihvcHRpb25zLnRtcERpciwgb3B0aW9ucy5zdHJlZXRaaXBGb2xkZXJOYW1lKTtcclxufTtcclxuXHJcbmNvbnN0IGRvd25sb2FkWmlwQW5kUGFyc2VGaWxlcyA9IGFzeW5jIChcclxuICB1cmw6IHN0cmluZyxcclxuICBpbmRleDogbnVtYmVyLFxyXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNcclxuKTogUHJvbWlzZTx7XHJcbiAgc3RyZWV0RGF0YTogRGJmU3RyZWV0W107XHJcbiAgcG9seWdvbkRhdGE6IEZlYXR1cmVDb2xsZWN0aW9uO1xyXG4gIGRpc3RyaWN0c1BvbHlnb25EYXRhPzogRmVhdHVyZUNvbGxlY3Rpb247XHJcbiAgY2l0eUNvZGU6IHN0cmluZztcclxufT4gPT4ge1xyXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcclxuICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgYFRoZSBaSVAgZmlsZSBmcm9tICcke3VybH0nIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkLiBIVFRQIENvZGU6ICR7cmVzcG9uc2Uuc3RhdHVzfWBcclxuICAgICk7XHJcbiAgfVxyXG4gIGNvbnN0IHppcEZpbGVQYXRoID0gam9pbihnZXRUZW1wRm9sZGVyKG9wdGlvbnMpLCBgc3RyZWV0JHtpbmRleH0uemlwYCk7XHJcbiAgYXdhaXQgcGlwZWxpbmUocmVzcG9uc2UuYm9keSwgY3JlYXRlV3JpdGVTdHJlYW0oemlwRmlsZVBhdGgpKTtcclxuXHJcbiAgY29uc3QgemlwID0gbmV3IEFkbVppcCh6aXBGaWxlUGF0aCk7XHJcbiAgY29uc3QgZm9sZGVyTmFtZSA9IHppcC5nZXRFbnRyaWVzKClbMF0uZW50cnlOYW1lO1xyXG4gIGNvbnN0IGNpdHlDb2RlID0gZm9sZGVyTmFtZS5zdWJzdHJpbmcoMCwgNik7XHJcbiAgY29uc3QgZGJmRW50cnlOYW1lID0gYCR7Zm9sZGVyTmFtZX0ke29wdGlvbnMuc3RyZWV0RGJmRmlsZU5hbWV9YDtcclxuICBjb25zdCBzdHJlZXREYXRhID0gcGFyc2VEQkYoemlwLmdldEVudHJ5KGRiZkVudHJ5TmFtZSkuZ2V0RGF0YSgpLCBcIndpbjEyNTBcIik7XHJcblxyXG4gIGNvbnN0IHNocEVudHJ5TmFtZSA9IGAke2ZvbGRlck5hbWV9JHtvcHRpb25zLnBvbHlnb25TaHBGaWxlTmFtZX1gO1xyXG4gIGNvbnN0IHBvbHlnb25EYXRhID0gY29udmVydFNocFRvR2VvSnNvbih6aXAuZ2V0RW50cnkoc2hwRW50cnlOYW1lKS5nZXREYXRhKCkpO1xyXG5cclxuICBjb25zdCBkaXN0cmljdFNocEVudHJ5TmFtZSA9IGAke2ZvbGRlck5hbWV9JHtvcHRpb25zLmRpc3RyaWN0UG9seWdvblNocEZpbGVOYW1lfWA7XHJcbiAgY29uc3QgZGlzdHJpY3RTaHBFbnRyeSA9IHppcC5nZXRFbnRyeShkaXN0cmljdFNocEVudHJ5TmFtZSk7XHJcblxyXG4gIGxldCBkaXN0cmljdHNQb2x5Z29uRGF0YTogRmVhdHVyZUNvbGxlY3Rpb24gPSB1bmRlZmluZWQ7XHJcbiAgaWYgKGRpc3RyaWN0U2hwRW50cnkgIT09IG51bGwpIHtcclxuICAgIGNvbnN0IGRpc3RyaWN0RGJmRW50cnlOYW1lID0gYCR7Zm9sZGVyTmFtZX0ke29wdGlvbnMuZGlzdHJpY3RQb2x5Z29uRGJmRmlsZU5hbWV9YDtcclxuICAgIGRpc3RyaWN0c1BvbHlnb25EYXRhID0gY29udmVydFNocFRvR2VvSnNvbihcclxuICAgICAgZGlzdHJpY3RTaHBFbnRyeS5nZXREYXRhKCksXHJcbiAgICAgIHppcC5nZXRFbnRyeShkaXN0cmljdERiZkVudHJ5TmFtZSkuZ2V0RGF0YSgpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcm1TeW5jKHppcEZpbGVQYXRoKTtcclxuICByZXR1cm4geyBzdHJlZXREYXRhLCBwb2x5Z29uRGF0YSwgZGlzdHJpY3RzUG9seWdvbkRhdGEsIGNpdHlDb2RlIH07XHJcbn07XHJcblxyXG5jb25zdCBjb252ZXJ0U2hwVG9HZW9Kc29uID0gKFxyXG4gIHNocEJ1ZmZlcjogQnVmZmVyLFxyXG4gIGRiZkJ1ZmZlcj86IEJ1ZmZlclxyXG4pOiBGZWF0dXJlQ29sbGVjdGlvbiA9PiB7XHJcbiAgY29uc3Qgc2hwID0gbmV3IFNocFRvR2VvSnNvbih7XHJcbiAgICBhcnJheWJ1ZmZlcnM6IHtcclxuICAgICAgc2hwQnVmZmVyLFxyXG4gICAgICAuLi4oZGJmQnVmZmVyID8geyBkYmZCdWZmZXIgfSA6IHt9KSxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgY29uc3QgZ2VvSnNvbiA9IHNocC5nZXRHZW9Kc29uKCk7XHJcbiAgZGVsZXRlIGdlb0pzb24uYmJveDtcclxuXHJcbiAgY29vcmRFYWNoKGdlb0pzb24sIChjdXJyZW50Q29vcmQpID0+IHtcclxuICAgIGNvbnN0IFt5LCB4XSA9IGN1cnJlbnRDb29yZDtcclxuICAgIGNvbnN0IHsgbGF0LCBsb24gfSA9IGp0c2syd2dzODQoLXgsIC15KTtcclxuICAgIGN1cnJlbnRDb29yZFswXSA9IGxvbjtcclxuICAgIGN1cnJlbnRDb29yZFsxXSA9IGxhdDtcclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIGdlb0pzb247XHJcbn07XHJcblxyXG5jb25zdCBpbXBvcnREYXRhVG9EYiA9IGFzeW5jICh7XHJcbiAgc3RyZWV0RGF0YSxcclxuICBjaXR5Q29kZSxcclxuICBwb2x5Z29uRGF0YSxcclxuICBkaXN0cmljdHNQb2x5Z29uRGF0YSxcclxufToge1xyXG4gIHN0cmVldERhdGE6IERiZlN0cmVldFtdO1xyXG4gIGNpdHlDb2RlOiBzdHJpbmc7XHJcbiAgcG9seWdvbkRhdGE6IEZlYXR1cmVDb2xsZWN0aW9uO1xyXG4gIGRpc3RyaWN0c1BvbHlnb25EYXRhPzogRmVhdHVyZUNvbGxlY3Rpb247XHJcbn0pID0+IHtcclxuICBpZiAoc3RyZWV0RGF0YS5sZW5ndGggPiAwKSB7XHJcbiAgICBhd2FpdCBpbnNlcnRTdHJlZXRzRnJvbURiZihzdHJlZXREYXRhKTtcclxuICB9XHJcbiAgYXdhaXQgc2V0Q2l0eVBvbHlnb25HZW9qc29uKGNpdHlDb2RlLCBwb2x5Z29uRGF0YSwgZGlzdHJpY3RzUG9seWdvbkRhdGEpO1xyXG59O1xyXG5cclxuY29uc3QgYXR0ZW1wdHMgPSA1O1xyXG5cclxuZXhwb3J0IGNvbnN0IGRvd25sb2FkQW5kSW1wb3J0U3RyZWV0cyA9IGFzeW5jIChcclxuICBvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCA9IHt9XHJcbik6IFByb21pc2U8dm9pZD4gPT4ge1xyXG4gIGF3YWl0IHJ1blN5bmNQYXJ0KFN5bmNQYXJ0LlN0cmVldHMsIFtTeW5jUGFydC5BZGRyZXNzUG9pbnRzXSwgYXN5bmMgKCkgPT4ge1xyXG4gICAgY29uc29sZS5sb2coXHJcbiAgICAgIFwiU3RhcnRpbmcgdG8gZG93bmxvYWQgYW5kIGltcG9ydCBzdHJlZXRzLiBUaGlzIHRha2VzIHVwIHRvIDEgaG91ci5cIlxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBjb21wbGV0ZU9wdGlvbnMgPSBwcmVwYXJlT3B0aW9ucyhvcHRpb25zKTtcclxuICAgIHByZXBhcmVGb2xkZXJzKGNvbXBsZXRlT3B0aW9ucyk7XHJcblxyXG4gICAgY29uc3QgYWxsRGF0YXNldEZlZWRMaW5rcyA9IGF3YWl0IGdldEFsbFVybHNGcm9tQXRvbUZlZWQoXHJcbiAgICAgIGNvbXBsZXRlT3B0aW9ucy5zdHJlZXRzQXRvbVVybFxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zb2xlLmxvZyhgVG90YWwgb2YgJHthbGxEYXRhc2V0RmVlZExpbmtzLmxlbmd0aH0gbGlua3MgdG8gWklQIGZpbGVzLmApO1xyXG5cclxuICAgIGNvbnN0IHN5bmNlZFN0cmVldExpbmtzID0gYXdhaXQgZ2V0QWxsU3luY2VkU3RyZWV0cygpO1xyXG5cclxuICAgIGNvbnN0IHRvRGVsZXRlOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgLy8gcmVtb3ZlIGFsbCBkZXByZWNhdGVkIGxpbmtzIChub3QgaW4gdGhlIG5ldyBsaXN0KVxyXG4gICAgc3luY2VkU3RyZWV0TGlua3MuZm9yRWFjaCgobGluaykgPT4ge1xyXG4gICAgICBpZiAoIWFsbERhdGFzZXRGZWVkTGlua3MuaW5jbHVkZXMobGluaykpIHtcclxuICAgICAgICB0b0RlbGV0ZS5wdXNoKGxpbmspO1xyXG4gICAgICAgIGRlbGV0ZSBzeW5jZWRTdHJlZXRMaW5rc1tsaW5rXTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgYXdhaXQgZGVsZXRlU3RyZWV0cyh0b0RlbGV0ZSk7XHJcblxyXG4gICAgbGV0IGRvbmUgPSBzeW5jZWRTdHJlZXRMaW5rcy5zaXplO1xyXG4gICAgY29uc29sZS5sb2coYFRvdGFsIG9mICR7ZG9uZX0gbGlua3MgdG8gWklQIGZpbGVzIGFscmVhZHkgc3RvcmVkLmApO1xyXG5cclxuICAgIC8vIGdldCBhbGwgbGlua3Mgbm90IHlldCBzdG9yZWRcclxuICAgIGNvbnN0IG5ld0xpbmtzID0gYWxsRGF0YXNldEZlZWRMaW5rcy5maWx0ZXIoXHJcbiAgICAgIChsaW5rKSA9PiAhc3luY2VkU3RyZWV0TGlua3MuaGFzKGxpbmspXHJcbiAgICApO1xyXG5cclxuICAgIGxldCBkZWxheSA9IDA7XHJcbiAgICBjb25zb2xlLmxvZyhgTG9hZGluZyAke25ld0xpbmtzLmxlbmd0aH0gbmV3IGxpbmtzIHRvIFpJUCBmaWxlcy5gKTtcclxuICAgIGZvciAoY29uc3QgbGluayBvZiBuZXdMaW5rcykge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dGVtcHRzOyBpKyspIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY29uc3QgemlwTGluayA9IGF3YWl0IGdldExhdGVzdFVybEZyb21BdG9tRmVlZChsaW5rKTtcclxuICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBkb3dubG9hZFppcEFuZFBhcnNlRmlsZXMoXHJcbiAgICAgICAgICAgIHppcExpbmssXHJcbiAgICAgICAgICAgIGRvbmUsXHJcbiAgICAgICAgICAgIGNvbXBsZXRlT3B0aW9uc1xyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGF3YWl0IGltcG9ydERhdGFUb0RiKGRhdGEpO1xyXG4gICAgICAgICAgYXdhaXQgc2V0U3RyZWV0QXNTeW5jZWQobGluayk7XHJcblxyXG4gICAgICAgICAgZG9uZSsrO1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYExvYWRlZCBsaW5rczogJHtkb25lfS8ke2FsbERhdGFzZXRGZWVkTGlua3MubGVuZ3RofWApO1xyXG4gICAgICAgICAgYXdhaXQgd2FpdChkZWxheSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgaWYgKGkgPCBhdHRlbXB0cyAtIDEpIHtcclxuICAgICAgICAgICAgZGVsYXkgKz0gMTAwOyAvLyBpZiBlcnJvciBvY2N1cmVkLCBpdCBpcyBsaWtlbHkgdG8gcmVwZWF0IHNvIHdlIHdhaXQgYSBiaXQgbG9uZ2VyXHJcbiAgICAgICAgICAgIGNvbnN0IHdhaXRUaW1lID0gKGkgKyAxKSAqIDM7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXHJcbiAgICAgICAgICAgICAgYEVycm9yIGNvbm5lY3RpbmcgdG8gQ1VaSyBzZXJ2ZXJzLCByZXRyeWluZyBpbiAke3dhaXRUaW1lfSBzZWNvbmRzLi4uYFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XHJcbiAgICAgICAgICAgIGF3YWl0IHdhaXQod2FpdFRpbWUgKiAxMDAwKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG59O1xyXG5cclxuY29uc3Qgd2FpdCA9IGFzeW5jIChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XHJcbiAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcclxufTtcclxuIl19
|