@dpkit/table
Version:
Data Package implementation in TypeScript.
200 lines • 23.8 kB
JavaScript
import { DataFrame } from "nodejs-polars";
import { describe, expect, it } from "vitest";
import { inspectTable } from "../../table/index.js";
describe("inspectTable", () => {
it("should inspect string to integer conversion errors", async () => {
const table = DataFrame({
id: ["1", "bad", "3", "4x"],
}).lazy();
const schema = {
fields: [{ name: "id", type: "integer" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(2);
expect(errors).toContainEqual({
type: "cell/type",
cell: "bad",
fieldName: "id",
rowNumber: 2,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "4x",
fieldName: "id",
rowNumber: 4,
});
});
it("should inspect string to number conversion errors", async () => {
const table = DataFrame({
price: ["10.5", "twenty", "30.75", "$40"],
}).lazy();
const schema = {
fields: [{ name: "price", type: "number" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(2);
expect(errors).toContainEqual({
type: "cell/type",
cell: "twenty",
fieldName: "price",
rowNumber: 2,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "$40",
fieldName: "price",
rowNumber: 4,
});
});
it("should inspect string to boolean conversion errors", async () => {
const table = DataFrame({
active: ["true", "yes", "false", "0", "1"],
}).lazy();
const schema = {
fields: [{ name: "active", type: "boolean" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(1);
expect(errors).toContainEqual({
type: "cell/type",
cell: "yes",
fieldName: "active",
rowNumber: 2,
});
});
it("should inspect string to date conversion errors", async () => {
const table = DataFrame({
created: ["2023-01-15", "Jan 15, 2023", "20230115", "not-a-date"],
}).lazy();
const schema = {
fields: [{ name: "created", type: "date" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(3);
expect(errors).toContainEqual({
type: "cell/type",
cell: "Jan 15, 2023",
fieldName: "created",
rowNumber: 2,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "20230115",
fieldName: "created",
rowNumber: 3,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "not-a-date",
fieldName: "created",
rowNumber: 4,
});
});
it("should inspect string to time conversion errors", async () => {
const table = DataFrame({
time: ["14:30:00", "2:30pm", "invalid", "14h30"],
}).lazy();
const schema = {
fields: [{ name: "time", type: "time" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(3);
expect(errors).toContainEqual({
type: "cell/type",
cell: "2:30pm",
fieldName: "time",
rowNumber: 2,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "invalid",
fieldName: "time",
rowNumber: 3,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "14h30",
fieldName: "time",
rowNumber: 4,
});
});
it("should inspect string to year conversion errors", async () => {
const table = DataFrame({
year: ["2023", "23", "MMXXIII", "two-thousand-twenty-three"],
}).lazy();
const schema = {
fields: [{ name: "year", type: "year" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(3);
expect(errors).toContainEqual({
type: "cell/type",
cell: "23",
fieldName: "year",
rowNumber: 2,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "MMXXIII",
fieldName: "year",
rowNumber: 3,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "two-thousand-twenty-three",
fieldName: "year",
rowNumber: 4,
});
});
it("should inspect string to datetime conversion errors", async () => {
const table = DataFrame({
timestamp: [
"2023-01-15T14:30:00",
"January 15, 2023 2:30 PM",
"2023-01-15 14:30",
"not-a-datetime",
],
}).lazy();
const schema = {
fields: [{ name: "timestamp", type: "datetime" }],
};
const errors = await inspectTable(table, { schema });
// Adjust the expectations to match actual behavior
expect(errors.length).toBeGreaterThan(0);
// Check for specific invalid values we expect to fail
expect(errors).toContainEqual({
type: "cell/type",
cell: "January 15, 2023 2:30 PM",
fieldName: "timestamp",
rowNumber: 2,
});
expect(errors).toContainEqual({
type: "cell/type",
cell: "not-a-datetime",
fieldName: "timestamp",
rowNumber: 4,
});
});
it("should pass validation when all cells are valid", async () => {
const table = DataFrame({
id: ["1", "2", "3", "4"],
}).lazy();
const schema = {
fields: [{ name: "id", type: "integer" }],
};
const errors = await inspectTable(table, { schema });
expect(errors).toHaveLength(0);
});
it("should inspect with non-string source data", async () => {
const table = DataFrame({
is_active: [true, false, 1, 0],
}).lazy();
const schema = {
fields: [{ name: "is_active", type: "boolean" }],
};
const errors = await inspectTable(table, { schema });
// Since the column isn't string type, inspectField will not process it
expect(errors).toHaveLength(0);
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZmllbGQvY2hlY2tzL3R5cGUuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFFbkQsUUFBUSxDQUFDLGNBQWMsRUFBRSxHQUFHLEVBQUU7SUFDNUIsRUFBRSxDQUFDLG9EQUFvRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2xFLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQztZQUN0QixFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUM7U0FDNUIsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO1FBRVQsTUFBTSxNQUFNLEdBQVc7WUFDckIsTUFBTSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztTQUMxQyxDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUMsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQTtRQUVwRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzlCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxjQUFjLENBQUM7WUFDNUIsSUFBSSxFQUFFLFdBQVc7WUFDakIsSUFBSSxFQUFFLEtBQUs7WUFDWCxTQUFTLEVBQUUsSUFBSTtZQUNmLFNBQVMsRUFBRSxDQUFDO1NBQ2IsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGNBQWMsQ0FBQztZQUM1QixJQUFJLEVBQUUsV0FBVztZQUNq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QUE7SUFDaEMsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSBcIkBkcGtpdC9jb3JlXCJcbmltcG9ydCB7IERhdGFGcmFtZSB9IGZyb20gXCJub2RlanMtcG9sYXJzXCJcbmltcG9ydCB7IGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSBcInZpdGVzdFwiXG5pbXBvcnQgeyBpbnNwZWN0VGFibGUgfSBmcm9tIFwiLi4vLi4vdGFibGUvaW5kZXgudHNcIlxuXG5kZXNjcmliZShcImluc3BlY3RUYWJsZVwiLCAoKSA9PiB7XG4gIGl0KFwic2hvdWxkIGluc3BlY3Qgc3RyaW5nIHRvIGludGVnZXIgY29udmVyc2lvbiBlcnJvcnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIGlkOiBbXCIxXCIsIFwiYmFkXCIsIFwiM1wiLCBcIjR4XCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfV0sXG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzID0gYXdhaXQgaW5zcGVjdFRhYmxlKHRhYmxlLCB7IHNjaGVtYSB9KVxuXG4gICAgZXhwZWN0KGVycm9ycykudG9IYXZlTGVuZ3RoKDIpXG4gICAgZXhwZWN0KGVycm9ycykudG9Db250YWluRXF1YWwoe1xuICAgICAgdHlwZTogXCJjZWxsL3R5cGVcIixcbiAgICAgIGNlbGw6IFwiYmFkXCIsXG4gICAgICBmaWVsZE5hbWU6IFwiaWRcIixcbiAgICAgIHJvd051bWJlcjogMixcbiAgICB9KVxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcIjR4XCIsXG4gICAgICBmaWVsZE5hbWU6IFwiaWRcIixcbiAgICAgIHJvd051bWJlcjogNCxcbiAgICB9KVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluc3BlY3Qgc3RyaW5nIHRvIG51bWJlciBjb252ZXJzaW9uIGVycm9yc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgcHJpY2U6IFtcIjEwLjVcIiwgXCJ0d2VudHlcIiwgXCIzMC43NVwiLCBcIiQ0MFwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbeyBuYW1lOiBcInByaWNlXCIsIHR5cGU6IFwibnVtYmVyXCIgfV0sXG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzID0gYXdhaXQgaW5zcGVjdFRhYmxlKHRhYmxlLCB7IHNjaGVtYSB9KVxuXG4gICAgZXhwZWN0KGVycm9ycykudG9IYXZlTGVuZ3RoKDIpXG4gICAgZXhwZWN0KGVycm9ycykudG9Db250YWluRXF1YWwoe1xuICAgICAgdHlwZTogXCJjZWxsL3R5cGVcIixcbiAgICAgIGNlbGw6IFwidHdlbnR5XCIsXG4gICAgICBmaWVsZE5hbWU6IFwicHJpY2VcIixcbiAgICAgIHJvd051bWJlcjogMixcbiAgICB9KVxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcIiQ0MFwiLFxuICAgICAgZmllbGROYW1lOiBcInByaWNlXCIsXG4gICAgICByb3dOdW1iZXI6IDQsXG4gICAgfSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbnNwZWN0IHN0cmluZyB0byBib29sZWFuIGNvbnZlcnNpb24gZXJyb3JzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBhY3RpdmU6IFtcInRydWVcIiwgXCJ5ZXNcIiwgXCJmYWxzZVwiLCBcIjBcIiwgXCIxXCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwiYWN0aXZlXCIsIHR5cGU6IFwiYm9vbGVhblwiIH1dLFxuICAgIH1cblxuICAgIGNvbnN0IGVycm9ycyA9IGF3YWl0IGluc3BlY3RUYWJsZSh0YWJsZSwgeyBzY2hlbWEgfSlcblxuICAgIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgxKVxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcInllc1wiLFxuICAgICAgZmllbGROYW1lOiBcImFjdGl2ZVwiLFxuICAgICAgcm93TnVtYmVyOiAyLFxuICAgIH0pXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5zcGVjdCBzdHJpbmcgdG8gZGF0ZSBjb252ZXJzaW9uIGVycm9yc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgY3JlYXRlZDogW1wiMjAyMy0wMS0xNVwiLCBcIkphbiAxNSwgMjAyM1wiLCBcIjIwMjMwMTE1XCIsIFwibm90LWEtZGF0ZVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbeyBuYW1lOiBcImNyZWF0ZWRcIiwgdHlwZTogXCJkYXRlXCIgfV0sXG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzID0gYXdhaXQgaW5zcGVjdFRhYmxlKHRhYmxlLCB7IHNjaGVtYSB9KVxuXG4gICAgZXhwZWN0KGVycm9ycykudG9IYXZlTGVuZ3RoKDMpXG4gICAgZXhwZWN0KGVycm9ycykudG9Db250YWluRXF1YWwoe1xuICAgICAgdHlwZTogXCJjZWxsL3R5cGVcIixcbiAgICAgIGNlbGw6IFwiSmFuIDE1LCAyMDIzXCIsXG4gICAgICBmaWVsZE5hbWU6IFwiY3JlYXRlZFwiLFxuICAgICAgcm93TnVtYmVyOiAyLFxuICAgIH0pXG4gICAgZXhwZWN0KGVycm9ycykudG9Db250YWluRXF1YWwoe1xuICAgICAgdHlwZTogXCJjZWxsL3R5cGVcIixcbiAgICAgIGNlbGw6IFwiMjAyMzAxMTVcIixcbiAgICAgIGZpZWxkTmFtZTogXCJjcmVhdGVkXCIsXG4gICAgICByb3dOdW1iZXI6IDMsXG4gICAgfSlcbiAgICBleHBlY3QoZXJyb3JzKS50b0NvbnRhaW5FcXVhbCh7XG4gICAgICB0eXBlOiBcImNlbGwvdHlwZVwiLFxuICAgICAgY2VsbDogXCJub3QtYS1kYXRlXCIsXG4gICAgICBmaWVsZE5hbWU6IFwiY3JlYXRlZFwiLFxuICAgICAgcm93TnVtYmVyOiA0LFxuICAgIH0pXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5zcGVjdCBzdHJpbmcgdG8gdGltZSBjb252ZXJzaW9uIGVycm9yc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgdGltZTogW1wiMTQ6MzA6MDBcIiwgXCIyOjMwcG1cIiwgXCJpbnZhbGlkXCIsIFwiMTRoMzBcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW3sgbmFtZTogXCJ0aW1lXCIsIHR5cGU6IFwidGltZVwiIH1dLFxuICAgIH1cblxuICAgIGNvbnN0IGVycm9ycyA9IGF3YWl0IGluc3BlY3RUYWJsZSh0YWJsZSwgeyBzY2hlbWEgfSlcblxuICAgIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgzKVxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcIjI6MzBwbVwiLFxuICAgICAgZmllbGROYW1lOiBcInRpbWVcIixcbiAgICAgIHJvd051bWJlcjogMixcbiAgICB9KVxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcImludmFsaWRcIixcbiAgICAgIGZpZWxkTmFtZTogXCJ0aW1lXCIsXG4gICAgICByb3dOdW1iZXI6IDMsXG4gICAgfSlcbiAgICBleHBlY3QoZXJyb3JzKS50b0NvbnRhaW5FcXVhbCh7XG4gICAgICB0eXBlOiBcImNlbGwvdHlwZVwiLFxuICAgICAgY2VsbDogXCIxNGgzMFwiLFxuICAgICAgZmllbGROYW1lOiBcInRpbWVcIixcbiAgICAgIHJvd051bWJlcjogNCxcbiAgICB9KVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluc3BlY3Qgc3RyaW5nIHRvIHllYXIgY29udmVyc2lvbiBlcnJvcnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIHllYXI6IFtcIjIwMjNcIiwgXCIyM1wiLCBcIk1NWFhJSUlcIiwgXCJ0d28tdGhvdXNhbmQtdHdlbnR5LXRocmVlXCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwieWVhclwiLCB0eXBlOiBcInllYXJcIiB9XSxcbiAgICB9XG5cbiAgICBjb25zdCBlcnJvcnMgPSBhd2FpdCBpbnNwZWN0VGFibGUodGFibGUsIHsgc2NoZW1hIH0pXG5cbiAgICBleHBlY3QoZXJyb3JzKS50b0hhdmVMZW5ndGgoMylcbiAgICBleHBlY3QoZXJyb3JzKS50b0NvbnRhaW5FcXVhbCh7XG4gICAgICB0eXBlOiBcImNlbGwvdHlwZVwiLFxuICAgICAgY2VsbDogXCIyM1wiLFxuICAgICAgZmllbGROYW1lOiBcInllYXJcIixcbiAgICAgIHJvd051bWJlcjogMixcbiAgICB9KVxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcIk1NWFhJSUlcIixcbiAgICAgIGZpZWxkTmFtZTogXCJ5ZWFyXCIsXG4gICAgICByb3dOdW1iZXI6IDMsXG4gICAgfSlcbiAgICBleHBlY3QoZXJyb3JzKS50b0NvbnRhaW5FcXVhbCh7XG4gICAgICB0eXBlOiBcImNlbGwvdHlwZVwiLFxuICAgICAgY2VsbDogXCJ0d28tdGhvdXNhbmQtdHdlbnR5LXRocmVlXCIsXG4gICAgICBmaWVsZE5hbWU6IFwieWVhclwiLFxuICAgICAgcm93TnVtYmVyOiA0LFxuICAgIH0pXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5zcGVjdCBzdHJpbmcgdG8gZGF0ZXRpbWUgY29udmVyc2lvbiBlcnJvcnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIHRpbWVzdGFtcDogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6MDBcIixcbiAgICAgICAgXCJKYW51YXJ5IDE1LCAyMDIzIDI6MzAgUE1cIixcbiAgICAgICAgXCIyMDIzLTAxLTE1IDE0OjMwXCIsXG4gICAgICAgIFwibm90LWEtZGF0ZXRpbWVcIixcbiAgICAgIF0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW3sgbmFtZTogXCJ0aW1lc3RhbXBcIiwgdHlwZTogXCJkYXRldGltZVwiIH1dLFxuICAgIH1cblxuICAgIGNvbnN0IGVycm9ycyA9IGF3YWl0IGluc3BlY3RUYWJsZSh0YWJsZSwgeyBzY2hlbWEgfSlcblxuICAgIC8vIEFkanVzdCB0aGUgZXhwZWN0YXRpb25zIHRvIG1hdGNoIGFjdHVhbCBiZWhhdmlvclxuICAgIGV4cGVjdChlcnJvcnMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMClcblxuICAgIC8vIENoZWNrIGZvciBzcGVjaWZpYyBpbnZhbGlkIHZhbHVlcyB3ZSBleHBlY3QgdG8gZmFpbFxuICAgIGV4cGVjdChlcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwiY2VsbC90eXBlXCIsXG4gICAgICBjZWxsOiBcIkphbnVhcnkgMTUsIDIwMjMgMjozMCBQTVwiLFxuICAgICAgZmllbGROYW1lOiBcInRpbWVzdGFtcFwiLFxuICAgICAgcm93TnVtYmVyOiAyLFxuICAgIH0pXG5cbiAgICBleHBlY3QoZXJyb3JzKS50b0NvbnRhaW5FcXVhbCh7XG4gICAgICB0eXBlOiBcImNlbGwvdHlwZVwiLFxuICAgICAgY2VsbDogXCJub3QtYS1kYXRldGltZVwiLFxuICAgICAgZmllbGROYW1lOiBcInRpbWVzdGFtcFwiLFxuICAgICAgcm93TnVtYmVyOiA0LFxuICAgIH0pXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgcGFzcyB2YWxpZGF0aW9uIHdoZW4gYWxsIGNlbGxzIGFyZSB2YWxpZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgaWQ6IFtcIjFcIiwgXCIyXCIsIFwiM1wiLCBcIjRcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW3sgbmFtZTogXCJpZFwiLCB0eXBlOiBcImludGVnZXJcIiB9XSxcbiAgICB9XG5cbiAgICBjb25zdCBlcnJvcnMgPSBhd2FpdCBpbnNwZWN0VGFibGUodGFibGUsIHsgc2NoZW1hIH0pXG5cbiAgICBleHBlY3QoZXJyb3JzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcblxuICBpdChcInNob3VsZCBpbnNwZWN0IHdpdGggbm9uLXN0cmluZyBzb3VyY2UgZGF0YVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgaXNfYWN0aXZlOiBbdHJ1ZSwgZmFsc2UsIDEsIDBdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwiaXNfYWN0aXZlXCIsIHR5cGU6IFwiYm9vbGVhblwiIH1dLFxuICAgIH1cblxuICAgIGNvbnN0IGVycm9ycyA9IGF3YWl0IGluc3BlY3RUYWJsZSh0YWJsZSwgeyBzY2hlbWEgfSlcblxuICAgIC8vIFNpbmNlIHRoZSBjb2x1bW4gaXNuJ3Qgc3RyaW5nIHR5cGUsIGluc3BlY3RGaWVsZCB3aWxsIG5vdCBwcm9jZXNzIGl0XG4gICAgZXhwZWN0KGVycm9ycykudG9IYXZlTGVuZ3RoKDApXG4gIH0pXG59KVxuIl19