text-to-map
Version:
Text To Map usiluje o lepší, strojově zpracovatelné využití částí vyhlášek s výčtem ulic a dalších lokací. Jde o rozšiřitelnou sadu konceptů a nástrojů, které zajistí hladký převod výčtu ulic a jejich rozsahů v lidsky srozumitelném jazyce do strojově zpra
81 lines • 16 kB
JavaScript
import { extractKeyValuesPairs, getKnexDb, insertMultipleRows } from "./db";
export const insertRegionsAndOrps = async (data, schema) => {
const columnIndex = getColumnIndexFromSchema(schema);
let changes = 0;
changes += await insertRegions(data, columnIndex);
changes += await insertCounties(data, columnIndex);
changes += await insertOrps(data, columnIndex);
// cities are most likely already inserted, but in case they're not,
// we need to insert them before updating them with region data
changes += await insertCities(data, columnIndex);
const knex = getKnexDb();
for (const row of data) {
await knex
.from("city")
.update({
region_code: row[columnIndex.regionRuianCode],
county_code: row[columnIndex.countyRuianCode],
orp_code: row[columnIndex.orpRuianCode],
})
.where({ code: row[columnIndex.cityCode] });
changes++;
}
return changes;
};
export const insertRegions = async (buffer, columnIndex) => {
return await insertMultipleRows(extractKeyValuesPairs(buffer, columnIndex.regionRuianCode, [
columnIndex.regionName,
columnIndex.regionShortName,
columnIndex.regionCsuCode100,
columnIndex.regionCsuCode108Nuts,
]), "region", ["code", "name", "short_name", "csu_code_100", "csu_code_108_nuts"]);
};
export const insertCounties = async (buffer, columnIndex) => {
return await insertMultipleRows(extractKeyValuesPairs(buffer, columnIndex.countyRuianCode, [
columnIndex.countyName,
columnIndex.countyCsuCode101Lau,
columnIndex.countyCsuCode109Nuts,
columnIndex.regionRuianCode,
]), "county", ["code", "name", "csu_code_101_lau", "csu_code_109_nuts", "region_code"]);
};
export const insertOrps = async (buffer, columnIndex) => {
return await insertMultipleRows(extractKeyValuesPairs(buffer, columnIndex.orpRuianCode, [
columnIndex.orpName,
columnIndex.orpCsuCode65,
columnIndex.regionRuianCode,
columnIndex.countyRuianCode,
]), "orp", ["code", "name", "csu_code_65", "region_code", "county_code"]);
};
export const insertCities = async (buffer, columnIndex) => {
return await insertMultipleRows(extractKeyValuesPairs(buffer, columnIndex.cityCode, [columnIndex.cityName]), "city", ["code", "name"]);
};
const getColumnIndexFromSchema = (schema) => {
const names = schema.tableSchema.columns.map((column) => column.name);
const columnIndex = {
cityName: findOrDie(names, "obec_text"),
cityCode: findOrDie(names, "obec_kod"),
cityType: findOrDie(names, "obec_typ"),
orpName: findOrDie(names, "orp_text"),
orpCsuCode65: findOrDie(names, "orp_csu_cis65_kod"),
orpRuianCode: findOrDie(names, "orp_ruian_kod"),
orpCityCode: findOrDie(names, "orp_sidlo_obec_kod"),
countyName: findOrDie(names, "okres_text"),
countyCsuCode101Lau: findOrDie(names, "okres_csu_cis101_lau_kod"),
countyCsuCode109Nuts: findOrDie(names, "okres_csu_cis109_nuts_kod"),
countyRuianCode: findOrDie(names, "okres_ruian_kod"),
regionName: findOrDie(names, "kraj_text"),
regionShortName: findOrDie(names, "kraj_zkratka"),
regionCsuCode100: findOrDie(names, "kraj_csu_cis100_kod"),
regionCsuCode108Nuts: findOrDie(names, "kraj_csu_cis108_nuts_kod"),
regionRuianCode: findOrDie(names, "kraj_ruian_vusc_kod"),
};
return columnIndex;
};
const findOrDie = (columnNames, name) => {
const index = columnNames.indexOf(name);
if (index < 0) {
throw new Error(`Column '${name}' not found in region schema. Check https://data.gov.cz/datov%C3%A1-sada?iri=https%3A%2F%2Fdata.gov.cz%2Fzdroj%2Fdatov%C3%A9-sady%2F00025593%2F271b0fb7c2abb7f44e12ad57617821b2 for current dataset info or search for 'Struktura území ČR se všemi kódy území od obcí po stát dle číselníků ČSÚ, klasifikace NUTS a kódů RÚIAN.'.`);
}
return index;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi9yZWdpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsU0FBUyxFQUNULGtCQUFrQixFQUNuQixNQUFNLE1BQU0sQ0FBQztBQTZCZCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLEVBQ3ZDLElBQWdCLEVBQ2hCLE1BQTBCLEVBQ1QsRUFBRTtJQUNuQixNQUFNLFdBQVcsR0FBRyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVyRCxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDaEIsT0FBTyxJQUFJLE1BQU0sYUFBYSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNsRCxPQUFPLElBQUksTUFBTSxjQUFjLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ25ELE9BQU8sSUFBSSxNQUFNLFVBQVUsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFFL0Msb0VBQW9FO0lBQ3BFLCtEQUErRDtJQUMvRCxPQUFPLElBQUksTUFBTSxZQUFZLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBRWpELE1BQU0sSUFBSSxHQUFHLFNBQVMsRUFBRSxDQUFDO0lBRXpCLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFO1FBQ3RCLE1BQU0sSUFBSTthQUNQLElBQUksQ0FBQyxNQUFNLENBQUM7YUFDWixNQUFNLENBQUM7WUFDTixXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUM7WUFDN0MsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDO1lBQzdDLFFBQVEsRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQztTQUN4QyxDQUFDO2FBQ0QsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxXQUFXLENB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RUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLG9CQUFvQixDQUFDO1FBQ25ELFVBQVUsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQztRQUMxQyxtQkFBbUIsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLDBCQUEwQixDQUFDO1FBQ2pFLG9CQUFvQixFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUsMkJBQTJCLENBQUM7UUFDbkUsZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUM7UUFDcEQsVUFBVSxFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDO1FBQ3pDLGVBQWUsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQztRQUNqRCxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLHFCQUFxQixDQUFDO1FBQ3pELG9CQUFvQixFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUsMEJBQTBCLENBQUM7UUFDbEUsZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUscUJBQXFCLENBQUM7S0FDekQsQ0FBQztJQUVGLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUMsQ0FBQztBQUVGLE1BQU0sU0FBUyxHQUFHLENBQUMsV0FBcUIsRUFBRSxJQUFZLEVBQVUsRUFBRTtJQUNoRSxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRTtRQUNiLE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxJQUFJLG9VQUFvVSxDQUNwVixDQUFDO0tBQ0g7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgZXh0cmFjdEtleVZhbHVlc1BhaXJzLFxyXG4gIGdldEtuZXhEYixcclxuICBpbnNlcnRNdWx0aXBsZVJvd3NcclxufSBmcm9tIFwiLi9kYlwiO1xyXG5cclxuaW50ZXJmYWNlIFJlZ2lvbnNDb2x1bW4ge1xyXG4gIGNpdHlOYW1lOiBudW1iZXI7XHJcbiAgY2l0eUNvZGU6IG51bWJlcjtcclxuICBjaXR5VHlwZTogbnVtYmVyO1xyXG4gIG9ycE5hbWU6IG51bWJlcjtcclxuICBvcnBDc3VDb2RlNjU6IG51bWJlcjtcclxuICBvcnBSdWlhbkNvZGU6IG51bWJlcjtcclxuICBvcnBDaXR5Q29kZTogbnVtYmVyO1xyXG4gIGNvdW50eU5hbWU6IG51bWJlcjtcclxuICBjb3VudHlDc3VDb2RlMTAxTGF1OiBudW1iZXI7XHJcbiAgY291bnR5Q3N1Q29kZTEwOU51dHM6IG51bWJlcjtcclxuICBjb3VudHlSdWlhbkNvZGU6IG51bWJlcjtcclxuICByZWdpb25OYW1lOiBudW1iZXI7XHJcbiAgcmVnaW9uU2hvcnROYW1lOiBudW1iZXI7XHJcbiAgcmVnaW9uQ3N1Q29kZTEwMDogbnVtYmVyO1xyXG4gIHJlZ2lvbkNzdUNvZGUxMDhOdXRzOiBudW1iZXI7XHJcbiAgcmVnaW9uUnVpYW5Db2RlOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVnaW9uc1RhYmxlU2NoZW1hIHtcclxuICB0YWJsZVNjaGVtYToge1xyXG4gICAgY29sdW1uczoge1xyXG4gICAgICBuYW1lOiBzdHJpbmc7XHJcbiAgICB9W107XHJcbiAgfTtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGluc2VydFJlZ2lvbnNBbmRPcnBzID0gYXN5bmMgKFxyXG4gIGRhdGE6IHN0cmluZ1tdW10sXHJcbiAgc2NoZW1hOiBSZWdpb25zVGFibGVTY2hlbWFcclxuKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcclxuICBjb25zdCBjb2x1bW5JbmRleCA9IGdldENvbHVtbkluZGV4RnJvbVNjaGVtYShzY2hlbWEpO1xyXG5cclxuICBsZXQgY2hhbmdlcyA9IDA7XHJcbiAgY2hhbmdlcyArPSBhd2FpdCBpbnNlcnRSZWdpb25zKGRhdGEsIGNvbHVtbkluZGV4KTtcclxuICBjaGFuZ2VzICs9IGF3YWl0IGluc2VydENvdW50aWVzKGRhdGEsIGNvbHVtbkluZGV4KTtcclxuICBjaGFuZ2VzICs9IGF3YWl0IGluc2VydE9ycHMoZGF0YSwgY29sdW1uSW5kZXgpO1xyXG5cclxuICAvLyBjaXRpZXMgYXJlIG1vc3QgbGlrZWx5IGFscmVhZHkgaW5zZXJ0ZWQsIGJ1dCBpbiBjYXNlIHRoZXkncmUgbm90LFxyXG4gIC8vIHdlIG5lZWQgdG8gaW5zZXJ0IHRoZW0gYmVmb3JlIHVwZGF0aW5nIHRoZW0gd2l0aCByZWdpb24gZGF0YVxyXG4gIGNoYW5nZXMgKz0gYXdhaXQgaW5zZXJ0Q2l0aWVzKGRhdGEsIGNvbHVtbkluZGV4KTtcclxuXHJcbiAgY29uc3Qga25leCA9IGdldEtuZXhEYigpO1xyXG5cclxuICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhKSB7XHJcbiAgICBhd2FpdCBrbmV4XHJcbiAgICAgIC5mcm9tKFwiY2l0eVwiKVxyXG4gICAgICAudXBkYXRlKHtcclxuICAgICAgICByZWdpb25fY29kZTogcm93W2NvbHVtbkluZGV4LnJlZ2lvblJ1aWFuQ29kZV0sXHJcbiAgICAgICAgY291bnR5X2NvZGU6IHJvd1tjb2x1bW5JbmRleC5jb3VudHlSdWlhbkNvZGVdLFxyXG4gICAgICAgIG9ycF9jb2RlOiByb3dbY29sdW1uSW5kZXgub3JwUnVpYW5Db2RlXSxcclxuICAgICAgfSlcclxuICAgICAgLndoZXJlKHsgY29kZTogcm93W2NvbHVtbkluZGV4LmNpdHlDb2RlXSB9KTtcclxuICAgIGNoYW5nZXMrKztcclxuICB9XHJcblxyXG4gIHJldHVybiBjaGFuZ2VzO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGluc2VydFJlZ2lvbnMgPSBhc3luYyAoXHJcbiAgYnVmZmVyOiBzdHJpbmdbXVtdLFxyXG4gIGNvbHVtbkluZGV4OiBSZWdpb25zQ29sdW1uXHJcbik6IFByb21pc2U8bnVtYmVyPiA9PiB7XHJcbiAgcmV0dXJuIGF3YWl0IGluc2VydE11bHRpcGxlUm93cyhcclxuICAgIGV4dHJhY3RLZXlWYWx1ZXNQYWlycyhidWZmZXIsIGNvbHVtbkluZGV4LnJlZ2lvblJ1aWFuQ29kZSwgW1xyXG4gICAgICBjb2x1bW5JbmRleC5yZWdpb25OYW1lLFxyXG4gICAgICBjb2x1bW5JbmRleC5yZWdpb25TaG9ydE5hbWUsXHJcbiAgICAgIGNvbHVtbkluZGV4LnJlZ2lvbkNzdUNvZGUxMDAsXHJcbiAgICAgIGNvbHVtbkluZGV4LnJlZ2lvbkNzdUNvZGUxMDhOdXRzLFxyXG4gICAgXSksXHJcbiAgICBcInJlZ2lvblwiLFxyXG4gICAgW1wiY29kZVwiLCBcIm5hbWVcIiwgXCJzaG9ydF9uYW1lXCIsIFwiY3N1X2NvZGVfMTAwXCIsIFwiY3N1X2NvZGVfMTA4X251dHNcIl1cclxuICApO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGluc2VydENvdW50aWVzID0gYXN5bmMgKFxyXG4gIGJ1ZmZlcjogc3RyaW5nW11bXSxcclxuICBjb2x1bW5JbmRleDogUmVnaW9uc0NvbHVtblxyXG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xyXG4gIHJldHVybiBhd2FpdCBpbnNlcnRNdWx0aXBsZVJvd3MoXHJcbiAgICBleHRyYWN0S2V5VmFsdWVzUGFpcnMoYnVmZmVyLCBjb2x1bW5JbmRleC5jb3VudHlSdWlhbkNvZGUsIFtcclxuICAgICAgY29sdW1uSW5kZXguY291bnR5TmFtZSxcclxuICAgICAgY29sdW1uSW5kZXguY291bnR5Q3N1Q29kZTEwMUxhdSxcclxuICAgICAgY29sdW1uSW5kZXguY291bnR5Q3N1Q29kZTEwOU51dHMsXHJcbiAgICAgIGNvbHVtbkluZGV4LnJlZ2lvblJ1aWFuQ29kZSxcclxuICAgIF0pLFxyXG4gICAgXCJjb3VudHlcIixcclxuICAgIFtcImNvZGVcIiwgXCJuYW1lXCIsIFwiY3N1X2NvZGVfMTAxX2xhdVwiLCBcImNzdV9jb2RlXzEwOV9udXRzXCIsIFwicmVnaW9uX2NvZGVcIl1cclxuICApO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGluc2VydE9ycHMgPSBhc3luYyAoXHJcbiAgYnVmZmVyOiBzdHJpbmdbXVtdLFxyXG4gIGNvbHVtbkluZGV4OiBSZWdpb25zQ29sdW1uXHJcbik6IFByb21pc2U8bnVtYmVyPiA9PiB7XHJcbiAgcmV0dXJuIGF3YWl0IGluc2VydE11bHRpcGxlUm93cyhcclxuICAgIGV4dHJhY3RLZXlWYWx1ZXNQYWlycyhidWZmZXIsIGNvbHVtbkluZGV4Lm9ycFJ1aWFuQ29kZSwgW1xyXG4gICAgICBjb2x1bW5JbmRleC5vcnBOYW1lLFxyXG4gICAgICBjb2x1bW5JbmRleC5vcnBDc3VDb2RlNjUsXHJcbiAgICAgIGNvbHVtbkluZGV4LnJlZ2lvblJ1aWFuQ29kZSxcclxuICAgICAgY29sdW1uSW5kZXguY291bnR5UnVpYW5Db2RlLFxyXG4gICAgXSksXHJcbiAgICBcIm9ycFwiLFxyXG4gICAgW1wiY29kZVwiLCBcIm5hbWVcIiwgXCJjc3VfY29kZV82NVwiLCBcInJlZ2lvbl9jb2RlXCIsIFwiY291bnR5X2NvZGVcIl1cclxuICApO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGluc2VydENpdGllcyA9IGFzeW5jIChcclxuICBidWZmZXI6IHN0cmluZ1tdW10sXHJcbiAgY29sdW1uSW5kZXg6IFJlZ2lvbnNDb2x1bW5cclxuKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcclxuICByZXR1cm4gYXdhaXQgaW5zZXJ0TXVsdGlwbGVSb3dzKFxyXG4gICAgZXh0cmFjdEtleVZhbHVlc1BhaXJzKGJ1ZmZlciwgY29sdW1uSW5kZXguY2l0eUNvZGUsIFtjb2x1bW5JbmRleC5jaXR5TmFtZV0pLFxyXG4gICAgXCJjaXR5XCIsXHJcbiAgICBbXCJjb2RlXCIsIFwibmFtZVwiXVxyXG4gICk7XHJcbn07XHJcblxyXG5jb25zdCBnZXRDb2x1bW5JbmRleEZyb21TY2hlbWEgPSAoXHJcbiAgc2NoZW1hOiBSZWdpb25zVGFibGVTY2hlbWFcclxuKTogUmVnaW9uc0NvbHVtbiA9PiB7XHJcbiAgY29uc3QgbmFtZXMgPSBzY2hlbWEudGFibGVTY2hlbWEuY29sdW1ucy5tYXAoKGNvbHVtbikgPT4gY29sdW1uLm5hbWUpO1xyXG5cclxuICBjb25zdCBjb2x1bW5JbmRleDogUmVnaW9uc0NvbHVtbiA9IHtcclxuICAgIGNpdHlOYW1lOiBmaW5kT3JEaWUobmFtZXMsIFwib2JlY190ZXh0XCIpLFxyXG4gICAgY2l0eUNvZGU6IGZpbmRPckRpZShuYW1lcywgXCJvYmVjX2tvZFwiKSxcclxuICAgIGNpdHlUeXBlOiBmaW5kT3JEaWUobmFtZXMsIFwib2JlY190eXBcIiksXHJcbiAgICBvcnBOYW1lOiBmaW5kT3JEaWUobmFtZXMsIFwib3JwX3RleHRcIiksXHJcbiAgICBvcnBDc3VDb2RlNjU6IGZpbmRPckRpZShuYW1lcywgXCJvcnBfY3N1X2NpczY1X2tvZFwiKSxcclxuICAgIG9ycFJ1aWFuQ29kZTogZmluZE9yRGllKG5hbWVzLCBcIm9ycF9ydWlhbl9rb2RcIiksXHJcbiAgICBvcnBDaXR5Q29kZTogZmluZE9yRGllKG5hbWVzLCBcIm9ycF9zaWRsb19vYmVjX2tvZFwiKSxcclxuICAgIGNvdW50eU5hbWU6IGZpbmRPckRpZShuYW1lcywgXCJva3Jlc190ZXh0XCIpLFxyXG4gICAgY291bnR5Q3N1Q29kZTEwMUxhdTogZmluZE9yRGllKG5hbWVzLCBcIm9rcmVzX2NzdV9jaXMxMDFfbGF1X2tvZFwiKSxcclxuICAgIGNvdW50eUNzdUNvZGUxMDlOdXRzOiBmaW5kT3JEaWUobmFtZXMsIFwib2tyZXNfY3N1X2NpczEwOV9udXRzX2tvZFwiKSxcclxuICAgIGNvdW50eVJ1aWFuQ29kZTogZmluZE9yRGllKG5hbWVzLCBcIm9rcmVzX3J1aWFuX2tvZFwiKSxcclxuICAgIHJlZ2lvbk5hbWU6IGZpbmRPckRpZShuYW1lcywgXCJrcmFqX3RleHRcIiksXHJcbiAgICByZWdpb25TaG9ydE5hbWU6IGZpbmRPckRpZShuYW1lcywgXCJrcmFqX3prcmF0a2FcIiksXHJcbiAgICByZWdpb25Dc3VDb2RlMTAwOiBmaW5kT3JEaWUobmFtZXMsIFwia3Jhal9jc3VfY2lzMTAwX2tvZFwiKSxcclxuICAgIHJlZ2lvbkNzdUNvZGUxMDhOdXRzOiBmaW5kT3JEaWUobmFtZXMsIFwia3Jhal9jc3VfY2lzMTA4X251dHNfa29kXCIpLFxyXG4gICAgcmVnaW9uUnVpYW5Db2RlOiBmaW5kT3JEaWUobmFtZXMsIFwia3Jhal9ydWlhbl92dXNjX2tvZFwiKSxcclxuICB9O1xyXG5cclxuICByZXR1cm4gY29sdW1uSW5kZXg7XHJcbn07XHJcblxyXG5jb25zdCBmaW5kT3JEaWUgPSAoY29sdW1uTmFtZXM6IHN0cmluZ1tdLCBuYW1lOiBzdHJpbmcpOiBudW1iZXIgPT4ge1xyXG4gIGNvbnN0IGluZGV4ID0gY29sdW1uTmFtZXMuaW5kZXhPZihuYW1lKTtcclxuICBpZiAoaW5kZXggPCAwKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgIGBDb2x1bW4gJyR7bmFtZX0nIG5vdCBmb3VuZCBpbiByZWdpb24gc2NoZW1hLiBDaGVjayBodHRwczovL2RhdGEuZ292LmN6L2RhdG92JUMzJUExLXNhZGE/aXJpPWh0dHBzJTNBJTJGJTJGZGF0YS5nb3YuY3olMkZ6ZHJvaiUyRmRhdG92JUMzJUE5LXNhZHklMkYwMDAyNTU5MyUyRjI3MWIwZmI3YzJhYmI3ZjQ0ZTEyYWQ1NzYxNzgyMWIyIGZvciBjdXJyZW50IGRhdGFzZXQgaW5mbyBvciBzZWFyY2ggZm9yICdTdHJ1a3R1cmEgw7p6ZW3DrSDEjFIgc2UgdsWhZW1pIGvDs2R5IMO6emVtw60gb2Qgb2Jjw60gcG8gc3TDoXQgZGxlIMSNw61zZWxuw61rxa8gxIxTw5osIGtsYXNpZmlrYWNlIE5VVFMgYSBrw7Nkxa8gUsOaSUFOLicuYFxyXG4gICAgKTtcclxuICB9XHJcbiAgcmV0dXJuIGluZGV4O1xyXG59O1xyXG4iXX0=