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
154 lines • 19.2 kB
JavaScript
import { readFileSync } from "fs";
const streetNamePattern = /^([^ -]+([ -]?[^ -]+)*)/;
const streetSeriesPartPattern = /(lichá č.|sudá č.|č. p.|č.)/;
const rangePattern = /(\d+[a-z]? ?[-] ?\d+[a-z]?|(od )?\d+[a-z]?( a)? výše|\d+[a-z]?)(, ?| a )/;
const numberPattern = /\d+/;
const OddTypeString = "lichá č.";
const EvenTypeString = "sudá č.";
const AllTypeString = "č.";
const CPTypeString = "č. p.";
const StreetNumberSeriesType = {
Odd: "odd",
Even: "even",
CP: "cp",
All: "all",
};
const _min = 0;
const _max = 10000;
const StreetNumberRule = {
MinFrom: _min,
MaxTo: _max,
EmptyRule: {
type: StreetNumberSeriesType.All,
from: _min,
to: _max,
},
};
const createStreetRule = (type, from = StreetNumberRule.MinFrom, to = StreetNumberRule.MaxTo) => {
return {
type: type,
from: from,
to: to,
};
};
const getStreetRules = (numberSpecification) => {
let rules = [];
let position = 0;
if (numberSpecification == "") {
return [StreetNumberRule.EmptyRule];
}
while (position < numberSpecification.length) {
var remainder = numberSpecification.substr(position);
var match = streetSeriesPartPattern.exec(remainder);
// if no series type is found, it's an error
if (match == null || match.index != 0) {
return null;
}
var type = getSeriesType(match[0]);
position += match[0].length;
remainder = numberSpecification.substr(position);
match = streetSeriesPartPattern.exec(remainder);
var end = numberSpecification.length;
if (match != null) {
end = position + match.index;
}
var rangePart = numberSpecification.substr(position, end - position);
rules = rules.concat(getRulesFromRangePart(rangePart, type));
position = end;
}
return rules;
};
const getRulesFromRangePart = (rangePart, seriesType) => {
let rules = [];
if (removeSeparatorFromEnd(rangePart) == "") {
rules.push(createStreetRule(seriesType));
return rules;
}
let position = 0;
rangePart = rangePart.trim() + ", ";
while (position < rangePart.length) {
var match = rangePattern.exec(rangePart.substr(position));
if (match == null) {
break;
}
position += match.index + match[0].length;
var value = removeSeparatorFromEnd(match[0]);
if (value.indexOf("-") != -1) {
var fromTo = value.split("-");
rules.push(createStreetRule(seriesType, parseInt(fromTo[0]), fromTo[1]));
}
else if (value.indexOf("výše") != -1) {
var number = parseInt(numberPattern.exec(value)[0]);
rules.push(createStreetRule(seriesType, number));
}
else {
var number = parseInt(numberPattern.exec(value)[0]);
rules.push(createStreetRule(seriesType, number, number));
}
}
return rules;
};
const getSeriesType = (pattern) => {
switch (pattern) {
case OddTypeString:
return StreetNumberSeriesType.Odd;
case EvenTypeString:
return StreetNumberSeriesType.Even;
case CPTypeString:
return StreetNumberSeriesType.CP;
case AllTypeString:
default:
return StreetNumberSeriesType.All;
}
};
const removeSeparatorFromEnd = (text) => {
text = text.trim();
if (text[text.length - 1] == "a" || text[text.length - 1] == ",") {
text = text.substr(0, text.length - 1);
}
return text.trim();
};
// desired output format:
// Příčná(str);from(int);to(int);[odd|even|all|cp];school(str)
export function districtsToCsvRules(districts, includeDistrictName = false) {
const lines = [];
districts.forEach((district) => {
district.schools.forEach((school) => {
school.lines.forEach((street) => {
if (street[0] == "!" || street == "") {
return;
}
let result = streetNamePattern.exec(street);
let streetName = result[0];
let numberSpecification = street.substr(streetName.length + 3).trim();
let rules = getStreetRules(numberSpecification);
if (rules == null || rules.length == 0) {
console.error("Error: " + street);
return;
}
rules.forEach((rule) => {
lines.push(streetName +
";" +
rule.from +
";" +
rule.to +
";" +
rule.type +
";" +
school.name +
(includeDistrictName ? ";" + district.name : ""));
});
});
});
});
return lines.join("\n");
}
// let raw = readFileSync("out.json", "utf-8");
// let districts;
// try {
// districts = JSON.parse(raw);
// } catch (error) {
// console.log(error);
// return;
// }
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi10by1jc3YuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc21kLXRvLWNzdi9qc29uLXRvLWNzdi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBRWxDLE1BQU0saUJBQWlCLEdBQUcseUJBQXlCLENBQUM7QUFDcEQsTUFBTSx1QkFBdUIsR0FBRyw2QkFBNkIsQ0FBQztBQUM5RCxNQUFNLFlBQVksR0FDaEIsMEVBQTBFLENBQUM7QUFDN0UsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDO0FBRTVCLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQztBQUNqQyxNQUFNLGNBQWMsR0FBRyxTQUFTLENBQUM7QUFDakMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQztBQUU3QixNQUFNLHNCQUFzQixHQUFHO0lBQzdCLEdBQUcsRUFBRSxLQUFLO0lBQ1YsSUFBSSxFQUFFLE1BQU07SUFDWixFQUFFLEVBQUUsSUFBSTtJQUNSLEdBQUcsRUFBRSxLQUFLO0NBQ1gsQ0FBQztBQUVGLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNmLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQztBQUNuQixNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLE9BQU8sRUFBRSxJQUFJO0lBQ2IsS0FBSyxFQUFFLElBQUk7SUFDWCxTQUFTLEVBQUU7UUFDVCxJQUFJLEVBQUUsc0JBQXNCLENBQUMsR0FBRztRQUNoQyxJQUFJLEVBQUUsSUFBSTtRQUNWLEVBQUUsRUFBRSxJQUFJO0tBQ1Q7Q0FDRixDQUFDO0FBRUYsTUFBTSxnQkFBZ0IsR0FBRyxDQUN2QixJQUFJLEVBQ0osSUFBSSxHQUFHLGdCQUFnQixDQUFDLE9BQU8sRUFDL0IsRUFBRSxHQUFHLGdCQUFnQixDQUFDLEtBQUssRUFDM0IsRUFBRTtJQUNGLE9BQU87UUFDTCxJQUFJLEVBQUUs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SyxJQUFJLElBQUksSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtvQkFDdEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLENBQUM7b0JBQ2xDLE9BQU87aUJBQ1I7Z0JBQ0QsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO29CQUNyQixLQUFLLENBQUMsSUFBSSxDQUNSLFVBQVU7d0JBQ1IsR0FBRzt3QkFDSCxJQUFJLENBQUMsSUFBSTt3QkFDVCxHQUFHO3dCQUNILElBQUksQ0FBQyxFQUFFO3dCQUNQLEdBQUc7d0JBQ0gsSUFBSSxDQUFDLElBQUk7d0JBQ1QsR0FBRzt3QkFDSCxNQUFNLENBQUMsSUFBSTt3QkFDWCxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQ25ELENBQUM7Z0JBQ0osQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVELCtDQUErQztBQUMvQyxpQkFBaUI7QUFDakIsUUFBUTtBQUNSLGlDQUFpQztBQUNqQyxvQkFBb0I7QUFDcEIsd0JBQXdCO0FBQ3hCLFlBQVk7QUFDWixJQUFJIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcImZzXCI7XHJcblxyXG5jb25zdCBzdHJlZXROYW1lUGF0dGVybiA9IC9eKFteIC1dKyhbIC1dP1teIC1dKykqKS87XHJcbmNvbnN0IHN0cmVldFNlcmllc1BhcnRQYXR0ZXJuID0gLyhsaWNow6EgxI0ufHN1ZMOhIMSNLnzEjS4gcC58xI0uKS87XHJcbmNvbnN0IHJhbmdlUGF0dGVybiA9XHJcbiAgLyhcXGQrW2Etel0/ID9bLV0gP1xcZCtbYS16XT98KG9kICk/XFxkK1thLXpdPyggYSk/IHbDvcWhZXxcXGQrW2Etel0/KSgsID98IGEgKS87XHJcbmNvbnN0IG51bWJlclBhdHRlcm4gPSAvXFxkKy87XHJcblxyXG5jb25zdCBPZGRUeXBlU3RyaW5nID0gXCJsaWNow6EgxI0uXCI7XHJcbmNvbnN0IEV2ZW5UeXBlU3RyaW5nID0gXCJzdWTDoSDEjS5cIjtcclxuY29uc3QgQWxsVHlwZVN0cmluZyA9IFwixI0uXCI7XHJcbmNvbnN0IENQVHlwZVN0cmluZyA9IFwixI0uIHAuXCI7XHJcblxyXG5jb25zdCBTdHJlZXROdW1iZXJTZXJpZXNUeXBlID0ge1xyXG4gIE9kZDogXCJvZGRcIixcclxuICBFdmVuOiBcImV2ZW5cIixcclxuICBDUDogXCJjcFwiLFxyXG4gIEFsbDogXCJhbGxcIixcclxufTtcclxuXHJcbmNvbnN0IF9taW4gPSAwO1xyXG5jb25zdCBfbWF4ID0gMTAwMDA7XHJcbmNvbnN0IFN0cmVldE51bWJlclJ1bGUgPSB7XHJcbiAgTWluRnJvbTogX21pbixcclxuICBNYXhUbzogX21heCxcclxuICBFbXB0eVJ1bGU6IHtcclxuICAgIHR5cGU6IFN0cmVldE51bWJlclNlcmllc1R5cGUuQWxsLFxyXG4gICAgZnJvbTogX21pbixcclxuICAgIHRvOiBfbWF4LFxyXG4gIH0sXHJcbn07XHJcblxyXG5jb25zdCBjcmVhdGVTdHJlZXRSdWxlID0gKFxyXG4gIHR5cGUsXHJcbiAgZnJvbSA9IFN0cmVldE51bWJlclJ1bGUuTWluRnJvbSxcclxuICB0byA9IFN0cmVldE51bWJlclJ1bGUuTWF4VG9cclxuKSA9PiB7XHJcbiAgcmV0dXJuIHtcclxuICAgIHR5cGU6IHR5cGUsXHJcbiAgICBmcm9tOiBmcm9tLFxyXG4gICAgdG86IHRvLFxyXG4gIH07XHJcbn07XHJcblxyXG5jb25zdCBnZXRTdHJlZXRSdWxlcyA9IChudW1iZXJTcGVjaWZpY2F0aW9uKSA9PiB7XHJcbiAgbGV0IHJ1bGVzID0gW107XHJcbiAgbGV0IHBvc2l0aW9uID0gMDtcclxuXHJcbiAgaWYgKG51bWJlclNwZWNpZmljYXRpb24gPT0gXCJcIikge1xyXG4gICAgcmV0dXJuIFtTdHJlZXROdW1iZXJSdWxlLkVtcHR5UnVsZV07XHJcbiAgfVxyXG5cclxuICB3aGlsZSAocG9zaXRpb24gPCBudW1iZXJTcGVjaWZpY2F0aW9uLmxlbmd0aCkge1xyXG4gICAgdmFyIHJlbWFpbmRlciA9IG51bWJlclNwZWNpZmljYXRpb24uc3Vic3RyKHBvc2l0aW9uKTtcclxuICAgIHZhciBtYXRjaCA9IHN0cmVldFNlcmllc1BhcnRQYXR0ZXJuLmV4ZWMocmVtYWluZGVyKTtcclxuICAgIC8vIGlmIG5vIHNlcmllcyB0eXBlIGlzIGZvdW5kLCBpdCdzIGFuIGVycm9yXHJcbiAgICBpZiAobWF0Y2ggPT0gbnVsbCB8fCBtYXRjaC5pbmRleCAhPSAwKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgdmFyIHR5cGUgPSBnZXRTZXJpZXNUeXBlKG1hdGNoWzBdKTtcclxuICAgIHBvc2l0aW9uICs9IG1hdGNoWzBdLmxlbmd0aDtcclxuICAgIHJlbWFpbmRlciA9IG51bWJlclNwZWNpZmljYXRpb24uc3Vic3RyKHBvc2l0aW9uKTtcclxuICAgIG1hdGNoID0gc3RyZWV0U2VyaWVzUGFydFBhdHRlcm4uZXhlYyhyZW1haW5kZXIpO1xyXG4gICAgdmFyIGVuZCA9IG51bWJlclNwZWNpZmljYXRpb24ubGVuZ3RoO1xyXG4gICAgaWYgKG1hdGNoICE9IG51bGwpIHtcclxuICAgICAgZW5kID0gcG9zaXRpb24gKyBtYXRjaC5pbmRleDtcclxuICAgIH1cclxuICAgIHZhciByYW5nZVBhcnQgPSBudW1iZXJTcGVjaWZpY2F0aW9uLnN1YnN0cihwb3NpdGlvbiwgZW5kIC0gcG9zaXRpb24pO1xyXG4gICAgcnVsZXMgPSBydWxlcy5jb25jYXQoZ2V0UnVsZXNGcm9tUmFuZ2VQYXJ0KHJhbmdlUGFydCwgdHlwZSkpO1xyXG4gICAgcG9zaXRpb24gPSBlbmQ7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcnVsZXM7XHJcbn07XHJcblxyXG5jb25zdCBnZXRSdWxlc0Zyb21SYW5nZVBhcnQgPSAocmFuZ2VQYXJ0LCBzZXJpZXNUeXBlKSA9PiB7XHJcbiAgbGV0IHJ1bGVzID0gW107XHJcblxyXG4gIGlmIChyZW1vdmVTZXBhcmF0b3JGcm9tRW5kKHJhbmdlUGFydCkgPT0gXCJcIikge1xyXG4gICAgcnVsZXMucHVzaChjcmVhdGVTdHJlZXRSdWxlKHNlcmllc1R5cGUpKTtcclxuICAgIHJldHVybiBydWxlcztcclxuICB9XHJcblxyXG4gIGxldCBwb3NpdGlvbiA9IDA7XHJcbiAgcmFuZ2VQYXJ0ID0gcmFuZ2VQYXJ0LnRyaW0oKSArIFwiLCBcIjtcclxuICB3aGlsZSAocG9zaXRpb24gPCByYW5nZVBhcnQubGVuZ3RoKSB7XHJcbiAgICB2YXIgbWF0Y2ggPSByYW5nZVBhdHRlcm4uZXhlYyhyYW5nZVBhcnQuc3Vic3RyKHBvc2l0aW9uKSk7XHJcbiAgICBpZiAobWF0Y2ggPT0gbnVsbCkge1xyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICAgIHBvc2l0aW9uICs9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xyXG5cclxuICAgIHZhciB2YWx1ZSA9IHJlbW92ZVNlcGFyYXRvckZyb21FbmQobWF0Y2hbMF0pO1xyXG4gICAgaWYgKHZhbHVlLmluZGV4T2YoXCItXCIpICE9IC0xKSB7XHJcbiAgICAgIHZhciBmcm9tVG8gPSB2YWx1ZS5zcGxpdChcIi1cIik7XHJcbiAgICAgIHJ1bGVzLnB1c2goY3JlYXRlU3RyZWV0UnVsZShzZXJpZXNUeXBlLCBwYXJzZUludChmcm9tVG9bMF0pLCBmcm9tVG9bMV0pKTtcclxuICAgIH0gZWxzZSBpZiAodmFsdWUuaW5kZXhPZihcInbDvcWhZVwiKSAhPSAtMSkge1xyXG4gICAgICB2YXIgbnVtYmVyID0gcGFyc2VJbnQobnVtYmVyUGF0dGVybi5leGVjKHZhbHVlKVswXSk7XHJcbiAgICAgIHJ1bGVzLnB1c2goY3JlYXRlU3RyZWV0UnVsZShzZXJpZXNUeXBlLCBudW1iZXIpKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhciBudW1iZXIgPSBwYXJzZUludChudW1iZXJQYXR0ZXJuLmV4ZWModmFsdWUpWzBdKTtcclxuICAgICAgcnVsZXMucHVzaChjcmVhdGVTdHJlZXRSdWxlKHNlcmllc1R5cGUsIG51bWJlciwgbnVtYmVyKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcnVsZXM7XHJcbn07XHJcblxyXG5jb25zdCBnZXRTZXJpZXNUeXBlID0gKHBhdHRlcm4pID0+IHtcclxuICBzd2l0Y2ggKHBhdHRlcm4pIHtcclxuICAgIGNhc2UgT2RkVHlwZVN0cmluZzpcclxuICAgICAgcmV0dXJuIFN0cmVldE51bWJlclNlcmllc1R5cGUuT2RkO1xyXG4gICAgY2FzZSBFdmVuVHlwZVN0cmluZzpcclxuICAgICAgcmV0dXJuIFN0cmVldE51bWJlclNlcmllc1R5cGUuRXZlbjtcclxuICAgIGNhc2UgQ1BUeXBlU3RyaW5nOlxyXG4gICAgICByZXR1cm4gU3RyZWV0TnVtYmVyU2VyaWVzVHlwZS5DUDtcclxuICAgIGNhc2UgQWxsVHlwZVN0cmluZzpcclxuICAgIGRlZmF1bHQ6XHJcbiAgICAgIHJldHVybiBTdHJlZXROdW1iZXJTZXJpZXNUeXBlLkFsbDtcclxuICB9XHJcbn07XHJcblxyXG5jb25zdCByZW1vdmVTZXBhcmF0b3JGcm9tRW5kID0gKHRleHQpID0+IHtcclxuICB0ZXh0ID0gdGV4dC50cmltKCk7XHJcbiAgaWYgKHRleHRbdGV4dC5sZW5ndGggLSAxXSA9PSBcImFcIiB8fCB0ZXh0W3RleHQubGVuZ3RoIC0gMV0gPT0gXCIsXCIpIHtcclxuICAgIHRleHQgPSB0ZXh0LnN1YnN0cigwLCB0ZXh0Lmxlbmd0aCAtIDEpO1xyXG4gIH1cclxuICByZXR1cm4gdGV4dC50cmltKCk7XHJcbn07XHJcblxyXG4vLyBkZXNpcmVkIG91dHB1dCBmb3JtYXQ6XHJcbi8vIFDFmcOtxI1uw6Eoc3RyKTtmcm9tKGludCk7dG8oaW50KTtbb2RkfGV2ZW58YWxsfGNwXTtzY2hvb2woc3RyKVxyXG5leHBvcnQgZnVuY3Rpb24gZGlzdHJpY3RzVG9Dc3ZSdWxlcyhkaXN0cmljdHMsIGluY2x1ZGVEaXN0cmljdE5hbWUgPSBmYWxzZSkge1xyXG4gIGNvbnN0IGxpbmVzID0gW107XHJcbiAgZGlzdHJpY3RzLmZvckVhY2goKGRpc3RyaWN0KSA9PiB7XHJcbiAgICBkaXN0cmljdC5zY2hvb2xzLmZvckVhY2goKHNjaG9vbCkgPT4ge1xyXG4gICAgICBzY2hvb2wubGluZXMuZm9yRWFjaCgoc3RyZWV0KSA9PiB7XHJcbiAgICAgICAgaWYgKHN0cmVldFswXSA9PSBcIiFcIiB8fCBzdHJlZXQgPT0gXCJcIikge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgcmVzdWx0ID0gc3RyZWV0TmFtZVBhdHRlcm4uZXhlYyhzdHJlZXQpO1xyXG4gICAgICAgIGxldCBzdHJlZXROYW1lID0gcmVzdWx0WzBdO1xyXG4gICAgICAgIGxldCBudW1iZXJTcGVjaWZpY2F0aW9uID0gc3RyZWV0LnN1YnN0cihzdHJlZXROYW1lLmxlbmd0aCArIDMpLnRyaW0oKTtcclxuICAgICAgICBsZXQgcnVsZXMgPSBnZXRTdHJlZXRSdWxlcyhudW1iZXJTcGVjaWZpY2F0aW9uKTtcclxuICAgICAgICBpZiAocnVsZXMgPT0gbnVsbCB8fCBydWxlcy5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yOiBcIiArIHN0cmVldCk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJ1bGVzLmZvckVhY2goKHJ1bGUpID0+IHtcclxuICAgICAgICAgIGxpbmVzLnB1c2goXHJcbiAgICAgICAgICAgIHN0cmVldE5hbWUgK1xyXG4gICAgICAgICAgICAgIFwiO1wiICtcclxuICAgICAgICAgICAgICBydWxlLmZyb20gK1xyXG4gICAgICAgICAgICAgIFwiO1wiICtcclxuICAgICAgICAgICAgICBydWxlLnRvICtcclxuICAgICAgICAgICAgICBcIjtcIiArXHJcbiAgICAgICAgICAgICAgcnVsZS50eXBlICtcclxuICAgICAgICAgICAgICBcIjtcIiArXHJcbiAgICAgICAgICAgICAgc2Nob29sLm5hbWUgK1xyXG4gICAgICAgICAgICAgIChpbmNsdWRlRGlzdHJpY3ROYW1lID8gXCI7XCIgKyBkaXN0cmljdC5uYW1lIDogXCJcIilcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xyXG59XHJcblxyXG4vLyBsZXQgcmF3ID0gcmVhZEZpbGVTeW5jKFwib3V0Lmpzb25cIiwgXCJ1dGYtOFwiKTtcclxuLy8gbGV0IGRpc3RyaWN0cztcclxuLy8gdHJ5IHtcclxuLy8gICBkaXN0cmljdHMgPSBKU09OLnBhcnNlKHJhdyk7XHJcbi8vIH0gY2F0Y2ggKGVycm9yKSB7XHJcbi8vICAgY29uc29sZS5sb2coZXJyb3IpO1xyXG4vLyAgIHJldHVybjtcclxuLy8gfVxyXG4iXX0=