UNPKG

@dpkit/table

Version:

Data Package implementation in TypeScript.

202 lines 24.7 kB
import { DataFrame } from "nodejs-polars"; import { describe, expect, it } from "vitest"; import { normalizeTable } from "./normalize.js"; describe("normalizeTable", () => { it("should work with schema", async () => { const table = DataFrame({ id: [1, 2], name: ["english", "中文"], }).lazy(); const schema = { fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work with less fields in data", async () => { const table = DataFrame({ id: [1, 2], name: ["english", "中文"], }).lazy(); const schema = { fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, { name: "other", type: "boolean" }, ], }; const records = [ { id: 1, name: "english", other: null }, { id: 2, name: "中文", other: null }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work with more fields in data", async () => { const table = DataFrame({ id: [1, 2], name: ["english", "中文"], other: [true, false], }).lazy(); const schema = { fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work based on fields order", async () => { const table = DataFrame({ field1: [1, 2], field2: ["english", "中文"], }).lazy(); const schema = { fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work based on field names (equal)", async () => { const table = DataFrame({ name: ["english", "中文"], id: [1, 2], }).lazy(); const schema = { fieldsMatch: "equal", fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work based on field names (subset)", async () => { const table = DataFrame({ name: ["english", "中文"], id: [1, 2], }).lazy(); const schema = { fieldsMatch: "subset", fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work based on field names (superset)", async () => { const table = DataFrame({ name: ["english", "中文"], id: [1, 2], }).lazy(); const schema = { fieldsMatch: "superset", fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should work based on field names (partial)", async () => { const table = DataFrame({ name: ["english", "中文"], id: [1, 2], }).lazy(); const schema = { fieldsMatch: "partial", fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should parse string columns", async () => { const table = DataFrame({ id: ["1", "2"], name: ["english", "中文"], }).lazy(); const schema = { fields: [ { name: "id", type: "integer" }, { name: "name", type: "string" }, ], }; const records = [ { id: 1, name: "english" }, { id: 2, name: "中文" }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); it("should read type errors as nulls", async () => { const table = DataFrame({ id: [1, 2], name: ["english", "中文"], }).lazy(); const schema = { fields: [ { name: "id", type: "integer" }, { name: "name", type: "integer" }, ], }; const records = [ { id: 1, name: null }, { id: 2, name: null }, ]; const ldf = await normalizeTable(table, schema); const df = await ldf.collect(); expect(df.toRecords()).toEqual(records); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9ybWFsaXplLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90YWJsZS9ub3JtYWxpemUuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFFL0MsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixFQUFFLENBQUMseUJBQXlCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkMsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDO1lBQ3RCLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVixJQUFJLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDO1NBQ3hCLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUVULE1BQU0sTUFBTSxHQUFXO1lBQ3JCLE1BQU0sRUFBRTtnQkFDTixFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTtnQkFDL0IsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7YUFDakM7U0FDRixDQUFBO1FBRUQsTUFBTSxPQUFPLEdBQUc7WUFDZCxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUMxQixFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRTtTQUN0QixDQUFBO1FBRUQsTUFBTSxHQUFHLEdBQUcsTUFBTSxjQUFjLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQy9DLE1BQU0sRUFBRSxHQUFHLE1BQU0sR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQzlCLE1BQU0s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RSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3pDLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gXCJAZHBraXQvY29yZVwiXG5pbXBvcnQgeyBEYXRhRnJhbWUgfSBmcm9tIFwibm9kZWpzLXBvbGFyc1wiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgbm9ybWFsaXplVGFibGUgfSBmcm9tIFwiLi9ub3JtYWxpemUudHNcIlxuXG5kZXNjcmliZShcIm5vcm1hbGl6ZVRhYmxlXCIsICgpID0+IHtcbiAgaXQoXCJzaG91bGQgd29yayB3aXRoIHNjaGVtYVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgaWQ6IFsxLCAyXSxcbiAgICAgIG5hbWU6IFtcImVuZ2xpc2hcIiwgXCLkuK3mlodcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWVcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfSxcbiAgICAgIHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfSxcbiAgICBdXG5cbiAgICBjb25zdCBsZGYgPSBhd2FpdCBub3JtYWxpemVUYWJsZSh0YWJsZSwgc2NoZW1hKVxuICAgIGNvbnN0IGRmID0gYXdhaXQgbGRmLmNvbGxlY3QoKVxuICAgIGV4cGVjdChkZi50b1JlY29yZHMoKSkudG9FcXVhbChyZWNvcmRzKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHdvcmsgd2l0aCBsZXNzIGZpZWxkcyBpbiBkYXRhXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBpZDogWzEsIDJdLFxuICAgICAgbmFtZTogW1wiZW5nbGlzaFwiLCBcIuS4reaWh1wiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJpZFwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZVwiLCB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgIHsgbmFtZTogXCJvdGhlclwiLCB0eXBlOiBcImJvb2xlYW5cIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIsIG90aGVyOiBudWxsIH0sXG4gICAgICB7IGlkOiAyLCBuYW1lOiBcIuS4reaWh1wiLCBvdGhlcjogbnVsbCB9LFxuICAgIF1cblxuICAgIGNvbnN0IGxkZiA9IGF3YWl0IG5vcm1hbGl6ZVRhYmxlKHRhYmxlLCBzY2hlbWEpXG4gICAgY29uc3QgZGYgPSBhd2FpdCBsZGYuY29sbGVjdCgpXG4gICAgZXhwZWN0KGRmLnRvUmVjb3JkcygpKS50b0VxdWFsKHJlY29yZHMpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgd29yayB3aXRoIG1vcmUgZmllbGRzIGluIGRhdGFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIGlkOiBbMSwgMl0sXG4gICAgICBuYW1lOiBbXCJlbmdsaXNoXCIsIFwi5Lit5paHXCJdLFxuICAgICAgb3RoZXI6IFt0cnVlLCBmYWxzZV0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWVcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfSxcbiAgICAgIHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfSxcbiAgICBdXG5cbiAgICBjb25zdCBsZGYgPSBhd2FpdCBub3JtYWxpemVUYWJsZSh0YWJsZSwgc2NoZW1hKVxuICAgIGNvbnN0IGRmID0gYXdhaXQgbGRmLmNvbGxlY3QoKVxuICAgIGV4cGVjdChkZi50b1JlY29yZHMoKSkudG9FcXVhbChyZWNvcmRzKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHdvcmsgYmFzZWQgb24gZmllbGRzIG9yZGVyXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBmaWVsZDE6IFsxLCAyXSxcbiAgICAgIGZpZWxkMjogW1wiZW5nbGlzaFwiLCBcIuS4reaWh1wiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJpZFwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZVwiLCB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlY29yZHMgPSBbXG4gICAgICB7IGlkOiAxLCBuYW1lOiBcImVuZ2xpc2hcIiB9LFxuICAgICAgeyBpZDogMiwgbmFtZTogXCLkuK3mlodcIiB9LFxuICAgIF1cblxuICAgIGNvbnN0IGxkZiA9IGF3YWl0IG5vcm1hbGl6ZVRhYmxlKHRhYmxlLCBzY2hlbWEpXG4gICAgY29uc3QgZGYgPSBhd2FpdCBsZGYuY29sbGVjdCgpXG4gICAgZXhwZWN0KGRmLnRvUmVjb3JkcygpKS50b0VxdWFsKHJlY29yZHMpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgd29yayBiYXNlZCBvbiBmaWVsZCBuYW1lcyAoZXF1YWwpXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBuYW1lOiBbXCJlbmdsaXNoXCIsIFwi5Lit5paHXCJdLFxuICAgICAgaWQ6IFsxLCAyXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzTWF0Y2g6IFwiZXF1YWxcIixcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWVcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfSxcbiAgICAgIHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfSxcbiAgICBdXG5cbiAgICBjb25zdCBsZGYgPSBhd2FpdCBub3JtYWxpemVUYWJsZSh0YWJsZSwgc2NoZW1hKVxuICAgIGNvbnN0IGRmID0gYXdhaXQgbGRmLmNvbGxlY3QoKVxuICAgIGV4cGVjdChkZi50b1JlY29yZHMoKSkudG9FcXVhbChyZWNvcmRzKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHdvcmsgYmFzZWQgb24gZmllbGQgbmFtZXMgKHN1YnNldClcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWU6IFtcImVuZ2xpc2hcIiwgXCLkuK3mlodcIl0sXG4gICAgICBpZDogWzEsIDJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHNNYXRjaDogXCJzdWJzZXRcIixcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWVcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfSxcbiAgICAgIHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfSxcbiAgICBdXG5cbiAgICBjb25zdCBsZGYgPSBhd2FpdCBub3JtYWxpemVUYWJsZSh0YWJsZSwgc2NoZW1hKVxuICAgIGNvbnN0IGRmID0gYXdhaXQgbGRmLmNvbGxlY3QoKVxuICAgIGV4cGVjdChkZi50b1JlY29yZHMoKSkudG9FcXVhbChyZWNvcmRzKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHdvcmsgYmFzZWQgb24gZmllbGQgbmFtZXMgKHN1cGVyc2V0KVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgbmFtZTogW1wiZW5nbGlzaFwiLCBcIuS4reaWh1wiXSxcbiAgICAgIGlkOiBbMSwgMl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkc01hdGNoOiBcInN1cGVyc2V0XCIsXG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAgeyBuYW1lOiBcImlkXCIsIHR5cGU6IFwiaW50ZWdlclwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJuYW1lXCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVjb3JkcyA9IFtcbiAgICAgIHsgaWQ6IDEsIG5hbWU6IFwiZW5nbGlzaFwiIH0sXG4gICAgICB7IGlkOiAyLCBuYW1lOiBcIuS4reaWh1wiIH0sXG4gICAgXVxuXG4gICAgY29uc3QgbGRmID0gYXdhaXQgbm9ybWFsaXplVGFibGUodGFibGUsIHNjaGVtYSlcbiAgICBjb25zdCBkZiA9IGF3YWl0IGxkZi5jb2xsZWN0KClcbiAgICBleHBlY3QoZGYudG9SZWNvcmRzKCkpLnRvRXF1YWwocmVjb3JkcylcbiAgfSlcblxuICBpdChcInNob3VsZCB3b3JrIGJhc2VkIG9uIGZpZWxkIG5hbWVzIChwYXJ0aWFsKVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgbmFtZTogW1wiZW5nbGlzaFwiLCBcIuS4reaWh1wiXSxcbiAgICAgIGlkOiBbMSwgMl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkc01hdGNoOiBcInBhcnRpYWxcIixcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWVcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfSxcbiAgICAgIHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfSxcbiAgICBdXG5cbiAgICBjb25zdCBsZGYgPSBhd2FpdCBub3JtYWxpemVUYWJsZSh0YWJsZSwgc2NoZW1hKVxuICAgIGNvbnN0IGRmID0gYXdhaXQgbGRmLmNvbGxlY3QoKVxuICAgIGV4cGVjdChkZi50b1JlY29yZHMoKSkudG9FcXVhbChyZWNvcmRzKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHBhcnNlIHN0cmluZyBjb2x1bW5zXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBpZDogW1wiMVwiLCBcIjJcIl0sXG4gICAgICBuYW1lOiBbXCJlbmdsaXNoXCIsIFwi5Lit5paHXCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAgeyBuYW1lOiBcImlkXCIsIHR5cGU6IFwiaW50ZWdlclwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJuYW1lXCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVjb3JkcyA9IFtcbiAgICAgIHsgaWQ6IDEsIG5hbWU6IFwiZW5nbGlzaFwiIH0sXG4gICAgICB7IGlkOiAyLCBuYW1lOiBcIuS4reaWh1wiIH0sXG4gICAgXVxuXG4gICAgY29uc3QgbGRmID0gYXdhaXQgbm9ybWFsaXplVGFibGUodGFibGUsIHNjaGVtYSlcbiAgICBjb25zdCBkZiA9IGF3YWl0IGxkZi5jb2xsZWN0KClcbiAgICBleHBlY3QoZGYudG9SZWNvcmRzKCkpLnRvRXF1YWwocmVjb3JkcylcbiAgfSlcblxuICBpdChcInNob3VsZCByZWFkIHR5cGUgZXJyb3JzIGFzIG51bGxzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBpZDogWzEsIDJdLFxuICAgICAgbmFtZTogW1wiZW5nbGlzaFwiLCBcIuS4reaWh1wiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJpZFwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZVwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gW1xuICAgICAgeyBpZDogMSwgbmFtZTogbnVsbCB9LFxuICAgICAgeyBpZDogMiwgbmFtZTogbnVsbCB9LFxuICAgIF1cblxuICAgIGNvbnN0IGxkZiA9IGF3YWl0IG5vcm1hbGl6ZVRhYmxlKHRhYmxlLCBzY2hlbWEpXG4gICAgY29uc3QgZGYgPSBhd2FpdCBsZGYuY29sbGVjdCgpXG4gICAgZXhwZWN0KGRmLnRvUmVjb3JkcygpKS50b0VxdWFsKHJlY29yZHMpXG4gIH0pXG59KVxuIl19