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

358 lines 52.6 kB
import { AudioSource, Billboard, engine, Material, MeshRenderer, TextShape, Transform, VisibilityComponent } from '@dcl/sdk/ecs';
import { Color4, Vector3 } from '@dcl/sdk/math';
import { addLineBreak, findDialogByName } from './dialog';
import { IsTypingBubble } from './components';
import { npcDataComponent } from './npc';
export let bubblesTexture = 'https://decentraland.org/images/ui/dialog-bubbles.png';
export let bubbles = new Map();
let textSize = 1;
let textYPos = 0;
let maxLengthShortBubble = 8;
let maxLengthNormalBubble = 25;
let maxLengthLongBubble = 50;
let maxLengthHugeBubble = 100;
let shortBubbleXOffset = 0.1;
let normalBubbleXOffset = 0.5;
let longBubbleXOffset = 0.8;
let hugeBubbleXOffset = 0.8;
let shortBubbleYOffset = -0.2;
let normalBubbleYOffset = -0.2;
let longBubbleYOffset = 0;
let hugeBubbleYOffset = 0.2;
let shortBubbleTextWidth = 0.7;
let normalBubbleTextWidth = 1.5;
let longBubbleTextWidth = 2;
let hugeBubbleTextWidth = 1.5;
let shortBubbleX = 116 * 0.005;
let shortBubbleY = 84 * 0.005;
let normalBubbleX = 286 * 0.005;
let normalBubbleY = 84 * 0.005;
let longBubbleX = 497 * 0.005;
let longBubbleY = 153 * 0.005;
let hugeBubbleX = 497 * 0.005;
let hugeBubbleY = 239 * 0.005;
let defaultYOffset = 2.5;
export function createDialogBubble(npc, height, sound) {
    let baseYOffset = height ? height : defaultYOffset;
    let root = engine.addEntity();
    Billboard.create(root, {
        billboardMode: 2
    });
    Transform.create(root, {
        parent: npc
    });
    let container = engine.addEntity();
    Transform.create(container, {
        parent: root,
        position: Vector3.create(shortBubbleXOffset, baseYOffset, 0)
    });
    let panel = engine.addEntity();
    Transform.create(panel, {
        parent: container,
        scale: Vector3.create(2, 1, 1),
    });
    MeshRenderer.setPlane(panel, setUVSection(bubbleOptions.normal, 1024, 1024));
    VisibilityComponent.create(panel, { visible: false });
    Material.setBasicMaterial(panel, {
        texture: Material.Texture.Common({
            src: bubblesTexture
        })
    });
    let text = engine.addEntity();
    Transform.create(text, {
        position: Vector3.create(0, textYPos, -.05),
        parent: container
    });
    TextShape.create(text, {
        text: "",
        fontSize: textSize,
        font: 0,
        textColor: Color4.create(0, 0, 0, 1),
        textAlign: 4
    });
    VisibilityComponent.create(text, { visible: false });
    bubbles.set(npc, {
        container: container,
        panel: panel,
        text: text,
        baseYOffset: baseYOffset,
        isBubbleOpen: false,
        typing: false,
        visibleText: "",
        visibleChars: 0,
        fullText: "",
        timer: 0,
        speed: 30,
        script: [],
        index: 0,
        sound: sound ? sound : undefined,
        soundPlayer: sound ? engine.addEntity() : undefined,
    });
}
export function openBubble(npc, dialog, startIndex) {
    let bubble = bubbles.get(npc);
    bubble.script = dialog.slice();
    let index;
    if (!startIndex) {
        index = 0;
    }
    else if (typeof startIndex === 'number') {
        index = startIndex;
    }
    else {
        index = findDialogByName(dialog, startIndex);
    }
    bubble.index = index;
    let currentText = dialog[bubble.index] ? dialog[bubble.index] : { text: '' };
    bubble.currentText = currentText;
    if (currentText.audio) {
        AudioSource.createOrReplace(bubble.soundPlayer, {
            audioClipUrl: currentText.audio,
            loop: false,
            playing: false
        });
        let audio = AudioSource.getMutable(bubble.soundPlayer);
        audio.volume = 0.5;
        audio.playing = true;
    }
    else if (bubble.sound) {
        AudioSource.createOrReplace(bubble.soundPlayer, {
            audioClipUrl: bubble.sound,
            loop: false,
            playing: false
        });
        let audio = AudioSource.getMutable(bubble.soundPlayer);
        audio.volume = 0.5;
        audio.playing = true;
    }
    let text = bubble.text;
    TextShape.getMutable(text).fontSize = currentText.fontSize ? currentText.fontSize : textSize;
    Transform.getMutable(text).position.y = currentText.offsetY ? currentText.offsetY + textYPos : textYPos;
    Transform.getMutable(text).position.x = currentText.offsetX ? currentText.offsetX : 0;
    VisibilityComponent.getMutable(bubble.panel).visible = true;
    if (currentText.text.length < maxLengthHugeBubble) {
        currentText.text.slice(0, maxLengthHugeBubble);
    }
    beginTyping(npc, currentText.text, bubble.index, currentText.timeOn ? currentText.timeOn : undefined, currentText.typeSpeed ? currentText.typeSpeed : undefined);
    adjustBubble(npc, currentText.text.length);
    layoutDialogWindow(npc, bubble.index);
    bubble.isBubbleOpen = true;
}
export function closeBubble(npc) {
    let bubble = bubbles.get(npc);
    bubble.isBubbleOpen = false;
    bubble.typing = false;
    bubble.visibleText = "";
    bubble.visibleChars = 0;
    bubble.fullText = "";
    bubble.timer = 0;
    bubble.index = 0;
    bubble.script = [];
    bubble.buttons = 0;
    bubble.margin = 0;
    bubble.currentText = null;
    TextShape.getMutable(bubble.text).text = "";
    VisibilityComponent.getMutable(bubble.text).visible = false;
    VisibilityComponent.getMutable(bubble.panel).visible = false;
}
export function closeBubbleEndAll(npc) {
    let bubble = bubbles.get(npc);
    if (bubble.isBubbleOpen) {
        bubble.done = true;
        closeBubble(npc);
    }
}
const DEFAULT_SPEED = 45;
const DEFAULT_TIME_ON = 3;
function beginTyping(npc, text, textId, timeOn, speed) {
    let dialogData = bubbles.get(npc);
    dialogData.fullText = addLineBreak(dialogData.script[dialogData.index].text, true);
    dialogData.typing = true;
    dialogData.done = false;
    dialogData.visibleText = "";
    dialogData.visibleChars = 0;
    dialogData.timer = 0;
    dialogData.buttons = 0;
    dialogData.timeOn = timeOn ? timeOn : DEFAULT_TIME_ON;
    dialogData.speed = speed ? speed : DEFAULT_SPEED;
    dialogData.openTime = Math.floor(Date.now());
    if (dialogData.speed <= 0) {
        rushText(npc);
    }
    else {
        if (!IsTypingBubble.has(npc)) {
            console.log('creating typuing bubble');
            IsTypingBubble.create(npc);
        }
    }
}
function rushText(npc) {
    let dialogData = bubbles.get(npc);
    dialogData.typing = false;
    dialogData.timer = 0;
    dialogData.visibleChars = dialogData.fullText.length;
    dialogData.visibleText = dialogData.fullText;
}
function adjustBubble(npc, textLength) {
    let bubble = bubbles.get(npc);
    let npcData = npcDataComponent.get(npc);
    if (textLength < maxLengthShortBubble) {
        MeshRenderer.setPlane(bubble.panel, setUVSection(bubbleOptions.short, 1024, 1024));
        Transform.getMutable(bubble.panel).scale.x = shortBubbleX;
        Transform.getMutable(bubble.panel).scale.y = shortBubbleY;
        Transform.getMutable(bubble.container).position.x = shortBubbleXOffset + npcData.bubbleXOffset;
        Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + shortBubbleYOffset + npcData.bubbleYOffset;
        TextShape.getMutable(bubble.text).width = shortBubbleTextWidth;
    }
    else if (textLength < maxLengthNormalBubble) {
        MeshRenderer.setPlane(bubble.panel, setUVSection(bubbleOptions.normal, 1024, 1024));
        Transform.getMutable(bubble.panel).scale.x = normalBubbleX;
        Transform.getMutable(bubble.panel).scale.y = normalBubbleY;
        Transform.getMutable(bubble.container).position.x = normalBubbleXOffset + npcData.bubbleXOffset;
        Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + normalBubbleYOffset + npcData.bubbleYOffset;
        TextShape.getMutable(bubble.text).width = normalBubbleTextWidth;
    }
    else if (textLength < maxLengthLongBubble) {
        MeshRenderer.setPlane(bubble.panel, setUVSection(bubbleOptions.long, 1024, 1024));
        Transform.getMutable(bubble.panel).scale.x = longBubbleX;
        Transform.getMutable(bubble.panel).scale.y = longBubbleY;
        Transform.getMutable(bubble.container).position.x = longBubbleXOffset + npcData.bubbleXOffset;
        Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + longBubbleYOffset + npcData.bubbleYOffset;
        TextShape.getMutable(bubble.text).width = longBubbleTextWidth;
    }
    else {
        MeshRenderer.setPlane(bubble.panel, setUVSection(bubbleOptions.huge, 1024, 1024));
        Transform.getMutable(bubble.panel).scale.x = hugeBubbleX;
        Transform.getMutable(bubble.panel).scale.y = hugeBubbleY;
        Transform.getMutable(bubble.container).position.x = hugeBubbleXOffset + npcData.bubbleXOffset;
        Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + hugeBubbleYOffset + npcData.bubbleYOffset;
        TextShape.getMutable(bubble.text).width = hugeBubbleTextWidth;
    }
}
function layoutDialogWindow(npc, textId) {
    let bubble = bubbles.get(npc);
    let currentText = bubble.script[textId]
        ? bubble.script[textId]
        : { text: '' };
    let textY = currentText.offsetY ? currentText.offsetY + textYPos : textYPos;
    if (currentText.buttons && currentText.buttons.length >= 3) {
        textY += 50;
    }
    else if (currentText.buttons && currentText.buttons.length >= 1) {
        textY += 24;
    }
    TextShape.getMutable(bubble.text).fontSize = currentText.fontSize
        ? currentText.fontSize
        : textSize;
    VisibilityComponent.getMutable(bubble.text).visible = true;
    Transform.getMutable(bubble.text).position.y = textY;
    if (currentText.audio) {
        AudioSource.createOrReplace(bubble.soundPlayer, {
            audioClipUrl: currentText.audio,
            loop: false,
            playing: false
        });
        let audio = AudioSource.getMutable(bubble.soundPlayer);
        audio.volume = 0.5;
        audio.playing = true;
    }
    else if (bubble.sound) {
        AudioSource.createOrReplace(bubble.soundPlayer, {
            audioClipUrl: bubble.sound,
            loop: false,
            playing: false
        });
        let audio = AudioSource.getMutable(bubble.soundPlayer);
        audio.volume = 0.5;
        audio.playing = true;
    }
}
export function next(npc) {
    let bubble = bubbles.get(npc);
    if (bubble.isBubbleOpen) {
        let currentText = bubble.script[bubble.index];
        if (!currentText) {
            currentText = bubble.script[bubble.index - 1];
        }
        if (currentText.triggeredByNext) {
            currentText.triggeredByNext();
        }
        if (currentText.isEndOfDialog) {
            closeBubble(npc);
            return;
        }
        bubble.index++;
        currentText = bubble.script[bubble.index];
        if (currentText.text.length < maxLengthHugeBubble) {
            currentText.text.slice(0, maxLengthHugeBubble);
        }
        TextShape.getMutable(bubble.text).text = "";
        adjustBubble(npc, currentText.text.length);
        beginTyping(npc, currentText.text, bubble.index, currentText.timeOn ? currentText.timeOn : undefined, currentText.typeSpeed ? currentText.typeSpeed : undefined);
        layoutDialogWindow(npc, bubble.index);
    }
}
function setUVSection(section, sizeX, sizeY) {
    return setUVs({ x: section.sourceLeft / sizeX, y: (sizeY - section.sourceTop - section.sourceHeight) / sizeY }, { x: (section.sourceLeft + section.sourceWidth) / sizeX, y: (sizeY - section.sourceTop - section.sourceHeight) / sizeY }, { x: (section.sourceLeft + section.sourceWidth) / sizeX, y: (sizeY - section.sourceTop) / sizeY }, { x: section.sourceLeft / sizeX, y: (sizeY - section.sourceTop) / sizeY });
}
function setUVs(_uv00, _uv10, _uv11, _uv01) {
    return [
        _uv00.x,
        _uv00.y,
        _uv10.x,
        _uv10.y,
        _uv11.x,
        _uv11.y,
        _uv01.x,
        _uv01.y,
        _uv00.x,
        _uv00.y,
        _uv10.x,
        _uv10.y,
        _uv11.x,
        _uv11.y,
        _uv01.x,
        _uv01.y,
    ];
}
let bubbleOptions = {
    short: {
        sourceWidth: 116 * 2,
        sourceHeight: 84 * 2,
        sourceLeft: 305 * 2,
        sourceTop: 417 * 2,
    },
    normal: {
        sourceWidth: 286 * 2,
        sourceHeight: 84 * 2,
        sourceLeft: 8 * 2,
        sourceTop: 417 * 2,
    },
    long: {
        sourceWidth: 497 * 2,
        sourceHeight: 153 * 2,
        sourceLeft: 6 * 2,
        sourceTop: 254 * 2,
    },
    huge: {
        sourceWidth: 497 * 2,
        sourceHeight: 239 * 2,
        sourceLeft: 6 * 2,
        sourceTop: 7 * 2,
    },
};
export function getBubbleTextLength(text) {
    if (text.length >= maxLengthHugeBubble) {
        return 40;
    }
    else if (text.length >= maxLengthLongBubble) {
        return 40;
    }
    else if (text.length >= maxLengthNormalBubble) {
        return 40;
    }
    else if (text.length >= maxLengthShortBubble) {
        return 40;
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnViYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2J1YmJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQVksV0FBVyxFQUFlLFNBQVMsRUFBaUIsTUFBTSxFQUEyQyxRQUFRLEVBQWMsWUFBWSxFQUFtQyxTQUFTLEVBQUMsU0FBUyxFQUFpQixtQkFBbUIsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUcxUSxPQUFPLEVBQVMsTUFBTSxFQUFjLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNsRSxPQUFPLEVBQUUsWUFBWSxFQUFpQixnQkFBZ0IsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUN4RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQzdDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUV4QyxNQUFNLENBQUMsSUFBSSxjQUFjLEdBQUcsdURBQXVELENBQUE7QUFFbkYsTUFBTSxDQUFDLElBQUksT0FBTyxHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFBO0FBRWhELElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQTtBQUNoQixJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUE7QUFFaEIsSUFBSSxvQkFBb0IsR0FBRyxDQUFDLENBQUE7QUFDNUIsSUFBSSxxQkFBcUIsR0FBRyxFQUFFLENBQUE7QUFDOUIsSUFBSSxtQkFBbUIsR0FBRyxFQUFFLENBQUE7QUFDNUIsSUFBSSxtQkFBbUIsR0FBRyxHQUFHLENBQUE7QUFFN0IsSUFBSSxrQkFBa0IsR0FBRyxHQUFHLENBQUE7QUFDNUIsSUFBSSxtQkFBbUIsR0FBRyxHQUFHLENBQUE7QUFDN0IsSUFBSSxpQkFBaUIsR0FBRyxHQUFHLENBQUE7QUFDM0IsSUFBSSxpQkFBaUIsR0FBRyxHQUFHLENBQUE7QUFFM0IsSUFBSSxrQkFBa0IsR0FBRyxDQUFDLEdBQUcsQ0FBQTtBQUM3QixJQUFJLG1CQUFtQixHQUFHLENBQUMsR0FBRyxD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QUFHLEdBQUcsQ0FBQztRQUNyQixVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUM7UUFDakIsU0FBUyxFQUFFLEdBQUcsR0FBRyxDQUFDO0tBQ25CO0lBQ0QsSUFBSSxFQUFFO1FBQ0osV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDO1FBQ3BCLFlBQVksRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUNyQixVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUM7UUFDakIsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO0tBQ2pCO0NBQ0osQ0FBQTtBQUdELE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxJQUFXO0lBQzNDLElBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxtQkFBbUIsRUFBQyxDQUFDO1FBQ25DLE9BQU8sRUFBRSxDQUFBO0lBQ2IsQ0FBQztTQUNJLElBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxtQkFBbUIsRUFBQyxDQUFDO1FBQ3hDLE9BQU8sRUFBRSxDQUFBO0lBQ2IsQ0FBQztTQUNJLElBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxxQkFBcUIsRUFBQyxDQUFDO1FBQzFDLE9BQU8sRUFBRSxDQUFBO0lBQ2IsQ0FBQztTQUNJLElBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxvQkFBb0IsRUFBQyxDQUFDO1FBQ3pDLE9BQU8sRUFBRSxDQUFBO0lBQ2IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7IEFuaW1hdG9yLCBBdWRpb1NvdXJjZSwgQXZhdGFyU2hhcGUsIEJpbGxib2FyZCwgQmlsbGJvYXJkTW9kZSwgZW5naW5lLCBFbnRpdHksIEZvbnQsIEdsdGZDb250YWluZXIsIElucHV0QWN0aW9uLE1hdGVyaWFsLE1lc2hDb2xsaWRlcixNZXNoUmVuZGVyZXIscG9pbnRlckV2ZW50c1N5c3RlbSxUZXh0QWxpZ25Nb2RlLFRleHRTaGFwZSxUcmFuc2Zvcm0sIFRyYW5zZm9ybVR5cGUsIFZpc2liaWxpdHlDb21wb25lbnQgfSBmcm9tICdAZGNsL3Nkay9lY3MnXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICdAZGNsLXNkay91dGlscydcbmltcG9ydCB7IERpYWxvZywgSW1hZ2VTZWN0aW9uIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IENvbG9yMyxDb2xvcjQsIFF1YXRlcm5pb24sIFZlY3RvcjMgfSBmcm9tICdAZGNsL3Nkay9tYXRoJ1xuaW1wb3J0IHsgYWRkTGluZUJyZWFrLCBhZGRMaW5lQnJlYWtzLCBmaW5kRGlhbG9nQnlOYW1lIH0gZnJvbSAnLi9kaWFsb2cnXG5pbXBvcnQgeyBJc1R5cGluZ0J1YmJsZSB9IGZyb20gJy4vY29tcG9uZW50cydcbmltcG9ydCB7IG5wY0RhdGFDb21wb25lbnQgfSBmcm9tICcuL25wYydcblxuZXhwb3J0IGxldCBidWJibGVzVGV4dHVyZSA9ICdodHRwczovL2RlY2VudHJhbGFuZC5vcmcvaW1hZ2VzL3VpL2RpYWxvZy1idWJibGVzLnBuZydcblxuZXhwb3J0IGxldCBidWJibGVzOiBNYXA8RW50aXR5LCBhbnk+ID0gbmV3IE1hcCgpXG5cbmxldCB0ZXh0U2l6ZSA9IDFcbmxldCB0ZXh0WVBvcyA9IDAgICAgXG5cbmxldCBtYXhMZW5ndGhTaG9ydEJ1YmJsZSA9IDhcbmxldCBtYXhMZW5ndGhOb3JtYWxCdWJibGUgPSAyNVxubGV0IG1heExlbmd0aExvbmdCdWJibGUgPSA1MFxubGV0IG1heExlbmd0aEh1Z2VCdWJibGUgPSAxMDBcblxubGV0IHNob3J0QnViYmxlWE9mZnNldCA9IDAuMVxubGV0IG5vcm1hbEJ1YmJsZVhPZmZzZXQgPSAwLjVcbmxldCBsb25nQnViYmxlWE9mZnNldCA9IDAuOFxubGV0IGh1Z2VCdWJibGVYT2Zmc2V0ID0gMC44XG5cbmxldCBzaG9ydEJ1YmJsZVlPZmZzZXQgPSAtMC4yXG5sZXQgbm9ybWFsQnViYmxlWU9mZnNldCA9IC0wLjJcbmxldCBsb25nQnViYmxlWU9mZnNldCA9IDBcbmxldCBodWdlQnViYmxlWU9mZnNldCA9IDAuMlxuXG5sZXQgc2hvcnRCdWJibGVUZXh0V2lkdGggPSAwLjdcbmxldCBub3JtYWxCdWJibGVUZXh0V2lkdGggPSAxLjVcbmxldCBsb25nQnViYmxlVGV4dFdpZHRoID0gMlxubGV0IGh1Z2VCdWJibGVUZXh0V2lkdGggPSAxLjVcblxubGV0IHNob3J0QnViYmxlWCA9IDExNiAqIDAuMDA1XG5sZXQgc2hvcnRCdWJibGVZID0gODQgKiAwLjAwNVxuXG5sZXQgbm9ybWFsQnViYmxlWCA9IDI4NiAqIDAuMDA1XG5sZXQgbm9ybWFsQnViYmxlWSA9IDg0ICogMC4wMDVcblxubGV0IGxvbmdCdWJibGVYID0gNDk3ICogMC4wMDVcbmxldCBsb25nQnViYmxlWSA9IDE1MyAqIDAuMDA1XG5cbmxldCBodWdlQnViYmxlWCA9IDQ5NyAqIDAuMDA1XG5sZXQgaHVnZUJ1YmJsZVkgPSAyMzkgKiAwLjAwNVxuXG5sZXQgZGVmYXVsdFlPZmZzZXQgPSAyLjVcblxuXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEaWFsb2dCdWJibGUobnBjOkVudGl0eSwgaGVpZ2h0PzpudW1iZXIsIHNvdW5kPzpzdHJpbmcpe1xuICAgIGxldCBiYXNlWU9mZnNldCA9IGhlaWdodCA/IGhlaWdodCA6IGRlZmF1bHRZT2Zmc2V0XG5cbiAgICBsZXQgcm9vdCA9IGVuZ2luZS5hZGRFbnRpdHkoKVxuICAgIEJpbGxib2FyZC5jcmVhdGUocm9vdCx7XG4gICAgICAgIGJpbGxib2FyZE1vZGU6QmlsbGJvYXJkTW9kZS5CTV9ZXG4gICAgfSlcblxuICAgIFRyYW5zZm9ybS5jcmVhdGUocm9vdCx7XG4gICAgICAgIHBhcmVudDpucGNcbiAgICB9KVxuXG4gICAgbGV0IGNvbnRhaW5lciA9IGVuZ2luZS5hZGRFbnRpdHkoKVxuICAgIFRyYW5zZm9ybS5jcmVhdGUoY29udGFpbmVyLHtcbiAgICAgICAgcGFyZW50OnJvb3QsXG4gICAgICAgIHBvc2l0aW9uOlZlY3RvcjMuY3JlYXRlKHNob3J0QnViYmxlWE9mZnNldCxiYXNlWU9mZnNldCwwKVxuICAgIH0pXG5cbiAgICBsZXQgcGFuZWwgPSBlbmdpbmUuYWRkRW50aXR5KClcbiAgICBUcmFuc2Zvcm0uY3JlYXRlKHBhbmVsLHtcbiAgICAgICAgcGFyZW50OmNvbnRhaW5lcixcbiAgICAgICAgc2NhbGU6IFZlY3RvcjMuY3JlYXRlKDIsMSwxKSxcbiAgICAgICAgLy9yb3RhdGlvbjpRdWF0ZXJuaW9uLmZyb21FdWxlckRlZ3JlZXMoMCwwLDkwKVxuICAgIH0pXG4gICAgTWVzaFJlbmRlcmVyLnNldFBsYW5lKHBhbmVsLFxuICAgICAgICBzZXRVVlNlY3Rpb24oXG4gICAgICAgIGJ1YmJsZU9wdGlvbnMubm9ybWFsLFxuICAgICAgICAxMDI0LFxuICAgICAgICAxMDI0XG4gICAgICApKVxuXG4gICAgVmlzaWJpbGl0eUNvbXBvbmVudC5jcmVhdGUocGFuZWwsIHt2aXNpYmxlOiBmYWxzZX0pXG5cbiAgICBNYXRlcmlhbC5zZXRCYXNpY01hdGVyaWFsKHBhbmVsLCB7XG4gICAgICAgIHRleHR1cmU6IE1hdGVyaWFsLlRleHR1cmUuQ29tbW9uKHtcbiAgICAgICAgICBzcmM6IGJ1YmJsZXNUZXh0dXJlXG4gICAgICAgIH0pXG4gICAgICB9KVxuXG4gICAgbGV0IHRleHQgPSBlbmdpbmUuYWRkRW50aXR5KClcbiAgICBUcmFuc2Zvcm0uY3JlYXRlKHRleHQse1xuICAgICAgICBwb3NpdGlvbjpWZWN0b3IzLmNyZWF0ZSgwLHRleHRZUG9zLCAtLjA1KSxcbiAgICAgICAgcGFyZW50OmNvbnRhaW5lclxuICAgIH0pXG4gICAgVGV4dFNoYXBlLmNyZWF0ZSh0ZXh0LCB7XG4gICAgICAgIHRleHQ6XCJcIiwgXG4gICAgICAgIGZvbnRTaXplOnRleHRTaXplLFxuICAgICAgICBmb250OiBGb250LkZfU0FOU19TRVJJRixcbiAgICAgICAgdGV4dENvbG9yOiBDb2xvcjQuY3JlYXRlKDAsMCwwLDEpLFxuICAgICAgICB0ZXh0QWxpZ246VGV4dEFsaWduTW9kZS5UQU1fTUlERExFX0NFTlRFUlxuICAgIH0pXG4gICAgVmlzaWJpbGl0eUNvbXBvbmVudC5jcmVhdGUodGV4dCwge3Zpc2libGU6IGZhbHNlfSlcblxuICAgIGJ1YmJsZXMuc2V0KG5wYywge1xuICAgICAgICBjb250YWluZXI6Y29udGFpbmVyLFxuICAgICAgICBwYW5lbDpwYW5lbCxcbiAgICAgICAgdGV4dDp0ZXh0LFxuICAgICAgICBiYXNlWU9mZnNldDogYmFzZVlPZmZzZXQsXG4gICAgICAgIGlzQnViYmxlT3BlbjpmYWxzZSxcbiAgICAgICAgdHlwaW5nOmZhbHNlLFxuICAgICAgICB2aXNpYmxlVGV4dDpcIlwiLFxuICAgICAgICB2aXNpYmxlQ2hhcnM6MCxcbiAgICAgICAgZnVsbFRleHQ6XCJcIixcbiAgICAgICAgdGltZXI6MCxcbiAgICAgICAgc3BlZWQ6MzAsXG4gICAgICAgIHNjcmlwdDpbXSxcbiAgICAgICAgaW5kZXg6MCxcbiAgICAgICAgc291bmQ6IHNvdW5kID8gc291bmQgOiB1bmRlZmluZWQsXG4gICAgICAgIHNvdW5kUGxheWVyOiBzb3VuZCA/IGVuZ2luZS5hZGRFbnRpdHkoKSA6IHVuZGVmaW5lZCxcbiAgICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gb3BlbkJ1YmJsZShucGM6RW50aXR5LCBkaWFsb2c6RGlhbG9nW10sIHN0YXJ0SW5kZXg/Om51bWJlciB8IHN0cmluZyl7XG4gICAgbGV0IGJ1YmJsZSA9IGJ1YmJsZXMuZ2V0KG5wYylcblxuICAgIGJ1YmJsZS5zY3JpcHQgPSBkaWFsb2cuc2xpY2UoKVxuICAgIGxldCBpbmRleDphbnlcbiAgICBpZiAoIXN0YXJ0SW5kZXgpIHtcbiAgICAgIGluZGV4ID0gMFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0YXJ0SW5kZXggPT09ICdudW1iZXInKSB7XG4gICAgICBpbmRleCA9IHN0YXJ0SW5kZXhcbiAgICB9IGVsc2Uge1xuICAgICAgaW5kZXggPSBmaW5kRGlhbG9nQnlOYW1lKGRpYWxvZywgc3RhcnRJbmRleClcbiAgICB9XG5cbiAgICBidWJibGUuaW5kZXggPSBpbmRleFxuICAgIFxuICAgIGxldCBjdXJyZW50VGV4dDogRGlhbG9nID0gZGlhbG9nW2J1YmJsZS5pbmRleF0gPyBkaWFsb2dbYnViYmxlLmluZGV4XSA6IHsgdGV4dDogJycgfVxuICAgIGJ1YmJsZS5jdXJyZW50VGV4dCA9IGN1cnJlbnRUZXh0XG5cbiAgICBpZiAoY3VycmVudFRleHQuYXVkaW8pIHtcbiAgICAgICAgQXVkaW9Tb3VyY2UuY3JlYXRlT3JSZXBsYWNlKGJ1YmJsZS5zb3VuZFBsYXllciwge1xuICAgICAgICAgICAgYXVkaW9DbGlwVXJsOiBjdXJyZW50VGV4dC5hdWRpbyxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgcGxheWluZzogZmFsc2VcbiAgICAgICAgfSlcbiAgICAgICAgbGV0IGF1ZGlvID0gQXVkaW9Tb3VyY2UuZ2V0TXV0YWJsZShidWJibGUuc291bmRQbGF5ZXIpXG4gICAgICAgIGF1ZGlvLnZvbHVtZSA9IDAuNVxuICAgICAgICBhdWRpby5wbGF5aW5nID0gdHJ1ZVxuICAgIH0gZWxzZSBpZiAoYnViYmxlLnNvdW5kKSB7XG4gICAgICAgIEF1ZGlvU291cmNlLmNyZWF0ZU9yUmVwbGFjZShidWJibGUuc291bmRQbGF5ZXIsIHtcbiAgICAgICAgICAgIGF1ZGlvQ2xpcFVybDogYnViYmxlLnNvdW5kLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBwbGF5aW5nOiBmYWxzZVxuICAgICAgICB9KVxuICAgICAgICBsZXQgYXVkaW8gPSBBdWRpb1NvdXJjZS5nZXRNdXRhYmxlKGJ1YmJsZS5zb3VuZFBsYXllcilcbiAgICAgICAgYXVkaW8udm9sdW1lID0gMC41XG4gICAgICAgIGF1ZGlvLnBsYXlpbmcgPSB0cnVlXG4gICAgfVxuXG4gICAgbGV0IHRleHQgPSBidWJibGUudGV4dFxuICAgIFRleHRTaGFwZS5nZXRNdXRhYmxlKHRleHQpLmZvbnRTaXplID0gY3VycmVudFRleHQuZm9udFNpemUgPyBjdXJyZW50VGV4dC5mb250U2l6ZSA6IHRleHRTaXplXG4gICAgVHJhbnNmb3JtLmdldE11dGFibGUodGV4dCkucG9zaXRpb24ueSA9IGN1cnJlbnRUZXh0Lm9mZnNldFkgPyBjdXJyZW50VGV4dC5vZmZzZXRZICsgdGV4dFlQb3MgOiB0ZXh0WVBvc1xuICAgIFRyYW5zZm9ybS5nZXRNdXRhYmxlKHRleHQpLnBvc2l0aW9uLnggPSBjdXJyZW50VGV4dC5vZmZzZXRYID8gY3VycmVudFRleHQub2Zmc2V0WCA6IDBcblxuICAgIFZpc2liaWxpdHlDb21wb25lbnQuZ2V0TXV0YWJsZShidWJibGUucGFuZWwpLnZpc2libGUgPSB0cnVlXG5cbiAgICBpZiAoY3VycmVudFRleHQudGV4dC5sZW5ndGggPCBtYXhMZW5ndGhIdWdlQnViYmxlKSB7XG4gICAgICAgIGN1cnJlbnRUZXh0LnRleHQuc2xpY2UoMCwgbWF4TGVuZ3RoSHVnZUJ1YmJsZSlcbiAgICAgIH1cblxuICAgIGJlZ2luVHlwaW5nKFxuICAgICAgICBucGMsXG4gICAgICAgIGN1cnJlbnRUZXh0LnRleHQsXG4gICAgICAgIGJ1YmJsZS5pbmRleCxcbiAgICAgICAgY3VycmVudFRleHQudGltZU9uID8gY3VycmVudFRleHQudGltZU9uIDogdW5kZWZpbmVkLFxuICAgICAgICBjdXJyZW50VGV4dC50eXBlU3BlZWQgPyBjdXJyZW50VGV4dC50eXBlU3BlZWQgOiB1bmRlZmluZWQgXG4gICAgKVxuXG4gICAgYWRqdXN0QnViYmxlKG5wYywgY3VycmVudFRleHQudGV4dC5sZW5ndGgpXG4gICAgbGF5b3V0RGlhbG9nV2luZG93KG5wYywgYnViYmxlLmluZGV4KVxuICAgIGJ1YmJsZS5pc0J1YmJsZU9wZW4gPSB0cnVlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZUJ1YmJsZShucGM6RW50aXR5KXtcbiAgICBsZXQgYnViYmxlID0gYnViYmxlcy5nZXQobnBjKVxuICAgICAgICBidWJibGUuaXNCdWJibGVPcGVuID0gZmFsc2VcbiAgICAgICAgYnViYmxlLnR5cGluZyA9IGZhbHNlXG4gICAgICAgIGJ1YmJsZS52aXNpYmxlVGV4dCA9IFwiXCJcbiAgICAgICAgYnViYmxlLnZpc2libGVDaGFycyA9IDBcbiAgICAgICAgYnViYmxlLmZ1bGxUZXh0ID0gXCJcIlxuICAgICAgICBidWJibGUudGltZXIgPSAwXG4gICAgICAgIGJ1YmJsZS5pbmRleCA9IDBcbiAgICAgICAgYnViYmxlLnNjcmlwdCA9IFtdXG4gICAgICAgIGJ1YmJsZS5idXR0b25zID0gMFxuICAgICAgICBidWJibGUubWFyZ2luID0gMFxuICAgICAgICBidWJibGUuY3VycmVudFRleHQgPSBudWxsXG4gICAgICAgIFRleHRTaGFwZS5nZXRNdXRhYmxlKGJ1YmJsZS50ZXh0KS50ZXh0ID0gXCJcIlxuICAgICAgICBWaXNpYmlsaXR5Q29tcG9uZW50LmdldE11dGFibGUoYnViYmxlLnRleHQpLnZpc2libGUgPSBmYWxzZVxuICAgICAgICBWaXNpYmlsaXR5Q29tcG9uZW50LmdldE11dGFibGUoYnViYmxlLnBhbmVsKS52aXNpYmxlID0gZmFsc2Vcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb3NlQnViYmxlRW5kQWxsKG5wYzpFbnRpdHkpOiB2b2lkIHtcbiAgICBsZXQgYnViYmxlID0gYnViYmxlcy5nZXQobnBjKVxuICAgIGlmIChidWJibGUuaXNCdWJibGVPcGVuKSB7XG4gICAgICAgIGJ1YmJsZS5kb25lID0gdHJ1ZVxuICAgICAgICBjbG9zZUJ1YmJsZShucGMpXG4gICAgfVxuICB9XG5cbmNvbnN0IERFRkFVTFRfU1BFRUQgPSA0NVxuXG5jb25zdCBERUZBVUxUX1RJTUVfT04gPSAzXG5cbmZ1bmN0aW9uIGJlZ2luVHlwaW5nKG5wYzpFbnRpdHksIHRleHQ6c3RyaW5nLCB0ZXh0SWQ6bnVtYmVyLCB0aW1lT24/Om51bWJlciwgc3BlZWQ/Om51bWJlcil7XG4gICAgbGV0IGRpYWxvZ0RhdGEgPSBidWJibGVzLmdldChucGMpXG4gICAgZGlhbG9nRGF0YS5mdWxsVGV4dCA9IGFkZExpbmVCcmVhayhkaWFsb2dEYXRhLnNjcmlwdFtkaWFsb2dEYXRhLmluZGV4XS50ZXh0LCB0cnVlKVxuICAgIGRpYWxvZ0RhdGEudHlwaW5nID0gdHJ1ZVxuICAgIGRpYWxvZ0RhdGEuZG9uZSA9IGZhbHNlXG4gICAgZGlhbG9nRGF0YS52aXNpYmxlVGV4dCA9IFwiXCJcbiAgICBkaWFsb2dEYXRhLnZpc2libGVDaGFycyA9IDBcbiAgICBkaWFsb2dEYXRhLnRpbWVyID0gMFxuICAgIGRpYWxvZ0RhdGEuYnV0dG9ucyA9IDBcbiAgICBkaWFsb2dEYXRhLnRpbWVPbiA9IHRpbWVPbiA/IHRpbWVPbiA6IERFRkFVTFRfVElNRV9PTlxuICAgIGRpYWxvZ0RhdGEuc3BlZWQgPSBzcGVlZCA/IHNwZWVkIDogREVGQVVMVF9TUEVFRFxuXG4gICAgZGlhbG9nRGF0YS5vcGVuVGltZSA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSlcblxuICAgIGlmKGRpYWxvZ0RhdGEuc3BlZWQgPD0gMCl7XG4gICAgICAgIHJ1c2hUZXh0KG5wYylcbiAgICB9XG4gICAgZWxzZXtcbiAgICAgICAgaWYoIUlzVHlwaW5nQnViYmxlLmhhcyhucGMpKXtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjcmVhdGluZyB0eXB1aW5nIGJ1YmJsZScpXG4gICAgICAgICAgICBJc1R5cGluZ0J1YmJsZS5jcmVhdGUobnBjKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBydXNoVGV4dChucGM6RW50aXR5KXtcbiAgICBsZXQgZGlhbG9nRGF0YSA9IGJ1YmJsZXMuZ2V0KG5wYylcbiAgICBkaWFsb2dEYXRhLnR5cGluZyA9IGZhbHNlXG4gICAgZGlhbG9nRGF0YS50aW1lciA9IDBcbiAgICBkaWFsb2dEYXRhLnZpc2libGVDaGFycyA9IGRpYWxvZ0RhdGEuZnVsbFRleHQubGVuZ3RoXG4gICAgZGlhbG9nRGF0YS52aXNpYmxlVGV4dCA9IGRpYWxvZ0RhdGEuZnVsbFRleHRcbn1cblxuZnVuY3Rpb24gYWRqdXN0QnViYmxlKG5wYzpFbnRpdHksIHRleHRMZW5ndGg6bnVtYmVyKXtcbiAgICBsZXQgYnViYmxlID0gYnViYmxlcy5nZXQobnBjKVxuICAgIGxldCBucGNEYXRhID0gbnBjRGF0YUNvbXBvbmVudC5nZXQobnBjKVxuXG4gICAgaWYgKHRleHRMZW5ndGggPCBtYXhMZW5ndGhTaG9ydEJ1YmJsZSkge1xuICAgICAgICBNZXNoUmVuZGVyZXIuc2V0UGxhbmUoYnViYmxlLnBhbmVsLFxuICAgICAgICAgICAgc2V0VVZTZWN0aW9uKFxuICAgICAgICAgICAgYnViYmxlT3B0aW9ucy5zaG9ydCxcbiAgICAgICAgICAgIDEwMjQsXG4gICAgICAgICAgICAxMDI0XG4gICAgICAgICAgKSlcblxuICAgICAgICBUcmFuc2Zvcm0uZ2V0TXV0YWJsZShidWJibGUucGFuZWwpLnNjYWxlLnggPSBzaG9ydEJ1YmJsZVhcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLnBhbmVsKS5zY2FsZS55ID0gc2hvcnRCdWJibGVZXG4gICAgICAgIFRyYW5zZm9ybS5nZXRNdXRhYmxlKGJ1YmJsZS5jb250YWluZXIpLnBvc2l0aW9uLnggPSBzaG9ydEJ1YmJsZVhPZmZzZXQgKyBucGNEYXRhLmJ1YmJsZVhPZmZzZXRcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLmNvbnRhaW5lcikucG9zaXRpb24ueSA9IGJ1YmJsZS5iYXNlWU9mZnNldCArIHNob3J0QnViYmxlWU9mZnNldCArIG5wY0RhdGEuYnViYmxlWU9mZnNldFxuICAgICAgICBUZXh0U2hhcGUuZ2V0TXV0YWJsZShidWJibGUudGV4dCkud2lkdGggPSBzaG9ydEJ1YmJsZVRleHRXaWR0aFxuICAgICAgfSBlbHNlIGlmICh0ZXh0TGVuZ3RoIDwgbWF4TGVuZ3RoTm9ybWFsQnViYmxlKSB7XG4gICAgICAgIE1lc2hSZW5kZXJlci5zZXRQbGFuZShidWJibGUucGFuZWwsXG4gICAgICAgICAgICBzZXRVVlNlY3Rpb24oXG4gICAgICAgICAgICBidWJibGVPcHRpb25zLm5vcm1hbCxcbiAgICAgICAgICAgIDEwMjQsXG4gICAgICAgICAgICAxMDI0XG4gICAgICAgICAgKSlcblxuICAgICAgICBUcmFuc2Zvcm0uZ2V0TXV0YWJsZShidWJibGUucGFuZWwpLnNjYWxlLnggPSBub3JtYWxCdWJibGVYXG4gICAgICAgIFRyYW5zZm9ybS5nZXRNdXRhYmxlKGJ1YmJsZS5wYW5lbCkuc2NhbGUueSA9IG5vcm1hbEJ1YmJsZVlcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLmNvbnRhaW5lcikucG9zaXRpb24ueCA9IG5vcm1hbEJ1YmJsZVhPZmZzZXQgKyBucGNEYXRhLmJ1YmJsZVhPZmZzZXRcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLmNvbnRhaW5lcikucG9zaXRpb24ueSA9IGJ1YmJsZS5iYXNlWU9mZnNldCArIG5vcm1hbEJ1YmJsZVlPZmZzZXQgKyBucGNEYXRhLmJ1YmJsZVlPZmZzZXRcbiAgICAgICAgVGV4dFNoYXBlLmdldE11dGFibGUoYnViYmxlLnRleHQpLndpZHRoID0gbm9ybWFsQnViYmxlVGV4dFdpZHRoXG4gICAgICB9IGVsc2UgaWYgKHRleHRMZW5ndGggPCBtYXhMZW5ndGhMb25nQnViYmxlKSB7XG4gICAgICAgIE1lc2hSZW5kZXJlci5zZXRQbGFuZShidWJibGUucGFuZWwsXG4gICAgICAgICAgICBzZXRVVlNlY3Rpb24oXG4gICAgICAgICAgICBidWJibGVPcHRpb25zLmxvbmcsXG4gICAgICAgICAgICAxMDI0LFxuICAgICAgICAgICAgMTAyNFxuICAgICAgICAgICkpXG5cbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLnBhbmVsKS5zY2FsZS54ID0gbG9uZ0J1YmJsZVhcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLnBhbmVsKS5zY2FsZS55ID0gbG9uZ0J1YmJsZVlcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLmNvbnRhaW5lcikucG9zaXRpb24ueCA9IGxvbmdCdWJibGVYT2Zmc2V0ICsgbnBjRGF0YS5idWJibGVYT2Zmc2V0XG4gICAgICAgIFRyYW5zZm9ybS5nZXRNdXRhYmxlKGJ1YmJsZS5jb250YWluZXIpLnBvc2l0aW9uLnkgPSBidWJibGUuYmFzZVlPZmZzZXQgKyBsb25nQnViYmxlWU9mZnNldCArIG5wY0RhdGEuYnViYmxlWU9mZnNldFxuICAgICAgICBUZXh0U2hhcGUuZ2V0TXV0YWJsZShidWJibGUudGV4dCkud2lkdGggPSBsb25nQnViYmxlVGV4dFdpZHRoXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBNZXNoUmVuZGVyZXIuc2V0UGxhbmUoYnViYmxlLnBhbmVsLFxuICAgICAgICAgICAgc2V0VVZTZWN0aW9uKFxuICAgICAgICAgICAgYnViYmxlT3B0aW9ucy5odWdlLFxuICAgICAgICAgICAgMTAyNCxcbiAgICAgICAgICAgIDEwMjRcbiAgICAgICAgICApKVxuICAgICAgICBUcmFuc2Zvcm0uZ2V0TXV0YWJsZShidWJibGUucGFuZWwpLnNjYWxlLnggPSBodWdlQnViYmxlWFxuICAgICAgICBUcmFuc2Zvcm0uZ2V0TXV0YWJsZShidWJibGUucGFuZWwpLnNjYWxlLnkgPSBodWdlQnViYmxlWVxuICAgICAgICBUcmFuc2Zvcm0uZ2V0TXV0YWJsZShidWJibGUuY29udGFpbmVyKS5wb3NpdGlvbi54ID0gaHVnZUJ1YmJsZVhPZmZzZXQgKyBucGNEYXRhLmJ1YmJsZVhPZmZzZXRcbiAgICAgICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLmNvbnRhaW5lcikucG9zaXRpb24ueSA9IGJ1YmJsZS5iYXNlWU9mZnNldCArIGh1Z2VCdWJibGVZT2Zmc2V0ICsgbnBjRGF0YS5idWJibGVZT2Zmc2V0XG4gICAgICAgIFRleHRTaGFwZS5nZXRNdXRhYmxlKGJ1YmJsZS50ZXh0KS53aWR0aCA9IGh1Z2VCdWJibGVUZXh0V2lkdGhcbiAgICAgIH1cbn1cblxuLy8gQWRkcyB0aGUgYnV0dG9ucyBvciBtb3VzZSBpY29uIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiB3aW5kb3dcbmZ1bmN0aW9uIGxheW91dERpYWxvZ1dpbmRvdyhucGM6RW50aXR5LCB0ZXh0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGxldCBidWJibGUgPSBidWJibGVzLmdldChucGMpXG4gICAgbGV0IGN1cnJlbnRUZXh0OiBEaWFsb2cgPSBidWJibGUuc2NyaXB0W3RleHRJZF1cbiAgICAgID8gYnViYmxlLnNjcmlwdFt0ZXh0SWRdXG4gICAgICA6IHsgdGV4dDogJycgfVxuXG4gICAgLy8gVXBkYXRlIHRleHRcbiAgICBsZXQgdGV4dFkgPSBjdXJyZW50VGV4dC5vZmZzZXRZID8gY3VycmVudFRleHQub2Zmc2V0WSArIHRleHRZUG9zIDogdGV4dFlQb3NcblxuICAgIGlmIChjdXJyZW50VGV4dC5idXR0b25zICYmIGN1cnJlbnRUZXh0LmJ1dHRvbnMubGVuZ3RoID49IDMpIHtcbiAgICAgIHRleHRZICs9IDUwXG4gICAgfSBlbHNlIGlmIChjdXJyZW50VGV4dC5idXR0b25zICYmIGN1cnJlbnRUZXh0LmJ1dHRvbnMubGVuZ3RoID49IDEpIHtcbiAgICAgIHRleHRZICs9IDI0XG4gICAgfVxuICAgIFRleHRTaGFwZS5nZXRNdXRhYmxlKGJ1YmJsZS50ZXh0KS5mb250U2l6ZSA9IGN1cnJlbnRUZXh0LmZvbnRTaXplXG4gICAgPyBjdXJyZW50VGV4dC5mb250U2l6ZVxuICAgIDogdGV4dFNpemVcbiAgICBcbiAgICBWaXNpYmlsaXR5Q29tcG9uZW50LmdldE11dGFibGUoYnViYmxlLnRleHQpLnZpc2libGUgPSB0cnVlXG4gICAgVHJhbnNmb3JtLmdldE11dGFibGUoYnViYmxlLnRleHQpLnBvc2l0aW9uLnkgPSB0ZXh0WVxuXG4gICAgaWYgKGN1cnJlbnRUZXh0LmF1ZGlvKSB7XG4gICAgICAgIEF1ZGlvU291cmNlLmNyZWF0ZU9yUmVwbGFjZShidWJibGUuc291bmRQbGF5ZXIsIHtcbiAgICAgICAgICAgIGF1ZGlvQ2xpcFVybDogY3VycmVudFRleHQuYXVkaW8sXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIHBsYXlpbmc6IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICAgIGxldCBhdWRpbyA9IEF1ZGlvU291cmNlLmdldE11dGFibGUoYnViYmxlLnNvdW5kUGxheWVyKVxuICAgICAgICBhdWRpby52b2x1bWUgPSAwLjVcbiAgICAgICAgYXVkaW8ucGxheWluZyA9IHRydWVcbiAgICB9IGVsc2UgaWYgKGJ1YmJsZS5zb3VuZCkge1xuICAgICAgICBBdWRpb1NvdXJjZS5jcmVhdGVPclJlcGxhY2UoYnViYmxlLnNvdW5kUGxheWVyLCB7XG4gICAgICAgICAgICBhdWRpb0NsaXBVcmw6IGJ1YmJsZS5zb3VuZCxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgcGxheWluZzogZmFsc2VcbiAgICAgICAgfSlcbiAgICAgICAgbGV0IGF1ZGlvID0gQXVkaW9Tb3VyY2UuZ2V0TXV0YWJsZShidWJibGUuc291bmRQbGF5ZXIpXG4gICAgICAgIGF1ZGlvLnZvbHVtZSA9IDAuNVxuICAgICAgICBhdWRpby5wbGF5aW5nID0gdHJ1ZVxuICAgIH1cblxuICB9XG5cbi8vIFByb2dyZXNzZXMgdGV4dFxuZXhwb3J0IGZ1bmN0aW9uIG5leHQobnBjOkVudGl0eSk6IHZvaWQge1xuICAgIGxldCBidWJibGUgPSBidWJibGVzLmdldChucGMpXG5cbiAgICBpZihidWJibGUuaXNCdWJibGVPcGVuKXtcbiAgICAgIGxldCBjdXJyZW50VGV4dCA9IGJ1YmJsZS5zY3JpcHRbYnViYmxlLmluZGV4XVxuXG4gICAgICBpZighY3VycmVudFRleHQpe1xuICAgICAgICBjdXJyZW50VGV4dCA9IGJ1YmJsZS5zY3JpcHRbYnViYmxlLmluZGV4LTFdXG4gICAgICB9XG4gICAgXG4gICAgICAgIGlmIChjdXJyZW50VGV4dC50cmlnZ2VyZWRCeU5leHQpIHtcbiAgICAgICAgICBjdXJyZW50VGV4dC50cmlnZ2VyZWRCeU5leHQoKVxuICAgICAgICB9XG4gICAgXG4gICAgICAgIGlmIChjdXJyZW50VGV4dC5pc0VuZE9mRGlhbG9nKSB7XG4gICAgICAgICAgY2xvc2VCdWJibGUobnBjKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgXG4gICAgICAgLy8gVXBkYXRlIGFjdGl2ZSB0ZXh0XG4gICAgICAgICBidWJibGUuaW5kZXgrK1xuICAgIFxuICAgICAgICAvLyBVcGRhdGUgYWN0aXZlIHRleHQgd2l0aCBuZXcgYWN0aXZlIHRleHRcbiAgICAgICAgY3VycmVudFRleHQgPSBidWJibGUuc2NyaXB0W2J1YmJsZS5pbmRleF1cbiAgICBcbiAgICAgICAgaWYgKGN1cnJlbnRUZXh0LnRleHQubGVuZ3RoIDwgbWF4TGVuZ3RoSHVnZUJ1YmJsZSkge1xuICAgICAgICAgIGN1cnJlbnRUZXh0LnRleHQuc2xpY2UoMCwgbWF4TGVuZ3RoSHVnZUJ1YmJsZSlcbiAgICAgICAgfVxuICAgIFxuICAgICAgICBUZXh0U2hhcGUuZ2V0TXV0YWJsZShidWJibGUudGV4dCkudGV4dCA9IFwiXCJcbiAgICBcbiAgICAgICAgYWRqdXN0QnViYmxlKG5wYywgY3VycmVudFRleHQudGV4dC5sZW5ndGgpXG4gICAgXG4gICAgICAgIGJlZ2luVHlwaW5nKFxuICAgICAgICAgICAgbnBjLFxuICAgICAgICAgICAgY3VycmVudFRleHQudGV4dCxcbiAgICAgICAgICAgIGJ1YmJsZS5pbmRleCxcbiAgICAgICAgICAgIGN1cnJlbnRUZXh0LnRpbWVPbiA/IGN1cnJlbnRUZXh0LnRpbWVPbiA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGN1cnJlbnRUZXh0LnR5cGVTcGVlZCA/IGN1cnJlbnRUZXh0LnR5cGVTcGVlZCA6IHVuZGVmaW5lZCBcbiAgICAgICAgKVxuICAgICAgbGF5b3V0RGlhbG9nV2luZG93KG5wYywgYnViYmxlLmluZGV4KVxuICAgIH1cblxuICAgIFxuICB9XG5cbmZ1bmN0aW9uIHNldFVWU2VjdGlvbihcblx0c2VjdGlvbjogSW1hZ2VTZWN0aW9uLFxuXHRzaXplWDogbnVtYmVyLFxuXHRzaXplWTogbnVtYmVyXG4gICkge1xuXHRyZXR1cm4gc2V0VVZzKFxuICAgICAgICB7eDogIHNlY3Rpb24uc291cmNlTGVmdCEgLyBzaXplWCwgeTogKHNpemVZIC0gc2VjdGlvbi5zb3VyY2VUb3AhIC0gc2VjdGlvbi5zb3VyY2VIZWlnaHQpIC8gc2l6ZVl9LFxuICAgICAgICB7eDogIChzZWN0aW9uLnNvdXJjZUxlZnQhICsgc2VjdGlvbi5zb3VyY2VXaWR0aCkgLyBzaXplWCwgeTogKHNpemVZIC0gc2VjdGlvbi5zb3VyY2VUb3AhIC0gc2VjdGlvbi5zb3VyY2VIZWlnaHQpIC8gc2l6ZVl9LFxuICAgICAgICB7eDogIChzZWN0aW9uLnNvdXJjZUxlZnQhICsgc2VjdGlvbi5zb3VyY2VXaWR0aCkgLyBzaXplWCwgeTogIChzaXplWSAtIHNlY3Rpb24uc291cmNlVG9wISkgLyBzaXplWX0sXG4gICAgICAgIHt4OiAgc2VjdGlvbi5zb3VyY2VMZWZ0ISAvIHNpemVYLCB5OiAoc2l6ZVkgLSBzZWN0aW9uLnNvdXJjZVRvcCEpIC8gc2l6ZVl9LFxuXHQpXG4gIH1cblxuZnVuY3Rpb24gc2V0VVZzKFxuXHRfdXYwMDogYW55LFxuXHRfdXYxMDogYW55LFxuXHRfdXYxMTogYW55LFxuXHRfdXYwMTogYW55XG4gICkge1xuXG5cdHJldHVybiBbXG5cdCAgX3V2MDAueCxcblx0ICBfdXYwMC55LFxuICBcblx0ICBfdXYxMC54LFxuXHQgIF91djEwLnksXG4gIFxuXHQgIF91djExLngsXG5cdCAgX3V2MTEueSxcbiAgXG5cdCAgX3V2MDEueCxcblx0ICBfdXYwMS55LFxuXHQgIC8vLS0tLVxuXHQgIF91djAwLngsXG5cdCAgX3V2MDAueSxcbiAgXG5cdCAgX3V2MTAueCxcblx0ICBfdXYxMC55LFxuICBcblx0ICBfdXYxMS54LFxuXHQgIF91djExLnksXG4gIFxuXHQgIF91djAxLngsXG5cdCAgX3V2MDEueSxcblx0XVxuICB9XG5cbiAgbGV0IGJ1YmJsZU9wdGlvbnM6YW55ID0ge1xuICAgIHNob3J0OiB7XG4gICAgICBzb3VyY2VXaWR0aDogMTE2ICogMixcbiAgICAgIHNvdXJjZUhlaWdodDogODQgKiAyLFxuICAgICAgc291cmNlTGVmdDogMzA1ICogMixcbiAgICAgIHNvdXJjZVRvcDogNDE3ICogMixcbiAgICB9LFxuICAgIG5vcm1hbDoge1xuICAgICAgc291cmNlV2lkdGg6IDI4NiAqIDIsXG4gICAgICBzb3VyY2VIZWlnaHQ6IDg0ICogMixcbiAgICAgIHNvdXJjZUxlZnQ6IDggKiAyLFxuICAgICAgc291cmNlVG9wOiA0MTcgKiAyLFxuICAgIH0sXG4gICAgbG9uZzoge1xuICAgICAgc291cmNlV2lkdGg6IDQ5NyAqIDIsXG4gICAgICBzb3VyY2VIZWlnaHQ6IDE1MyAqIDIsXG4gICAgICBzb3VyY2VMZWZ0OiA2ICogMixcbiAgICAgIHNvdXJjZVRvcDogMjU0ICogMixcbiAgICB9LFxuICAgIGh1Z2U6IHtcbiAgICAgIHNvdXJjZVdpZHRoOiA0OTcgKiAyLFxuICAgICAgc291cmNlSGVpZ2h0OiAyMzkgKiAyLFxuICAgICAgc291cmNlTGVmdDogNiAqIDIsXG4gICAgICBzb3VyY2VUb3A6IDcgKiAyLFxuICAgIH0sXG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJ1YmJsZVRleHRMZW5ndGgodGV4dDpzdHJpbmcpe1xuICAgIGlmKHRleHQubGVuZ3RoID49IG1heExlbmd0aEh1Z2VCdWJibGUpe1xuICAgICAgICByZXR1cm4gNDBcbiAgICB9XG4gICAgZWxzZSBpZih0ZXh0Lmxlbmd0aCA+PSBtYXhMZW5ndGhMb25nQnViYmxlKXtcbiAgICAgICAgcmV0dXJuIDQwXG4gICAgfVxuICAgIGVsc2UgaWYodGV4dC5sZW5ndGggPj0gbWF4TGVuZ3RoTm9ybWFsQnViYmxlKXtcbiAgICAgICAgcmV0dXJuIDQwXG4gICAgfVxuICAgIGVsc2UgaWYodGV4dC5sZW5ndGggPj0gbWF4TGVuZ3RoU2hvcnRCdWJibGUpe1xuICAgICAgICByZXR1cm4gNDBcbiAgICB9XG4gIH0iXX0=