@dpkit/table
Version:
Data Package implementation in TypeScript.
118 lines • 16.5 kB
JavaScript
import { col } from "nodejs-polars";
import { getPolarsSchema } from "../schema/index.js";
export async function inferSchema(table, options) {
const { sampleRows = 100, confidence = 0.9 } = options ?? {};
const schema = {
fields: [],
};
const typeMapping = createTypeMapping();
const regexMapping = createRegexMapping(options);
const sample = await table.head(sampleRows).collect();
const polarsSchema = getPolarsSchema(sample.schema);
const failureThreshold = sample.height - Math.floor(sample.height * confidence) || 1;
for (const polarsField of polarsSchema.fields) {
const name = polarsField.name;
const type = typeMapping[polarsField.type.variant] ?? "any";
let field = { name, type };
if (type === "string") {
for (const [regex, patch] of Object.entries(regexMapping)) {
const failures = sample
.filter(col(name).str.contains(regex).not())
.head(failureThreshold).height;
if (failures < failureThreshold) {
field = { ...field, ...patch };
break;
}
}
}
schema.fields.push(field);
}
return schema;
}
function createTypeMapping() {
const mapping = {
Array: "array",
Bool: "boolean",
Categorical: "string",
Date: "date",
Datetime: "datetime",
Decimal: "number",
Float32: "number",
Float64: "number",
Int16: "integer",
Int32: "integer",
Int64: "integer",
Int8: "integer",
List: "array",
Null: "any",
Object: "object",
String: "string",
Struct: "object",
Time: "time",
UInt16: "integer",
UInt32: "integer",
UInt64: "integer",
UInt8: "integer",
Utf8: "string",
};
return mapping;
}
function createRegexMapping(options) {
const { commaDecimal, monthFirst } = options ?? {};
const mapping = {
// Numeric
"^\\d+$": { type: "integer" },
"^[,\\d]+$": commaDecimal
? { type: "number" }
: { type: "integer", groupChar: "," },
"^\\d+\\.\\d+$": commaDecimal
? { type: "integer", groupChar: "." }
: { type: "number" },
"^[,\\d]+\\.\\d+$": { type: "number", groupChar: "," },
"^[.\\d]+\\,\\d+$": { type: "number", groupChar: ".", decimalChar: "," },
// Boolean
"^(true|True|TRUE|false|False|FALSE)$": { type: "boolean" },
// Date
"^\\d{4}-\\d{2}-\\d{2}$": { type: "date" },
"^\\d{4}/\\d{2}/\\d{2}$": { type: "date", format: "%Y/%m/%d" },
"^\\d{2}/\\d{2}/\\d{4}$": monthFirst
? { type: "date", format: "%m/%d/%Y" }
: { type: "date", format: "%d/%m/%Y" },
"^\\d{2}-\\d{2}-\\d{4}$": monthFirst
? { type: "date", format: "%m-%d-%Y" }
: { type: "date", format: "%d-%m-%Y" },
"^\\d{2}\\.\\d{2}\\.\\d{4}$": monthFirst
? { type: "date", format: "%m.%d.%Y" }
: { type: "date", format: "%d.%m.%Y" },
// Time
"^\\d{2}:\\d{2}:\\d{2}$": { type: "time" },
"^\\d{2}:\\d{2}$": { type: "time", format: "%H:%M" },
"^\\d{1,2}:\\d{2}:\\d{2}\\s*(am|pm|AM|PM)$": {
type: "time",
format: "%I:%M:%S %p",
},
"^\\d{1,2}:\\d{2}\\s*(am|pm|AM|PM)$": { type: "time", format: "%I:%M %p" },
"^\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:?\\d{2}$": { type: "time" },
// Datetime - ISO format
"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z?$": { type: "datetime" },
"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:?\\d{2}$": {
type: "datetime",
},
"^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$": {
type: "datetime",
format: "%Y-%m-%d %H:%M:%S",
},
"^\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}$": monthFirst
? { type: "datetime", format: "%m/%d/%Y %H:%M" }
: { type: "datetime", format: "%d/%m/%Y %H:%M" },
"^\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}:\\d{2}$": monthFirst
? { type: "datetime", format: "%m/%d/%Y %H:%M:%S" }
: { type: "datetime", format: "%d/%m/%Y %H:%M:%S" },
// Object
"^\\{": { type: "object" },
// Array
"^\\[": { type: "array" },
};
return mapping;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zY2hlbWEvaW5mZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNuQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFZcEQsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBWSxFQUFFLE9BQTRCO0lBQzFFLE1BQU0sRUFBRSxVQUFVLEdBQUcsR0FBRyxFQUFFLFVBQVUsR0FBRyxHQUFHLEVBQUUsR0FBRyxPQUFPLElBQUksRUFBRSxDQUFBO0lBQzVELE1BQU0sTUFBTSxHQUFXO1FBQ3JCLE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQTtJQUVELE1BQU0sV0FBVyxHQUFHLGlCQUFpQixFQUFFLENBQUE7SUFDdkMsTUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFaEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFBO0lBQ3JELE1BQU0sWUFBWSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFbkQsTUFBTSxnQkFBZ0IsR0FDcEIsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBRTdELEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzlDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUE7UUFDN0IsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFBO1FBRTNELElBQUksS0FBSyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFBO1FBRTFCLElBQUksSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3RCLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQzFELE1BQU0sUUFBUSxHQUFHLE1BQU07cUJBQ3BCLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztxQkFDM0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxDQUFBO2dCQUNoQyxJQUFJLFFBQVEsR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO29CQUNoQyxLQUFLLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxHQUFHLEtBQUssRUFBRSxDQUFBO29CQUM5QixNQUFLO2dCQUNQLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzNCLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUM7QUFFRCxTQUFTLGlCQUFpQjtJQUN4QixNQUFNLE9BQU8sR0FBa0M7UUFDN0MsS0FBSyxFQUFFLE9BQU87UUFDZCxJQUFJLEVBQUUsU0FBUztRQUNmLFdBQVcsRUFBRSxRQUFRO1FBQ3JCLElBQUksRUFBRSxNQUFNO1FBQ1osUUFBUSxFQUFFLFVBQVU7UUFDcEIsT0FBTyxFQUFFLFFBQVE7UUFDakIsT0FBTyxFQUFFLFFBQVE7UUFDakIsT0FBTyxFQUFFLFFBQVE7UUFDakIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsSUFBSSxFQUFFLFNBQVM7UUFDZixJQUFJLEVBQUUsT0FBTztRQUNiLElBQUksRUFBRSxLQUFLO1FBQ1gsTUFBTSxFQUFFLFFBQVE7UUFDaEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsSUFBSSxFQUFFLE1BQU07UUFDWixNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsU0FBUztRQUNqQixLQUFLLEVBQUUsU0FBUztRQUNoQixJQUFJLEVBQUUsUUFBUTtLQUNmLENBQUE7SUFFRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxPQUczQjtJQUNDLE1BQU0sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUVsRCxNQUFNLE9BQU8sR0FBbUM7UUFDOUMsVUFBVTtRQUNWLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7UUFDN0IsV0FBVyxFQUFFLFlBQVk7WUFDdkIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUNwQixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDdkMsZUFBZSxFQUFFLFlBQVk7WUFDM0IsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQ3JDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7UUFDdEIsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDdEQsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRTtRQUV4RSxVQUFVO1FBQ1Ysc0NBQXNDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO1FBRTNELE9BQU87UUFDUCx3QkFBd0IsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUU7UUFDMUMsd0JBQXdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7UUFDOUQsd0JBQXdCLEVBQUUsVUFBVTtZQUNsQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7WUFDdEMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFO1FBQ3hDLHdCQUF3QixFQUFFLFVBQVU7WUFDbEMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFO1lBQ3RDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRTtRQUN4Qyw0QkFBNEIsRUFBRSxVQUFVO1lBQ3RDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRTtZQUN0QyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7UUFFeEMsT0FBTztRQUNQLHdCQUF3QixFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtRQUMxQyxpQkFBaUIsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRTtRQUNwRCwyQ0FBMkMsRUFBRTtZQUMzQyxJQUFJLEVBQUUsTUFBTTtZQUNaLE1BQU0sRUFBRSxhQUFhO1NBQ3RCO1FBQ0Qsb0NBQW9DLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7UUFDMUUsMENBQTBDLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO1FBRTVELHdCQUF3QjtRQUN4QiwrQ0FBK0MsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUU7UUFDckUsK0RBQStELEVBQUU7WUFDL0QsSUFBSSxFQUFFLFVBQVU7U0FDakI7UUFDRCw2Q0FBNkMsRUFBRTtZQUM3QyxJQUFJLEVBQUUsVUFBVTtZQUNoQixNQUFNLEVBQUUsbUJBQW1CO1NBQzVCO1FBQ0Qsc0NBQXNDLEVBQUUsVUFBVTtZQUNoRCxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRTtZQUNoRCxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRTtRQUNsRCw2Q0FBNkMsRUFBRSxVQUFVO1lBQ3ZELENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFO1lBQ25ELENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFO1FBRXJELFNBQVM7UUFDVCxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO1FBRTFCLFFBQVE7UUFDUixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0tBQzFCLENBQUE7SUFFRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBGaWVsZCwgU2NoZW1hIH0gZnJvbSBcIkBkcGtpdC9jb3JlXCJcbmltcG9ydCB7IGNvbCB9IGZyb20gXCJub2RlanMtcG9sYXJzXCJcbmltcG9ydCB7IGdldFBvbGFyc1NjaGVtYSB9IGZyb20gXCIuLi9zY2hlbWEvaW5kZXgudHNcIlxuaW1wb3J0IHR5cGUgeyBUYWJsZSB9IGZyb20gXCIuLi90YWJsZS9pbmRleC50c1wiXG5cbi8vIFRPRE86IFJldmlldyBkZWZhdWx0IHZhbHVlcyBiZWluZyB7ZmllbGRzOiBbXX0gdnMgdW5kZWZpbmVkXG5cbmV4cG9ydCB0eXBlIEluZmVyU2NoZW1hT3B0aW9ucyA9IHtcbiAgc2FtcGxlUm93cz86IG51bWJlclxuICBjb25maWRlbmNlPzogbnVtYmVyXG4gIGNvbW1hRGVjaW1hbD86IGJvb2xlYW5cbiAgbW9udGhGaXJzdD86IGJvb2xlYW5cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluZmVyU2NoZW1hKHRhYmxlOiBUYWJsZSwgb3B0aW9ucz86IEluZmVyU2NoZW1hT3B0aW9ucykge1xuICBjb25zdCB7IHNhbXBsZVJvd3MgPSAxMDAsIGNvbmZpZGVuY2UgPSAwLjkgfSA9IG9wdGlvbnMgPz8ge31cbiAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgZmllbGRzOiBbXSxcbiAgfVxuXG4gIGNvbnN0IHR5cGVNYXBwaW5nID0gY3JlYXRlVHlwZU1hcHBpbmcoKVxuICBjb25zdCByZWdleE1hcHBpbmcgPSBjcmVhdGVSZWdleE1hcHBpbmcob3B0aW9ucylcblxuICBjb25zdCBzYW1wbGUgPSBhd2FpdCB0YWJsZS5oZWFkKHNhbXBsZVJvd3MpLmNvbGxlY3QoKVxuICBjb25zdCBwb2xhcnNTY2hlbWEgPSBnZXRQb2xhcnNTY2hlbWEoc2FtcGxlLnNjaGVtYSlcblxuICBjb25zdCBmYWlsdXJlVGhyZXNob2xkID1cbiAgICBzYW1wbGUuaGVpZ2h0IC0gTWF0aC5mbG9vcihzYW1wbGUuaGVpZ2h0ICogY29uZmlkZW5jZSkgfHwgMVxuXG4gIGZvciAoY29uc3QgcG9sYXJzRmllbGQgb2YgcG9sYXJzU2NoZW1hLmZpZWxkcykge1xuICAgIGNvbnN0IG5hbWUgPSBwb2xhcnNGaWVsZC5uYW1lXG4gICAgY29uc3QgdHlwZSA9IHR5cGVNYXBwaW5nW3BvbGFyc0ZpZWxkLnR5cGUudmFyaWFudF0gPz8gXCJhbnlcIlxuXG4gICAgbGV0IGZpZWxkID0geyBuYW1lLCB0eXBlIH1cblxuICAgIGlmICh0eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBmb3IgKGNvbnN0IFtyZWdleCwgcGF0Y2hdIG9mIE9iamVjdC5lbnRyaWVzKHJlZ2V4TWFwcGluZykpIHtcbiAgICAgICAgY29uc3QgZmFpbHVyZXMgPSBzYW1wbGVcbiAgICAgICAgICAuZmlsdGVyKGNvbChuYW1lKS5zdHIuY29udGFpbnMocmVnZXgpLm5vdCgpKVxuICAgICAgICAgIC5oZWFkKGZhaWx1cmVUaHJlc2hvbGQpLmhlaWdodFxuICAgICAgICBpZiAoZmFpbHVyZXMgPCBmYWlsdXJlVGhyZXNob2xkKSB7XG4gICAgICAgICAgZmllbGQgPSB7IC4uLmZpZWxkLCAuLi5wYXRjaCB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHNjaGVtYS5maWVsZHMucHVzaChmaWVsZClcbiAgfVxuXG4gIHJldHVybiBzY2hlbWFcbn1cblxuZnVuY3Rpb24gY3JlYXRlVHlwZU1hcHBpbmcoKSB7XG4gIGNvbnN0IG1hcHBpbmc6IFJlY29yZDxzdHJpbmcsIEZpZWxkW1widHlwZVwiXT4gPSB7XG4gICAgQXJyYXk6IFwiYXJyYXlcIixcbiAgICBCb29sOiBcImJvb2xlYW5cIixcbiAgICBDYXRlZ29yaWNhbDogXCJzdHJpbmdcIixcbiAgICBEYXRlOiBcImRhdGVcIixcbiAgICBEYXRldGltZTogXCJkYXRldGltZVwiLFxuICAgIERlY2ltYWw6IFwibnVtYmVyXCIsXG4gICAgRmxvYXQzMjogXCJudW1iZXJcIixcbiAgICBGbG9hdDY0OiBcIm51bWJlclwiLFxuICAgIEludDE2OiBcImludGVnZXJcIixcbiAgICBJbnQzMjogXCJpbnRlZ2VyXCIsXG4gICAgSW50NjQ6IFwiaW50ZWdlclwiLFxuICAgIEludDg6IFwiaW50ZWdlclwiLFxuICAgIExpc3Q6IFwiYXJyYXlcIixcbiAgICBOdWxsOiBcImFueVwiLFxuICAgIE9iamVjdDogXCJvYmplY3RcIixcbiAgICBTdHJpbmc6IFwic3RyaW5nXCIsXG4gICAgU3RydWN0OiBcIm9iamVjdFwiLFxuICAgIFRpbWU6IFwidGltZVwiLFxuICAgIFVJbnQxNjogXCJpbnRlZ2VyXCIsXG4gICAgVUludDMyOiBcImludGVnZXJcIixcbiAgICBVSW50NjQ6IFwiaW50ZWdlclwiLFxuICAgIFVJbnQ4OiBcImludGVnZXJcIixcbiAgICBVdGY4OiBcInN0cmluZ1wiLFxuICB9XG5cbiAgcmV0dXJuIG1hcHBpbmdcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVnZXhNYXBwaW5nKG9wdGlvbnM/OiB7XG4gIGNvbW1hRGVjaW1hbD86IGJvb2xlYW5cbiAgbW9udGhGaXJzdD86IGJvb2xlYW5cbn0pIHtcbiAgY29uc3QgeyBjb21tYURlY2ltYWwsIG1vbnRoRmlyc3QgfSA9IG9wdGlvbnMgPz8ge31cblxuICBjb25zdCBtYXBwaW5nOiBSZWNvcmQ8c3RyaW5nLCBQYXJ0aWFsPEZpZWxkPj4gPSB7XG4gICAgLy8gTnVtZXJpY1xuICAgIFwiXlxcXFxkKyRcIjogeyB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgIFwiXlssXFxcXGRdKyRcIjogY29tbWFEZWNpbWFsXG4gICAgICA/IHsgdHlwZTogXCJudW1iZXJcIiB9XG4gICAgICA6IHsgdHlwZTogXCJpbnRlZ2VyXCIsIGdyb3VwQ2hhcjogXCIsXCIgfSxcbiAgICBcIl5cXFxcZCtcXFxcLlxcXFxkKyRcIjogY29tbWFEZWNpbWFsXG4gICAgICA/IHsgdHlwZTogXCJpbnRlZ2VyXCIsIGdyb3VwQ2hhcjogXCIuXCIgfVxuICAgICAgOiB7IHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICBcIl5bLFxcXFxkXStcXFxcLlxcXFxkKyRcIjogeyB0eXBlOiBcIm51bWJlclwiLCBncm91cENoYXI6IFwiLFwiIH0sXG4gICAgXCJeWy5cXFxcZF0rXFxcXCxcXFxcZCskXCI6IHsgdHlwZTogXCJudW1iZXJcIiwgZ3JvdXBDaGFyOiBcIi5cIiwgZGVjaW1hbENoYXI6IFwiLFwiIH0sXG5cbiAgICAvLyBCb29sZWFuXG4gICAgXCJeKHRydWV8VHJ1ZXxUUlVFfGZhbHNlfEZhbHNlfEZBTFNFKSRcIjogeyB0eXBlOiBcImJvb2xlYW5cIiB9LFxuXG4gICAgLy8gRGF0ZVxuICAgIFwiXlxcXFxkezR9LVxcXFxkezJ9LVxcXFxkezJ9JFwiOiB7IHR5cGU6IFwiZGF0ZVwiIH0sXG4gICAgXCJeXFxcXGR7NH0vXFxcXGR7Mn0vXFxcXGR7Mn0kXCI6IHsgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlWS8lbS8lZFwiIH0sXG4gICAgXCJeXFxcXGR7Mn0vXFxcXGR7Mn0vXFxcXGR7NH0kXCI6IG1vbnRoRmlyc3RcbiAgICAgID8geyB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZXCIgfVxuICAgICAgOiB7IHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJWQvJW0vJVlcIiB9LFxuICAgIFwiXlxcXFxkezJ9LVxcXFxkezJ9LVxcXFxkezR9JFwiOiBtb250aEZpcnN0XG4gICAgICA/IHsgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlbS0lZC0lWVwiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVkLSVtLSVZXCIgfSxcbiAgICBcIl5cXFxcZHsyfVxcXFwuXFxcXGR7Mn1cXFxcLlxcXFxkezR9JFwiOiBtb250aEZpcnN0XG4gICAgICA/IHsgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlbS4lZC4lWVwiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVkLiVtLiVZXCIgfSxcblxuICAgIC8vIFRpbWVcbiAgICBcIl5cXFxcZHsyfTpcXFxcZHsyfTpcXFxcZHsyfSRcIjogeyB0eXBlOiBcInRpbWVcIiB9LFxuICAgIFwiXlxcXFxkezJ9OlxcXFxkezJ9JFwiOiB7IHR5cGU6IFwidGltZVwiLCBmb3JtYXQ6IFwiJUg6JU1cIiB9LFxuICAgIFwiXlxcXFxkezEsMn06XFxcXGR7Mn06XFxcXGR7Mn1cXFxccyooYW18cG18QU18UE0pJFwiOiB7XG4gICAgICB0eXBlOiBcInRpbWVcIixcbiAgICAgIGZvcm1hdDogXCIlSTolTTolUyAlcFwiLFxuICAgIH0sXG4gICAgXCJeXFxcXGR7MSwyfTpcXFxcZHsyfVxcXFxzKihhbXxwbXxBTXxQTSkkXCI6IHsgdHlwZTogXCJ0aW1lXCIsIGZvcm1hdDogXCIlSTolTSAlcFwiIH0sXG4gICAgXCJeXFxcXGR7Mn06XFxcXGR7Mn06XFxcXGR7Mn1bKy1dXFxcXGR7Mn06P1xcXFxkezJ9JFwiOiB7IHR5cGU6IFwidGltZVwiIH0sXG5cbiAgICAvLyBEYXRldGltZSAtIElTTyBmb3JtYXRcbiAgICBcIl5cXFxcZHs0fS1cXFxcZHsyfS1cXFxcZHsyfVRcXFxcZHsyfTpcXFxcZHsyfTpcXFxcZHsyfVo/JFwiOiB7IHR5cGU6IFwiZGF0ZXRpbWVcIiB9LFxuICAgIFwiXlxcXFxkezR9LVxcXFxkezJ9LVxcXFxkezJ9VFxcXFxkezJ9OlxcXFxkezJ9OlxcXFxkezJ9WystXVxcXFxkezJ9Oj9cXFxcZHsyfSRcIjoge1xuICAgICAgdHlwZTogXCJkYXRldGltZVwiLFxuICAgIH0sXG4gICAgXCJeXFxcXGR7NH0tXFxcXGR7Mn0tXFxcXGR7Mn0gXFxcXGR7Mn06XFxcXGR7Mn06XFxcXGR7Mn0kXCI6IHtcbiAgICAgIHR5cGU6IFwiZGF0ZXRpbWVcIixcbiAgICAgIGZvcm1hdDogXCIlWS0lbS0lZCAlSDolTTolU1wiLFxuICAgIH0sXG4gICAgXCJeXFxcXGR7Mn0vXFxcXGR7Mn0vXFxcXGR7NH0gXFxcXGR7Mn06XFxcXGR7Mn0kXCI6IG1vbnRoRmlyc3RcbiAgICAgID8geyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlbS8lZC8lWSAlSDolTVwiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTVwiIH0sXG4gICAgXCJeXFxcXGR7Mn0vXFxcXGR7Mn0vXFxcXGR7NH0gXFxcXGR7Mn06XFxcXGR7Mn06XFxcXGR7Mn0kXCI6IG1vbnRoRmlyc3RcbiAgICAgID8geyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlbS8lZC8lWSAlSDolTTolU1wiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTTolU1wiIH0sXG5cbiAgICAvLyBPYmplY3RcbiAgICBcIl5cXFxce1wiOiB7IHR5cGU6IFwib2JqZWN0XCIgfSxcblxuICAgIC8vIEFycmF5XG4gICAgXCJeXFxcXFtcIjogeyB0eXBlOiBcImFycmF5XCIgfSxcbiAgfVxuXG4gIHJldHVybiBtYXBwaW5nXG59XG4iXX0=