UNPKG

dcl-npc-toolkit-ai-version

Version:

A collection of tools for creating Non-Player-Characters (NPCs). These are capable of having conversations with the player, and play different animations. AI usage is added atop of it

142 lines 19.8 kB
import { AudioStream, AvatarAttach, engine } from "@dcl/sdk/ecs"; import { Client } from "colyseus.js"; import { openDialogWindow } from "./npc"; import { getUserData } from '~system/UserIdentity'; import { closeLoading, invokeInput, invokeLoading } from "./uiInput"; import * as utils from '@dcl-sdk/utils'; export let debug_on = true; export let connected = false; export let connectedRoom; export let npcId = new Map(); export let npcRagMode = new Map(); export let npcConfiguredMode = new Map(); let npcCounter = 0; let colyseusServerURL = "http://localhost:2574"; let serverFileURL = "http://localhost:2574"; let colyseusRoom = "lobby_room"; export function debugOff() { debug_on = false; } function enablePlayerSound(sound) { let playerSoundEntity; playerSoundEntity = engine.addEntity(); AudioStream.createOrReplace(playerSoundEntity, { url: sound, playing: false, }); AvatarAttach.createOrReplace(playerSoundEntity, { anchorPointId: 0, }); AudioStream.getMutable(playerSoundEntity).playing = true; utils.timers.setTimeout(() => { engine.removeEntity(playerSoundEntity); }, 100 * 1000); } export async function setCustomServerUrl(customURL, customFileURL = "") { colyseusServerURL = customURL; if (customFileURL == "") serverFileURL = colyseusServerURL; else serverFileURL = customFileURL; if (debug_on) console.log("Custom server URL is set"); } export async function setCustomServerRoomName(customRoom) { colyseusRoom = customRoom; if (debug_on) console.log("Custom server room name is set"); } export async function initServerModel(npc, ragMode, configuredMode) { if (connectedRoom == undefined) { const colyseusClient = new Client(colyseusServerURL); let user = await getUserData({}); while (!connected) { try { const availableRooms = await colyseusClient.getAvailableRooms(colyseusRoom); let roomExist = false; for (let room of availableRooms) { if (room.roomId == "primary") { roomExist = true; } } connectedRoom = !roomExist ? await colyseusClient.create(colyseusRoom, { user: user }) : await colyseusClient.joinById("primary", { user: user }); if (debug_on) console.log("Connected to llm server ", connectedRoom?.roomId); connected = true; } catch (error) { console.log("error connecting", error?.message); await dclSleep(3000); connected = false; } } connectedRoom.onMessage("getAnswer", (msg) => { closeLoading(); npcId.forEach((value, key) => { if (value == msg.id) { if (debug_on) console.log("Received prompt response from server: ", msg); openDialogWindow(key, createAiDialogSequence(key, msg.answer)); if (msg.voiceEnabled) { if (msg.voiceUrl) enablePlayerSound(`${serverFileURL}${msg.voiceUrl}`); else if (msg.voiceFullUrl) enablePlayerSound(`${msg.voiceFullUrl}`); } } }); }); } npcId.set(npc, npcCounter++); npcRagMode.set(npc, ragMode); npcConfiguredMode.set(npc, configuredMode); } export function npcAiTalk(npc, text) { connectedRoom.send("getAnswer", { id: npcId.get(npc), text: text, rag: npcRagMode.get(npc), configured: npcConfiguredMode.get(npc) }); } export function initAiDialog(npc) { openDialogWindow(npc, createAiDialogSequence(npc)); } function createAiDialogSequence(npc, firstText = 'Hi there!') { let NPCTalk = [ { text: firstText, }, { text: 'What do you want?', isQuestion: true, buttons: [ { label: 'Talk!', goToDialog: 3, triggeredActions: () => { invokeInput("Hey!", "Tell me something!", (input) => { invokeLoading(); npcAiTalk(npc, input); }); } }, { label: 'Exit!', goToDialog: 2 }, ] }, { text: 'I must go, my planet needs me', isEndOfDialog: true, }, { text: 'Listening...', isEndOfDialog: true, }, ]; return NPCTalk; } function dclSleep(milliseconds) { return new Promise((resolve, reject) => { utils.timers.setTimeout(() => { resolve(null); }, milliseconds); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBeUIsWUFBWSxFQUFVLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNoRyxPQUFPLEVBQUUsTUFBTSxFQUFRLE1BQU0sYUFBYSxDQUFBO0FBQzFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUV6QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3JFLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUE7QUFHdkMsTUFBTSxDQUFDLElBQUksUUFBUSxHQUFZLElBQUksQ0FBQztBQUNwQyxNQUFNLENBQUMsSUFBSSxTQUFTLEdBQVksS0FBSyxDQUFDO0FBQ3RDLE1BQU0sQ0FBQyxJQUFJLGFBQW1CLENBQUM7QUFDL0IsTUFBTSxDQUFDLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0FBQzdDLE1BQU0sQ0FBQyxJQUFJLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztBQUNuRCxNQUFNLENBQUMsSUFBSSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztBQUUxRCxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFDbkIsSUFBSSxpQkFBaUIsR0FBRyx1QkFBdUIsQ0FBQztBQUNoRCxJQUFJLGFBQWEsR0FBRyx1QkFBdUIsQ0FBQztBQUM1QyxJQUFJLFlBQVksR0FBRyxZQUFZLENBQUM7QUFHaEMsTUFBTSxVQUFVLFFBQVE7SUFDcEIsUUFBUSxHQUFHLEtBQUssQ0FBQztBQUNyQixDQUFDO0FBR0QsU0FBUyxpQkFBaUIsQ0FBQyxLQUFhO0lBQ3BDLElBQUksaUJBQXlCLENBQUE7SUFDN0IsaUJB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QUFVLENBQUMsR0FBRyxFQUFFO1lBQ3pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDckIsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXVkaW9TdHJlYW0sIEF2YXRhckFuY2hvclBvaW50VHlwZSwgQXZhdGFyQXR0YWNoLCBFbnRpdHksIGVuZ2luZSB9IGZyb20gXCJAZGNsL3Nkay9lY3NcIjtcbmltcG9ydCB7IENsaWVudCwgUm9vbSB9IGZyb20gXCJjb2x5c2V1cy5qc1wiXG5pbXBvcnQgeyBvcGVuRGlhbG9nV2luZG93IH0gZnJvbSBcIi4vbnBjXCI7XG5pbXBvcnQgeyBEaWFsb2cgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0VXNlckRhdGEgfSBmcm9tICd+c3lzdGVtL1VzZXJJZGVudGl0eSdcbmltcG9ydCB7IGNsb3NlTG9hZGluZywgaW52b2tlSW5wdXQsIGludm9rZUxvYWRpbmcgfSBmcm9tIFwiLi91aUlucHV0XCI7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICdAZGNsLXNkay91dGlscydcblxuLy8gY29ubmVjdGlvbiB2YXJpYWJsZXMsIG5wYyBtYXBzXG5leHBvcnQgbGV0IGRlYnVnX29uOiBib29sZWFuID0gdHJ1ZTtcbmV4cG9ydCBsZXQgY29ubmVjdGVkOiBib29sZWFuID0gZmFsc2U7XG5leHBvcnQgbGV0IGNvbm5lY3RlZFJvb206IFJvb207XG5leHBvcnQgbGV0IG5wY0lkID0gbmV3IE1hcDxFbnRpdHksIG51bWJlcj4oKTtcbmV4cG9ydCBsZXQgbnBjUmFnTW9kZSA9IG5ldyBNYXA8RW50aXR5LCBib29sZWFuPigpO1xuZXhwb3J0IGxldCBucGNDb25maWd1cmVkTW9kZSA9IG5ldyBNYXA8RW50aXR5LCBib29sZWFuPigpO1xuXG5sZXQgbnBjQ291bnRlciA9IDA7XG5sZXQgY29seXNldXNTZXJ2ZXJVUkwgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6MjU3NFwiO1xubGV0IHNlcnZlckZpbGVVUkwgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6MjU3NFwiO1xubGV0IGNvbHlzZXVzUm9vbSA9IFwibG9iYnlfcm9vbVwiO1xuXG4vLyBjYWxsIHRoaXMgZnVuY3Rpb24gdG8gcmVtb3ZlIGxvZ3NcbmV4cG9ydCBmdW5jdGlvbiBkZWJ1Z09mZigpIHtcbiAgICBkZWJ1Z19vbiA9IGZhbHNlO1xufVxuXG4vLyBmdW5jdGlvbiB0byBpbnZva2Ugdm9pY2Ugc291bmQgYWZ0ZXIgZ2VuZXJhdGlvblxuZnVuY3Rpb24gZW5hYmxlUGxheWVyU291bmQoc291bmQ6IHN0cmluZykge1xuICAgIGxldCBwbGF5ZXJTb3VuZEVudGl0eTogRW50aXR5XG4gICAgcGxheWVyU291bmRFbnRpdHkgPSBlbmdpbmUuYWRkRW50aXR5KClcblxuICAgIEF1ZGlvU3RyZWFtLmNyZWF0ZU9yUmVwbGFjZShwbGF5ZXJTb3VuZEVudGl0eSxcbiAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBzb3VuZCxcbiAgICAgICAgICAgIHBsYXlpbmc6IGZhbHNlLFxuICAgICAgICB9KVxuXG4gICAgQXZhdGFyQXR0YWNoLmNyZWF0ZU9yUmVwbGFjZShwbGF5ZXJTb3VuZEVudGl0eSx7XG4gICAgICAgIGFuY2hvclBvaW50SWQ6IEF2YXRhckFuY2hvclBvaW50VHlwZS5BQVBUX1BPU0lUSU9OLFxuICAgIH0pXG5cbiAgICAvL0F1ZGlvU3RyZWFtLmdldE11dGFibGUocGxheWVyU291bmRFbnRpdHkpLnZvbHVtZSA9IDRcbiAgICBBdWRpb1N0cmVhbS5nZXRNdXRhYmxlKHBsYXllclNvdW5kRW50aXR5KS5wbGF5aW5nID0gdHJ1ZVxuICAgIHV0aWxzLnRpbWVycy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgZW5naW5lLnJlbW92ZUVudGl0eShwbGF5ZXJTb3VuZEVudGl0eSlcbiAgICB9LCAxMDAgKiAxMDAwKTtcbn1cblxuLy8gQ2FsbCB0aGlzIGZ1bmN0aW9uIGJlZm9yZSBjcmVhdGluZyBOUEMgdG8gc2V0IGNvbHlzZXVzIHNlcnZlciB1cmwgT1IgaW5wdXQgdXJsIGRpcmVjdGx5IGluIGNyZWF0ZSgpIGZ1bmN0aW9uIGFyZ3VtZW50XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0Q3VzdG9tU2VydmVyVXJsKGN1c3RvbVVSTDogc3RyaW5nLCBjdXN0b21GaWxlVVJMOiBzdHJpbmcgPSBcIlwiKSB7XG4gICAgY29seXNldXNTZXJ2ZXJVUkwgPSBjdXN0b21VUkw7XG4gICAgaWYgKGN1c3RvbUZpbGVVUkwgPT0gXCJcIilcbiAgICAgICAgc2VydmVyRmlsZVVSTCA9IGNvbHlzZXVzU2VydmVyVVJMO1xuICAgIGVsc2VcbiAgICAgICAgc2VydmVyRmlsZVVSTCA9IGN1c3RvbUZpbGVVUkw7XG4gICAgaWYgKGRlYnVnX29uKSBjb25zb2xlLmxvZyhcIkN1c3RvbSBzZXJ2ZXIgVVJMIGlzIHNldFwiKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXRDdXN0b21TZXJ2ZXJSb29tTmFtZShjdXN0b21Sb29tOiBzdHJpbmcpIHtcbiAgICBjb2x5c2V1c1Jvb20gPSBjdXN0b21Sb29tXG4gICAgaWYgKGRlYnVnX29uKSBjb25zb2xlLmxvZyhcIkN1c3RvbSBzZXJ2ZXIgcm9vbSBuYW1lIGlzIHNldFwiKTtcbn1cblxuLy8gSW5pdGlhdGluZyBzZXJ2ZXIgLyBhZGRpbmcgbmV3IG5wYyB0byB0aGUgbWFwXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gbmV3IE5QQyBpcyBjcmVhdGVkXG4vLyBXaGVuIGNhbGxlZCBmb3IgdGhlIGZpcnN0IHRpbWUgaXQgY29ubmVjdHMgdG8gY29seXNldXMgc2VydmVyIGJ5IHNwZWNpZmllZCB1cmwgZnJvbSBzZXRDdXN0b21TZXJ2ZXJVcmwoKVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluaXRTZXJ2ZXJNb2RlbChucGM6IEVudGl0eSwgcmFnTW9kZTogYm9vbGVhbiwgY29uZmlndXJlZE1vZGU6IGJvb2xlYW4pIHtcbiAgICBpZiAoY29ubmVjdGVkUm9vbSA9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgY29seXNldXNDbGllbnQ6IENsaWVudCA9IG5ldyBDbGllbnQoY29seXNldXNTZXJ2ZXJVUkwpO1xuICAgICAgICBsZXQgdXNlciA9IGF3YWl0IGdldFVzZXJEYXRhKHt9KTtcbiAgICAgICAgd2hpbGUoIWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhdmFpbGFibGVSb29tcyA9IGF3YWl0IGNvbHlzZXVzQ2xpZW50LmdldEF2YWlsYWJsZVJvb21zKGNvbHlzZXVzUm9vbSk7XG4gICAgICAgICAgICAgICAgbGV0IHJvb21FeGlzdCA9IGZhbHNlXG4gICAgICAgICAgICAgICAgLy8gdXNpbmcgXCJwcmltYXJ5XCIgYXMgaWQgdG8gbm90IGNyZWF0ZSBleHRyYSBjb2x5c2V1cyByb29tc1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHJvb20gb2YgYXZhaWxhYmxlUm9vbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJvb20ucm9vbUlkID09IFwicHJpbWFyeVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByb29tRXhpc3QgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25uZWN0ZWRSb29tID0gIXJvb21FeGlzdCA/IGF3YWl0IGNvbHlzZXVzQ2xpZW50LmNyZWF0ZTxhbnk+KGNvbHlzZXVzUm9vbSwge3VzZXI6IHVzZXJ9KVxuICAgICAgICAgICAgICAgICAgICA6IGF3YWl0IGNvbHlzZXVzQ2xpZW50LmpvaW5CeUlkPGFueT4oXCJwcmltYXJ5XCIsIHt1c2VyOiB1c2VyfSlcblxuICAgICAgICAgICAgICAgIGlmIChkZWJ1Z19vbikgY29uc29sZS5sb2coXCJDb25uZWN0ZWQgdG8gbGxtIHNlcnZlciBcIiwgY29ubmVjdGVkUm9vbT8ucm9vbUlkKTtcbiAgICAgICAgICAgICAgICBjb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaChlcnJvcjphbnkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcImVycm9yIGNvbm5lY3RpbmdcIiwgZXJyb3I/Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGRjbFNsZWVwKDMwMDApO1xuICAgICAgICAgICAgICAgIGNvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRkaW5nIG9uTWVzc2FnZSBsaXN0ZW5lciB0byByZWNlaXZlIGFuc3dlcnMgZnJvbSBsbG0gc2VydmVyXG4gICAgICAgIGNvbm5lY3RlZFJvb20ub25NZXNzYWdlKFwiZ2V0QW5zd2VyXCIsKG1zZyk9PntcbiAgICAgICAgICAgIGNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgbnBjSWQuZm9yRWFjaCgodmFsdWUsIGtleSk9PntcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbXNnLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkZWJ1Z19vbikgY29uc29sZS5sb2coXCJSZWNlaXZlZCBwcm9tcHQgcmVzcG9uc2UgZnJvbSBzZXJ2ZXI6IFwiLCBtc2cpO1xuICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGluZyBkaWFsb2cgZm9yIG5wY1xuICAgICAgICAgICAgICAgICAgICBvcGVuRGlhbG9nV2luZG93KGtleSxjcmVhdGVBaURpYWxvZ1NlcXVlbmNlKGtleSxtc2cuYW5zd2VyKSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFBsYXlpbmcgdm9pY2UgZmlsZSBpZiB2b2ljZSBpcyBlbmFibGVkIG9uIHNlcnZlclxuICAgICAgICAgICAgICAgICAgICBpZiAobXNnLnZvaWNlRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zZy52b2ljZVVybClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVQbGF5ZXJTb3VuZChgJHtzZXJ2ZXJGaWxlVVJMfSR7bXNnLnZvaWNlVXJsfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobXNnLnZvaWNlRnVsbFVybClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVQbGF5ZXJTb3VuZChgJHttc2cudm9pY2VGdWxsVXJsfWApXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIC8vIEFkZGluZyBOUEMgdG8gbWFwcywgaW5jbHVkaW5nIGlmIFJhZyBzeXN0ZW0gaXMgb24vb2ZmIGZvciBwYXJ0aWN1bGFyIE5QQ1xuICAgIG5wY0lkLnNldChucGMsbnBjQ291bnRlcisrKTtcbiAgICBucGNSYWdNb2RlLnNldChucGMscmFnTW9kZSk7XG4gICAgbnBjQ29uZmlndXJlZE1vZGUuc2V0KG5wYyxjb25maWd1cmVkTW9kZSk7XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIHNlbmQgbWVzc2FnZSB0byBzZXJ2ZXIsIGNvbnNpc3Rpbmcgb2YgdXNlciBwcm9tcHRcbmV4cG9ydCBmdW5jdGlvbiBucGNBaVRhbGsobnBjOiBFbnRpdHksIHRleHQ6IHN0cmluZykge1xuICAgIGNvbm5lY3RlZFJvb20uc2VuZChcImdldEFuc3dlclwiLHtcbiAgICAgICAgaWQ6IG5wY0lkLmdldChucGMpLFxuICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICByYWc6IG5wY1JhZ01vZGUuZ2V0KG5wYyksXG4gICAgICAgIGNvbmZpZ3VyZWQ6IG5wY0NvbmZpZ3VyZWRNb2RlLmdldChucGMpXG4gICAgfSk7XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIGNyZWF0ZSBhIGdlbmVyaWMgZGlhbG9nLCB0aGF0IGFza3MgdXNlciB0byBzdWJtaXQgdGhlaXIgcHJvbXB0XG5leHBvcnQgZnVuY3Rpb24gaW5pdEFpRGlhbG9nKG5wYzogRW50aXR5KSB7XG4gICAgb3BlbkRpYWxvZ1dpbmRvdyhucGMsY3JlYXRlQWlEaWFsb2dTZXF1ZW5jZShucGMpKTtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBnZW5lcmF0ZXMgYSBnZW5lcmljIGRpYWxvZyBzZXF1ZW5jZSwgdGhhdCBhc2tzIHVzZXIgdG8gc3VibWl0IHRoZWlyIHByb21wdFxuZnVuY3Rpb24gY3JlYXRlQWlEaWFsb2dTZXF1ZW5jZShucGM6IEVudGl0eSwgZmlyc3RUZXh0OiBzdHJpbmcgPSAnSGkgdGhlcmUhJykge1xuICAgIGxldCBOUENUYWxrOiBEaWFsb2dbXSA9IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogZmlyc3RUZXh0LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0ZXh0OiAnV2hhdCBkbyB5b3Ugd2FudD8nLFxuICAgICAgICAgICAgaXNRdWVzdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7bGFiZWw6ICdUYWxrIScsIGdvVG9EaWFsb2c6IDMsIHRyaWdnZXJlZEFjdGlvbnM6ICgpPT57XG4gICAgICAgICAgICAgICAgICAgIGludm9rZUlucHV0KFwiSGV5IVwiLFwiVGVsbCBtZSBzb21ldGhpbmchXCIsKGlucHV0OiBzdHJpbmcpPT57XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnZva2VMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBucGNBaVRhbGsobnBjLGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9fSxcbiAgICAgICAgICAgICAgICB7bGFiZWw6ICdFeGl0IScsIGdvVG9EaWFsb2c6IDJ9LFxuICAgICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0ZXh0OiAnSSBtdXN0IGdvLCBteSBwbGFuZXQgbmVlZHMgbWUnLFxuICAgICAgICAgICAgaXNFbmRPZkRpYWxvZzogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogJ0xpc3RlbmluZy4uLicsXG4gICAgICAgICAgICBpc0VuZE9mRGlhbG9nOiB0cnVlLFxuICAgICAgICB9LFxuICAgIF1cbiAgICByZXR1cm4gTlBDVGFsaztcbn1cblxuZnVuY3Rpb24gZGNsU2xlZXAobWlsbGlzZWNvbmRzOiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB1dGlscy50aW1lcnMuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKG51bGwpO1xuICAgICAgICB9LCBtaWxsaXNlY29uZHMpO1xuICAgIH0pO1xufSJdfQ==