4329 lines
1.3 MiB
4329 lines
1.3 MiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Session Export</title>
|
|
<style>
|
|
:root {
|
|
--accent: #5a8080;
|
|
--border: #547da7;
|
|
--borderAccent: #5a8080;
|
|
--borderMuted: #b0b0b0;
|
|
--success: #588458;
|
|
--error: #aa5555;
|
|
--warning: #9a7326;
|
|
--muted: #6c6c6c;
|
|
--dim: #767676;
|
|
--text: #1f2328;
|
|
--thinkingText: #6c6c6c;
|
|
--selectedBg: #d0d0e0;
|
|
--userMessageBg: #e8e8e8;
|
|
--userMessageText: #1f2328;
|
|
--customMessageBg: #ede7f6;
|
|
--customMessageText: #1f2328;
|
|
--customMessageLabel: #7e57c2;
|
|
--toolPendingBg: #e8e8f0;
|
|
--toolSuccessBg: #e8f0e8;
|
|
--toolErrorBg: #f0e8e8;
|
|
--toolTitle: #1f2328;
|
|
--toolOutput: #6c6c6c;
|
|
--mdHeading: #9a7326;
|
|
--mdLink: #547da7;
|
|
--mdLinkUrl: #767676;
|
|
--mdCode: #5a8080;
|
|
--mdCodeBlock: #588458;
|
|
--mdCodeBlockBorder: #6c6c6c;
|
|
--mdQuote: #6c6c6c;
|
|
--mdQuoteBorder: #6c6c6c;
|
|
--mdHr: #6c6c6c;
|
|
--mdListBullet: #588458;
|
|
--toolDiffAdded: #588458;
|
|
--toolDiffRemoved: #aa5555;
|
|
--toolDiffContext: #6c6c6c;
|
|
--syntaxComment: #008000;
|
|
--syntaxKeyword: #0000FF;
|
|
--syntaxFunction: #795E26;
|
|
--syntaxVariable: #001080;
|
|
--syntaxString: #A31515;
|
|
--syntaxNumber: #098658;
|
|
--syntaxType: #267F99;
|
|
--syntaxOperator: #000000;
|
|
--syntaxPunctuation: #000000;
|
|
--thinkingOff: #b0b0b0;
|
|
--thinkingMinimal: #767676;
|
|
--thinkingLow: #547da7;
|
|
--thinkingMedium: #5a8080;
|
|
--thinkingHigh: #875f87;
|
|
--thinkingXhigh: #8b008b;
|
|
--bashMode: #588458;
|
|
--exportPageBg: #f8f8f8;
|
|
--exportCardBg: #ffffff;
|
|
--exportInfoBg: #fffae6;
|
|
--body-bg: #f8f8f8;
|
|
--container-bg: #ffffff;
|
|
--info-bg: #fffae6;
|
|
}
|
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
|
|
:root {
|
|
--line-height: 18px; /* 12px font * 1.5 */
|
|
--sidebar-width: 400px;
|
|
--sidebar-min-width: 240px;
|
|
--sidebar-max-width: 840px;
|
|
--sidebar-resizer-width: 6px;
|
|
}
|
|
|
|
body {
|
|
font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
|
|
font-size: 12px;
|
|
line-height: var(--line-height);
|
|
color: var(--text);
|
|
background: var(--body-bg);
|
|
}
|
|
|
|
body.sidebar-resizing {
|
|
cursor: col-resize;
|
|
user-select: none;
|
|
}
|
|
|
|
#app {
|
|
display: flex;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Sidebar */
|
|
#sidebar {
|
|
width: var(--sidebar-width);
|
|
min-width: var(--sidebar-width);
|
|
max-width: var(--sidebar-width);
|
|
background: var(--container-bg);
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: sticky;
|
|
top: 0;
|
|
height: 100vh;
|
|
border-right: 1px solid var(--dim);
|
|
}
|
|
|
|
#sidebar-resizer {
|
|
width: var(--sidebar-resizer-width);
|
|
flex-shrink: 0;
|
|
position: sticky;
|
|
top: 0;
|
|
height: 100vh;
|
|
cursor: col-resize;
|
|
touch-action: none;
|
|
background: transparent;
|
|
border-right: 1px solid transparent;
|
|
}
|
|
|
|
#sidebar-resizer:hover,
|
|
body.sidebar-resizing #sidebar-resizer {
|
|
background: var(--selectedBg);
|
|
border-right-color: var(--dim);
|
|
}
|
|
|
|
.sidebar-header {
|
|
padding: 8px 12px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.sidebar-controls {
|
|
padding: 8px 8px 4px 8px;
|
|
}
|
|
|
|
.sidebar-search {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
padding: 4px 8px;
|
|
font-size: 11px;
|
|
font-family: inherit;
|
|
background: var(--body-bg);
|
|
color: var(--text);
|
|
border: 1px solid var(--dim);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.sidebar-filters {
|
|
display: flex;
|
|
padding: 4px 8px 8px 8px;
|
|
gap: 4px;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.sidebar-search:focus {
|
|
outline: none;
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.sidebar-search::placeholder {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.filter-btn {
|
|
padding: 3px 8px;
|
|
font-size: 10px;
|
|
font-family: inherit;
|
|
background: transparent;
|
|
color: var(--muted);
|
|
border: 1px solid var(--dim);
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.filter-btn:hover {
|
|
color: var(--text);
|
|
border-color: var(--text);
|
|
}
|
|
|
|
.filter-btn.active {
|
|
background: var(--accent);
|
|
color: var(--body-bg);
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.sidebar-close {
|
|
display: none;
|
|
padding: 3px 8px;
|
|
font-size: 12px;
|
|
font-family: inherit;
|
|
background: transparent;
|
|
color: var(--muted);
|
|
border: 1px solid var(--dim);
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
margin-left: auto;
|
|
}
|
|
|
|
.sidebar-close:hover {
|
|
color: var(--text);
|
|
border-color: var(--text);
|
|
}
|
|
|
|
.tree-container {
|
|
flex: 1;
|
|
overflow: auto;
|
|
padding: 4px 0;
|
|
}
|
|
|
|
.tree-node {
|
|
padding: 0 8px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: baseline;
|
|
font-size: 11px;
|
|
line-height: 13px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.tree-node:hover {
|
|
background: var(--selectedBg);
|
|
}
|
|
|
|
.tree-node.active {
|
|
background: var(--selectedBg);
|
|
}
|
|
|
|
.tree-node.active .tree-content {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.tree-node.in-path {
|
|
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
}
|
|
|
|
.tree-node:not(.in-path) {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.tree-node:not(.in-path):hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
.tree-prefix {
|
|
color: var(--muted);
|
|
flex-shrink: 0;
|
|
font-family: monospace;
|
|
white-space: pre;
|
|
}
|
|
|
|
.tree-marker {
|
|
color: var(--accent);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.tree-content {
|
|
color: var(--text);
|
|
}
|
|
|
|
.tree-role-user {
|
|
color: var(--accent);
|
|
}
|
|
|
|
.tree-role-skill {
|
|
color: var(--customMessageLabel);
|
|
}
|
|
|
|
.tree-role-assistant {
|
|
color: var(--success);
|
|
}
|
|
|
|
.tree-role-tool {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.tree-muted {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.tree-error {
|
|
color: var(--error);
|
|
}
|
|
|
|
.tree-compaction {
|
|
color: var(--borderAccent);
|
|
}
|
|
|
|
.tree-branch-summary {
|
|
color: var(--warning);
|
|
}
|
|
|
|
.tree-custom-message {
|
|
color: var(--customMessageLabel);
|
|
}
|
|
|
|
.tree-status {
|
|
padding: 4px 12px;
|
|
font-size: 10px;
|
|
color: var(--muted);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Main content */
|
|
#content {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow-y: auto;
|
|
padding: var(--line-height) calc(var(--line-height) * 2);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
#content > * {
|
|
width: 100%;
|
|
max-width: 800px;
|
|
}
|
|
|
|
/* Help bar */
|
|
.help-bar {
|
|
font-size: 11px;
|
|
color: var(--warning);
|
|
margin-bottom: var(--line-height);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
}
|
|
|
|
.help-hint {
|
|
flex: 1 1 240px;
|
|
}
|
|
|
|
.help-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.header-toggle-btn,
|
|
.download-json-btn {
|
|
font-size: 10px;
|
|
padding: 2px 8px;
|
|
background: var(--container-bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 3px;
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.header-toggle-btn:hover,
|
|
.download-json-btn:hover {
|
|
background: var(--hover);
|
|
border-color: var(--borderAccent);
|
|
}
|
|
|
|
/* Header */
|
|
.header {
|
|
background: var(--container-bg);
|
|
border-radius: 4px;
|
|
padding: var(--line-height);
|
|
margin-bottom: var(--line-height);
|
|
}
|
|
|
|
.header h1 {
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
color: var(--borderAccent);
|
|
margin-bottom: var(--line-height);
|
|
}
|
|
|
|
.header-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.info-item {
|
|
color: var(--dim);
|
|
display: flex;
|
|
align-items: baseline;
|
|
}
|
|
|
|
.info-label {
|
|
font-weight: 600;
|
|
margin-right: 8px;
|
|
min-width: 100px;
|
|
}
|
|
|
|
.info-value {
|
|
color: var(--text);
|
|
flex: 1;
|
|
}
|
|
|
|
/* Messages */
|
|
#messages {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--line-height);
|
|
}
|
|
|
|
.message-timestamp {
|
|
font-size: 10px;
|
|
color: var(--dim);
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.user-message {
|
|
background: var(--userMessageBg);
|
|
color: var(--userMessageText);
|
|
padding: var(--line-height);
|
|
border-radius: 4px;
|
|
position: relative;
|
|
}
|
|
|
|
.assistant-message {
|
|
padding: 0;
|
|
position: relative;
|
|
}
|
|
|
|
/* Copy link button - appears on hover */
|
|
.copy-link-btn {
|
|
position: absolute;
|
|
top: 8px;
|
|
right: 8px;
|
|
width: 28px;
|
|
height: 28px;
|
|
padding: 6px;
|
|
background: var(--container-bg);
|
|
border: 1px solid var(--dim);
|
|
border-radius: 4px;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
opacity: 0;
|
|
transition: opacity 0.15s, background 0.15s, color 0.15s;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 10;
|
|
}
|
|
|
|
.user-message:hover .copy-link-btn,
|
|
.assistant-message:hover .copy-link-btn,
|
|
.skill-user-entry:hover .copy-link-btn {
|
|
opacity: 1;
|
|
}
|
|
|
|
.copy-link-btn:hover {
|
|
background: var(--accent);
|
|
color: var(--body-bg);
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.copy-link-btn.copied {
|
|
background: var(--success, #22c55e);
|
|
color: white;
|
|
border-color: var(--success, #22c55e);
|
|
}
|
|
|
|
/* Highlight effect for deep-linked messages */
|
|
.user-message.highlight,
|
|
.assistant-message.highlight {
|
|
animation: highlight-pulse 2s ease-out;
|
|
}
|
|
|
|
@keyframes highlight-pulse {
|
|
0% {
|
|
box-shadow: 0 0 0 3px var(--accent);
|
|
}
|
|
100% {
|
|
box-shadow: 0 0 0 0 transparent;
|
|
}
|
|
}
|
|
|
|
.assistant-message > .message-timestamp {
|
|
padding-left: var(--line-height);
|
|
}
|
|
|
|
.assistant-text {
|
|
padding: var(--line-height);
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.message-timestamp + .assistant-text,
|
|
.message-timestamp + .thinking-block {
|
|
padding-top: 0;
|
|
}
|
|
|
|
.thinking-block + .assistant-text {
|
|
padding-top: 0;
|
|
}
|
|
|
|
.thinking-text {
|
|
padding: var(--line-height);
|
|
color: var(--thinkingText);
|
|
font-style: italic;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.message-timestamp + .thinking-block .thinking-text,
|
|
.message-timestamp + .thinking-block .thinking-collapsed {
|
|
padding-top: 0;
|
|
}
|
|
|
|
.thinking-collapsed {
|
|
display: none;
|
|
padding: var(--line-height);
|
|
color: var(--thinkingText);
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Tool execution */
|
|
.tool-execution {
|
|
padding: var(--line-height);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.tool-execution + .tool-execution {
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.assistant-text + .tool-execution {
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.tool-execution.pending { background: var(--toolPendingBg); }
|
|
.tool-execution.success { background: var(--toolSuccessBg); }
|
|
.tool-execution.error { background: var(--toolErrorBg); }
|
|
|
|
.tool-header, .tool-name {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.tool-path {
|
|
color: var(--accent);
|
|
word-break: break-all;
|
|
}
|
|
|
|
.line-numbers {
|
|
color: var(--warning);
|
|
}
|
|
|
|
.line-count {
|
|
color: var(--dim);
|
|
}
|
|
|
|
.tool-command {
|
|
font-weight: bold;
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
overflow-wrap: break-word;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.tool-output {
|
|
margin-top: var(--line-height);
|
|
color: var(--toolOutput);
|
|
word-wrap: break-word;
|
|
overflow-wrap: break-word;
|
|
word-break: break-word;
|
|
font-family: inherit;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.tool-output > div,
|
|
.output-preview > div,
|
|
.output-full > div {
|
|
margin: 0;
|
|
padding: 0;
|
|
line-height: var(--line-height);
|
|
}
|
|
|
|
.tool-output > div:not(.output-preview):not(.output-full),
|
|
.output-preview > div:not(.expand-hint),
|
|
.output-full > div:not(.expand-hint) {
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.tool-output pre {
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: inherit;
|
|
color: inherit;
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
overflow-wrap: break-word;
|
|
}
|
|
|
|
.tool-output code {
|
|
padding: 0;
|
|
background: none;
|
|
color: var(--text);
|
|
}
|
|
|
|
.tool-output.expandable {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.tool-output.expandable:hover {
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.tool-output.expandable .output-full {
|
|
display: none;
|
|
}
|
|
|
|
.tool-output.expandable.expanded .output-preview {
|
|
display: none;
|
|
}
|
|
|
|
.tool-output.expandable.expanded .output-full {
|
|
display: block;
|
|
}
|
|
|
|
.ansi-line {
|
|
white-space: pre;
|
|
}
|
|
|
|
.tool-images {
|
|
}
|
|
|
|
.tool-image {
|
|
max-width: 100%;
|
|
max-height: 500px;
|
|
border-radius: 4px;
|
|
margin: var(--line-height) 0;
|
|
}
|
|
|
|
.expand-hint {
|
|
color: var(--toolOutput);
|
|
}
|
|
|
|
/* Diff */
|
|
.tool-diff {
|
|
font-size: 11px;
|
|
overflow-x: auto;
|
|
white-space: pre;
|
|
}
|
|
|
|
.diff-added { color: var(--toolDiffAdded); }
|
|
.diff-removed { color: var(--toolDiffRemoved); }
|
|
.diff-context { color: var(--toolDiffContext); }
|
|
|
|
/* Model change */
|
|
.model-change {
|
|
padding: 0 var(--line-height);
|
|
color: var(--dim);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.model-name {
|
|
color: var(--borderAccent);
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Compaction / Branch Summary - matches customMessage colors from TUI */
|
|
.compaction {
|
|
background: var(--customMessageBg);
|
|
border-radius: 4px;
|
|
padding: var(--line-height);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.compaction-label {
|
|
color: var(--customMessageLabel);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.compaction-collapsed {
|
|
color: var(--customMessageText);
|
|
}
|
|
|
|
.compaction-content {
|
|
display: none;
|
|
color: var(--customMessageText);
|
|
white-space: pre-wrap;
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.compaction.expanded .compaction-collapsed {
|
|
display: none;
|
|
}
|
|
|
|
.compaction.expanded .compaction-content {
|
|
display: block;
|
|
}
|
|
|
|
/* System prompt */
|
|
.system-prompt {
|
|
background: var(--customMessageBg);
|
|
padding: var(--line-height);
|
|
border-radius: 4px;
|
|
margin-bottom: var(--line-height);
|
|
}
|
|
|
|
.system-prompt.expandable {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.system-prompt-header {
|
|
font-weight: bold;
|
|
color: var(--customMessageLabel);
|
|
}
|
|
|
|
.system-prompt-preview {
|
|
color: var(--customMessageText);
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
font-size: 11px;
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.system-prompt-expand-hint {
|
|
color: var(--muted);
|
|
font-style: italic;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.system-prompt-full {
|
|
display: none;
|
|
color: var(--customMessageText);
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
font-size: 11px;
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.system-prompt.expanded .system-prompt-preview,
|
|
.system-prompt.expanded .system-prompt-expand-hint {
|
|
display: none;
|
|
}
|
|
|
|
.system-prompt.expanded .system-prompt-full {
|
|
display: block;
|
|
}
|
|
|
|
.system-prompt.provider-prompt {
|
|
border-left: 3px solid var(--warning);
|
|
}
|
|
|
|
.system-prompt-note {
|
|
font-size: 10px;
|
|
font-style: italic;
|
|
color: var(--muted);
|
|
margin-top: 4px;
|
|
}
|
|
|
|
/* Tools list */
|
|
.tools-list {
|
|
background: var(--customMessageBg);
|
|
padding: var(--line-height);
|
|
border-radius: 4px;
|
|
margin-bottom: var(--line-height);
|
|
}
|
|
|
|
.tools-header {
|
|
font-weight: bold;
|
|
color: var(--customMessageLabel);
|
|
margin-bottom: var(--line-height);
|
|
}
|
|
|
|
.tool-item {
|
|
font-size: 11px;
|
|
}
|
|
|
|
.tool-item-name {
|
|
font-weight: bold;
|
|
color: var(--text);
|
|
}
|
|
|
|
.tool-item-desc {
|
|
color: var(--dim);
|
|
}
|
|
|
|
.tool-params-hint {
|
|
color: var(--muted);
|
|
font-style: italic;
|
|
}
|
|
|
|
.tool-item:has(.tool-params-hint) {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.tool-params-hint::after {
|
|
content: '[click to show parameters]';
|
|
}
|
|
|
|
.tool-item.params-expanded .tool-params-hint::after {
|
|
content: '[hide parameters]';
|
|
}
|
|
|
|
.tool-params-content {
|
|
display: none;
|
|
margin-top: 4px;
|
|
margin-left: 12px;
|
|
padding-left: 8px;
|
|
border-left: 1px solid var(--dim);
|
|
}
|
|
|
|
.tool-item.params-expanded .tool-params-content {
|
|
display: block;
|
|
}
|
|
|
|
.tool-param {
|
|
margin-bottom: 4px;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.tool-param-name {
|
|
font-weight: bold;
|
|
color: var(--text);
|
|
}
|
|
|
|
.tool-param-type {
|
|
color: var(--dim);
|
|
font-style: italic;
|
|
}
|
|
|
|
.tool-param-required {
|
|
color: var(--warning, #e8a838);
|
|
font-size: 10px;
|
|
}
|
|
|
|
.tool-param-optional {
|
|
color: var(--dim);
|
|
font-size: 10px;
|
|
}
|
|
|
|
.tool-param-desc {
|
|
color: var(--dim);
|
|
margin-left: 8px;
|
|
}
|
|
|
|
/* Hook/custom messages */
|
|
.hook-message {
|
|
background: var(--customMessageBg);
|
|
color: var(--customMessageText);
|
|
padding: var(--line-height);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.hook-type {
|
|
color: var(--customMessageLabel);
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Skill invocation - matches compaction style (clickable, collapsed by default) */
|
|
.skill-invocation {
|
|
background: var(--customMessageBg);
|
|
border-radius: 4px;
|
|
padding: var(--line-height);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.skill-invocation-label {
|
|
color: var(--customMessageLabel);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.skill-invocation-collapsed {
|
|
color: var(--customMessageText);
|
|
}
|
|
|
|
.skill-invocation-content {
|
|
display: none;
|
|
color: var(--customMessageText);
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.skill-invocation.expanded .skill-invocation-collapsed {
|
|
display: none;
|
|
}
|
|
|
|
.skill-invocation.expanded .skill-invocation-content {
|
|
display: block;
|
|
}
|
|
|
|
.skill-invocation + .user-message {
|
|
margin-top: var(--line-height);
|
|
}
|
|
|
|
.skill-user-entry {
|
|
position: relative;
|
|
}
|
|
|
|
/* Branch summary */
|
|
.branch-summary {
|
|
background: var(--customMessageBg);
|
|
padding: var(--line-height);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.branch-summary-header {
|
|
font-weight: bold;
|
|
color: var(--borderAccent);
|
|
}
|
|
|
|
/* Error */
|
|
.error-text {
|
|
color: var(--error);
|
|
padding: 0 var(--line-height);
|
|
}
|
|
.tool-error {
|
|
color: var(--error);
|
|
}
|
|
|
|
/* Images */
|
|
.message-images {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.message-image {
|
|
max-width: 100%;
|
|
max-height: 400px;
|
|
border-radius: 4px;
|
|
margin: var(--line-height) 0;
|
|
}
|
|
|
|
/* Markdown content */
|
|
.markdown-content h1,
|
|
.markdown-content h2,
|
|
.markdown-content h3,
|
|
.markdown-content h4,
|
|
.markdown-content h5,
|
|
.markdown-content h6 {
|
|
color: var(--mdHeading);
|
|
margin: var(--line-height) 0 0 0;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.markdown-content h1 { font-size: 1em; }
|
|
.markdown-content h2 { font-size: 1em; }
|
|
.markdown-content h3 { font-size: 1em; }
|
|
.markdown-content h4 { font-size: 1em; }
|
|
.markdown-content h5 { font-size: 1em; }
|
|
.markdown-content h6 { font-size: 1em; }
|
|
.markdown-content p { margin: 0; }
|
|
.markdown-content p + p { margin-top: var(--line-height); }
|
|
|
|
.markdown-content a {
|
|
color: var(--mdLink);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.markdown-content code {
|
|
background: rgba(128, 128, 128, 0.2);
|
|
color: var(--mdCode);
|
|
padding: 0 4px;
|
|
border-radius: 3px;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.markdown-content pre {
|
|
background: transparent;
|
|
margin: var(--line-height) 0;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.markdown-content pre code {
|
|
display: block;
|
|
background: none;
|
|
color: var(--text);
|
|
}
|
|
|
|
.markdown-content blockquote {
|
|
border-left: 3px solid var(--mdQuoteBorder);
|
|
padding-left: var(--line-height);
|
|
margin: var(--line-height) 0;
|
|
color: var(--mdQuote);
|
|
font-style: italic;
|
|
}
|
|
|
|
.markdown-content ul,
|
|
.markdown-content ol {
|
|
margin: var(--line-height) 0;
|
|
padding-left: calc(var(--line-height) * 2);
|
|
}
|
|
|
|
.markdown-content li { margin: 0; }
|
|
.markdown-content li::marker { color: var(--mdListBullet); }
|
|
|
|
.markdown-content hr {
|
|
border: none;
|
|
border-top: 1px solid var(--mdHr);
|
|
margin: var(--line-height) 0;
|
|
}
|
|
|
|
.markdown-content table {
|
|
border-collapse: collapse;
|
|
margin: 0.5em 0;
|
|
width: 100%;
|
|
}
|
|
|
|
.markdown-content th,
|
|
.markdown-content td {
|
|
border: 1px solid var(--mdCodeBlockBorder);
|
|
padding: 6px 10px;
|
|
text-align: left;
|
|
}
|
|
|
|
.markdown-content th {
|
|
background: rgba(128, 128, 128, 0.1);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.markdown-content img {
|
|
max-width: 100%;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* Syntax highlighting */
|
|
.hljs { background: transparent; color: var(--text); }
|
|
.hljs-comment, .hljs-quote { color: var(--syntaxComment); }
|
|
.hljs-keyword, .hljs-selector-tag { color: var(--syntaxKeyword); }
|
|
.hljs-number, .hljs-literal { color: var(--syntaxNumber); }
|
|
.hljs-string, .hljs-doctag { color: var(--syntaxString); }
|
|
/* Function names: hljs v11 uses .hljs-title.function_ compound class */
|
|
.hljs-function, .hljs-title, .hljs-title.function_, .hljs-section, .hljs-name { color: var(--syntaxFunction); }
|
|
/* Types: hljs v11 uses .hljs-title.class_ for class names */
|
|
.hljs-type, .hljs-class, .hljs-title.class_, .hljs-built_in { color: var(--syntaxType); }
|
|
.hljs-attr, .hljs-variable, .hljs-variable.language_, .hljs-params, .hljs-property { color: var(--syntaxVariable); }
|
|
.hljs-meta, .hljs-meta .hljs-keyword, .hljs-meta .hljs-string { color: var(--syntaxKeyword); }
|
|
.hljs-operator { color: var(--syntaxOperator); }
|
|
.hljs-punctuation { color: var(--syntaxPunctuation); }
|
|
.hljs-subst { color: var(--text); }
|
|
|
|
/* Footer */
|
|
.footer {
|
|
margin-top: 48px;
|
|
padding: 20px;
|
|
text-align: center;
|
|
color: var(--dim);
|
|
font-size: 10px;
|
|
}
|
|
|
|
/* Mobile */
|
|
#hamburger {
|
|
display: none;
|
|
position: fixed;
|
|
top: 10px;
|
|
left: 10px;
|
|
z-index: 100;
|
|
padding: 3px 8px;
|
|
font-size: 12px;
|
|
font-family: inherit;
|
|
background: transparent;
|
|
color: var(--muted);
|
|
border: 1px solid var(--dim);
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#hamburger:hover {
|
|
color: var(--text);
|
|
border-color: var(--text);
|
|
}
|
|
|
|
|
|
|
|
#sidebar-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
z-index: 98;
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
#sidebar {
|
|
position: fixed;
|
|
left: 0;
|
|
width: min(var(--sidebar-width), 100vw);
|
|
min-width: min(var(--sidebar-width), 100vw);
|
|
max-width: min(var(--sidebar-width), 100vw);
|
|
top: 0;
|
|
bottom: 0;
|
|
height: 100vh;
|
|
z-index: 99;
|
|
transform: translateX(-100%);
|
|
transition: transform 0.3s;
|
|
}
|
|
|
|
#sidebar.open {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
#sidebar-resizer {
|
|
display: none;
|
|
}
|
|
|
|
#sidebar-overlay.open {
|
|
display: block;
|
|
}
|
|
|
|
#hamburger {
|
|
display: block;
|
|
}
|
|
|
|
.sidebar-close {
|
|
display: block;
|
|
}
|
|
|
|
#content {
|
|
padding: var(--line-height) 16px;
|
|
}
|
|
|
|
#content > * {
|
|
max-width: 100%;
|
|
}
|
|
}
|
|
|
|
@media print {
|
|
#sidebar, #sidebar-resizer, #sidebar-toggle { display: none !important; }
|
|
body { background: white; color: black; }
|
|
#content { max-width: none; }
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<button id="hamburger" title="Open sidebar"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><rect x="5" y="6" width="2" height="12"/><path d="M6 12h10c1 0 2 0 2-2V8"/></svg></button>
|
|
<div id="sidebar-overlay"></div>
|
|
<div id="app">
|
|
<aside id="sidebar">
|
|
<div class="sidebar-header">
|
|
<div class="sidebar-controls">
|
|
<input type="text" class="sidebar-search" id="tree-search" placeholder="Search...">
|
|
</div>
|
|
<div class="sidebar-filters">
|
|
<button class="filter-btn active" data-filter="default" title="Hide settings entries">Default</button>
|
|
<button class="filter-btn" data-filter="no-tools" title="Default minus tool results">No-tools</button>
|
|
<button class="filter-btn" data-filter="user-only" title="Only user messages">User</button>
|
|
<button class="filter-btn" data-filter="labeled-only" title="Only labeled entries">Labeled</button>
|
|
<button class="filter-btn" data-filter="all" title="Show everything">All</button>
|
|
<button class="sidebar-close" id="sidebar-close" title="Close">✕</button>
|
|
</div>
|
|
</div>
|
|
<div class="tree-container" id="tree-container"></div>
|
|
<div class="tree-status" id="tree-status"></div>
|
|
</aside>
|
|
<div id="sidebar-resizer" role="separator" aria-orientation="vertical" aria-label="Resize session tree sidebar"></div>
|
|
<main id="content">
|
|
<div id="header-container"></div>
|
|
<div id="messages"></div>
|
|
</main>
|
|
<div id="image-modal" class="image-modal">
|
|
<img id="modal-image" src="" alt="">
|
|
</div>
|
|
</div>
|
|
|
|
<script id="session-data" type="application/json">eyJoZWFkZXIiOnsidHlwZSI6InNlc3Npb24iLCJ2ZXJzaW9uIjozLCJpZCI6IjAxOWVlM2M4LTgzMjQtNzc3OC1hZDkyLTA5ZTA5YTc2NzkyMyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NDc6MDkuMzQ4WiIsImN3ZCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlIn0sImVudHJpZXMiOlt7InR5cGUiOiJtb2RlbF9jaGFuZ2UiLCJpZCI6ImRiYzAzMWRiIiwicGFyZW50SWQiOm51bGwsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NDc6MDkuMzY2WiIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWxJZCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiJ9LHsidHlwZSI6InRoaW5raW5nX2xldmVsX2NoYW5nZSIsImlkIjoiYjFjZDZhNzMiLCJwYXJlbnRJZCI6ImRiYzAzMWRiIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo0NzowOS4zNjZaIiwidGhpbmtpbmdMZXZlbCI6ImhpZ2gifSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJmNDA2YjYxZCIsInBhcmVudElkIjoiYjFjZDZhNzMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjUwOjA2LjcwM1oiLCJtZXNzYWdlIjp7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiSSB3b3VsZCBsaWtlIHRvIHN0YXJ0IGRldmVsb3BtZW50IG9mIGEgbmV3IFBpIGV4dGVuc2lvbiBoZXJlLiBJdCBzaG91bGQgYmUgaW5zdGFsbGFibGUgYnkgbnBtIGZyb20gdGhlIGxvY2FsIGZpbGVzeXN0ZW0uIEkgd291bGQgbGlrZSB0byBydW4gdGVzdHMgb24gcGFydHMgb2YgaXQgd2l0aCB2aXRlc3QuIFRoZSBnb2FsIG9mIHRoZSBleHRlbnNpb24gaXMgdG8gc3RlZXIgYW4gYWdlbnQgdGhyb3VnaCB0aGUgcmVkLWdyZWVuLXJlZmFjdG9yIGN5Y2xlLCBtYWtpbmcgaXQgaW1wb3NzaWJsZSB0byBza2lwIHJlZmFjdG9yaW5nLCBhbmQga2VlcGluZyB0aGUgZGV2ZWxvcGVyIGluIHRoZSBsb29wIGF0IGFsbCB0aW1lcy4gZS5nLiB0aGUgdGVzdHMgYXJlIHJ1biB3aGVuIHRoZSBhZ2VudCBjYWxscyB0aGUgJ2dvLXRvLWdyZWVuJyB0b29sLCBhbmQgd2hlbiB0aGUgdGVzdCBmYWlscywgdGhlIHN0YXRlIHN0YXlzIGluIHJlZC4gd2hlbiB0aGUgdGVzdHMgcGFzcywgdGhlIGFnZW50IGdldHMgYSBzdGVlcmluZyBtZXNzYWdlIHRoYXQgdGhlIG5leHQgcGhhc2Ugd2lsbCBiZSByZWZhY3Rvci4gVGhlIGRldmVsb3BlciBzaG91bGQgYmUgcHJlc2VudGVkIHdpdGggYSBxdWVzdGlvbiBvbiB3aGV0aGVyIHRvIDEuIHJlZmFjdG9yIHRoZSB0ZXN0cyAyLiByZWZhY3RvciB0aGUgaW1wbGVtZW50YXRpb24gMy4gY29udGludWUgdG8gdGhlIG5leHQgdGVzdCA0LiBzb21ldGhpbmcgZWxzZSAoZS5nLiBjdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb24gYnkgdGhlIGRldmVsb3BlcikuIn1dLCJ0aW1lc3RhbXAiOjE3ODE5MzgyMDY2OTl9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJjMmNiN2NkMiIsInBhcmVudElkIjoiZjQwNmI2MWQiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjUwOjEzLjAyMloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkxldCBtZSBzdGFydCBieSB1bmRlcnN0YW5kaW5nIHRoZSBwcm9qZWN0IHN0cnVjdHVyZSBhbmQgdGhlIFBpIGV4dGVuc2lvbiBzeXN0ZW0uIEknbGwgcmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBhbmQgZXhhbXBsZXMgdG8gdW5kZXJzdGFuZCBob3cgdG8gYnVpbGQgYSBQaSBleHRlbnNpb24uXG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJMZXQgbWUgc3RhcnQgYnkgcmVhZGluZyB0aGUgUGkgZXh0ZW5zaW9uIGRvY3VtZW50YXRpb24gYW5kIGV4YW1wbGVzIHRvIHVuZGVyc3RhbmQgdGhlIGV4dGVuc2lvbiBzeXN0ZW0uXG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJhMVo2YUFHTXkxTnhkYXdCczBQQ2VNTUpyTngzZmZUaiIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtLy5sb2NhbC9zaGFyZS9taXNlL2luc3RhbGxzL25vZGUvMjQuMC4xL2xpYi9ub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudC9SRUFETUUubWQifX0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6Im1FRHdpVmplZUt5ZTJ5Qnl3Z1hnZlhIVm5vemZ5RUJjIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2RvY3MvZXh0ZW5zaW9ucy5tZCJ9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiT1lMSWZLQjJRYVo0QXFDMVNUeURrVlY2cHI0Q0FidVEiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoibHMgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoxNzQ1LCJvdXRwdXQiOjIxMSwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTk1NiwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4MjA2NzM1LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtMVU1SmRPVkV3Z2tVYnhIbDAyNzZIaFFkQkRJVjJkYTMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMTZjNjllNzAiLCJwYXJlbnRJZCI6ImMyY2I3Y2QyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MDoxMy4wNDJaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJhMVo2YUFHTXkxTnhkYXdCczBQQ2VNTUpyTngzZmZUaiIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IjxwIGFsaWduPVwiY2VudGVyXCI+XG4gIDxhIGhyZWY9XCJodHRwczovL3BpLmRldlwiPlxuICAgIDxpbWcgYWx0PVwicGkgbG9nb1wiIHNyYz1cImh0dHBzOi8vcGkuZGV2L2xvZ28tYXV0by5zdmdcIiB3aWR0aD1cIjEyOFwiPlxuICA8L2E+XG48L3A+XG48cCBhbGlnbj1cImNlbnRlclwiPlxuICA8YSBocmVmPVwiaHR0cHM6Ly9kaXNjb3JkLmNvbS9pbnZpdGUvM2NVN0J6NFVQeFwiPjxpbWcgYWx0PVwiRGlzY29yZFwiIHNyYz1cImh0dHBzOi8vaW1nLnNoaWVsZHMuaW8vYmFkZ2UvZGlzY29yZC1jb21tdW5pdHktNTg2NUYyP3N0eWxlPWZsYXQtc3F1YXJlJmxvZ289ZGlzY29yZCZsb2dvQ29sb3I9d2hpdGVcIiAvPjwvYT5cbiAgPGEgaHJlZj1cImh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIj48aW1nIGFsdD1cIm5wbVwiIHNyYz1cImh0dHBzOi8vaW1nLnNoaWVsZHMuaW8vbnBtL3YvQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudD9zdHlsZT1mbGF0LXNxdWFyZVwiIC8+PC9hPlxuPC9wPlxuXG4+IE5ldyBpc3N1ZXMgYW5kIFBScyBmcm9tIG5ldyBjb250cmlidXRvcnMgYXJlIGF1dG8tY2xvc2VkIGJ5IGRlZmF1bHQuIE1haW50YWluZXJzIHJldmlldyBhdXRvLWNsb3NlZCBpc3N1ZXMgZGFpbHkuIFNlZSBbQ09OVFJJQlVUSU5HLm1kXSguLi8uLi9DT05UUklCVVRJTkcubWQpLlxuXG4tLS1cblxuUGkgaXMgYSBtaW5pbWFsIHRlcm1pbmFsIGNvZGluZyBoYXJuZXNzLiBBZGFwdCBwaSB0byB5b3VyIHdvcmtmbG93cywgbm90IHRoZSBvdGhlciB3YXkgYXJvdW5kLCB3aXRob3V0IGhhdmluZyB0byBmb3JrIGFuZCBtb2RpZnkgcGkgaW50ZXJuYWxzLiBFeHRlbmQgaXQgd2l0aCBUeXBlU2NyaXB0IFtFeHRlbnNpb25zXSgjZXh0ZW5zaW9ucyksIFtTa2lsbHNdKCNza2lsbHMpLCBbUHJvbXB0IFRlbXBsYXRlc10oI3Byb21wdC10ZW1wbGF0ZXMpLCBhbmQgW1RoZW1lc10oI3RoZW1lcykuIFB1dCB5b3VyIGV4dGVuc2lvbnMsIHNraWxscywgcHJvbXB0IHRlbXBsYXRlcywgYW5kIHRoZW1lcyBpbiBbUGkgUGFja2FnZXNdKCNwaS1wYWNrYWdlcykgYW5kIHNoYXJlIHRoZW0gd2l0aCBvdGhlcnMgdmlhIG5wbSBvciBnaXQuXG5cblBpIHNoaXBzIHdpdGggcG93ZXJmdWwgZGVmYXVsdHMgYnV0IHNraXBzIGZlYXR1cmVzIGxpa2Ugc3ViIGFnZW50cyBhbmQgcGxhbiBtb2RlLiBJbnN0ZWFkLCB5b3UgY2FuIGFzayBwaSB0byBidWlsZCB3aGF0IHlvdSB3YW50IG9yIGluc3RhbGwgYSB0aGlyZCBwYXJ0eSBwaSBwYWNrYWdlIHRoYXQgbWF0Y2hlcyB5b3VyIHdvcmtmbG93LlxuXG5QaSBydW5zIGluIGZvdXIgbW9kZXM6IGludGVyYWN0aXZlLCBwcmludCBvciBKU09OLCBSUEMgZm9yIHByb2Nlc3MgaW50ZWdyYXRpb24sIGFuZCBhbiBTREsgZm9yIGVtYmVkZGluZyBpbiB5b3VyIG93biBhcHBzLiBTZWUgW29wZW5jbGF3L29wZW5jbGF3XShodHRwczovL2dpdGh1Yi5jb20vb3BlbmNsYXcvb3BlbmNsYXcpIGZvciBhIHJlYWwtd29ybGQgU0RLIGludGVncmF0aW9uLlxuXG4jIyBTaGFyZSB5b3VyIE9TUyBjb2RpbmcgYWdlbnQgc2Vzc2lvbnNcblxuSWYgeW91IHVzZSBwaSBmb3Igb3BlbiBzb3VyY2Ugd29yaywgcGxlYXNlIHNoYXJlIHlvdXIgY29kaW5nIGFnZW50IHNlc3Npb25zLlxuXG5QdWJsaWMgT1NTIHNlc3Npb24gZGF0YSBoZWxwcyBpbXByb3ZlIG1vZGVscywgcHJvbXB0cywgdG9vbHMsIGFuZCBldmFsdWF0aW9ucyB1c2luZyByZWFsIGRldmVsb3BtZW50IHdvcmtmbG93cy5cblxuRm9yIHRoZSBmdWxsIGV4cGxhbmF0aW9uLCBzZWUgW3RoaXMgcG9zdCBvbiBYXShodHRwczovL3guY29tL2JhZGxvZ2ljZ2FtZXMvc3RhdHVzLzIwMzc4MTE2NDM3NzQ2NTI5MTEpLlxuXG5UbyBwdWJsaXNoIHNlc3Npb25zLCB1c2UgW2BiYWRsb2dpYy9waS1zaGFyZS1oZmBdKGh0dHBzOi8vZ2l0aHViLmNvbS9iYWRsb2dpYy9waS1zaGFyZS1oZikuIFJlYWQgaXRzIFJFQURNRS5tZCBmb3Igc2V0dXAgaW5zdHJ1Y3Rpb25zLiBBbGwgeW91IG5lZWQgaXMgYSBIdWdnaW5nIEZhY2UgYWNjb3VudCwgdGhlIEh1Z2dpbmcgRmFjZSBDTEksIGFuZCBgcGktc2hhcmUtaGZgLlxuXG5Zb3UgY2FuIGFsc28gd2F0Y2ggW3RoaXMgdmlkZW9dKGh0dHBzOi8veC5jb20vYmFkbG9naWNnYW1lcy9zdGF0dXMvMjA0MTE1MTk2NzY5NTYzNDYxOSksIHdoZXJlIEkgc2hvdyBob3cgSSBwdWJsaXNoIG15IGBwaS1tb25vYCBzZXNzaW9ucy5cblxuSSByZWd1bGFybHkgcHVibGlzaCBteSBvd24gYHBpLW1vbm9gIHdvcmsgc2Vzc2lvbnMgaGVyZTpcblxuLSBbYmFkbG9naWNnYW1lcy9waS1tb25vIG9uIEh1Z2dpbmcgRmFjZV0oaHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kYXRhc2V0cy9iYWRsb2dpY2dhbWVzL3BpLW1vbm8pXG5cbiMjIFRhYmxlIG9mIENvbnRlbnRzXG5cbi0gW1F1aWNrIFN0YXJ0XSgjcXVpY2stc3RhcnQpXG4tIFtQcm92aWRlcnMgJiBNb2RlbHNdKCNwcm92aWRlcnMtLW1vZGVscylcbi0gW0ludGVyYWN0aXZlIE1vZGVdKCNpbnRlcmFjdGl2ZS1tb2RlKVxuICAtIFtFZGl0b3JdKCNlZGl0b3IpXG4gIC0gW0NvbW1hbmRzXSgjY29tbWFuZHMpXG4gIC0gW0tleWJvYXJkIFNob3J0Y3V0c10oI2tleWJvYXJkLXNob3J0Y3V0cylcbiAgLSBbTWVzc2FnZSBRdWV1ZV0oI21lc3NhZ2UtcXVldWUpXG4tIFtTZXNzaW9uc10oI3Nlc3Npb25zKVxuICAtIFtCcmFuY2hpbmddKCNicmFuY2hpbmcpXG4gIC0gW0NvbXBhY3Rpb25dKCNjb21wYWN0aW9uKVxuLSBbU2V0dGluZ3NdKCNzZXR0aW5ncylcbi0gW0NvbnRleHQgRmlsZXNdKCNjb250ZXh0LWZpbGVzKVxuLSBbQ3VzdG9taXphdGlvbl0oI2N1c3RvbWl6YXRpb24pXG4gIC0gW1Byb21wdCBUZW1wbGF0ZXNdKCNwcm9tcHQtdGVtcGxhdGVzKVxuICAtIFtTa2lsbHNdKCNza2lsbHMpXG4gIC0gW0V4dGVuc2lvbnNdKCNleHRlbnNpb25zKVxuICAtIFtUaGVtZXNdKCN0aGVtZXMpXG4gIC0gW1BpIFBhY2thZ2VzXSgjcGktcGFja2FnZXMpXG4tIFtQcm9ncmFtbWF0aWMgVXNhZ2VdKCNwcm9ncmFtbWF0aWMtdXNhZ2UpXG4tIFtQaGlsb3NvcGh5XSgjcGhpbG9zb3BoeSlcbi0gW0NMSSBSZWZlcmVuY2VdKCNjbGktcmVmZXJlbmNlKVxuXG4tLS1cblxuIyMgUXVpY2sgU3RhcnRcblxuYGBgYmFzaFxubnBtIGluc3RhbGwgLWcgLS1pZ25vcmUtc2NyaXB0cyBAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XG5gYGBcblxuYC0taWdub3JlLXNjcmlwdHNgIGRpc2FibGVzIGRlcGVuZGVuY3kgbGlmZWN5Y2xlIHNjcmlwdHMgZHVyaW5nIGluc3RhbGwuIFBpIGRvZXMgbm90IHJlcXVpcmUgaW5zdGFsbCBzY3JpcHRzIGZvciBub3JtYWwgbnBtIGluc3RhbGxzLlxuXG5JbnN0YWxsZXIgYWx0ZXJuYXRpdmU6XG5cbmBgYGJhc2hcbmN1cmwgLWZzU0wgaHR0cHM6Ly9waS5kZXYvaW5zdGFsbC5zaCB8IHNoXG5gYGBcblxuQXV0aGVudGljYXRlIHdpdGggYW4gQVBJIGtleTpcblxuYGBgYmFzaFxuZXhwb3J0IEFOVEhST1BJQ19BUElfS0VZPXNrLWFudC0uLi5cbnBpXG5gYGBcblxuT3IgdXNlIHlvdXIgZXhpc3Rpbmcgc3Vic2NyaXB0aW9uOlxuXG5gYGBiYXNoXG5waVxuL2xvZ2luICAjIFRoZW4gc2VsZWN0IHByb3ZpZGVyXG5gYGBcblxuVGhlbiBqdXN0IHRhbGsgdG8gcGkuIEJ5IGRlZmF1bHQsIHBpIGdpdmVzIHRoZSBtb2RlbCBmb3VyIHRvb2xzOiBgcmVhZGAsIGB3cml0ZWAsIGBlZGl0YCwgYW5kIGBiYXNoYC4gVGhlIG1vZGVsIHVzZXMgdGhlc2UgdG8gZnVsZmlsbCB5b3VyIHJlcXVlc3RzLiBBZGQgY2FwYWJpbGl0aWVzIHZpYSBbc2tpbGxzXSgjc2tpbGxzKSwgW3Byb21wdCB0ZW1wbGF0ZXNdKCNwcm9tcHQtdGVtcGxhdGVzKSwgW2V4dGVuc2lvbnNdKCNleHRlbnNpb25zKSwgb3IgW3BpIHBhY2thZ2VzXSgjcGktcGFja2FnZXMpLlxuXG4qKlBsYXRmb3JtIG5vdGVzOioqIFtXaW5kb3dzXShkb2NzL3dpbmRvd3MubWQpIHwgW1Rlcm11eCAoQW5kcm9pZCldKGRvY3MvdGVybXV4Lm1kKSB8IFt0bXV4XShkb2NzL3RtdXgubWQpIHwgW1Rlcm1pbmFsIHNldHVwXShkb2NzL3Rlcm1pbmFsLXNldHVwLm1kKSB8IFtTaGVsbCBhbGlhc2VzXShkb2NzL3NoZWxsLWFsaWFzZXMubWQpXG5cbi0tLVxuXG4jIyBQcm92aWRlcnMgJiBNb2RlbHNcblxuRm9yIGVhY2ggYnVpbHQtaW4gcHJvdmlkZXIsIHBpIG1haW50YWlucyBhIGxpc3Qgb2YgdG9vbC1jYXBhYmxlIG1vZGVscywgdXBkYXRlZCB3aXRoIGV2ZXJ5IHJlbGVhc2UuIEF1dGhlbnRpY2F0ZSB2aWEgc3Vic2NyaXB0aW9uIChgL2xvZ2luYCkgb3IgQVBJIGtleSwgdGhlbiBzZWxlY3QgYW55IG1vZGVsIGZyb20gdGhhdCBwcm92aWRlciB2aWEgYC9tb2RlbGAgKG9yIEN0cmwrTCkuXG5cbioqU3Vic2NyaXB0aW9uczoqKlxuLSBBbnRocm9waWMgQ2xhdWRlIFByby9NYXhcbi0gT3BlbkFJIENoYXRHUFQgUGx1cy9Qcm8gKENvZGV4KVxuLSBHaXRIdWIgQ29waWxvdFxuXG4qKkFQSSBrZXlzOioqXG4tIEFudGhyb3BpY1xuLSBBbnQgTGluZ1xuLSBPcGVuQUlcbi0gQXp1cmUgT3BlbkFJXG4tIERlZXBTZWVrXG4tIE5WSURJQSBOSU1cbi0gR29vZ2xlIEdlbWluaVxuLSBHb29nbGUgVmVydGV4XG4tIEFtYXpvbiBCZWRyb2NrXG4tIE1pc3RyYWxcbi0gR3JvcVxuLSBDZXJlYnJhc1xuLSBDbG91ZGZsYXJlIEFJIEdhdGV3YXlcbi0gQ2xvdWRmbGFyZSBXb3JrZXJzIEFJXG4tIHhBSVxuLSBPcGVuUm91dGVyXG4tIFZlcmNlbCBBSSBHYXRld2F5XG4tIFpBSVxuLSBaQUkgQ29kaW5nIFBsYW4gKENoaW5hKVxuLSBPcGVuQ29kZSBaZW5cbi0gT3BlbkNvZGUgR29cbi0gSHVnZ2luZyBGYWNlXG4tIEZpcmV3b3Jrc1xuLSBUb2dldGhlciBBSVxuLSBLaW1pIEZvciBDb2Rpbmdcbi0gTWluaU1heFxuLSBYaWFvbWkgTWlNb1xuLSBYaWFvbWkgTWlNbyBUb2tlbiBQbGFuIChDaGluYSlcbi0gWGlhb21pIE1pTW8gVG9rZW4gUGxhbiAoQW1zdGVyZGFtKVxuLSBYaWFvbWkgTWlNbyBUb2tlbiBQbGFuIChTaW5nYXBvcmUpXG5cblNlZSBbZG9jcy9wcm92aWRlcnMubWRdKGRvY3MvcHJvdmlkZXJzLm1kKSBmb3IgZGV0YWlsZWQgc2V0dXAgaW5zdHJ1Y3Rpb25zLlxuXG4qKkN1c3RvbSBwcm92aWRlcnMgJiBtb2RlbHM6KiogQWRkIHByb3ZpZGVycyB2aWEgYH4vLnBpL2FnZW50L21vZGVscy5qc29uYCBpZiB0aGV5IHNwZWFrIGEgc3VwcG9ydGVkIEFQSSAoT3BlbkFJLCBBbnRocm9waWMsIEdvb2dsZSkuIEZvciBjdXN0b20gQVBJcyBvciBPQXV0aCwgdXNlIGV4dGVuc2lvbnMuIFNlZSBbZG9jcy9tb2RlbHMubWRdKGRvY3MvbW9kZWxzLm1kKSBhbmQgW2RvY3MvY3VzdG9tLXByb3ZpZGVyLm1kXShkb2NzL2N1c3RvbS1wcm92aWRlci5tZCkuXG5cbi0tLVxuXG4jIyBJbnRlcmFjdGl2ZSBNb2RlXG5cbjxwIGFsaWduPVwiY2VudGVyXCI+PGltZyBzcmM9XCJkb2NzL2ltYWdlcy9pbnRlcmFjdGl2ZS1tb2RlLnBuZ1wiIGFsdD1cIkludGVyYWN0aXZlIE1vZGVcIiB3aWR0aD1cIjYwMFwiPjwvcD5cblxuVGhlIGludGVyZmFjZSBmcm9tIHRvcCB0byBib3R0b206XG5cbi0gKipTdGFydHVwIGhlYWRlcioqIC0gU2hvd3Mgc2hvcnRjdXRzIChgL2hvdGtleXNgIGZvciBhbGwpLCBsb2FkZWQgQUdFTlRTLm1kIGZpbGVzLCBwcm9tcHQgdGVtcGxhdGVzLCBza2lsbHMsIGFuZCBleHRlbnNpb25zXG4tICoqTWVzc2FnZXMqKiAtIFlvdXIgbWVzc2FnZXMsIGFzc2lzdGFudCByZXNwb25zZXMsIHRvb2wgY2FsbHMgYW5kIHJlc3VsdHMsIG5vdGlmaWNhdGlvbnMsIGVycm9ycywgYW5kIGV4dGVuc2lvbiBVSVxuLSAqKkVkaXRvcioqIC0gV2hlcmUgeW91IHR5cGU7IGJvcmRlciBjb2xvciBpbmRpY2F0ZXMgdGhpbmtpbmcgbGV2ZWxcbi0gKipGb290ZXIqKiAtIFdvcmtpbmcgZGlyZWN0b3J5LCBzZXNzaW9uIG5hbWUsIHRvdGFsIHRva2VuL2NhY2hlIHVzYWdlIChg4oaRYCBpbnB1dCwgYOKGk2Agb3V0cHV0LCBgUmAgY2FjaGUgcmVhZCwgYFdgIGNhY2hlIHdyaXRlLCBgQ0hgIGxhdGVzdCBjYWNoZSBoaXQgcmF0ZSksIGNvc3QsIGNvbnRleHQgdXNhZ2UsIGN1cnJlbnQgbW9kZWxcblxuVGhlIGVkaXRvciBjYW4gYmUgdGVtcG9yYXJpbHkgcmVwbGFjZWQgYnkgb3RoZXIgVUksIGxpa2UgYnVpbHQtaW4gYC9zZXR0aW5nc2Agb3IgY3VzdG9tIFVJIGZyb20gZXh0ZW5zaW9ucyAoZS5nLiwgYSBRJkEgdG9vbCB0aGF0IGxldHMgdGhlIHVzZXIgYW5zd2VyIG1vZGVsIHF1ZXN0aW9ucyBpbiBhIHN0cnVjdHVyZWQgZm9ybWF0KS4gW0V4dGVuc2lvbnNdKCNleHRlbnNpb25zKSBjYW4gYWxzbyByZXBsYWNlIHRoZSBlZGl0b3IsIGFkZCB3aWRnZXRzIGFib3ZlL2JlbG93IGl0LCBhIHN0YXR1cyBsaW5lLCBjdXN0b20gZm9vdGVyLCBvciBvdmVybGF5cy5cblxuIyMjIEVkaXRvclxuXG58IEZlYXR1cmUgfCBIb3cgfFxufC0tLS0tLS0tLXwtLS0tLXxcbnwgRmlsZSByZWZlcmVuY2UgfCBUeXBlIGBAYCB0byBmdXp6eS1zZWFyY2ggcHJvamVjdCBmaWxlcyB8XG58IFBhdGggY29tcGxldGlvbiB8IFRhYiB0byBjb21wbGV0ZSBwYXRocyB8XG58IE11bHRpLWxpbmUgfCBTaGlmdCtFbnRlciAob3IgQ3RybCtFbnRlciBvbiBXaW5kb3dzIFRlcm1pbmFsKSB8XG58IEltYWdlcyB8IEN0cmwrViB0byBwYXN0ZSAoQWx0K1Ygb24gV2luZG93cyksIG9yIGRyYWcgb250byB0ZXJtaW5hbCB8XG58IEJhc2ggY29tbWFuZHMgfCBgIWNvbW1hbmRgIHJ1bnMgYW5kIHNlbmRzIG91dHB1dCB0byBMTE0sIGAhIWNvbW1hbmRgIHJ1bnMgd2l0aG91dCBzZW5kaW5nIHxcblxuU3RhbmRhcmQgZWRpdGluZyBrZXliaW5kaW5ncyBmb3IgZGVsZXRlIHdvcmQsIHVuZG8sIGV0Yy4gU2VlIFtkb2NzL2tleWJpbmRpbmdzLm1kXShkb2NzL2tleWJpbmRpbmdzLm1kKS5cblxuIyMjIENvbW1hbmRzXG5cblR5cGUgYC9gIGluIHRoZSBlZGl0b3IgdG8gdHJpZ2dlciBjb21tYW5kcy4gW0V4dGVuc2lvbnNdKCNleHRlbnNpb25zKSBjYW4gcmVnaXN0ZXIgY3VzdG9tIGNvbW1hbmRzLCBbc2tpbGxzXSgjc2tpbGxzKSBhcmUgYXZhaWxhYmxlIGFzIGAvc2tpbGw6bmFtZWAsIGFuZCBbcHJvbXB0IHRlbXBsYXRlc10oI3Byb21wdC10ZW1wbGF0ZXMpIGV4cGFuZCB2aWEgYC90ZW1wbGF0ZW5hbWVgLlxuXG58IENvbW1hbmQgfCBEZXNjcmlwdGlvbiB8XG58LS0tLS0tLS0tfC0tLS0tLS0tLS0tLS18XG58IGAvbG9naW5gLCBgL2xvZ291dGAgfCBPQXV0aCBhdXRoZW50aWNhdGlvbiB8XG58IGAvbW9kZWxgIHwgU3dpdGNoIG1vZGVscyB8XG58IGAvc2NvcGVkLW1vZGVsc2AgfCBFbmFibGUvZGlzYWJsZSBtb2RlbHMgZm9yIEN0cmwrUCBjeWNsaW5nIHxcbnwgYC9zZXR0aW5nc2AgfCBUaGlua2luZyBsZXZlbCwgdGhlbWUsIG1lc3NhZ2UgZGVsaXZlcnksIHRyYW5zcG9ydCB8XG58IGAvcmVzdW1lYCB8IFBpY2sgZnJvbSBwcmV2aW91cyBzZXNzaW9ucyB8XG58IGAvbmV3YCB8IFN0YXJ0IGEgbmV3IHNlc3Npb24gfFxufCBgL25hbWUgPG5hbWU+YCB8IFNldCBzZXNzaW9uIGRpc3BsYXkgbmFtZSB8XG58IGAvc2Vzc2lvbmAgfCBTaG93IHNlc3Npb24gaW5mbyAoZmlsZSwgSUQsIG1lc3NhZ2VzLCB0b2tlbnMsIGNvc3QpIHxcbnwgYC90cmVlYCB8IEp1bXAgdG8gYW55IHBvaW50IGluIHRoZSBzZXNzaW9uIGFuZCBjb250aW51ZSBmcm9tIHRoZXJlIHxcbnwgYC90cnVzdGAgfCBTYXZlIHByb2plY3QgdHJ1c3QgZGVjaXNpb24gZm9yIGZ1dHVyZSBzZXNzaW9ucyAocmVzdGFydCByZXF1aXJlZCkgfFxufCBgL2ZvcmtgIHwgQ3JlYXRlIGEgbmV3IHNlc3Npb24gZnJvbSBhIHByZXZpb3VzIHVzZXIgbWVzc2FnZSB8XG58IGAvY2xvbmVgIHwgRHVwbGljYXRlIHRoZSBjdXJyZW50IGFjdGl2ZSBicmFuY2ggaW50byBhIG5ldyBzZXNzaW9uIHxcbnwgYC9jb21wYWN0IFtwcm9tcHRdYCB8IE1hbnVhbGx5IGNvbXBhY3QgY29udGV4dCwgb3B0aW9uYWwgY3VzdG9tIGluc3RydWN0aW9ucyB8XG58IGAvY29weWAgfCBDb3B5IGxhc3QgYXNzaXN0YW50IG1lc3NhZ2UgdG8gY2xpcGJvYXJkIHxcbnwgYC9leHBvcnQgW2ZpbGVdYCB8IEV4cG9ydCBzZXNzaW9uIHRvIEhUTUwgZmlsZSB8XG58IGAvc2hhcmVgIHwgVXBsb2FkIGFzIHByaXZhdGUgR2l0SHViIGdpc3Qgd2l0aCBzaGFyZWFibGUgSFRNTCBsaW5rIHxcbnwgYC9yZWxvYWRgIHwgUmVsb2FkIGtleWJpbmRpbmdzLCBleHRlbnNpb25zLCBza2lsbHMsIHByb21wdHMsIGFuZCBjb250ZXh0IGZpbGVzICh0aGVtZXMgaG90LXJlbG9hZCBhdXRvbWF0aWNhbGx5KSB8XG58IGAvaG90a2V5c2AgfCBTaG93IGFsbCBrZXlib2FyZCBzaG9ydGN1dHMgfFxufCBgL2NoYW5nZWxvZ2AgfCBEaXNwbGF5IHZlcnNpb24gaGlzdG9yeSB8XG58IGAvcXVpdGAgfCBRdWl0IHBpIHxcblxuIyMjIEtleWJvYXJkIFNob3J0Y3V0c1xuXG5TZWUgYC9ob3RrZXlzYCBmb3IgdGhlIGZ1bGwgbGlzdC4gQ3VzdG9taXplIHZpYSBgfi8ucGkvYWdlbnQva2V5YmluZGluZ3MuanNvbmAuIFNlZSBbZG9jcy9rZXliaW5kaW5ncy5tZF0oZG9jcy9rZXliaW5kaW5ncy5tZCkuXG5cbioqQ29tbW9ubHkgdXNlZDoqKlxuXG58IEtleSB8IEFjdGlvbiB8XG58LS0tLS18LS0tLS0tLS18XG58IEN0cmwrQyB8IENsZWFyIGVkaXRvciB8XG58IEN0cmwrQyB0d2ljZSB8IFF1aXQgfFxufCBFc2NhcGUgfCBDYW5jZWwvYWJvcnQgfFxufCBFc2NhcGUgdHdpY2UgfCBPcGVuIGAvdHJlZWAgfFxufCBDdHJsK0wgfCBPcGVuIG1vZGVsIHNlbGVjdG9yIHxcbnwgQ3RybCtQIC8gU2hpZnQrQ3RybCtQIHwgQ3ljbGUgc2NvcGVkIG1vZGVscyBmb3J3YXJkL2JhY2t3YXJkIHxcbnwgU2hpZnQrVGFiIHwgQ3ljbGUgdGhpbmtpbmcgbGV2ZWwgfFxufCBDdHJsK08gfCBDb2xsYXBzZS9leHBhbmQgdG9vbCBvdXRwdXQgfFxufCBDdHJsK1QgfCBDb2xsYXBzZS9leHBhbmQgdGhpbmtpbmcgYmxvY2tzIHxcblxuIyMjIE1lc3NhZ2UgUXVldWVcblxuU3VibWl0IG1lc3NhZ2VzIHdoaWxlIHRoZSBhZ2VudCBpcyB3b3JraW5nOlxuXG4tICoqRW50ZXIqKiBxdWV1ZXMgYSAqc3RlZXJpbmcqIG1lc3NhZ2UsIGRlbGl2ZXJlZCBhZnRlciB0aGUgY3VycmVudCBhc3Npc3RhbnQgdHVybiBmaW5pc2hlcyBleGVjdXRpbmcgaXRzIHRvb2wgY2FsbHNcbi0gKipBbHQrRW50ZXIqKiBxdWV1ZXMgYSAqZm9sbG93LXVwKiBtZXNzYWdlLCBkZWxpdmVyZWQgb25seSBhZnRlciB0aGUgYWdlbnQgZmluaXNoZXMgYWxsIHdvcmtcbi0gKipFc2NhcGUqKiBhYm9ydHMgYW5kIHJlc3RvcmVzIHF1ZXVlZCBtZXNzYWdlcyB0byBlZGl0b3Jcbi0gKipBbHQrVXAqKiByZXRyaWV2ZXMgcXVldWVkIG1lc3NhZ2VzIGJhY2sgdG8gZWRpdG9yXG5cbk9uIFdpbmRvd3MgVGVybWluYWwsIGBBbHQrRW50ZXJgIGlzIGZ1bGxzY3JlZW4gYnkgZGVmYXVsdC4gUmVtYXAgaXQgaW4gW2RvY3MvdGVybWluYWwtc2V0dXAubWRdKGRvY3MvdGVybWluYWwtc2V0dXAubWQpIHNvIHBpIGNhbiByZWNlaXZlIHRoZSBmb2xsb3ctdXAgc2hvcnRjdXQuXG5cbkNvbmZpZ3VyZSBkZWxpdmVyeSBpbiBbc2V0dGluZ3NdKGRvY3Mvc2V0dGluZ3MubWQpOiBgc3RlZXJpbmdNb2RlYCBhbmQgYGZvbGxvd1VwTW9kZWAgY2FuIGJlIGBcIm9uZS1hdC1hLXRpbWVcImAgKGRlZmF1bHQsIHdhaXRzIGZvciByZXNwb25zZSkgb3IgYFwiYWxsXCJgIChkZWxpdmVycyBhbGwgcXVldWVkIGF0IG9uY2UpLiBgdHJhbnNwb3J0YCBzZWxlY3RzIHByb3ZpZGVyIHRyYW5zcG9ydCBwcmVmZXJlbmNlIChgXCJzc2VcImAsIGBcIndlYnNvY2tldFwiYCwgb3IgYFwiYXV0b1wiYCkgZm9yIHByb3ZpZGVycyB0aGF0IHN1cHBvcnQgbXVsdGlwbGUgdHJhbnNwb3J0cy5cblxuLS0tXG5cbiMjIFNlc3Npb25zXG5cblNlc3Npb25zIGFyZSBzdG9yZWQgYXMgSlNPTkwgZmlsZXMgd2l0aCBhIHRyZWUgc3RydWN0dXJlLiBFYWNoIGVudHJ5IGhhcyBhbiBgaWRgIGFuZCBgcGFyZW50SWRgLCBlbmFibGluZyBpbi1wbGFjZSBicmFuY2hpbmcgd2l0aG91dCBjcmVhdGluZyBuZXcgZmlsZXMuIFNlZSBbZG9jcy9zZXNzaW9uLWZvcm1hdC5tZF0oZG9jcy9zZXNzaW9uLWZvcm1hdC5tZCkgZm9yIGZpbGUgZm9ybWF0LlxuXG4jIyMgTWFuYWdlbWVudFxuXG5TZXNzaW9ucyBhdXRvLXNhdmUgdG8gYH4vLnBpL2FnZW50L3Nlc3Npb25zL2Agb3JnYW5pemVkIGJ5IHdvcmtpbmcgZGlyZWN0b3J5LlxuXG5gYGBiYXNoXG5waSAtYyAgICAgICAgICAgICAgICAgICMgQ29udGludWUgbW9zdCByZWNlbnQgc2Vzc2lvblxucGkgLXIgICAgICAgICAgICAgICAgICAjIEJyb3dzZSBhbmQgc2VsZWN0IGZyb20gcGFzdCBzZXNzaW9uc1xucGkgLS1uby1zZXNzaW9uICAgICAgICAjIEVwaGVtZXJhbCBtb2RlIChkb24ndCBzYXZlKVxucGkgLS1uYW1lIFwibXkgdGFza1wiICAgICMgU2V0IHNlc3Npb24gZGlzcGxheSBuYW1lIGF0IHN0YXJ0dXBcbnBpIC0tc2Vzc2lvbiA8cGF0aHxpZD4gIyBVc2Ugc3BlY2lmaWMgc2Vzc2lvbiBmaWxlIG9yIElEXG5waSAtLWZvcmsgPHBhdGh8aWQ+ICAgICMgRm9yayBzcGVjaWZpYyBzZXNzaW9uIGZpbGUgb3IgSUQgaW50byBhIG5ldyBzZXNzaW9uXG5gYGBcblxuVXNlIGAvc2Vzc2lvbmAgaW4gaW50ZXJhY3RpdmUgbW9kZSB0byBzZWUgdGhlIGN1cnJlbnQgc2Vzc2lvbiBJRCBiZWZvcmUgcmV1c2luZyBpdCB3aXRoIGAtLXNlc3Npb24gPGlkPmAgb3IgYC0tZm9yayA8aWQ+YC5cblxuIyMjIEJyYW5jaGluZ1xuXG4qKmAvdHJlZWAqKiAtIE5hdmlnYXRlIHRoZSBzZXNzaW9uIHRyZWUgaW4tcGxhY2UuIFNlbGVjdCBhbnkgcHJldmlvdXMgcG9pbnQsIGNvbnRpbnVlIGZyb20gdGhlcmUsIGFuZCBzd2l0Y2ggYmV0d2VlbiBicmFuY2hlcy4gQWxsIGhpc3RvcnkgcHJlc2VydmVkIGluIGEgc2luZ2xlIGZpbGUuXG5cbjxwIGFsaWduPVwiY2VudGVyXCI+PGltZyBzcmM9XCJkb2NzL2ltYWdlcy90cmVlLXZpZXcucG5nXCIgYWx0PVwiVHJlZSBWaWV3XCIgd2lkdGg9XCI2MDBcIj48L3A+XG5cbi0gU2VhcmNoIGJ5IHR5cGluZywgZm9sZC91bmZvbGQgYW5kIGp1bXAgYmV0d2VlbiBicmFuY2hlcyB3aXRoIEN0cmwr4oaQL0N0cmwr4oaSIG9yIEFsdCvihpAvQWx0K+KGkiwgcGFnZSB3aXRoIOKGkC/ihpJcbi0gRmlsdGVyIG1vZGVzIChDdHJsK08pOiBkZWZhdWx0IOKGkiBuby10b29scyDihpIgdXNlci1vbmx5IOKGkiBsYWJlbGVkLW9ubHkg4oaSIGFsbFxuLSBQcmVzcyBTaGlmdCtMIHRvIGxhYmVsIGVudHJpZXMgYXMgYm9va21hcmtzIGFuZCBTaGlmdCtUIHRvIHRvZ2dsZSBsYWJlbCB0aW1lc3RhbXBzXG5cbioqYC9mb3JrYCoqIC0gQ3JlYXRlIGEgbmV3IHNlc3Npb24gZmlsZSBmcm9tIGEgcHJldmlvdXMgdXNlciBtZXNzYWdlIG9uIHRoZSBhY3RpdmUgYnJhbmNoLiBPcGVucyBhIHNlbGVjdG9yLCBjb3BpZXMgdGhlIGFjdGl2ZSBwYXRoIHVwIHRvIHRoYXQgcG9pbnQsIGFuZCBwbGFjZXMgdGhlIHNlbGVjdGVkIHByb21wdCBpbiB0aGUgZWRpdG9yIGZvciBtb2RpZmljYXRpb24uXG5cbioqYC9jbG9uZWAqKiAtIER1cGxpY2F0ZSB0aGUgY3VycmVudCBhY3RpdmUgYnJhbmNoIGludG8gYSBuZXcgc2Vzc2lvbiBmaWxlIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBUaGUgbmV3IHNlc3Npb24ga2VlcHMgdGhlIGZ1bGwgYWN0aXZlLXBhdGggaGlzdG9yeSBhbmQgb3BlbnMgd2l0aCBhbiBlbXB0eSBlZGl0b3IuXG5cbioqYC0tZm9yayA8cGF0aHxpZD5gKiogLSBGb3JrIGFuIGV4aXN0aW5nIHNlc3Npb24gZmlsZSBvciBwYXJ0aWFsIHNlc3Npb24gVVVJRCBkaXJlY3RseSBmcm9tIHRoZSBDTEkuIFRoaXMgY29waWVzIHRoZSBmdWxsIHNvdXJjZSBzZXNzaW9uIGludG8gYSBuZXcgc2Vzc2lvbiBmaWxlIGluIHRoZSBjdXJyZW50IHByb2plY3QuXG5cbiMjIyBDb21wYWN0aW9uXG5cbkxvbmcgc2Vzc2lvbnMgY2FuIGV4aGF1c3QgY29udGV4dCB3aW5kb3dzLiBDb21wYWN0aW9uIHN1bW1hcml6ZXMgb2xkZXIgbWVzc2FnZXMgd2hpbGUga2VlcGluZyByZWNlbnQgb25lcy5cblxuKipNYW51YWw6KiogYC9jb21wYWN0YCBvciBgL2NvbXBhY3QgPGN1c3RvbSBpbnN0cnVjdGlvbnM+YFxuXG4qKkF1dG9tYXRpYzoqKiBFbmFibGVkIGJ5IGRlZmF1bHQuIFRyaWdnZXJzIG9uIGNvbnRleHQgb3ZlcmZsb3cgKHJlY292ZXJzIGFuZCByZXRyaWVzKSBvciB3aGVuIGFwcHJvYWNoaW5nIHRoZSBsaW1pdCAocHJvYWN0aXZlKS4gQ29uZmlndXJlIHZpYSBgL3NldHRpbmdzYCBvciBgc2V0dGluZ3MuanNvbmAuXG5cbkNvbXBhY3Rpb24gaXMgbG9zc3kuIFRoZSBmdWxsIGhpc3RvcnkgcmVtYWlucyBpbiB0aGUgSlNPTkwgZmlsZTsgdXNlIGAvdHJlZWAgdG8gcmV2aXNpdC4gQ3VzdG9taXplIGNvbXBhY3Rpb24gYmVoYXZpb3IgdmlhIFtleHRlbnNpb25zXSgjZXh0ZW5zaW9ucykuIFNlZSBbZG9jcy9jb21wYWN0aW9uLm1kXShkb2NzL2NvbXBhY3Rpb24ubWQpIGZvciBpbnRlcm5hbHMuXG5cbi0tLVxuXG4jIyBTZXR0aW5nc1xuXG5Vc2UgYC9zZXR0aW5nc2AgdG8gbW9kaWZ5IGNvbW1vbiBvcHRpb25zLCBvciBlZGl0IEpTT04gZmlsZXMgZGlyZWN0bHk6XG5cbnwgTG9jYXRpb24gfCBTY29wZSB8XG58LS0tLS0tLS0tLXwtLS0tLS0tfFxufCBgfi8ucGkvYWdlbnQvc2V0dGluZ3MuanNvbmAgfCBHbG9iYWwgKGFsbCBwcm9qZWN0cykgfFxufCBgLnBpL3NldHRpbmdzLmpzb25gIHwgUHJvamVjdCAob3ZlcnJpZGVzIGdsb2JhbCkgfFxuXG5TZWUgW2RvY3Mvc2V0dGluZ3MubWRdKGRvY3Mvc2V0dGluZ3MubWQpIGZvciBhbGwgb3B0aW9ucy5cblxuIyMjIFByb2plY3QgVHJ1c3RcblxuT24gaW50ZXJhY3RpdmUgc3RhcnR1cCwgcGkgYXNrcyBiZWZvcmUgdHJ1c3RpbmcgYSBwcm9qZWN0IGZvbGRlciB0aGF0IGNvbnRhaW5zIHByb2plY3QtbG9jYWwgc2V0dGluZ3MsIHJlc291cmNlcywgb3IgcHJvamVjdCBgLmFnZW50cy9za2lsbHNgIGFuZCBoYXMgbm8gc2F2ZWQgZGVjaXNpb24gZm9yIHRoZSBmb2xkZXIgb3IgYSBwYXJlbnQgZm9sZGVyIGluIGB+Ly5waS9hZ2VudC90cnVzdC5qc29uYC4gVHJ1c3RpbmcgYSBwcm9qZWN0IGFsbG93cyBwaSB0byBsb2FkIGAucGkvc2V0dGluZ3MuanNvbmAgYW5kIGAucGlgIHJlc291cmNlcywgaW5zdGFsbCBtaXNzaW5nIHByb2plY3QgcGFja2FnZXMsIGFuZCBleGVjdXRlIHByb2plY3QgZXh0ZW5zaW9ucy5cblxuQmVmb3JlIHRoZSB0cnVzdCBkZWNpc2lvbiwgcGkgbG9hZHMgb25seSBjb250ZXh0IGZpbGVzLCB1c2VyL2dsb2JhbCBleHRlbnNpb25zLCBhbmQgQ0xJIGAtZWAgZXh0ZW5zaW9ucyBzbyB0aGV5IGNhbiBoYW5kbGUgdGhlIGBwcm9qZWN0X3RydXN0YCBldmVudC4gUHJvamVjdC1sb2NhbCBleHRlbnNpb25zLCBwcm9qZWN0IHBhY2thZ2UtbWFuYWdlZCBleHRlbnNpb25zLCBhbmQgcHJvamVjdCBzZXR0aW5ncyBhcmUgbG9hZGVkIG9ubHkgYWZ0ZXIgdGhlIHByb2plY3QgaXMgdHJ1c3RlZC4gVGhpcyBzcGxpdCBhbHNvIGFwcGxpZXMgd2hlbiBzd2l0Y2hpbmcgdG8gYSBzZXNzaW9uIGZyb20gYSBkaWZmZXJlbnQgY3dkIHdob3NlIHRydXN0IGhhcyBub3QgYmVlbiByZXNvbHZlZCBpbiB0aGUgY3VycmVudCBwcm9jZXNzLlxuXG5Ob24taW50ZXJhY3RpdmUgbW9kZXMgKGAtcGAsIGAtLW1vZGUganNvbmAsIGFuZCBgLS1tb2RlIHJwY2ApIGRvIG5vdCBzaG93IGEgdHJ1c3QgcHJvbXB0LiBXaXRob3V0IGFuIGFwcGxpY2FibGUgc2F2ZWQgdHJ1c3QgZGVjaXNpb24sIHRoZXkgdXNlIGBkZWZhdWx0UHJvamVjdFRydXN0YCBmcm9tIGdsb2JhbCBzZXR0aW5nczogYGFza2AgKGRlZmF1bHQpIGFuZCBgbmV2ZXJgIGlnbm9yZSB0aG9zZSBwcm9qZWN0IHJlc291cmNlcywgd2hpbGUgYGFsd2F5c2AgdHJ1c3RzIHRoZW0uIFBhc3MgYC0tYXBwcm92ZWAvYC1hYCBvciBgLS1uby1hcHByb3ZlYC9gLW5hYCB0byBvdmVycmlkZSBwcm9qZWN0IHRydXN0IGZvciBvbmUgcnVuLlxuXG5JZiBubyBleHRlbnNpb24gb3Igc2F2ZWQgZGVjaXNpb24gYXBwbGllcywgYGRlZmF1bHRQcm9qZWN0VHJ1c3RgIGNvbnRyb2xzIHRoZSBmYWxsYmFjayBiZWhhdmlvci4gU2V0IGl0IHRvIGBcImFza1wiYCwgYFwiYWx3YXlzXCJgLCBvciBgXCJuZXZlclwiYCBpbiBgfi8ucGkvYWdlbnQvc2V0dGluZ3MuanNvbmAsIG9yIGNoYW5nZSBpdCB3aXRoIGAvc2V0dGluZ3NgLlxuXG5gcGkgY29uZmlnYCBhbmQgcGFja2FnZSBjb21tYW5kcyB1c2UgdGhlIHNhbWUgcHJvamVjdCB0cnVzdCBmbG93LCBleGNlcHQgYHBpIHVwZGF0ZWAgbmV2ZXIgcHJvbXB0cy4gUGFzcyBgLS1hcHByb3ZlYCB0byB0cnVzdCBwcm9qZWN0LWxvY2FsIHNldHRpbmdzIGZvciBvbmUgY29tbWFuZCBvciBgLS1uby1hcHByb3ZlYCB0byBpZ25vcmUgdGhlbS5cblxuVXNlIGAvdHJ1c3RgIGluIGludGVyYWN0aXZlIG1vZGUgdG8gc2F2ZSBhIHByb2plY3QgdHJ1c3QgZGVjaXNpb24gZm9yIGZ1dHVyZSBzZXNzaW9ucywgaW5jbHVkaW5nIHRydXN0IGZvciB0aGUgaW1tZWRpYXRlIHBhcmVudCBmb2xkZXIuIEl0IHdyaXRlcyBgfi8ucGkvYWdlbnQvdHJ1c3QuanNvbmAgb25seTsgdGhlIGN1cnJlbnQgc2Vzc2lvbiBpcyBub3QgcmVsb2FkZWQsIHNvIHJlc3RhcnQgcGkgZm9yIGNoYW5nZXMgdG8gdGFrZSBlZmZlY3QuXG5cbiMjIyBUZWxlbWV0cnkgYW5kIHVwZGF0ZSBjaGVja3NcblxuUGkgaGFzIHR3byBzZXBhcmF0ZSBzdGFydHVwIGZlYXR1cmVzOlxuXG4tICoqVXBkYXRlIGNoZWNrOioqIGZldGNoZXMgYGh0dHBzOi8vcGkuZGV2L2FwaS9sYXRlc3QtdmVyc2lvbmAgdG8gY2hlY2sgd2hldGhlciBhIG5ld2VyIFBpIHZlcnNpb24gZXhpc3RzLiBEaXNhYmxlIGl0IHdpdGggYFBJX1NLSVBfVkVSU0lPTl9DSEVDSz0xYC4gRGlzYWJsaW5nIHVwZGF0ZSBjaGVja3Mgb25seSB0dXJucyBvZmYgdGhpcyBjaGVjay5cbi0gKipJbnN0YWxsL3VwZGF0ZSB0ZWxlbWV0cnk6KiogYWZ0ZXIgZmlyc3QgaW5zdGFsbCBvciBhIGNoYW5nZWxvZy1kZXRlY3RlZCB1cGRhdGUsIHNlbmRzIGFuIGFub255bW91cyB2ZXJzaW9uIHBpbmcgdG8gYGh0dHBzOi8vcGkuZGV2L2FwaS9yZXBvcnQtaW5zdGFsbGAuIFRoaXMgc2V0dGluZyBhbHNvIGNvbnRyb2xzIG9wdGlvbmFsIHByb3ZpZGVyIGF0dHJpYnV0aW9uIGhlYWRlcnMgZm9yIE9wZW5Sb3V0ZXIsIENsb3VkZmxhcmUsIGFuZCBkaXJlY3QgTlZJRElBIE5JTSByZXF1ZXN0cy4gT3B0IG91dCBieSBzZXR0aW5nIGBlbmFibGVJbnN0YWxsVGVsZW1ldHJ5YCB0byBgZmFsc2VgIGluIGBzZXR0aW5ncy5qc29uYCwgb3IgYnkgc2V0dGluZyBgUElfVEVMRU1FVFJZPTBgLiBUaGlzIGRvZXMgbm90IGRpc2FibGUgdXBkYXRlIGNoZWNrczsgUGkgbWF5IHN0aWxsIGNvbnRhY3QgYHBpLmRldmAgZm9yIHRoZSBsYXRlc3QgdmVyc2lvbiB1bmxlc3MgdXBkYXRlIGNoZWNrcyBhcmUgZGlzYWJsZWQgb3Igb2ZmbGluZSBtb2RlIGlzIGVuYWJsZWQuXG5cblVzZSBgLS1vZmZsaW5lYCBvciBgUElfT0ZGTElORT0xYCB0byBkaXNhYmxlIGFsbCBzdGFydHVwIG5ldHdvcmsgb3BlcmF0aW9ucyBkZXNjcmliZWQgaGVyZSwgaW5jbHVkaW5nIHVwZGF0ZSBjaGVja3MsIHBhY2thZ2UgdXBkYXRlIGNoZWNrcywgYW5kIGluc3RhbGwvdXBkYXRlIHRlbGVtZXRyeS5cblxuLS0tXG5cbiMjIENvbnRleHQgRmlsZXNcblxuUGkgbG9hZHMgYEFHRU5UUy5tZGAgKG9yIGBDTEFVREUubWRgKSBhdCBzdGFydHVwIGZyb206XG4tIGB+Ly5waS9hZ2VudC9BR0VOVFMubWRgIChnbG9iYWwpXG4tIFBhcmVudCBkaXJlY3RvcmllcyAod2Fsa2luZyB1cCBmcm9tIGN3ZClcbi0gQ3VycmVudCBkaXJlY3RvcnlcblxuVXNlIGZvciBwcm9qZWN0IGluc3RydWN0aW9ucyAoYEFHRU5UUy5tZGAvYENMQVVERS5tZGApLCBjb252ZW50aW9ucywgY29tbW9uIGNvbW1hbmRzLiBBbGwgbWF0Y2hpbmcgZmlsZXMgYXJlIGNvbmNhdGVuYXRlZC5cblxuRGlzYWJsZSBjb250ZXh0IGZpbGUgbG9hZGluZyB3aXRoIGAtLW5vLWNvbnRleHQtZmlsZXNgIChvciBgLW5jYCkuXG5cbiMjIyBTeXN0ZW0gUHJvbXB0XG5cblJlcGxhY2UgdGhlIGRlZmF1bHQgc3lzdGVtIHByb21wdCB3aXRoIGAucGkvU1lTVEVNLm1kYCAocHJvamVjdCkgb3IgYH4vLnBpL2FnZW50L1NZU1RFTS5tZGAgKGdsb2JhbCkuIEFwcGVuZCB3aXRob3V0IHJlcGxhY2luZyB2aWEgYEFQUEVORF9TWVNURU0ubWRgLlxuXG4tLS1cblxuIyMgQ3VzdG9taXphdGlvblxuXG4jIyMgUHJvbXB0IFRlbXBsYXRlc1xuXG5SZXVzYWJsZSBwcm9tcHRzIGFzIE1hcmtkb3duIGZpbGVzLiBUeXBlIGAvbmFtZWAgdG8gZXhwYW5kLlxuXG5gYGBtYXJrZG93blxuPCEtLSB+Ly5waS9hZ2VudC9wcm9tcHRzL3Jldmlldy5tZCAtLT5cblJldmlldyB0aGlzIGNvZGUgZm9yIGJ1Z3MsIHNlY3VyaXR5IGlzc3VlcywgYW5kIHBlcmZvcm1hbmNlIHByb2JsZW1zLlxuRm9jdXMgb246IHt7Zm9jdXN9fVxuYGBgXG5cblBsYWNlIGluIGB+Ly5waS9hZ2VudC9wcm9tcHRzL2AsIGAucGkvcHJvbXB0cy9gLCBvciBhIFtwaSBwYWNrYWdlXSgjcGktcGFja2FnZXMpIHRvIHNoYXJlIHdpdGggb3RoZXJzLiBTZWUgW2RvY3MvcHJvbXB0LXRlbXBsYXRlcy5tZF0oZG9jcy9wcm9tcHQtdGVtcGxhdGVzLm1kKS5cblxuIyMjIFNraWxsc1xuXG5Pbi1kZW1hbmQgY2FwYWJpbGl0eSBwYWNrYWdlcyBmb2xsb3dpbmcgdGhlIFtBZ2VudCBTa2lsbHMgc3RhbmRhcmRdKGh0dHBzOi8vYWdlbnRza2lsbHMuaW8pLiBJbnZva2UgdmlhIGAvc2tpbGw6bmFtZWAgb3IgbGV0IHRoZSBhZ2VudCBsb2FkIHRoZW0gYXV0b21hdGljYWxseS5cblxuYGBgbWFya2Rvd25cbjwhLS0gfi8ucGkvYWdlbnQvc2tpbGxzL215LXNraWxsL1NLSUxMLm1kIC0tPlxuIyBNeSBTa2lsbFxuVXNlIHRoaXMgc2tpbGwgd2hlbiB0aGUgdXNlciBhc2tzIGFib3V0IFguXG5cbiMjIFN0ZXBzXG4xLiBEbyB0aGlzXG4yLiBUaGVuIHRoYXRcbmBgYFxuXG5QbGFjZSBpbiBgfi8ucGkvYWdlbnQvc2tpbGxzL2AsIGB+Ly5hZ2VudHMvc2tpbGxzL2AsIGAucGkvc2tpbGxzL2AsIG9yIGAuYWdlbnRzL3NraWxscy9gIChmcm9tIGBjd2RgIHVwIHRocm91Z2ggcGFyZW50IGRpcmVjdG9yaWVzKSBvciBhIFtwaSBwYWNrYWdlXSgjcGktcGFja2FnZXMpIHRvIHNoYXJlIHdpdGggb3RoZXJzLiBTZWUgW2RvY3Mvc2tpbGxzLm1kXShkb2NzL3NraWxscy5tZCkuXG5cbiMjIyBFeHRlbnNpb25zXG5cbjxwIGFsaWduPVwiY2VudGVyXCI+PGltZyBzcmM9XCJkb2NzL2ltYWdlcy9kb29tLWV4dGVuc2lvbi5wbmdcIiBhbHQ9XCJEb29tIEV4dGVuc2lvblwiIHdpZHRoPVwiNjAwXCI+PC9wPlxuXG5UeXBlU2NyaXB0IG1vZHVsZXMgdGhhdCBleHRlbmQgcGkgd2l0aCBjdXN0b20gdG9vbHMsIGNvbW1hbmRzLCBrZXlib2FyZCBzaG9ydGN1dHMsIGV2ZW50IGhhbmRsZXJzLCBhbmQgVUkgY29tcG9uZW50cy5cblxuYGBgdHlwZXNjcmlwdFxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBpOiBFeHRlbnNpb25BUEkpIHtcbiAgcGkucmVnaXN0ZXJUb29sKHsgbmFtZTogXCJkZXBsb3lcIiwgLi4uIH0pO1xuICBwaS5yZWdpc3RlckNvbW1hbmQoXCJzdGF0c1wiLCB7IC4uLiB9KTtcbiAgcGkub24oXCJ0b29sX2NhbGxcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHsgLi4uIH0pO1xufVxuYGBgXG5cblRoZSBkZWZhdWx0IGV4cG9ydCBjYW4gYWxzbyBiZSBgYXN5bmNgLiBwaSB3YWl0cyBmb3IgYXN5bmMgZXh0ZW5zaW9uIGZhY3RvcmllcyBiZWZvcmUgc3RhcnR1cCBjb250aW51ZXMsIHdoaWNoIGlzIHVzZWZ1bCBmb3Igb25lLXRpbWUgaW5pdGlhbGl6YXRpb24gc3VjaCBhcyBmZXRjaGluZyByZW1vdGUgbW9kZWwgbGlzdHMgYmVmb3JlIGNhbGxpbmcgYHBpLnJlZ2lzdGVyUHJvdmlkZXIoKWAuXG5cbioqV2hhdCdzIHBvc3NpYmxlOioqXG4tIEN1c3RvbSB0b29scyAob3IgcmVwbGFjZSBidWlsdC1pbiB0b29scyBlbnRpcmVseSlcbi0gU3ViLWFnZW50cyBhbmQgcGxhbiBtb2RlXG4tIEN1c3RvbSBjb21wYWN0aW9uIGFuZCBzdW1tYXJpemF0aW9uXG4tIFBlcm1pc3Npb24gZ2F0ZXMgYW5kIHBhdGggcHJvdGVjdGlvblxuLSBDdXN0b20gZWRpdG9ycyBhbmQgVUkgY29tcG9uZW50c1xuLSBTdGF0dXMgbGluZXMsIGhlYWRlcnMsIGZvb3RlcnNcbi0gR2l0IGNoZWNrcG9pbnRpbmcgYW5kIGF1dG8tY29tbWl0XG4tIFNTSCBhbmQgc2FuZGJveCBleGVjdXRpb25cbi0gTUNQIHNlcnZlciBpbnRlZ3JhdGlvblxuLSBNYWtlIHBpIGxvb2sgbGlrZSBDbGF1ZGUgQ29kZVxuLSBHYW1lcyB3aGlsZSB3YWl0aW5nICh5ZXMsIERvb20gcnVucylcbi0gLi4uYW55dGhpbmcgeW91IGNhbiBkcmVhbSB1cFxuXG5QbGFjZSBpbiBgfi8ucGkvYWdlbnQvZXh0ZW5zaW9ucy9gLCBgLnBpL2V4dGVuc2lvbnMvYCwgb3IgYSBbcGkgcGFja2FnZV0oI3BpLXBhY2thZ2VzKSB0byBzaGFyZSB3aXRoIG90aGVycy4gU2VlIFtkb2NzL2V4dGVuc2lvbnMubWRdKGRvY3MvZXh0ZW5zaW9ucy5tZCkgYW5kIFtleGFtcGxlcy9leHRlbnNpb25zL10oZXhhbXBsZXMvZXh0ZW5zaW9ucy8pLlxuXG4jIyMgVGhlbWVzXG5cbkJ1aWx0LWluOiBgZGFya2AsIGBsaWdodGAuIFRoZW1lcyBob3QtcmVsb2FkOiBtb2RpZnkgdGhlIGFjdGl2ZSB0aGVtZSBmaWxlIGFuZCBwaSBpbW1lZGlhdGVseSBhcHBsaWVzIGNoYW5nZXMuXG5cblBsYWNlIGluIGB+Ly5waS9hZ2VudC90aGVtZXMvYCwgYC5waS90aGVtZXMvYCwgb3IgYSBbcGkgcGFja2FnZV0oI3BpLXBhY2thZ2VzKSB0byBzaGFyZSB3aXRoIG90aGVycy4gU2VlIFtkb2NzL3RoZW1lcy5tZF0oZG9jcy90aGVtZXMubWQpLlxuXG4jIyMgUGkgUGFja2FnZXNcblxuQnVuZGxlIGFuZCBzaGFyZSBleHRlbnNpb25zLCBza2lsbHMsIHByb21wdHMsIGFuZCB0aGVtZXMgdmlhIG5wbSBvciBnaXQuIEZpbmQgcGFja2FnZXMgb24gW25wbWpzLmNvbV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3NlYXJjaD9xPWtleXdvcmRzJTNBcGktcGFja2FnZSkgb3IgW0Rpc2NvcmRdKGh0dHBzOi8vZGlzY29yZC5jb20vY2hhbm5lbHMvMTQ1NjgwNjM2MjM1MTY2OTQ5Mi8xNDU3NzQ0NDg1NDI4NjI5NjI4KS5cblxuPiAqKlNlY3VyaXR5OioqIFBpIHBhY2thZ2VzIHJ1biB3aXRoIGZ1bGwgc3lzdGVtIGFjY2Vzcy4gRXh0ZW5zaW9ucyBleGVjdXRlIGFyYml0cmFyeSBjb2RlLCBhbmQgc2tpbGxzIGNhbiBpbnN0cnVjdCB0aGUgbW9kZWwgdG8gcGVyZm9ybSBhbnkgYWN0aW9uIGluY2x1ZGluZyBydW5uaW5nIGV4ZWN1dGFibGVzLiBSZXZpZXcgc291cmNlIGNvZGUgYmVmb3JlIGluc3RhbGxpbmcgdGhpcmQtcGFydHkgcGFja2FnZXMuXG5cbmBgYGJhc2hcbnBpIGluc3RhbGwgbnBtOkBmb28vcGktdG9vbHNcbnBpIGluc3RhbGwgbnBtOkBmb28vcGktdG9vbHNAMS4yLjMgICAgICAjIHBpbm5lZCB2ZXJzaW9uXG5waSBpbnN0YWxsIGdpdDpnaXRodWIuY29tL3VzZXIvcmVwb1xucGkgaW5zdGFsbCBnaXQ6Z2l0aHViLmNvbS91c2VyL3JlcG9AdjEgICMgdGFnIG9yIGNvbW1pdFxucGkgaW5zdGFsbCBnaXQ6Z2l0QGdpdGh1Yi5jb206dXNlci9yZXBvXG5waSBpbnN0YWxsIGdpdDpnaXRAZ2l0aHViLmNvbTp1c2VyL3JlcG9AdjEgICMgdGFnIG9yIGNvbW1pdFxucGkgaW5zdGFsbCBodHRwczovL2dpdGh1Yi5jb20vdXNlci9yZXBvXG5waSBpbnN0YWxsIGh0dHBzOi8vZ2l0aHViLmNvbS91c2VyL3JlcG9AdjEgICAgICAjIHRhZyBvciBjb21taXRcbnBpIGluc3RhbGwgc3NoOi8vZ2l0QGdpdGh1Yi5jb20vdXNlci9yZXBvXG5waSBpbnN0YWxsIHNzaDovL2dpdEBnaXRodWIuY29tL3VzZXIvcmVwb0B2MSAgICAjIHRhZyBvciBjb21taXRcbnBpIHJlbW92ZSBucG06QGZvby9waS10b29sc1xucGkgdW5pbnN0YWxsIG5wbTpAZm9vL3BpLXRvb2xzICAgICAgICAgICMgYWxpYXMgZm9yIHJlbW92ZVxucGkgbGlzdFxucGkgdXBkYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdXBkYXRlIHBpIG9ubHlcbnBpIHVwZGF0ZSAtLWFsbCAgICAgICAgICAgICAgICAgICAgICAgICAjIHVwZGF0ZSBwaSBhbmQgcGFja2FnZXNcbnBpIHVwZGF0ZSAtLWV4dGVuc2lvbnMgICAgICAgICAgICAgICAgICAjIHVwZGF0ZSBwYWNrYWdlcyBvbmx5XG5waSB1cGRhdGUgLS1zZWxmICAgICAgICAgICAgICAgICAgICAgICAgIyB1cGRhdGUgcGkgb25seVxucGkgdXBkYXRlIC0tc2VsZiAtLWZvcmNlICAgICAgICAgICAgICAgICMgcmVpbnN0YWxsIHBpIGV2ZW4gaWYgY3VycmVudFxucGkgdXBkYXRlIG5wbTpAZm9vL3BpLXRvb2xzICAgICAgICAgICAgICMgdXBkYXRlIG9uZSBwYWNrYWdlXG5waSBjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBlbmFibGUvZGlzYWJsZSBleHRlbnNpb25zLCBza2lsbHMsIHByb21wdHMsIHRoZW1lc1xuYGBgXG5cblBhY2thZ2VzIGluc3RhbGwgdG8gYH4vLnBpL2FnZW50L2dpdC9gIChnaXQpIG9yIGB+Ly5waS9hZ2VudC9ucG0vYCAobnBtKS4gVXNlIGAtbGAgZm9yIHByb2plY3QtbG9jYWwgaW5zdGFsbHMgKGAucGkvZ2l0L2AsIGAucGkvbnBtL2ApLiBHaXQgYEByZWZgIHZhbHVlcyBhcmUgcGlubmVkIHRhZ3Mgb3IgY29tbWl0czsgcGlubmVkIHBhY2thZ2VzIGFyZSBza2lwcGVkIGJ5IGBwaSB1cGRhdGUgLS1leHRlbnNpb25zYCBhbmQgYHBpIHVwZGF0ZSAtLWFsbGAsIHNvIHVzZSBgcGkgaW5zdGFsbCBnaXQ6aG9zdC91c2VyL3JlcG9AbmV3LXJlZmAgdG8gbW92ZSBhbiBleGlzdGluZyBwYWNrYWdlIHRvIGEgbmV3IHJlZi4gR2l0IHBhY2thZ2VzIGluc3RhbGwgZGVwZW5kZW5jaWVzIHdpdGggYG5wbSBpbnN0YWxsIC0tb21pdD1kZXZgIGJ5IGRlZmF1bHQsIHNvIHJ1bnRpbWUgZGVwcyBtdXN0IGJlIGxpc3RlZCB1bmRlciBgZGVwZW5kZW5jaWVzYDsgd2hlbiBgbnBtQ29tbWFuZGAgaXMgY29uZmlndXJlZCwgZ2l0IHBhY2thZ2VzIHVzZSBwbGFpbiBgaW5zdGFsbGAgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCB3cmFwcGVycy4gSWYgeW91IHVzZSBhIE5vZGUgdmVyc2lvbiBtYW5hZ2VyIGFuZCB3YW50IHBhY2thZ2UgaW5zdGFsbHMgdG8gcmV1c2UgYSBzdGFibGUgbnBtIGNvbnRleHQsIHNldCBgbnBtQ29tbWFuZGAgaW4gYHNldHRpbmdzLmpzb25gLCBmb3IgZXhhbXBsZSBgW1wibWlzZVwiLCBcImV4ZWNcIiwgXCJub2RlQDIwXCIsIFwiLS1cIiwgXCJucG1cIl1gLlxuXG5DcmVhdGUgYSBwYWNrYWdlIGJ5IGFkZGluZyBhIGBwaWAga2V5IHRvIGBwYWNrYWdlLmpzb25gOlxuXG5gYGBqc29uXG57XG4gIFwibmFtZVwiOiBcIm15LXBpLXBhY2thZ2VcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXCJwaS1wYWNrYWdlXCJdLFxuICBcInBpXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1wiLi9leHRlbnNpb25zXCJdLFxuICAgIFwic2tpbGxzXCI6IFtcIi4vc2tpbGxzXCJdLFxuICAgIFwicHJvbXB0c1wiOiBbXCIuL3Byb21wdHNcIl0sXG4gICAgXCJ0aGVtZXNcIjogW1wiLi90aGVtZXNcIl1cbiAgfVxufVxuYGBgXG5cbldpdGhvdXQgYSBgcGlgIG1hbmlmZXN0LCBwaSBhdXRvLWRpc2NvdmVycyBmcm9tIGNvbnZlbnRpb25hbCBkaXJlY3RvcmllcyAoYGV4dGVuc2lvbnMvYCwgYHNraWxscy9gLCBgcHJvbXB0cy9gLCBgdGhlbWVzL2ApLlxuXG5TZWUgW2RvY3MvcGFja2FnZXMubWRdKGRvY3MvcGFja2FnZXMubWQpLlxuXG4tLS1cblxuIyMgUHJvZ3JhbW1hdGljIFVzYWdlXG5cbiMjIyBTREtcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgQXV0aFN0b3JhZ2UsIGNyZWF0ZUFnZW50U2Vzc2lvbiwgTW9kZWxSZWdpc3RyeSwgU2Vzc2lvbk1hbmFnZXIgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG5jb25zdCBhdXRoU3RvcmFnZSA9IEF1dGhTdG9yYWdlLmNyZWF0ZSgpO1xuY29uc3QgbW9kZWxSZWdpc3RyeSA9IE1vZGVsUmVnaXN0cnkuY3JlYXRlKGF1dGhTdG9yYWdlKTtcbmNvbnN0IHsgc2Vzc2lvbiB9ID0gYXdhaXQgY3JlYXRlQWdlbnRTZXNzaW9uKHtcbiAgc2Vzc2lvbk1hbmFnZXI6IFNlc3Npb25NYW5hZ2VyLmluTWVtb3J5KCksXG4gIGF1dGhTdG9yYWdlLFxuICBtb2RlbFJlZ2lzdHJ5LFxufSk7XG5cbmF3YWl0IHNlc3Npb24ucHJvbXB0KFwiV2hhdCBmaWxlcyBhcmUgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5P1wiKTtcbmBgYFxuXG5Gb3IgYWR2YW5jZWQgbXVsdGktc2Vzc2lvbiBydW50aW1lIHJlcGxhY2VtZW50LCB1c2UgYGNyZWF0ZUFnZW50U2Vzc2lvblJ1bnRpbWUoKWAgYW5kIGBBZ2VudFNlc3Npb25SdW50aW1lYC5cblxuU2VlIFtkb2NzL3Nkay5tZF0oZG9jcy9zZGsubWQpIGFuZCBbZXhhbXBsZXMvc2RrL10oZXhhbXBsZXMvc2RrLykuXG5cbiMjIyBSUEMgTW9kZVxuXG5Gb3Igbm9uLU5vZGUuanMgaW50ZWdyYXRpb25zLCB1c2UgUlBDIG1vZGUgb3ZlciBzdGRpbi9zdGRvdXQ6XG5cbmBgYGJhc2hcbnBpIC0tbW9kZSBycGNcbmBgYFxuXG5SUEMgbW9kZSB1c2VzIHN0cmljdCBMRi1kZWxpbWl0ZWQgSlNPTkwgZnJhbWluZy4gQ2xpZW50cyBtdXN0IHNwbGl0IHJlY29yZHMgb24gYFxcbmAgb25seS4gRG8gbm90IHVzZSBnZW5lcmljIGxpbmUgcmVhZGVycyBsaWtlIE5vZGUgYHJlYWRsaW5lYCwgd2hpY2ggYWxzbyBzcGxpdCBvbiBVbmljb2RlIHNlcGFyYXRvcnMgaW5zaWRlIEpTT04gcGF5bG9hZHMuXG5cblNlZSBbZG9jcy9ycGMubWRdKGRvY3MvcnBjLm1kKSBmb3IgdGhlIHByb3RvY29sLlxuXG4tLS1cblxuIyMgUGhpbG9zb3BoeVxuXG5QaSBpcyBhZ2dyZXNzaXZlbHkgZXh0ZW5zaWJsZSBzbyBpdCBkb2Vzbid0IGhhdmUgdG8gZGljdGF0ZSB5b3VyIHdvcmtmbG93LiBGZWF0dXJlcyB0aGF0IG90aGVyIHRvb2xzIGJha2UgaW4gY2FuIGJlIGJ1aWx0IHdpdGggW2V4dGVuc2lvbnNdKCNleHRlbnNpb25zKSwgW3NraWxsc10oI3NraWxscyksIG9yIGluc3RhbGxlZCBmcm9tIHRoaXJkLXBhcnR5IFtwaSBwYWNrYWdlc10oI3BpLXBhY2thZ2VzKS4gVGhpcyBrZWVwcyB0aGUgY29yZSBtaW5pbWFsIHdoaWxlIGxldHRpbmcgeW91IHNoYXBlIHBpIHRvIGZpdCBob3cgeW91IHdvcmsuXG5cbioqTm8gTUNQLioqIEJ1aWxkIENMSSB0b29scyB3aXRoIFJFQURNRXMgKHNlZSBbU2tpbGxzXSgjc2tpbGxzKSksIG9yIGJ1aWxkIGFuIGV4dGVuc2lvbiB0aGF0IGFkZHMgTUNQIHN1cHBvcnQuIFtXaHk/XShodHRwczovL21hcmlvemVjaG5lci5hdC9wb3N0cy8yMDI1LTExLTAyLXdoYXQtaWYteW91LWRvbnQtbmVlZC1tY3AvKVxuXG4qKk5vIHN1Yi1hZ2VudHMuKiogVGhlcmUncyBtYW55IHdheXMgdG8gZG8gdGhpcy4gU3Bhd24gcGkgaW5zdGFuY2VzIHZpYSB0bXV4LCBvciBidWlsZCB5b3VyIG93biB3aXRoIFtleHRlbnNpb25zXSgjZXh0ZW5zaW9ucyksIG9yIGluc3RhbGwgYSBwYWNrYWdlIHRoYXQgZG9lcyBpdCB5b3VyIHdheS5cblxuKipObyBwZXJtaXNzaW9uIHBvcHVwcy4qKiBSdW4gaW4gYSBjb250YWluZXIsIG9yIGJ1aWxkIHlvdXIgb3duIGNvbmZpcm1hdGlvbiBmbG93IHdpdGggW2V4dGVuc2lvbnNdKCNleHRlbnNpb25zKSBpbmxpbmUgd2l0aCB5b3VyIGVudmlyb25tZW50IGFuZCBzZWN1cml0eSByZXF1aXJlbWVudHMuXG5cbioqTm8gcGxhbiBtb2RlLioqIFdyaXRlIHBsYW5zIHRvIGZpbGVzLCBvciBidWlsZCBpdCB3aXRoIFtleHRlbnNpb25zXSgjZXh0ZW5zaW9ucyksIG9yIGluc3RhbGwgYSBwYWNrYWdlLlxuXG4qKk5vIGJ1aWx0LWluIHRvLWRvcy4qKiBUaGV5IGNvbmZ1c2UgbW9kZWxzLiBVc2UgYSBUT0RPLm1kIGZpbGUsIG9yIGJ1aWxkIHlvdXIgb3duIHdpdGggW2V4dGVuc2lvbnNdKCNleHRlbnNpb25zKS5cblxuKipObyBiYWNrZ3JvdW5kIGJhc2guKiogVXNlIHRtdXguIEZ1bGwgb2JzZXJ2YWJpbGl0eSwgZGlyZWN0IGludGVyYWN0aW9uLlxuXG5SZWFkIHRoZSBbYmxvZyBwb3N0XShodHRwczovL21hcmlvemVjaG5lci5hdC9wb3N0cy8yMDI1LTExLTMwLXBpLWNvZGluZy1hZ2VudC8pIGZvciB0aGUgZnVsbCByYXRpb25hbGUuXG5cbi0tLVxuXG4jIyBDTEkgUmVmZXJlbmNlXG5cbmBgYGJhc2hcbnBpIFtvcHRpb25zXSBbQGZpbGVzLi4uXSBbbWVzc2FnZXMuLi5dXG5gYGBcblxuIyMjIFBhY2thZ2UgQ29tbWFuZHNcblxuYGBgYmFzaFxucGkgaW5zdGFsbCA8c291cmNlPiBbLWxdICAgICAjIEluc3RhbGwgcGFja2FnZSwgLWwgZm9yIHByb2plY3QtbG9jYWxcbnBpIHJlbW92ZSA8c291cmNlPiBbLWxdICAgICAgIyBSZW1vdmUgcGFja2FnZVxucGkgdW5pbnN0YWxsIDxzb3VyY2U+IFstbF0gICAjIEFsaWFzIGZvciByZW1vdmVcbnBpIHVwZGF0ZSBbc291cmNlfHNlbGZ8cGldICAgIyBVcGRhdGUgcGkgb25seSwgb3Igb25lIHBhY2thZ2Ugc291cmNlXG5waSB1cGRhdGUgLS1hbGwgICAgICAgICAgICAgICMgVXBkYXRlIHBpIGFuZCBwYWNrYWdlc1xucGkgdXBkYXRlIC0tZXh0ZW5zaW9ucyAgICAgICAjIFVwZGF0ZSBwYWNrYWdlcyBvbmx5XG5waSB1cGRhdGUgLS1zZWxmICAgICAgICAgICAgICMgVXBkYXRlIHBpIG9ubHlcbnBpIHVwZGF0ZSAtLXNlbGYgLS1mb3JjZSAgICAgIyBSZWluc3RhbGwgcGkgZXZlbiBpZiBjdXJyZW50XG5waSB1cGRhdGUgLS1leHRlbnNpb24gPHNyYz4gICMgVXBkYXRlIG9uZSBwYWNrYWdlXG5waSBsaXN0ICAgICAgICAgICAgICAgICAgICAgICMgTGlzdCBpbnN0YWxsZWQgcGFja2FnZXNcbnBpIGNvbmZpZyAgICAgICAgICAgICAgICAgICAgIyBFbmFibGUvZGlzYWJsZSBwYWNrYWdlIHJlc291cmNlc1xuYGBgXG5cbmBwaSBjb25maWdgIGFuZCBwcm9qZWN0IHBhY2thZ2UgY29tbWFuZHMgYWNjZXB0IGAtLWFwcHJvdmVgL2AtLW5vLWFwcHJvdmVgIHRvIHRydXN0IG9yIGlnbm9yZSBwcm9qZWN0LWxvY2FsIHNldHRpbmdzIGZvciBvbmUgY29tbWFuZC4gYHBpIHVwZGF0ZWAgbmV2ZXIgcHJvbXB0cyBmb3IgcHJvamVjdCB0cnVzdC5cblxuIyMjIE1vZGVzXG5cbnwgRmxhZyB8IERlc2NyaXB0aW9uIHxcbnwtLS0tLS18LS0tLS0tLS0tLS0tLXxcbnwgKGRlZmF1bHQpIHwgSW50ZXJhY3RpdmUgbW9kZSB8XG58IGAtcGAsIGAtLXByaW50YCB8IFByaW50IHJlc3BvbnNlIGFuZCBleGl0IHxcbnwgYC0tbW9kZSBqc29uYCB8IE91dHB1dCBhbGwgZXZlbnRzIGFzIEpTT04gbGluZXMgKHNlZSBbZG9jcy9qc29uLm1kXShkb2NzL2pzb24ubWQpKSB8XG58IGAtLW1vZGUgcnBjYCB8IFJQQyBtb2RlIGZvciBwcm9jZXNzIGludGVncmF0aW9uIChzZWUgW2RvY3MvcnBjLm1kXShkb2NzL3JwYy5tZCkpIHxcbnwgYC0tZXhwb3J0IDxpbj4gW291dF1gIHwgRXhwb3J0IHNlc3Npb24gdG8gSFRNTCB8XG5cbkluIHByaW50IG1vZGUsIHBpIGFsc28gcmVhZHMgcGlwZWQgc3RkaW4gYW5kIG1lcmdlcyBpdCBpbnRvIHRoZSBpbml0aWFsIHByb21wdDpcblxuYGBgYmFzaFxuY2F0IFJFQURNRS5tZCB8IHBpIC1wIFwiU3VtbWFyaXplIHRoaXMgdGV4dFwiXG5gYGBcblxuIyMjIE1vZGVsIE9wdGlvbnNcblxufCBPcHRpb24gfCBEZXNjcmlwdGlvbiB8XG58LS0tLS0tLS18LS0tLS0tLS0tLS0tLXxcbnwgYC0tcHJvdmlkZXIgPG5hbWU+YCB8IFByb3ZpZGVyIChhbnRocm9waWMsIG9wZW5haSwgZ29vZ2xlLCBldGMuKSB8XG58IGAtLW1vZGVsIDxwYXR0ZXJuPmAgfCBNb2RlbCBwYXR0ZXJuIG9yIElEIChzdXBwb3J0cyBgcHJvdmlkZXIvaWRgIGFuZCBvcHRpb25hbCBgOjx0aGlua2luZz5gKSB8XG58IGAtLWFwaS1rZXkgPGtleT5gIHwgQVBJIGtleSAob3ZlcnJpZGVzIGVudiB2YXJzKSB8XG58IGAtLXRoaW5raW5nIDxsZXZlbD5gIHwgYG9mZmAsIGBtaW5pbWFsYCwgYGxvd2AsIGBtZWRpdW1gLCBgaGlnaGAsIGB4aGlnaGAgfFxufCBgLS1tb2RlbHMgPHBhdHRlcm5zPmAgfCBDb21tYS1zZXBhcmF0ZWQgcGF0dGVybnMgZm9yIEN0cmwrUCBjeWNsaW5nIHxcbnwgYC0tbGlzdC1tb2RlbHMgW3NlYXJjaF1gIHwgTGlzdCBhdmFpbGFibGUgbW9kZWxzIHxcblxuIyMjIFNlc3Npb24gT3B0aW9uc1xuXG58IE9wdGlvbiB8IERlc2NyaXB0aW9uIHxcbnwtLS0tLS0tLXwtLS0tLS0tLS0tLS0tfFxufCBgLWNgLCBgLS1jb250aW51ZWAgfCBDb250aW51ZSBtb3N0IHJlY2VudCBzZXNzaW9uIHxcbnwgYC1yYCwgYC0tcmVzdW1lYCB8IEJyb3dzZSBhbmQgc2VsZWN0IHNlc3Npb24gfFxufCBgLS1zZXNzaW9uIDxwYXRoXFx8aWQ+YCB8IFVzZSBzcGVjaWZpYyBzZXNzaW9uIGZpbGUgb3IgcGFydGlhbCBVVUlEIHxcbnwgYC0tZm9yayA8cGF0aFxcfGlkPmAgfCBGb3JrIHNwZWNpZmljIHNlc3Npb24gZmlsZSBvciBwYXJ0aWFsIFVVSUQgaW50byBhIG5ldyBzZXNzaW9uIHxcbnwgYC0tc2Vzc2lvbi1kaXIgPGRpcj5gIHwgQ3VzdG9tIHNlc3Npb24gc3RvcmFnZSBkaXJlY3RvcnkgfFxufCBgLS1uby1zZXNzaW9uYCB8IEVwaGVtZXJhbCBtb2RlIChkb24ndCBzYXZlKSB8XG58IGAtLW5hbWUgPG5hbWU+YCwgYC1uIDxuYW1lPmAgfCBTZXQgc2Vzc2lvbiBkaXNwbGF5IG5hbWUgYXQgc3RhcnR1cCB8XG5cbiMjIyBUb29sIE9wdGlvbnNcblxufCBPcHRpb24gfCBEZXNjcmlwdGlvbiB8XG58LS0tLS0tLS18LS0tLS0tLS0tLS0tLXxcbnwgYC0tdG9vbHMgPGxpc3Q+YCwgYC10IDxsaXN0PmAgfCBBbGxvd2xpc3Qgc3BlY2lmaWMgdG9vbCBuYW1lcyBhY3Jvc3MgYnVpbHQtaW4sIGV4dGVuc2lvbiwgYW5kIGN1c3RvbSB0b29scyB8XG58IGAtLWV4Y2x1ZGUtdG9vbHMgPGxpc3Q+YCwgYC14dCA8bGlzdD5gIHwgRGlzYWJsZSBzcGVjaWZpYyB0b29sIG5hbWVzIGFjcm9zcyBidWlsdC1pbiwgZXh0ZW5zaW9uLCBhbmQgY3VzdG9tIHRvb2xzIHxcbnwgYC0tbm8tYnVpbHRpbi10b29sc2AsIGAtbmJ0YCB8IERpc2FibGUgYnVpbHQtaW4gdG9vbHMgYnkgZGVmYXVsdCBidXQga2VlcCBleHRlbnNpb24vY3VzdG9tIHRvb2xzIGVuYWJsZWQgfFxufCBgLS1uby10b29sc2AsIGAtbnRgIHwgRGlzYWJsZSBhbGwgdG9vbHMgYnkgZGVmYXVsdCB8XG5cbkF2YWlsYWJsZSBidWlsdC1pbiB0b29sczogYHJlYWRgLCBgYmFzaGAsIGBlZGl0YCwgYHdyaXRlYCwgYGdyZXBgLCBgZmluZGAsIGBsc2BcblxuIyMjIFJlc291cmNlIE9wdGlvbnNcblxufCBPcHRpb24gfCBEZXNjcmlwdGlvbiB8XG58LS0tLS0tLS18LS0tLS0tLS0tLS0tLXxcbnwgYC1lYCwgYC0tZXh0ZW5zaW9uIDxzb3VyY2U+YCB8IExvYWQgZXh0ZW5zaW9uIGZyb20gcGF0aCwgbnBtLCBvciBnaXQgKHJlcGVhdGFibGUpIHxcbnwgYC0tbm8tZXh0ZW5zaW9uc2AgfCBEaXNhYmxlIGV4dGVuc2lvbiBkaXNjb3ZlcnkgfFxufCBgLS1za2lsbCA8cGF0aD5gIHwgTG9hZCBza2lsbCAocmVwZWF0YWJsZSkgfFxufCBgLS1uby1za2lsbHNgIHwgRGlzYWJsZSBza2lsbCBkaXNjb3ZlcnkgfFxufCBgLS1wcm9tcHQtdGVtcGxhdGUgPHBhdGg+YCB8IExvYWQgcHJvbXB0IHRlbXBsYXRlIChyZXBlYXRhYmxlKSB8XG58IGAtLW5vLXByb21wdC10ZW1wbGF0ZXNgIHwgRGlzYWJsZSBwcm9tcHQgdGVtcGxhdGUgZGlzY292ZXJ5IHxcbnwgYC0tdGhlbWUgPHBhdGg+YCB8IExvYWQgdGhlbWUgKHJlcGVhdGFibGUpIHxcbnwgYC0tbm8tdGhlbWVzYCB8IERpc2FibGUgdGhlbWUgZGlzY292ZXJ5IHxcbnwgYC0tbm8tY29udGV4dC1maWxlc2AsIGAtbmNgIHwgRGlzYWJsZSBBR0VOVFMubWQgYW5kIENMQVVERS5tZCBjb250ZXh0IGZpbGUgZGlzY292ZXJ5IHxcblxuQ29tYmluZSBgLS1uby0qYCB3aXRoIGV4cGxpY2l0IGZsYWdzIHRvIGxvYWQgZXhhY3RseSB3aGF0IHlvdSBuZWVkLCBpZ25vcmluZyBzZXR0aW5ncy5qc29uIChlLmcuLCBgLS1uby1leHRlbnNpb25zIC1lIC4vbXktZXh0LnRzYCkuXG5cbiMjIyBPdGhlciBPcHRpb25zXG5cbnwgT3B0aW9uIHwgRGVzY3JpcHRpb24gfFxufC0tLS0tLS0tfC0tLS0tLS0tLS0tLS18XG58IGAtLXN5c3RlbS1wcm9tcHQgPHRleHQ+YCB8IFJlcGxhY2UgZGVmYXVsdCBwcm9tcHQgKGNvbnRleHQgZmlsZXMgYW5kIHNraWxscyBzdGlsbCBhcHBlbmRlZCkgfFxufCBgLS1hcHBlbmQtc3lzdGVtLXByb21wdCA8dGV4dD5gIHwgQXBwZW5kIHRvIHN5c3RlbSBwcm9tcHQgfFxufCBgLS12ZXJib3NlYCB8IEZvcmNlIHZlcmJvc2Ugc3RhcnR1cCB8XG58IGAtYWAsIGAtLWFwcHJvdmVgIHwgVHJ1c3QgcHJvamVjdC1sb2NhbCBmaWxlcyBmb3IgdGhpcyBydW4gfFxufCBgLW5hYCwgYC0tbm8tYXBwcm92ZWAgfCBJZ25vcmUgcHJvamVjdC1sb2NhbCBmaWxlcyBmb3IgdGhpcyBydW4gfFxufCBgLWhgLCBgLS1oZWxwYCB8IFNob3cgaGVscCB8XG58IGAtdmAsIGAtLXZlcnNpb25gIHwgU2hvdyB2ZXJzaW9uIHxcblxuIyMjIEZpbGUgQXJndW1lbnRzXG5cblByZWZpeCBmaWxlcyB3aXRoIGBAYCB0byBpbmNsdWRlIGluIHRoZSBtZXNzYWdlOlxuXG5gYGBiYXNoXG5waSBAcHJvbXB0Lm1kIFwiQW5zd2VyIHRoaXNcIlxucGkgLXAgQHNjcmVlbnNob3QucG5nIFwiV2hhdCdzIGluIHRoaXMgaW1hZ2U/XCJcbnBpIEBjb2RlLnRzIEB0ZXN0LnRzIFwiUmV2aWV3IHRoZXNlIGZpbGVzXCJcbmBgYFxuXG4jIyMgRXhhbXBsZXNcblxuYGBgYmFzaFxuIyBJbnRlcmFjdGl2ZSB3aXRoIGluaXRpYWwgcHJvbXB0XG5waSBcIkxpc3QgYWxsIC50cyBmaWxlcyBpbiBzcmMvXCJcblxuIyBOb24taW50ZXJhY3RpdmVcbnBpIC1wIFwiU3VtbWFyaXplIHRoaXMgY29kZWJhc2VcIlxuXG4jIE5vbi1pbnRlcmFjdGl2ZSB3aXRoIHBpcGVkIHN0ZGluXG5jYXQgUkVBRE1FLm1kIHwgcGkgLXAgXCJTdW1tYXJpemUgdGhpcyB0ZXh0XCJcblxuIyBOYW1lZCBvbmUtc2hvdCBzZXNzaW9uXG5waSAtLW5hbWUgXCJyZWxlYXNlIGF1ZGl0XCIgLXAgXCJBdWRpdCB0aGlzIHJlcG9zaXRvcnlcIlxuXG4jIERpZmZlcmVudCBtb2RlbFxucGkgLS1wcm92aWRlciBvcGVuYWkgLS1tb2RlbCBncHQtNG8gXCJIZWxwIG1lIHJlZmFjdG9yXCJcblxuIyBNb2RlbCB3aXRoIHByb3ZpZGVyIHByZWZpeCAobm8gLS1wcm92aWRlciBuZWVkZWQpXG5waSAtLW1vZGVsIG9wZW5haS9ncHQtNG8gXCJIZWxwIG1lIHJlZmFjdG9yXCJcblxuIyBNb2RlbCB3aXRoIHRoaW5raW5nIGxldmVsIHNob3J0aGFuZFxucGkgLS1tb2RlbCBzb25uZXQ6aGlnaCBcIlNvbHZlIHRoaXMgY29tcGxleCBwcm9ibGVtXCJcblxuIyBMaW1pdCBtb2RlbCBjeWNsaW5nXG5waSAtLW1vZGVscyBcImNsYXVkZS0qLGdwdC00b1wiXG5cbiMgUmVhZC1vbmx5IG1vZGVcbnBpIC0tdG9vbHMgcmVhZCxncmVwLGZpbmQsbHMgLXAgXCJSZXZpZXcgdGhlIGNvZGVcIlxuXG4jIERpc2FibGUgb25lIGV4dGVuc2lvbiBvciBidWlsdC1pbiB0b29sIHdoaWxlIGtlZXBpbmcgdGhlIHJlc3QgYXZhaWxhYmxlXG5waSAtLWV4Y2x1ZGUtdG9vbHMgYXNrX3F1ZXN0aW9uXG5cbiMgSGlnaCB0aGlua2luZyBsZXZlbFxucGkgLS10aGlua2luZyBoaWdoIFwiU29sdmUgdGhpcyBjb21wbGV4IHByb2JsZW1cIlxuYGBgXG5cbiMjIyBFbnZpcm9ubWVudCBWYXJpYWJsZXNcblxufCBWYXJpYWJsZSB8IERlc2NyaXB0aW9uIHxcbnwtLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS18XG58IGBQSV9DT0RJTkdfQUdFTlRfRElSYCB8IE92ZXJyaWRlIGNvbmZpZyBkaXJlY3RvcnkgKGRlZmF1bHQ6IGB+Ly5waS9hZ2VudGApIHxcbnwgYFBJX0NPRElOR19BR0VOVF9TRVNTSU9OX0RJUmAgfCBPdmVycmlkZSBzZXNzaW9uIHN0b3JhZ2UgZGlyZWN0b3J5IChvdmVycmlkZGVuIGJ5IGAtLXNlc3Npb24tZGlyYCkgfFxufCBgUElfUEFDS0FHRV9ESVJgIHwgT3ZlcnJpZGUgcGFja2FnZSBkaXJlY3RvcnkgKHVzZWZ1bCBmb3IgTml4L0d1aXggd2hlcmUgc3RvcmUgcGF0aHMgdG9rZW5pemUgcG9vcmx5KSB8XG58IGBQSV9PRkZMSU5FYCB8IERpc2FibGUgc3RhcnR1cCBuZXR3b3JrIG9wZXJhdGlvbnMsIGluY2x1ZGluZyB1cGRhdGUgY2hlY2tzLCBwYWNrYWdlIHVwZGF0ZSBjaGVja3MsIGFuZCBpbnN0YWxsL3VwZGF0ZSB0ZWxlbWV0cnkgfFxufCBgUElfU0tJUF9WRVJTSU9OX0NIRUNLYCB8IFNraXAgdGhlIFBpIHZlcnNpb24gdXBkYXRlIGNoZWNrIGF0IHN0YXJ0dXAuIFRoaXMgcHJldmVudHMgdGhlIGBwaS5kZXZgIGxhdGVzdC12ZXJzaW9uIHJlcXVlc3QgfFxufCBgUElfVEVMRU1FVFJZYCB8IE92ZXJyaWRlIGluc3RhbGwvdXBkYXRlIHRlbGVtZXRyeSBhbmQgcHJvdmlkZXIgYXR0cmlidXRpb24gaGVhZGVycy4gVXNlIGAxYC9gdHJ1ZWAvYHllc2AgdG8gZW5hYmxlIG9yIGAwYC9gZmFsc2VgL2Bub2AgdG8gZGlzYWJsZS4gVGhpcyBkb2VzIG5vdCBkaXNhYmxlIHVwZGF0ZSBjaGVja3MgfFxufCBgUElfQ0FDSEVfUkVURU5USU9OYCB8IFNldCB0byBgbG9uZ2AgZm9yIGV4dGVuZGVkIHByb21wdCBjYWNoZSAoQW50aHJvcGljOiAxaCwgT3BlbkFJOiAyNGgpIHxcbnwgYFZJU1VBTGAsIGBFRElUT1JgIHwgRXh0ZXJuYWwgZWRpdG9yIGZvciBDdHJsK0cgfFxuXG4tLS1cblxuIyMgQ29udHJpYnV0aW5nICYgRGV2ZWxvcG1lbnRcblxuU2VlIFtDT05UUklCVVRJTkcubWRdKC4uLy4uL0NPTlRSSUJVVElORy5tZCkgZm9yIGd1aWRlbGluZXMgYW5kIFtkb2NzL2RldmVsb3BtZW50Lm1kXShkb2NzL2RldmVsb3BtZW50Lm1kKSBmb3Igc2V0dXAsIGZvcmtpbmcsIGFuZCBkZWJ1Z2dpbmcuXG5cbiMjIExpY2Vuc2VcblxuTUlUXG5cbiMjIFNlZSBBbHNvXG5cbi0gW0BlYXJlbmRpbC13b3Jrcy9waS1haV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvQGVhcmVuZGlsLXdvcmtzL3BpLWFpKTogQ29yZSBMTE0gdG9vbGtpdFxuLSBbQGVhcmVuZGlsLXdvcmtzL3BpLWFnZW50LWNvcmVdKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL0BlYXJlbmRpbC13b3Jrcy9waS1hZ2VudC1jb3JlKTogQWdlbnQgZnJhbWV3b3JrXG4tIFtAZWFyZW5kaWwtd29ya3MvcGktdHVpXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9AZWFyZW5kaWwtd29ya3MvcGktdHVpKTogVGVybWluYWwgVUkgY29tcG9uZW50c1xuXG48cCBhbGlnbj1cImNlbnRlclwiPlxuICA8YSBocmVmPVwiaHR0cHM6Ly9waS5kZXZcIj5waS5kZXY8L2E+IGRvbWFpbiBncmFjaW91c2x5IGRvbmF0ZWQgYnlcbiAgPGJyIC8+PGJyIC8+XG4gIDxhIGhyZWY9XCJodHRwczovL2V4ZS5kZXZcIj48aW1nIHNyYz1cImRvY3MvaW1hZ2VzL2V4eS5wbmdcIiBhbHQ9XCJFeHkgbWFzY290XCIgd2lkdGg9XCI0OFwiIC8+PGJyIC8+ZXhlLmRldjwvYT5cbjwvcD5cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODIxMzA0MX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjIyN2ZlYzIxIiwicGFyZW50SWQiOiIxNmM2OWU3MCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTA6MTMuMDQyWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoibUVEd2lWamVlS3llMnlCeXdnWGdmWEhWbm96ZnlFQmMiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiI+IHBpIGNhbiBjcmVhdGUgZXh0ZW5zaW9ucy4gQXNrIGl0IHRvIGJ1aWxkIG9uZSBmb3IgeW91ciB1c2UgY2FzZS5cblxuIyBFeHRlbnNpb25zXG5cbkV4dGVuc2lvbnMgYXJlIFR5cGVTY3JpcHQgbW9kdWxlcyB0aGF0IGV4dGVuZCBwaSdzIGJlaGF2aW9yLiBUaGV5IGNhbiBzdWJzY3JpYmUgdG8gbGlmZWN5Y2xlIGV2ZW50cywgcmVnaXN0ZXIgY3VzdG9tIHRvb2xzIGNhbGxhYmxlIGJ5IHRoZSBMTE0sIGFkZCBjb21tYW5kcywgYW5kIG1vcmUuXG5cbj4gKipQbGFjZW1lbnQgZm9yIC9yZWxvYWQ6KiogUHV0IGV4dGVuc2lvbnMgaW4gYH4vLnBpL2FnZW50L2V4dGVuc2lvbnMvYCAoZ2xvYmFsKSBvciBgLnBpL2V4dGVuc2lvbnMvYCAocHJvamVjdC1sb2NhbCkgZm9yIGF1dG8tZGlzY292ZXJ5LiBVc2UgYHBpIC1lIC4vcGF0aC50c2Agb25seSBmb3IgcXVpY2sgdGVzdHMuIEV4dGVuc2lvbnMgaW4gYXV0by1kaXNjb3ZlcmVkIGxvY2F0aW9ucyBjYW4gYmUgaG90LXJlbG9hZGVkIHdpdGggYC9yZWxvYWRgLlxuXG4qKktleSBjYXBhYmlsaXRpZXM6Kipcbi0gKipDdXN0b20gdG9vbHMqKiAtIFJlZ2lzdGVyIHRvb2xzIHRoZSBMTE0gY2FuIGNhbGwgdmlhIGBwaS5yZWdpc3RlclRvb2woKWBcbi0gKipFdmVudCBpbnRlcmNlcHRpb24qKiAtIEJsb2NrIG9yIG1vZGlmeSB0b29sIGNhbGxzLCBpbmplY3QgY29udGV4dCwgY3VzdG9taXplIGNvbXBhY3Rpb25cbi0gKipVc2VyIGludGVyYWN0aW9uKiogLSBQcm9tcHQgdXNlcnMgdmlhIGBjdHgudWlgIChzZWxlY3QsIGNvbmZpcm0sIGlucHV0LCBub3RpZnkpXG4tICoqQ3VzdG9tIFVJIGNvbXBvbmVudHMqKiAtIEZ1bGwgVFVJIGNvbXBvbmVudHMgd2l0aCBrZXlib2FyZCBpbnB1dCB2aWEgYGN0eC51aS5jdXN0b20oKWAgZm9yIGNvbXBsZXggaW50ZXJhY3Rpb25zXG4tICoqQ3VzdG9tIGNvbW1hbmRzKiogLSBSZWdpc3RlciBjb21tYW5kcyBsaWtlIGAvbXljb21tYW5kYCB2aWEgYHBpLnJlZ2lzdGVyQ29tbWFuZCgpYFxuLSAqKlNlc3Npb24gcGVyc2lzdGVuY2UqKiAtIFN0b3JlIHN0YXRlIHRoYXQgc3Vydml2ZXMgcmVzdGFydHMgdmlhIGBwaS5hcHBlbmRFbnRyeSgpYFxuLSAqKkN1c3RvbSByZW5kZXJpbmcqKiAtIENvbnRyb2wgaG93IHRvb2wgY2FsbHMvcmVzdWx0cyBhbmQgbWVzc2FnZXMgYXBwZWFyIGluIFRVSVxuXG4qKkV4YW1wbGUgdXNlIGNhc2VzOioqXG4tIFBlcm1pc3Npb24gZ2F0ZXMgKGNvbmZpcm0gYmVmb3JlIGBybSAtcmZgLCBgc3Vkb2AsIGV0Yy4pXG4tIEdpdCBjaGVja3BvaW50aW5nIChzdGFzaCBhdCBlYWNoIHR1cm4sIHJlc3RvcmUgb24gYnJhbmNoKVxuLSBQYXRoIHByb3RlY3Rpb24gKGJsb2NrIHdyaXRlcyB0byBgLmVudmAsIGBub2RlX21vZHVsZXMvYClcbi0gQ3VzdG9tIGNvbXBhY3Rpb24gKHN1bW1hcml6ZSBjb252ZXJzYXRpb24geW91ciB3YXkpXG4tIENvbnZlcnNhdGlvbiBzdW1tYXJpZXMgKHNlZSBgc3VtbWFyaXplLnRzYCBleGFtcGxlKVxuLSBJbnRlcmFjdGl2ZSB0b29scyAocXVlc3Rpb25zLCB3aXphcmRzLCBjdXN0b20gZGlhbG9ncylcbi0gU3RhdGVmdWwgdG9vbHMgKHRvZG8gbGlzdHMsIGNvbm5lY3Rpb24gcG9vbHMpXG4tIEV4dGVybmFsIGludGVncmF0aW9ucyAoZmlsZSB3YXRjaGVycywgd2ViaG9va3MsIENJIHRyaWdnZXJzKVxuLSBHYW1lcyB3aGlsZSB5b3Ugd2FpdCAoc2VlIGBzbmFrZS50c2AgZXhhbXBsZSlcblxuU2VlIFtleGFtcGxlcy9leHRlbnNpb25zL10oLi4vZXhhbXBsZXMvZXh0ZW5zaW9ucy8pIGZvciB3b3JraW5nIGltcGxlbWVudGF0aW9ucy5cblxuIyMgVGFibGUgb2YgQ29udGVudHNcblxuLSBbUXVpY2sgU3RhcnRdKCNxdWljay1zdGFydClcbi0gW0V4dGVuc2lvbiBMb2NhdGlvbnNdKCNleHRlbnNpb24tbG9jYXRpb25zKVxuLSBbQXZhaWxhYmxlIEltcG9ydHNdKCNhdmFpbGFibGUtaW1wb3J0cylcbi0gW1dyaXRpbmcgYW4gRXh0ZW5zaW9uXSgjd3JpdGluZy1hbi1leHRlbnNpb24pXG4gIC0gW0V4dGVuc2lvbiBTdHlsZXNdKCNleHRlbnNpb24tc3R5bGVzKVxuLSBbRXZlbnRzXSgjZXZlbnRzKVxuICAtIFtMaWZlY3ljbGUgT3ZlcnZpZXddKCNsaWZlY3ljbGUtb3ZlcnZpZXcpXG4gIC0gW1Jlc291cmNlIEV2ZW50c10oI3Jlc291cmNlLWV2ZW50cylcbiAgLSBbU2Vzc2lvbiBFdmVudHNdKCNzZXNzaW9uLWV2ZW50cylcbiAgLSBbQWdlbnQgRXZlbnRzXSgjYWdlbnQtZXZlbnRzKVxuICAtIFtNb2RlbCBFdmVudHNdKCNtb2RlbC1ldmVudHMpXG4gIC0gW1Rvb2wgRXZlbnRzXSgjdG9vbC1ldmVudHMpXG4tIFtFeHRlbnNpb25Db250ZXh0XSgjZXh0ZW5zaW9uY29udGV4dClcbi0gW0V4dGVuc2lvbkNvbW1hbmRDb250ZXh0XSgjZXh0ZW5zaW9uY29tbWFuZGNvbnRleHQpXG4tIFtFeHRlbnNpb25BUEkgTWV0aG9kc10oI2V4dGVuc2lvbmFwaS1tZXRob2RzKVxuLSBbU3RhdGUgTWFuYWdlbWVudF0oI3N0YXRlLW1hbmFnZW1lbnQpXG4tIFtDdXN0b20gVG9vbHNdKCNjdXN0b20tdG9vbHMpXG4tIFtDdXN0b20gVUldKCNjdXN0b20tdWkpXG4tIFtFcnJvciBIYW5kbGluZ10oI2Vycm9yLWhhbmRsaW5nKVxuLSBbTW9kZSBCZWhhdmlvcl0oI21vZGUtYmVoYXZpb3IpXG4tIFtFeGFtcGxlcyBSZWZlcmVuY2VdKCNleGFtcGxlcy1yZWZlcmVuY2UpXG5cbiMjIFF1aWNrIFN0YXJ0XG5cbkNyZWF0ZSBgfi8ucGkvYWdlbnQvZXh0ZW5zaW9ucy9teS1leHRlbnNpb24udHNgOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBpOiBFeHRlbnNpb25BUEkpIHtcbiAgLy8gUmVhY3QgdG8gZXZlbnRzXG4gIHBpLm9uKFwic2Vzc2lvbl9zdGFydFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICBjdHgudWkubm90aWZ5KFwiRXh0ZW5zaW9uIGxvYWRlZCFcIiwgXCJpbmZvXCIpO1xuICB9KTtcblxuICBwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAgIGlmIChldmVudC50b29sTmFtZSA9PT0gXCJiYXNoXCIgJiYgZXZlbnQuaW5wdXQuY29tbWFuZD8uaW5jbHVkZXMoXCJybSAtcmZcIikpIHtcbiAgICAgIGNvbnN0IG9rID0gYXdhaXQgY3R4LnVpLmNvbmZpcm0oXCJEYW5nZXJvdXMhXCIsIFwiQWxsb3cgcm0gLXJmP1wiKTtcbiAgICAgIGlmICghb2spIHJldHVybiB7IGJsb2NrOiB0cnVlLCByZWFzb246IFwiQmxvY2tlZCBieSB1c2VyXCIgfTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFJlZ2lzdGVyIGEgY3VzdG9tIHRvb2xcbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdyZWV0XCIsXG4gICAgbGFiZWw6IFwiR3JlZXRcIixcbiAgICBkZXNjcmlwdGlvbjogXCJHcmVldCBzb21lb25lIGJ5IG5hbWVcIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICBuYW1lOiBUeXBlLlN0cmluZyh7IGRlc2NyaXB0aW9uOiBcIk5hbWUgdG8gZ3JlZXRcIiB9KSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogYEhlbGxvLCAke3BhcmFtcy5uYW1lfSFgIH1dLFxuICAgICAgICBkZXRhaWxzOiB7fSxcbiAgICAgIH07XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXIgYSBjb21tYW5kXG4gIHBpLnJlZ2lzdGVyQ29tbWFuZChcImhlbGxvXCIsIHtcbiAgICBkZXNjcmlwdGlvbjogXCJTYXkgaGVsbG9cIixcbiAgICBoYW5kbGVyOiBhc3luYyAoYXJncywgY3R4KSA9PiB7XG4gICAgICBjdHgudWkubm90aWZ5KGBIZWxsbyAke2FyZ3MgfHwgXCJ3b3JsZFwifSFgLCBcImluZm9cIik7XG4gICAgfSxcbiAgfSk7XG59XG5gYGBcblxuVGVzdCB3aXRoIGAtLWV4dGVuc2lvbmAgKG9yIGAtZWApIGZsYWc6XG5cbmBgYGJhc2hcbnBpIC1lIC4vbXktZXh0ZW5zaW9uLnRzXG5gYGBcblxuIyMgRXh0ZW5zaW9uIExvY2F0aW9uc1xuXG4+ICoqU2VjdXJpdHk6KiogRXh0ZW5zaW9ucyBydW4gd2l0aCB5b3VyIGZ1bGwgc3lzdGVtIHBlcm1pc3Npb25zIGFuZCBjYW4gZXhlY3V0ZSBhcmJpdHJhcnkgY29kZS4gT25seSBpbnN0YWxsIGZyb20gc291cmNlcyB5b3UgdHJ1c3QuXG5cbkV4dGVuc2lvbnMgYXJlIGF1dG8tZGlzY292ZXJlZCBmcm9tIHRydXN0ZWQgbG9jYXRpb25zLiBQcm9qZWN0LWxvY2FsIGAucGkvZXh0ZW5zaW9uc2AgZW50cmllcyBsb2FkIG9ubHkgYWZ0ZXIgdGhlIHByb2plY3QgaXMgdHJ1c3RlZC5cblxufCBMb2NhdGlvbiB8IFNjb3BlIHxcbnwtLS0tLS0tLS0tfC0tLS0tLS18XG58IGB+Ly5waS9hZ2VudC9leHRlbnNpb25zLyoudHNgIHwgR2xvYmFsIChhbGwgcHJvamVjdHMpIHxcbnwgYH4vLnBpL2FnZW50L2V4dGVuc2lvbnMvKi9pbmRleC50c2AgfCBHbG9iYWwgKHN1YmRpcmVjdG9yeSkgfFxufCBgLnBpL2V4dGVuc2lvbnMvKi50c2AgfCBQcm9qZWN0LWxvY2FsIHxcbnwgYC5waS9leHRlbnNpb25zLyovaW5kZXgudHNgIHwgUHJvamVjdC1sb2NhbCAoc3ViZGlyZWN0b3J5KSB8XG5cbkFkZGl0aW9uYWwgcGF0aHMgdmlhIGBzZXR0aW5ncy5qc29uYDpcblxuYGBganNvblxue1xuICBcInBhY2thZ2VzXCI6IFtcbiAgICBcIm5wbTpAZm9vL2JhckAxLjAuMFwiLFxuICAgIFwiZ2l0OmdpdGh1Yi5jb20vdXNlci9yZXBvQHYxXCJcbiAgXSxcbiAgXCJleHRlbnNpb25zXCI6IFtcbiAgICBcIi9wYXRoL3RvL2xvY2FsL2V4dGVuc2lvbi50c1wiLFxuICAgIFwiL3BhdGgvdG8vbG9jYWwvZXh0ZW5zaW9uL2RpclwiXG4gIF1cbn1cbmBgYFxuXG5UbyBzaGFyZSBleHRlbnNpb25zIHZpYSBucG0gb3IgZ2l0IGFzIHBpIHBhY2thZ2VzLCBzZWUgW3BhY2thZ2VzLm1kXShwYWNrYWdlcy5tZCkuXG5cbiMjIEF2YWlsYWJsZSBJbXBvcnRzXG5cbnwgUGFja2FnZSB8IFB1cnBvc2UgfFxufC0tLS0tLS0tLXwtLS0tLS0tLS18XG58IGBAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50YCB8IEV4dGVuc2lvbiB0eXBlcyAoYEV4dGVuc2lvbkFQSWAsIGBFeHRlbnNpb25Db250ZXh0YCwgZXZlbnRzKSB8XG58IGB0eXBlYm94YCB8IFNjaGVtYSBkZWZpbml0aW9ucyBmb3IgdG9vbCBwYXJhbWV0ZXJzIHxcbnwgYEBlYXJlbmRpbC13b3Jrcy9waS1haWAgfCBBSSB1dGlsaXRpZXMgKGBTdHJpbmdFbnVtYCBmb3IgR29vZ2xlLWNvbXBhdGlibGUgZW51bXMpIHxcbnwgYEBlYXJlbmRpbC13b3Jrcy9waS10dWlgIHwgVFVJIGNvbXBvbmVudHMgZm9yIGN1c3RvbSByZW5kZXJpbmcgfFxuXG5ucG0gZGVwZW5kZW5jaWVzIHdvcmsgdG9vLiBBZGQgYSBgcGFja2FnZS5qc29uYCBuZXh0IHRvIHlvdXIgZXh0ZW5zaW9uIChvciBpbiBhIHBhcmVudCBkaXJlY3RvcnkpLCBydW4gYG5wbSBpbnN0YWxsYCwgYW5kIGltcG9ydHMgZnJvbSBgbm9kZV9tb2R1bGVzL2AgYXJlIHJlc29sdmVkIGF1dG9tYXRpY2FsbHkuXG5cbkZvciBkaXN0cmlidXRlZCBwaSBwYWNrYWdlcyBpbnN0YWxsZWQgd2l0aCBgcGkgaW5zdGFsbGAgKG5wbSBvciBnaXQpLCBydW50aW1lIGRlcHMgbXVzdCBiZSBpbiBgZGVwZW5kZW5jaWVzYC4gUGFja2FnZSBpbnN0YWxsYXRpb24gdXNlcyBwcm9kdWN0aW9uIGluc3RhbGxzIChgbnBtIGluc3RhbGwgLS1vbWl0PWRldmApIGJ5IGRlZmF1bHQsIHNvIGBkZXZEZXBlbmRlbmNpZXNgIGFyZSBub3QgYXZhaWxhYmxlIGF0IHJ1bnRpbWU7IHdoZW4gYG5wbUNvbW1hbmRgIGlzIGNvbmZpZ3VyZWQsIGdpdCBwYWNrYWdlcyB1c2UgcGxhaW4gYGluc3RhbGxgIGZvciBjb21wYXRpYmlsaXR5IHdpdGggd3JhcHBlcnMuXG5cbk5vZGUuanMgYnVpbHQtaW5zIChgbm9kZTpmc2AsIGBub2RlOnBhdGhgLCBldGMuKSBhcmUgYWxzbyBhdmFpbGFibGUuXG5cbiMjIFdyaXRpbmcgYW4gRXh0ZW5zaW9uXG5cbkFuIGV4dGVuc2lvbiBleHBvcnRzIGEgZGVmYXVsdCBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgcmVjZWl2ZXMgYEV4dGVuc2lvbkFQSWAuIFRoZSBmYWN0b3J5IGNhbiBiZSBzeW5jaHJvbm91cyBvciBhc3luY2hyb25vdXM6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBpOiBFeHRlbnNpb25BUEkpIHtcbiAgLy8gU3Vic2NyaWJlIHRvIGV2ZW50c1xuICBwaS5vbihcImV2ZW50X25hbWVcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgICAvLyBjdHgudWkgZm9yIHVzZXIgaW50ZXJhY3Rpb25cbiAgICBjb25zdCBvayA9IGF3YWl0IGN0eC51aS5jb25maXJtKFwiVGl0bGVcIiwgXCJBcmUgeW91IHN1cmU/XCIpO1xuICAgIGN0eC51aS5ub3RpZnkoXCJEb25lIVwiLCBcImluZm9cIik7XG4gICAgY3R4LnVpLnNldFN0YXR1cyhcIm15LWV4dFwiLCBcIlByb2Nlc3NpbmcuLi5cIik7ICAvLyBGb290ZXIgc3RhdHVzXG4gICAgY3R4LnVpLnNldFdpZGdldChcIm15LWV4dFwiLCBbXCJMaW5lIDFcIiwgXCJMaW5lIDJcIl0pOyAgLy8gV2lkZ2V0IGFib3ZlIGVkaXRvciAoZGVmYXVsdClcbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXIgdG9vbHMsIGNvbW1hbmRzLCBzaG9ydGN1dHMsIGZsYWdzXG4gIHBpLnJlZ2lzdGVyVG9vbCh7IC4uLiB9KTtcbiAgcGkucmVnaXN0ZXJDb21tYW5kKFwibmFtZVwiLCB7IC4uLiB9KTtcbiAgcGkucmVnaXN0ZXJTaG9ydGN1dChcImN0cmwreFwiLCB7IC4uLiB9KTtcbiAgcGkucmVnaXN0ZXJGbGFnKFwibXktZmxhZ1wiLCB7IC4uLiB9KTtcbn1cbmBgYFxuXG5FeHRlbnNpb25zIGFyZSBsb2FkZWQgdmlhIFtqaXRpXShodHRwczovL2dpdGh1Yi5jb20vdW5qcy9qaXRpKSwgc28gVHlwZVNjcmlwdCB3b3JrcyB3aXRob3V0IGNvbXBpbGF0aW9uLlxuXG5JZiB0aGUgZmFjdG9yeSByZXR1cm5zIGEgYFByb21pc2VgLCBwaSBhd2FpdHMgaXQgYmVmb3JlIGNvbnRpbnVpbmcgc3RhcnR1cC4gVGhhdCBtZWFucyBhc3luYyBpbml0aWFsaXphdGlvbiBjb21wbGV0ZXMgYmVmb3JlIGBzZXNzaW9uX3N0YXJ0YCwgYmVmb3JlIGByZXNvdXJjZXNfZGlzY292ZXJgLCBhbmQgYmVmb3JlIHByb3ZpZGVyIHJlZ2lzdHJhdGlvbnMgcXVldWVkIHZpYSBgcGkucmVnaXN0ZXJQcm92aWRlcigpYCBhcmUgZmx1c2hlZC5cblxuIyMjIEFzeW5jIGZhY3RvcnkgZnVuY3Rpb25zXG5cblVzZSBhbiBhc3luYyBmYWN0b3J5IGZvciBvbmUtdGltZSBzdGFydHVwIHdvcmsgc3VjaCBhcyBmZXRjaGluZyByZW1vdGUgY29uZmlndXJhdGlvbiBvciBkeW5hbWljYWxseSBkaXNjb3ZlcmluZyBhdmFpbGFibGUgbW9kZWxzLlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jIGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXCJodHRwOi8vbG9jYWxob3N0OjEyMzQvdjEvbW9kZWxzXCIpO1xuICBjb25zdCBwYXlsb2FkID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMge1xuICAgIGRhdGE6IEFycmF5PHtcbiAgICAgIGlkOiBzdHJpbmc7XG4gICAgICBuYW1lPzogc3RyaW5nO1xuICAgICAgY29udGV4dF93aW5kb3c/OiBudW1iZXI7XG4gICAgICBtYXhfdG9rZW5zPzogbnVtYmVyO1xuICAgIH0+O1xuICB9O1xuXG4gIHBpLnJlZ2lzdGVyUHJvdmlkZXIoXCJsb2NhbC1vcGVuYWlcIiwge1xuICAgIGJhc2VVcmw6IFwiaHR0cDovL2xvY2FsaG9zdDoxMjM0L3YxXCIsXG4gICAgYXBpS2V5OiBcIiRMT0NBTF9PUEVOQUlfQVBJX0tFWVwiLFxuICAgIGFwaTogXCJvcGVuYWktY29tcGxldGlvbnNcIixcbiAgICBtb2RlbHM6IHBheWxvYWQuZGF0YS5tYXAoKG1vZGVsKSA9PiAoe1xuICAgICAgaWQ6IG1vZGVsLmlkLFxuICAgICAgbmFtZTogbW9kZWwubmFtZSA/PyBtb2RlbC5pZCxcbiAgICAgIHJlYXNvbmluZzogZmFsc2UsXG4gICAgICBpbnB1dDogW1widGV4dFwiXSxcbiAgICAgIGNvc3Q6IHsgaW5wdXQ6IDAsIG91dHB1dDogMCwgY2FjaGVSZWFkOiAwLCBjYWNoZVdyaXRlOiAwIH0sXG4gICAgICBjb250ZXh0V2luZG93OiBtb2RlbC5jb250ZXh0X3dpbmRvdyA/PyAxMjgwMDAsXG4gICAgICBtYXhUb2tlbnM6IG1vZGVsLm1heF90b2tlbnMgPz8gNDA5NixcbiAgICB9KSksXG4gIH0pO1xufVxuYGBgXG5cblRoaXMgcGF0dGVybiBtYWtlcyB0aGUgZmV0Y2hlZCBtb2RlbHMgYXZhaWxhYmxlIGR1cmluZyBub3JtYWwgc3RhcnR1cCBhbmQgdG8gYHBpIC0tbGlzdC1tb2RlbHNgLlxuXG4jIyMgTG9uZy1saXZlZCByZXNvdXJjZXMgYW5kIHNodXRkb3duXG5cbkV4dGVuc2lvbiBmYWN0b3JpZXMgbWF5IHJ1biBpbiBpbnZvY2F0aW9ucyB0aGF0IG5ldmVyIHN0YXJ0IGEgc2Vzc2lvbi4gRG8gbm90IHN0YXJ0IGJhY2tncm91bmQgcmVzb3VyY2VzIHN1Y2ggYXMgcHJvY2Vzc2VzLCBzb2NrZXRzLCBmaWxlIHdhdGNoZXJzLCBvciB0aW1lcnMgZnJvbSB0aGUgZmFjdG9yeS5cblxuRGVmZXIgYmFja2dyb3VuZCByZXNvdXJjZSBzdGFydHVwIHVudGlsIGBzZXNzaW9uX3N0YXJ0YCBvciB0aGUgY29tbWFuZC90b29sL2V2ZW50IHRoYXQgbmVlZHMgdGhlIHJlc291cmNlLiBSZWdpc3RlciBhbiBpZGVtcG90ZW50IGBzZXNzaW9uX3NodXRkb3duYCBoYW5kbGVyIHRvIGNsb3NlIGFueSBzZXNzaW9uLXNjb3BlZCByZXNvdXJjZXMgeW91IHN0YXJ0LlxuXG4jIyMgRXh0ZW5zaW9uIFN0eWxlc1xuXG4qKlNpbmdsZSBmaWxlKiogLSBzaW1wbGVzdCwgZm9yIHNtYWxsIGV4dGVuc2lvbnM6XG5cbmBgYFxufi8ucGkvYWdlbnQvZXh0ZW5zaW9ucy9cbuKUlOKUgOKUgCBteS1leHRlbnNpb24udHNcbmBgYFxuXG4qKkRpcmVjdG9yeSB3aXRoIGluZGV4LnRzKiogLSBmb3IgbXVsdGktZmlsZSBleHRlbnNpb25zOlxuXG5gYGBcbn4vLnBpL2FnZW50L2V4dGVuc2lvbnMvXG7ilJTilIDilIAgbXktZXh0ZW5zaW9uL1xuICAgIOKUnOKUgOKUgCBpbmRleC50cyAgICAgICAgIyBFbnRyeSBwb2ludCAoZXhwb3J0cyBkZWZhdWx0IGZ1bmN0aW9uKVxuICAgIOKUnOKUgOKUgCB0b29scy50cyAgICAgICAgIyBIZWxwZXIgbW9kdWxlXG4gICAg4pSU4pSA4pSAIHV0aWxzLnRzICAgICAgICAjIEhlbHBlciBtb2R1bGVcbmBgYFxuXG4qKlBhY2thZ2Ugd2l0aCBkZXBlbmRlbmNpZXMqKiAtIGZvciBleHRlbnNpb25zIHRoYXQgbmVlZCBucG0gcGFja2FnZXM6XG5cbmBgYFxufi8ucGkvYWdlbnQvZXh0ZW5zaW9ucy9cbuKUlOKUgOKUgCBteS1leHRlbnNpb24vXG4gICAg4pSc4pSA4pSAIHBhY2thZ2UuanNvbiAgICAjIERlY2xhcmVzIGRlcGVuZGVuY2llcyBhbmQgZW50cnkgcG9pbnRzXG4gICAg4pSc4pSA4pSAIHBhY2thZ2UtbG9jay5qc29uXG4gICAg4pSc4pSA4pSAIG5vZGVfbW9kdWxlcy8gICAjIEFmdGVyIG5wbSBpbnN0YWxsXG4gICAg4pSU4pSA4pSAIHNyYy9cbiAgICAgICAg4pSU4pSA4pSAIGluZGV4LnRzXG5gYGBcblxuYGBganNvblxuLy8gcGFja2FnZS5qc29uXG57XG4gIFwibmFtZVwiOiBcIm15LWV4dGVuc2lvblwiLFxuICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJ6b2RcIjogXCJeMy4wLjBcIixcbiAgICBcImNoYWxrXCI6IFwiXjUuMC4wXCJcbiAgfSxcbiAgXCJwaVwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcIi4vc3JjL2luZGV4LnRzXCJdXG4gIH1cbn1cbmBgYFxuXG5SdW4gYG5wbSBpbnN0YWxsYCBpbiB0aGUgZXh0ZW5zaW9uIGRpcmVjdG9yeSwgdGhlbiBpbXBvcnRzIGZyb20gYG5vZGVfbW9kdWxlcy9gIHdvcmsgYXV0b21hdGljYWxseS5cblxuIyMgRXZlbnRzXG5cbiMjIyBMaWZlY3ljbGUgT3ZlcnZpZXdcblxuYGBgXG5waSBzdGFydHNcbiAg4pSCXG4gIOKUnOKUgOKWuiBwcm9qZWN0X3RydXN0ICh1c2VyL2dsb2JhbCBhbmQgQ0xJIGV4dGVuc2lvbnMgb25seSwgYmVmb3JlIHByb2plY3QgcmVzb3VyY2VzIGxvYWQpXG4gIOKUnOKUgOKWuiBzZXNzaW9uX3N0YXJ0IHsgcmVhc29uOiBcInN0YXJ0dXBcIiB9XG4gIOKUlOKUgOKWuiByZXNvdXJjZXNfZGlzY292ZXIgeyByZWFzb246IFwic3RhcnR1cFwiIH1cbiAgICAgIOKUglxuICAgICAg4pa8XG51c2VyIHNlbmRzIHByb21wdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJBcbiAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAg4pSc4pSA4pa6IChleHRlbnNpb24gY29tbWFuZHMgY2hlY2tlZCBmaXJzdCwgYnlwYXNzIGlmIGZvdW5kKSAg4pSCXG4gIOKUnOKUgOKWuiBpbnB1dCAoY2FuIGludGVyY2VwdCwgdHJhbnNmb3JtLCBvciBoYW5kbGUpICAgICAgICAgIOKUglxuICDilJzilIDilrogKHNraWxsL3RlbXBsYXRlIGV4cGFuc2lvbiBpZiBub3QgaGFuZGxlZCkgICAgICAgICAgICDilIJcbiAg4pSc4pSA4pa6IGJlZm9yZV9hZ2VudF9zdGFydCAoY2FuIGluamVjdCBtZXNzYWdlLCBtb2RpZnkgc3lzdGVtIHByb21wdClcbiAg4pSc4pSA4pa6IGFnZW50X3N0YXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG4gIOKUnOKUgOKWuiBtZXNzYWdlX3N0YXJ0IC8gbWVzc2FnZV91cGRhdGUgLyBtZXNzYWdlX2VuZCAgICAgICAgIOKUglxuICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICDilIIgICDilIzilIDilIDilIAgdHVybiAocmVwZWF0cyB3aGlsZSBMTE0gY2FsbHMgdG9vbHMpIOKUgOKUgOKUgOKUkCAgICAgICDilIJcbiAg4pSCICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUnOKUgOKWuiB0dXJuX3N0YXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSc4pSA4pa6IGNvbnRleHQgKGNhbiBtb2RpZnkgbWVzc2FnZXMpICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilJzilIDilrogYmVmb3JlX3Byb3ZpZGVyX3JlcXVlc3QgKGNhbiBpbnNwZWN0IG9yIHJlcGxhY2UgcGF5bG9hZClcbiAg4pSCICAg4pSc4pSA4pa6IGFmdGVyX3Byb3ZpZGVyX3Jlc3BvbnNlIChzdGF0dXMgKyBoZWFkZXJzLCBiZWZvcmUgc3RyZWFtIGNvbnN1bWUpXG4gIOKUgiAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilIIgICBMTE0gcmVzcG9uZHMsIG1heSBjYWxsIHRvb2xzOiAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSCICAgICDilJzilIDilrogdG9vbF9leGVjdXRpb25fc3RhcnQgICAgICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUgiAgICAg4pSc4pSA4pa6IHRvb2xfY2FsbCAoY2FuIGJsb2NrKSAgICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilIIgICAgIOKUnOKUgOKWuiB0b29sX2V4ZWN1dGlvbl91cGRhdGUgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSCICAgICDilJzilIDilrogdG9vbF9yZXN1bHQgKGNhbiBtb2RpZnkpICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUgiAgICAg4pSU4pSA4pa6IHRvb2xfZXhlY3V0aW9uX2VuZCAgICAgICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSU4pSA4pa6IHR1cm5fZW5kICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICDilJTilIDilrogYWdlbnRfZW5kICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG51c2VyIHNlbmRzIGFub3RoZXIgcHJvbXB0IOKXhOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuXG4vbmV3IChuZXcgc2Vzc2lvbikgb3IgL3Jlc3VtZSAoc3dpdGNoIHNlc3Npb24pXG4gIOKUnOKUgOKWuiBzZXNzaW9uX2JlZm9yZV9zd2l0Y2ggKGNhbiBjYW5jZWwpXG4gIOKUnOKUgOKWuiBzZXNzaW9uX3NodXRkb3duXG4gIOKUnOKUgOKWuiBzZXNzaW9uX3N0YXJ0IHsgcmVhc29uOiBcIm5ld1wiIHwgXCJyZXN1bWVcIiwgcHJldmlvdXNTZXNzaW9uRmlsZT8gfVxuICDilJTilIDilrogcmVzb3VyY2VzX2Rpc2NvdmVyIHsgcmVhc29uOiBcInN0YXJ0dXBcIiB9XG5cbi9mb3JrIG9yIC9jbG9uZVxuICDilJzilIDilrogc2Vzc2lvbl9iZWZvcmVfZm9yayAoY2FuIGNhbmNlbClcbiAg4pSc4pSA4pa6IHNlc3Npb25fc2h1dGRvd25cbiAg4pSc4pSA4pa6IHNlc3Npb25fc3RhcnQgeyByZWFzb246IFwiZm9ya1wiLCBwcmV2aW91c1Nlc3Npb25GaWxlIH1cbiAg4pSU4pSA4pa6IHJlc291cmNlc19kaXNjb3ZlciB7IHJlYXNvbjogXCJzdGFydHVwXCIgfVxuXG4vY29tcGFjdCBvciBhdXRvLWNvbXBhY3Rpb25cbiAg4pSc4pSA4pa6IHNlc3Npb25fYmVmb3JlX2NvbXBhY3QgKGNhbiBjYW5jZWwgb3IgY3VzdG9taXplKVxuICDilJTilIDilrogc2Vzc2lvbl9jb21wYWN0XG5cbi90cmVlIG5hdmlnYXRpb25cbiAg4pSc4pSA4pa6IHNlc3Npb25fYmVmb3JlX3RyZWUgKGNhbiBjYW5jZWwgb3IgY3VzdG9taXplKVxuICDilJTilIDilrogc2Vzc2lvbl90cmVlXG5cbi9tb2RlbCBvciBDdHJsK1AgKG1vZGVsIHNlbGVjdGlvbi9jeWNsaW5nKVxuICDilJzilIDilrogdGhpbmtpbmdfbGV2ZWxfc2VsZWN0IChpZiBtb2RlbCBjaGFuZ2UgY2hhbmdlcy9jbGFtcHMgdGhpbmtpbmcgbGV2ZWwpXG4gIOKUlOKUgOKWuiBtb2RlbF9zZWxlY3RcblxudGhpbmtpbmcgbGV2ZWwgY2hhbmdlcyAoc2V0dGluZ3MsIGtleWJpbmRpbmcsIHBpLnNldFRoaW5raW5nTGV2ZWwoKSlcbiAg4pSU4pSA4pa6IHRoaW5raW5nX2xldmVsX3NlbGVjdFxuXG5leGl0IChDdHJsK0MsIEN0cmwrRCwgU0lHSFVQLCBTSUdURVJNKVxuICDilJTilIDilrogc2Vzc2lvbl9zaHV0ZG93blxuYGBgXG5cbiMjIyBTdGFydHVwIEV2ZW50c1xuXG4jIyMjIHByb2plY3RfdHJ1c3RcblxuRmlyZWQgYmVmb3JlIHBpIGRlY2lkZXMgd2hldGhlciB0byB0cnVzdCBhIHByb2plY3Qgd2l0aCBkeW5hbWljIGNvbmZpZ3MgKGAucGlgIG9yIGAuYWdlbnRzL3NraWxsc2ApLiBJdCBydW5zIGR1cmluZyBzdGFydHVwIGFuZCB3aGVuIHNlc3Npb24gcmVwbGFjZW1lbnQgKGZvciBleGFtcGxlIGAvcmVzdW1lYCkgZW50ZXJzIGEgY3dkIHdob3NlIHRydXN0IGhhcyBub3QgYmVlbiByZXNvbHZlZCBpbiB0aGUgY3VycmVudCBwcm9jZXNzLiBPbmx5IHVzZXIvZ2xvYmFsIGV4dGVuc2lvbnMgYW5kIENMSSBgLWVgIGV4dGVuc2lvbnMgcGFydGljaXBhdGU7IHByb2plY3QtbG9jYWwgZXh0ZW5zaW9ucyBhcmUgbm90IGxvYWRlZCB1bnRpbCBhZnRlciB0cnVzdCBpcyByZXNvbHZlZC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJwcm9qZWN0X3RydXN0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LmN3ZCAtIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnlcbiAgLy8gY3R4IGhhcyBhIGxpbWl0ZWQgdHJ1c3QgY29udGV4dDogY3dkLCBtb2RlLCBoYXNVSSwgYW5kIHNlbGVjdC9jb25maXJtL2lucHV0L25vdGlmeSBVSSBoZWxwZXJzXG4gIGlmIChhd2FpdCBjdHgudWkuY29uZmlybShcIlRydXN0IHByb2plY3Q/XCIsIGV2ZW50LmN3ZCkpIHtcbiAgICByZXR1cm4geyB0cnVzdGVkOiBcInllc1wiLCByZW1lbWJlcjogdHJ1ZSB9O1xuICB9XG4gIHJldHVybiB7IHRydXN0ZWQ6IFwidW5kZWNpZGVkXCIgfTtcbn0pO1xuYGBgXG5cbkEgYHByb2plY3RfdHJ1c3RgIGhhbmRsZXIgbXVzdCByZXR1cm4gYHsgdHJ1c3RlZDogXCJ5ZXNcIiB8IFwibm9cIiB8IFwidW5kZWNpZGVkXCIgfWAuIEEgdXNlci9nbG9iYWwgb3IgQ0xJIGV4dGVuc2lvbiB0aGF0IHJldHVybnMgYFwieWVzXCJgIG9yIGBcIm5vXCJgIG93bnMgdGhlIGRlY2lzaW9uOyB0aGUgZmlyc3QgeWVzL25vIGRlY2lzaW9uIHdpbnMgYW5kIHN1cHByZXNzZXMgdGhlIGJ1aWx0LWluIHRydXN0IHByb21wdC4gVXNlIGByZW1lbWJlcjogdHJ1ZWAgdG8gcGVyc2lzdCBhIHllcy9ubyBkZWNpc2lvbjsgb3RoZXJ3aXNlIGl0IGFwcGxpZXMgb25seSB0byB0aGUgY3VycmVudCBwcm9jZXNzLiBSZXR1cm4gYFwidW5kZWNpZGVkXCJgIHRvIGxldCBsYXRlciBoYW5kbGVycyBvciB0aGUgYnVpbHQtaW4gdHJ1c3QgZmxvdyBkZWNpZGUuIENoZWNrIGBjdHguaGFzVUlgIGJlZm9yZSBwcm9tcHRpbmcuIElmIG5vIGhhbmRsZXIgcmV0dXJucyB5ZXMvbm8sIG5vcm1hbCB0cnVzdCByZXNvbHV0aW9uIGNvbnRpbnVlczogc2F2ZWQgYHRydXN0Lmpzb25gIGRlY2lzaW9ucyBhcHBseSBmaXJzdCwgdGhlbiBgZGVmYXVsdFByb2plY3RUcnVzdGAgY29udHJvbHMgd2hldGhlciBwaSBhc2tzLCB0cnVzdHMsIG9yIGRlY2xpbmVzIGJ5IGRlZmF1bHQuXG5cbiMjIyBSZXNvdXJjZSBFdmVudHNcblxuIyMjIyByZXNvdXJjZXNfZGlzY292ZXJcblxuRmlyZWQgYWZ0ZXIgYHNlc3Npb25fc3RhcnRgIHNvIGV4dGVuc2lvbnMgY2FuIGNvbnRyaWJ1dGUgYWRkaXRpb25hbCBza2lsbCwgcHJvbXB0LCBhbmQgdGhlbWUgcGF0aHMuXG5UaGUgc3RhcnR1cCBwYXRoIHVzZXMgYHJlYXNvbjogXCJzdGFydHVwXCJgLiBSZWxvYWQgdXNlcyBgcmVhc29uOiBcInJlbG9hZFwiYC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJyZXNvdXJjZXNfZGlzY292ZXJcIiwgYXN5bmMgKGV2ZW50LCBfY3R4KSA9PiB7XG4gIC8vIGV2ZW50LmN3ZCAtIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnlcbiAgLy8gZXZlbnQucmVhc29uIC0gXCJzdGFydHVwXCIgfCBcInJlbG9hZFwiXG4gIHJldHVybiB7XG4gICAgc2tpbGxQYXRoczogW1wiL3BhdGgvdG8vc2tpbGxzXCJdLFxuICAgIHByb21wdFBhdGhzOiBbXCIvcGF0aC90by9wcm9tcHRzXCJdLFxuICAgIHRoZW1lUGF0aHM6IFtcIi9wYXRoL3RvL3RoZW1lc1wiXSxcbiAgfTtcbn0pO1xuYGBgXG5cbiMjIyBTZXNzaW9uIEV2ZW50c1xuXG5TZWUgW1Nlc3Npb24gRm9ybWF0XShzZXNzaW9uLWZvcm1hdC5tZCkgZm9yIHNlc3Npb24gc3RvcmFnZSBpbnRlcm5hbHMgYW5kIHRoZSBTZXNzaW9uTWFuYWdlciBBUEkuXG5cbiMjIyMgc2Vzc2lvbl9zdGFydFxuXG5GaXJlZCB3aGVuIGEgc2Vzc2lvbiBpcyBzdGFydGVkLCBsb2FkZWQsIG9yIHJlbG9hZGVkLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQucmVhc29uIC0gXCJzdGFydHVwXCIgfCBcInJlbG9hZFwiIHwgXCJuZXdcIiB8IFwicmVzdW1lXCIgfCBcImZvcmtcIlxuICAvLyBldmVudC5wcmV2aW91c1Nlc3Npb25GaWxlIC0gcHJlc2VudCBmb3IgXCJuZXdcIiwgXCJyZXN1bWVcIiwgYW5kIFwiZm9ya1wiXG4gIGN0eC51aS5ub3RpZnkoYFNlc3Npb246ICR7Y3R4LnNlc3Npb25NYW5hZ2VyLmdldFNlc3Npb25GaWxlKCkgPz8gXCJlcGhlbWVyYWxcIn1gLCBcImluZm9cIik7XG59KTtcbmBgYFxuXG4jIyMjIHNlc3Npb25fYmVmb3JlX3N3aXRjaFxuXG5GaXJlZCBiZWZvcmUgc3RhcnRpbmcgYSBuZXcgc2Vzc2lvbiAoYC9uZXdgKSBvciBzd2l0Y2hpbmcgc2Vzc2lvbnMgKGAvcmVzdW1lYCkuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwic2Vzc2lvbl9iZWZvcmVfc3dpdGNoXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnJlYXNvbiAtIFwibmV3XCIgb3IgXCJyZXN1bWVcIlxuICAvLyBldmVudC50YXJnZXRTZXNzaW9uRmlsZSAtIHNlc3Npb24gd2UncmUgc3dpdGNoaW5nIHRvIChvbmx5IGZvciBcInJlc3VtZVwiKVxuXG4gIGlmIChldmVudC5yZWFzb24gPT09IFwibmV3XCIpIHtcbiAgICBjb25zdCBvayA9IGF3YWl0IGN0eC51aS5jb25maXJtKFwiQ2xlYXI/XCIsIFwiRGVsZXRlIGFsbCBtZXNzYWdlcz9cIik7XG4gICAgaWYgKCFvaykgcmV0dXJuIHsgY2FuY2VsOiB0cnVlIH07XG4gIH1cbn0pO1xuYGBgXG5cbkFmdGVyIGEgc3VjY2Vzc2Z1bCBzd2l0Y2ggb3IgbmV3LXNlc3Npb24gYWN0aW9uLCBwaSBlbWl0cyBgc2Vzc2lvbl9zaHV0ZG93bmAgZm9yIHRoZSBvbGQgZXh0ZW5zaW9uIGluc3RhbmNlLCByZWxvYWRzIGFuZCByZWJpbmRzIGV4dGVuc2lvbnMgZm9yIHRoZSBuZXcgc2Vzc2lvbiwgdGhlbiBlbWl0cyBgc2Vzc2lvbl9zdGFydGAgd2l0aCBgcmVhc29uOiBcIm5ld1wiIHwgXCJyZXN1bWVcImAgYW5kIGBwcmV2aW91c1Nlc3Npb25GaWxlYC5cbkRvIGNsZWFudXAgd29yayBpbiBgc2Vzc2lvbl9zaHV0ZG93bmAsIHRoZW4gcmVlc3RhYmxpc2ggYW55IGluLW1lbW9yeSBzdGF0ZSBpbiBgc2Vzc2lvbl9zdGFydGAuXG5cbiMjIyMgc2Vzc2lvbl9iZWZvcmVfZm9ya1xuXG5GaXJlZCB3aGVuIGZvcmtpbmcgdmlhIGAvZm9ya2Agb3IgY2xvbmluZyB2aWEgYC9jbG9uZWAuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwic2Vzc2lvbl9iZWZvcmVfZm9ya1wiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5lbnRyeUlkIC0gSUQgb2YgdGhlIHNlbGVjdGVkIGVudHJ5XG4gIC8vIGV2ZW50LnBvc2l0aW9uIC0gXCJiZWZvcmVcIiBmb3IgL2ZvcmssIFwiYXRcIiBmb3IgL2Nsb25lXG4gIHJldHVybiB7IGNhbmNlbDogdHJ1ZSB9OyAvLyBDYW5jZWwgZm9yay9jbG9uZVxuICAvLyBPUlxuICByZXR1cm4geyBza2lwQ29udmVyc2F0aW9uUmVzdG9yZTogdHJ1ZSB9OyAvLyBSZXNlcnZlZCBmb3IgZnV0dXJlIGNvbnZlcnNhdGlvbiByZXN0b3JlIGNvbnRyb2xcbn0pO1xuYGBgXG5cbkFmdGVyIGEgc3VjY2Vzc2Z1bCBmb3JrIG9yIGNsb25lLCBwaSBlbWl0cyBgc2Vzc2lvbl9zaHV0ZG93bmAgZm9yIHRoZSBvbGQgZXh0ZW5zaW9uIGluc3RhbmNlLCByZWxvYWRzIGFuZCByZWJpbmRzIGV4dGVuc2lvbnMgZm9yIHRoZSBuZXcgc2Vzc2lvbiwgdGhlbiBlbWl0cyBgc2Vzc2lvbl9zdGFydGAgd2l0aCBgcmVhc29uOiBcImZvcmtcImAgYW5kIGBwcmV2aW91c1Nlc3Npb25GaWxlYC5cbkRvIGNsZWFudXAgd29yayBpbiBgc2Vzc2lvbl9zaHV0ZG93bmAsIHRoZW4gcmVlc3RhYmxpc2ggYW55IGluLW1lbW9yeSBzdGF0ZSBpbiBgc2Vzc2lvbl9zdGFydGAuXG5cbiMjIyMgc2Vzc2lvbl9iZWZvcmVfY29tcGFjdCAvIHNlc3Npb25fY29tcGFjdFxuXG5GaXJlZCBvbiBjb21wYWN0aW9uLiBTZWUgW2NvbXBhY3Rpb24ubWRdKGNvbXBhY3Rpb24ubWQpIGZvciBkZXRhaWxzLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInNlc3Npb25fYmVmb3JlX2NvbXBhY3RcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgY29uc3QgeyBwcmVwYXJhdGlvbiwgYnJhbmNoRW50cmllcywgY3VzdG9tSW5zdHJ1Y3Rpb25zLCBzaWduYWwgfSA9IGV2ZW50O1xuXG4gIC8vIENhbmNlbDpcbiAgcmV0dXJuIHsgY2FuY2VsOiB0cnVlIH07XG5cbiAgLy8gQ3VzdG9tIHN1bW1hcnk6XG4gIHJldHVybiB7XG4gICAgY29tcGFjdGlvbjoge1xuICAgICAgc3VtbWFyeTogXCIuLi5cIixcbiAgICAgIGZpcnN0S2VwdEVudHJ5SWQ6IHByZXBhcmF0aW9uLmZpcnN0S2VwdEVudHJ5SWQsXG4gICAgICB0b2tlbnNCZWZvcmU6IHByZXBhcmF0aW9uLnRva2Vuc0JlZm9yZSxcbiAgICB9XG4gIH07XG59KTtcblxucGkub24oXCJzZXNzaW9uX2NvbXBhY3RcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQuY29tcGFjdGlvbkVudHJ5IC0gdGhlIHNhdmVkIGNvbXBhY3Rpb25cbiAgLy8gZXZlbnQuZnJvbUV4dGVuc2lvbiAtIHdoZXRoZXIgZXh0ZW5zaW9uIHByb3ZpZGVkIGl0XG59KTtcbmBgYFxuXG4jIyMjIHNlc3Npb25fYmVmb3JlX3RyZWUgLyBzZXNzaW9uX3RyZWVcblxuRmlyZWQgb24gYC90cmVlYCBuYXZpZ2F0aW9uLiBTZWUgW1Nlc3Npb25zXShzZXNzaW9ucy5tZCkgZm9yIHRyZWUgbmF2aWdhdGlvbiBjb25jZXB0cy5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJzZXNzaW9uX2JlZm9yZV90cmVlXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIGNvbnN0IHsgcHJlcGFyYXRpb24sIHNpZ25hbCB9ID0gZXZlbnQ7XG4gIHJldHVybiB7IGNhbmNlbDogdHJ1ZSB9O1xuICAvLyBPUiBwcm92aWRlIGN1c3RvbSBzdW1tYXJ5OlxuICByZXR1cm4geyBzdW1tYXJ5OiB7IHN1bW1hcnk6IFwiLi4uXCIsIGRldGFpbHM6IHt9IH0gfTtcbn0pO1xuXG5waS5vbihcInNlc3Npb25fdHJlZVwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5uZXdMZWFmSWQsIG9sZExlYWZJZCwgc3VtbWFyeUVudHJ5LCBmcm9tRXh0ZW5zaW9uXG59KTtcbmBgYFxuXG4jIyMjIHNlc3Npb25fc2h1dGRvd25cblxuRmlyZWQgYmVmb3JlIGEgc3RhcnRlZCBzZXNzaW9uIHJ1bnRpbWUgaXMgdG9ybiBkb3duLiBVc2UgdGhpcyB0byBjbGVhbiB1cCByZXNvdXJjZXMgb3BlbmVkIGZyb20gYHNlc3Npb25fc3RhcnRgIG9yIG90aGVyIHNlc3Npb24tc2NvcGVkIGhvb2tzLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInNlc3Npb25fc2h1dGRvd25cIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQucmVhc29uIC0gXCJxdWl0XCIgfCBcInJlbG9hZFwiIHwgXCJuZXdcIiB8IFwicmVzdW1lXCIgfCBcImZvcmtcIlxuICAvLyBldmVudC50YXJnZXRTZXNzaW9uRmlsZSAtIGRlc3RpbmF0aW9uIHNlc3Npb24gZm9yIHNlc3Npb24gcmVwbGFjZW1lbnQgZmxvd3NcbiAgLy8gQ2xlYW51cCwgc2F2ZSBzdGF0ZSwgZXRjLlxufSk7XG5gYGBcblxuIyMjIEFnZW50IEV2ZW50c1xuXG4jIyMjIGJlZm9yZV9hZ2VudF9zdGFydFxuXG5GaXJlZCBhZnRlciB1c2VyIHN1Ym1pdHMgcHJvbXB0LCBiZWZvcmUgYWdlbnQgbG9vcC4gQ2FuIGluamVjdCBhIG1lc3NhZ2UgYW5kL29yIG1vZGlmeSB0aGUgc3lzdGVtIHByb21wdC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJiZWZvcmVfYWdlbnRfc3RhcnRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQucHJvbXB0IC0gdXNlcidzIHByb21wdCB0ZXh0XG4gIC8vIGV2ZW50LmltYWdlcyAtIGF0dGFjaGVkIGltYWdlcyAoaWYgYW55KVxuICAvLyBldmVudC5zeXN0ZW1Qcm9tcHQgLSBjdXJyZW50IGNoYWluZWQgc3lzdGVtIHByb21wdCBmb3IgdGhpcyBoYW5kbGVyXG4gIC8vICAgKGluY2x1ZGVzIGNoYW5nZXMgZnJvbSBlYXJsaWVyIGJlZm9yZV9hZ2VudF9zdGFydCBoYW5kbGVycylcbiAgLy8gZXZlbnQuc3lzdGVtUHJvbXB0T3B0aW9ucyAtIHN0cnVjdHVyZWQgb3B0aW9ucyB1c2VkIHRvIGJ1aWxkIHRoZSBzeXN0ZW0gcHJvbXB0XG4gIC8vICAgLmN1c3RvbVByb21wdCAtIGFueSBjdXN0b20gc3lzdGVtIHByb21wdCAoZnJvbSAtLXN5c3RlbS1wcm9tcHQsIFNZU1RFTS5tZCwgb3IgY3VzdG9tIHRlbXBsYXRlcylcbiAgLy8gICAuc2VsZWN0ZWRUb29scyAtIHRvb2xzIGN1cnJlbnRseSBhY3RpdmUgaW4gdGhlIHByb21wdFxuICAvLyAgIC50b29sU25pcHBldHMgLSBvbmUtbGluZSBkZXNjcmlwdGlvbnMgZm9yIGVhY2ggdG9vbFxuICAvLyAgIC5wcm9tcHRHdWlkZWxpbmVzIC0gY3VzdG9tIGd1aWRlbGluZSBidWxsZXRzXG4gIC8vICAgLmFwcGVuZFN5c3RlbVByb21wdCAtIHRleHQgZnJvbSAtLWFwcGVuZC1zeXN0ZW0tcHJvbXB0IGZsYWdzXG4gIC8vICAgLmN3ZCAtIHdvcmtpbmcgZGlyZWN0b3J5XG4gIC8vICAgLmNvbnRleHRGaWxlcyAtIEFHRU5UUy5tZCBmaWxlcyBhbmQgb3RoZXIgbG9hZGVkIGNvbnRleHQgZmlsZXNcbiAgLy8gICAuc2tpbGxzIC0gbG9hZGVkIHNraWxsc1xuXG4gIHJldHVybiB7XG4gICAgLy8gSW5qZWN0IGEgcGVyc2lzdGVudCBtZXNzYWdlIChzdG9yZWQgaW4gc2Vzc2lvbiwgc2VudCB0byBMTE0pXG4gICAgbWVzc2FnZToge1xuICAgICAgY3VzdG9tVHlwZTogXCJteS1leHRlbnNpb25cIixcbiAgICAgIGNvbnRlbnQ6IFwiQWRkaXRpb25hbCBjb250ZXh0IGZvciB0aGUgTExNXCIsXG4gICAgICBkaXNwbGF5OiB0cnVlLFxuICAgIH0sXG4gICAgLy8gUmVwbGFjZSB0aGUgc3lzdGVtIHByb21wdCBmb3IgdGhpcyB0dXJuIChjaGFpbmVkIGFjcm9zcyBleHRlbnNpb25zKVxuICAgIHN5c3RlbVByb21wdDogZXZlbnQuc3lzdGVtUHJvbXB0ICsgXCJcXG5cXG5FeHRyYSBpbnN0cnVjdGlvbnMgZm9yIHRoaXMgdHVybi4uLlwiLFxuICB9O1xufSk7XG5gYGBcblxuVGhlIGBzeXN0ZW1Qcm9tcHRPcHRpb25zYCBmaWVsZCBnaXZlcyBleHRlbnNpb25zIGFjY2VzcyB0byB0aGUgc2FtZSBzdHJ1Y3R1cmVkIGRhdGEgUGkgdXNlcyB0byBidWlsZCB0aGUgc3lzdGVtIHByb21wdC4gVGhpcyBsZXRzIHlvdSBpbnNwZWN0IHdoYXQgUGkgaGFzIGxvYWRlZCDigJQgY3VzdG9tIHByb21wdHMsIGd1aWRlbGluZXMsIHRvb2wgc25pcHBldHMsIGNvbnRleHQgZmlsZXMsIHNraWxscyDigJQgd2l0aG91dCByZS1kaXNjb3ZlcmluZyByZXNvdXJjZXMgb3IgcmUtcGFyc2luZyBmbGFncy4gVXNlIGl0IHdoZW4geW91ciBleHRlbnNpb24gbmVlZHMgdG8gbWFrZSBkZWVwLCBpbmZvcm1lZCBjaGFuZ2VzIHRvIHRoZSBzeXN0ZW0gcHJvbXB0IHdoaWxlIHJlc3BlY3RpbmcgdXNlci1wcm92aWRlZCBjb25maWd1cmF0aW9uLlxuXG5JbnNpZGUgYGJlZm9yZV9hZ2VudF9zdGFydGAsIGBldmVudC5zeXN0ZW1Qcm9tcHRgIGFuZCBgY3R4LmdldFN5c3RlbVByb21wdCgpYCBib3RoIHJlZmxlY3QgdGhlIGNoYWluZWQgc3lzdGVtIHByb21wdCBhcyBvZiB0aGUgY3VycmVudCBoYW5kbGVyLiBMYXRlciBgYmVmb3JlX2FnZW50X3N0YXJ0YCBoYW5kbGVycyBjYW4gc3RpbGwgbW9kaWZ5IGl0IGFnYWluLlxuXG4jIyMjIGFnZW50X3N0YXJ0IC8gYWdlbnRfZW5kXG5cbkZpcmVkIG9uY2UgcGVyIHVzZXIgcHJvbXB0LlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcImFnZW50X3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge30pO1xuXG5waS5vbihcImFnZW50X2VuZFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5tZXNzYWdlcyAtIG1lc3NhZ2VzIGZyb20gdGhpcyBwcm9tcHRcbn0pO1xuYGBgXG5cbiMjIyMgdHVybl9zdGFydCAvIHR1cm5fZW5kXG5cbkZpcmVkIGZvciBlYWNoIHR1cm4gKG9uZSBMTE0gcmVzcG9uc2UgKyB0b29sIGNhbGxzKS5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJ0dXJuX3N0YXJ0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnR1cm5JbmRleCwgZXZlbnQudGltZXN0YW1wXG59KTtcblxucGkub24oXCJ0dXJuX2VuZFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC50dXJuSW5kZXgsIGV2ZW50Lm1lc3NhZ2UsIGV2ZW50LnRvb2xSZXN1bHRzXG59KTtcbmBgYFxuXG4jIyMjIG1lc3NhZ2Vfc3RhcnQgLyBtZXNzYWdlX3VwZGF0ZSAvIG1lc3NhZ2VfZW5kXG5cbkZpcmVkIGZvciBtZXNzYWdlIGxpZmVjeWNsZSB1cGRhdGVzLlxuXG4tIGBtZXNzYWdlX3N0YXJ0YCBhbmQgYG1lc3NhZ2VfZW5kYCBmaXJlIGZvciB1c2VyLCBhc3Npc3RhbnQsIGFuZCB0b29sUmVzdWx0IG1lc3NhZ2VzLlxuLSBgbWVzc2FnZV91cGRhdGVgIGZpcmVzIGZvciBhc3Npc3RhbnQgc3RyZWFtaW5nIHVwZGF0ZXMuXG4tIGBtZXNzYWdlX2VuZGAgaGFuZGxlcnMgY2FuIHJldHVybiBgeyBtZXNzYWdlIH1gIHRvIHJlcGxhY2UgdGhlIGZpbmFsaXplZCBtZXNzYWdlLiBUaGUgcmVwbGFjZW1lbnQgbXVzdCBrZWVwIHRoZSBzYW1lIGByb2xlYC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJtZXNzYWdlX3N0YXJ0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50Lm1lc3NhZ2Vcbn0pO1xuXG5waS5vbihcIm1lc3NhZ2VfdXBkYXRlXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50Lm1lc3NhZ2VcbiAgLy8gZXZlbnQuYXNzaXN0YW50TWVzc2FnZUV2ZW50ICh0b2tlbi1ieS10b2tlbiBzdHJlYW0gZXZlbnQpXG59KTtcblxucGkub24oXCJtZXNzYWdlX2VuZFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICBpZiAoZXZlbnQubWVzc2FnZS5yb2xlICE9PSBcImFzc2lzdGFudFwiKSByZXR1cm47XG5cbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlOiB7XG4gICAgICAuLi5ldmVudC5tZXNzYWdlLFxuICAgICAgdXNhZ2U6IHtcbiAgICAgICAgLi4uZXZlbnQubWVzc2FnZS51c2FnZSxcbiAgICAgICAgY29zdDoge1xuICAgICAgICAgIC4uLmV2ZW50Lm1lc3NhZ2UudXNhZ2UuY29zdCxcbiAgICAgICAgICB0b3RhbDogMC4xMjMsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59KTtcbmBgYFxuXG4jIyMjIHRvb2xfZXhlY3V0aW9uX3N0YXJ0IC8gdG9vbF9leGVjdXRpb25fdXBkYXRlIC8gdG9vbF9leGVjdXRpb25fZW5kXG5cbkZpcmVkIGZvciB0b29sIGV4ZWN1dGlvbiBsaWZlY3ljbGUgdXBkYXRlcy5cblxuSW4gcGFyYWxsZWwgdG9vbCBtb2RlOlxuLSBgdG9vbF9leGVjdXRpb25fc3RhcnRgIGlzIGVtaXR0ZWQgaW4gYXNzaXN0YW50IHNvdXJjZSBvcmRlciBkdXJpbmcgdGhlIHByZWZsaWdodCBwaGFzZVxuLSBgdG9vbF9leGVjdXRpb25fdXBkYXRlYCBldmVudHMgbWF5IGludGVybGVhdmUgYWNyb3NzIHRvb2xzXG4tIGB0b29sX2V4ZWN1dGlvbl9lbmRgIGlzIGVtaXR0ZWQgaW4gdG9vbCBjb21wbGV0aW9uIG9yZGVyIGFmdGVyIGVhY2ggdG9vbCBpcyBmaW5hbGl6ZWRcbi0gZmluYWwgYHRvb2xSZXN1bHRgIG1lc3NhZ2UgZXZlbnRzIGFyZSBzdGlsbCBlbWl0dGVkIGxhdGVyIGluIGFzc2lzdGFudCBzb3VyY2Ugb3JkZXJcblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJ0b29sX2V4ZWN1dGlvbl9zdGFydFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC50b29sQ2FsbElkLCBldmVudC50b29sTmFtZSwgZXZlbnQuYXJnc1xufSk7XG5cbnBpLm9uKFwidG9vbF9leGVjdXRpb25fdXBkYXRlXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnRvb2xDYWxsSWQsIGV2ZW50LnRvb2xOYW1lLCBldmVudC5hcmdzLCBldmVudC5wYXJ0aWFsUmVzdWx0XG59KTtcblxucGkub24oXCJ0b29sX2V4ZWN1dGlvbl9lbmRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQudG9vbENhbGxJZCwgZXZlbnQudG9vbE5hbWUsIGV2ZW50LnJlc3VsdCwgZXZlbnQuaXNFcnJvclxufSk7XG5gYGBcblxuIyMjIyBjb250ZXh0XG5cbkZpcmVkIGJlZm9yZSBlYWNoIExMTSBjYWxsLiBNb2RpZnkgbWVzc2FnZXMgbm9uLWRlc3RydWN0aXZlbHkuIFNlZSBbU2Vzc2lvbiBGb3JtYXRdKHNlc3Npb24tZm9ybWF0Lm1kKSBmb3IgbWVzc2FnZSB0eXBlcy5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJjb250ZXh0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50Lm1lc3NhZ2VzIC0gZGVlcCBjb3B5LCBzYWZlIHRvIG1vZGlmeVxuICBjb25zdCBmaWx0ZXJlZCA9IGV2ZW50Lm1lc3NhZ2VzLmZpbHRlcihtID0+ICFzaG91bGRQcnVuZShtKSk7XG4gIHJldHVybiB7IG1lc3NhZ2VzOiBmaWx0ZXJlZCB9O1xufSk7XG5gYGBcblxuIyMjIyBiZWZvcmVfcHJvdmlkZXJfcmVxdWVzdFxuXG5GaXJlZCBhZnRlciB0aGUgcHJvdmlkZXItc3BlY2lmaWMgcGF5bG9hZCBpcyBidWlsdCwgcmlnaHQgYmVmb3JlIHRoZSByZXF1ZXN0IGlzIHNlbnQuIEhhbmRsZXJzIHJ1biBpbiBleHRlbnNpb24gbG9hZCBvcmRlci4gUmV0dXJuaW5nIGB1bmRlZmluZWRgIGtlZXBzIHRoZSBwYXlsb2FkIHVuY2hhbmdlZC4gUmV0dXJuaW5nIGFueSBvdGhlciB2YWx1ZSByZXBsYWNlcyB0aGUgcGF5bG9hZCBmb3IgbGF0ZXIgaGFuZGxlcnMgYW5kIGZvciB0aGUgYWN0dWFsIHJlcXVlc3QuXG5cblRoaXMgaG9vayBjYW4gcmV3cml0ZSBwcm92aWRlci1sZXZlbCBzeXN0ZW0gaW5zdHJ1Y3Rpb25zIG9yIHJlbW92ZSB0aGVtIGVudGlyZWx5LiBUaG9zZSBwYXlsb2FkLWxldmVsIGNoYW5nZXMgYXJlIG5vdCByZWZsZWN0ZWQgYnkgYGN0eC5nZXRTeXN0ZW1Qcm9tcHQoKWAsIHdoaWNoIHJlcG9ydHMgUGkncyBzeXN0ZW0gcHJvbXB0IHN0cmluZyByYXRoZXIgdGhhbiB0aGUgZmluYWwgc2VyaWFsaXplZCBwcm92aWRlciBwYXlsb2FkLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcImJlZm9yZV9wcm92aWRlcl9yZXF1ZXN0XCIsIChldmVudCwgY3R4KSA9PiB7XG4gIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGV2ZW50LnBheWxvYWQsIG51bGwsIDIpKTtcblxuICAvLyBPcHRpb25hbDogcmVwbGFjZSBwYXlsb2FkXG4gIC8vIHJldHVybiB7IC4uLmV2ZW50LnBheWxvYWQsIHRlbXBlcmF0dXJlOiAwIH07XG59KTtcbmBgYFxuXG5UaGlzIGlzIG1haW5seSB1c2VmdWwgZm9yIGRlYnVnZ2luZyBwcm92aWRlciBzZXJpYWxpemF0aW9uIGFuZCBjYWNoZSBiZWhhdmlvci5cblxuIyMjIyBhZnRlcl9wcm92aWRlcl9yZXNwb25zZVxuXG5GaXJlZCBhZnRlciBhbiBIVFRQIHJlc3BvbnNlIGlzIHJlY2VpdmVkIGFuZCBiZWZvcmUgaXRzIHN0cmVhbSBib2R5IGlzIGNvbnN1bWVkLiBIYW5kbGVycyBydW4gaW4gZXh0ZW5zaW9uIGxvYWQgb3JkZXIuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwiYWZ0ZXJfcHJvdmlkZXJfcmVzcG9uc2VcIiwgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQuc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZVxuICAvLyBldmVudC5oZWFkZXJzIC0gbm9ybWFsaXplZCByZXNwb25zZSBoZWFkZXJzXG4gIGlmIChldmVudC5zdGF0dXMgPT09IDQyOSkge1xuICAgIGNvbnNvbGUubG9nKFwicmF0ZSBsaW1pdGVkXCIsIGV2ZW50LmhlYWRlcnNbXCJyZXRyeS1hZnRlclwiXSk7XG4gIH1cbn0pO1xuYGBgXG5cbkhlYWRlciBhdmFpbGFiaWxpdHkgZGVwZW5kcyBvbiBwcm92aWRlciBhbmQgdHJhbnNwb3J0LiBQcm92aWRlcnMgdGhhdCBhYnN0cmFjdCBIVFRQIHJlc3BvbnNlcyBtYXkgbm90IGV4cG9zZSBoZWFkZXJzLlxuXG4jIyMgTW9kZWwgRXZlbnRzXG5cbiMjIyMgbW9kZWxfc2VsZWN0XG5cbkZpcmVkIHdoZW4gdGhlIG1vZGVsIGNoYW5nZXMgdmlhIGAvbW9kZWxgIGNvbW1hbmQsIG1vZGVsIGN5Y2xpbmcgKGBDdHJsK1BgKSwgb3Igc2Vzc2lvbiByZXN0b3JlLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcIm1vZGVsX3NlbGVjdFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5tb2RlbCAtIG5ld2x5IHNlbGVjdGVkIG1vZGVsXG4gIC8vIGV2ZW50LnByZXZpb3VzTW9kZWwgLSBwcmV2aW91cyBtb2RlbCAodW5kZWZpbmVkIGlmIGZpcnN0IHNlbGVjdGlvbilcbiAgLy8gZXZlbnQuc291cmNlIC0gXCJzZXRcIiB8IFwiY3ljbGVcIiB8IFwicmVzdG9yZVwiXG5cbiAgY29uc3QgcHJldiA9IGV2ZW50LnByZXZpb3VzTW9kZWxcbiAgICA/IGAke2V2ZW50LnByZXZpb3VzTW9kZWwucHJvdmlkZXJ9LyR7ZXZlbnQucHJldmlvdXNNb2RlbC5pZH1gXG4gICAgOiBcIm5vbmVcIjtcbiAgY29uc3QgbmV4dCA9IGAke2V2ZW50Lm1vZGVsLnByb3ZpZGVyfS8ke2V2ZW50Lm1vZGVsLmlkfWA7XG5cbiAgY3R4LnVpLm5vdGlmeShgTW9kZWwgY2hhbmdlZCAoJHtldmVudC5zb3VyY2V9KTogJHtwcmV2fSAtPiAke25leHR9YCwgXCJpbmZvXCIpO1xufSk7XG5gYGBcblxuVXNlIHRoaXMgdG8gdXBkYXRlIFVJIGVsZW1lbnRzIChzdGF0dXMgYmFycywgZm9vdGVycykgb3IgcGVyZm9ybSBtb2RlbC1zcGVjaWZpYyBpbml0aWFsaXphdGlvbiB3aGVuIHRoZSBhY3RpdmUgbW9kZWwgY2hhbmdlcy5cblxuIyMjIyB0aGlua2luZ19sZXZlbF9zZWxlY3RcblxuRmlyZWQgd2hlbiB0aGUgdGhpbmtpbmcgbGV2ZWwgY2hhbmdlcy4gVGhpcyBpcyBub3RpZmljYXRpb24tb25seTsgaGFuZGxlciByZXR1cm4gdmFsdWVzIGFyZSBpZ25vcmVkLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInRoaW5raW5nX2xldmVsX3NlbGVjdFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5sZXZlbCAtIG5ld2x5IHNlbGVjdGVkIHRoaW5raW5nIGxldmVsXG4gIC8vIGV2ZW50LnByZXZpb3VzTGV2ZWwgLSBwcmV2aW91cyB0aGlua2luZyBsZXZlbFxuXG4gIGN0eC51aS5zZXRTdGF0dXMoXCJ0aGlua2luZ1wiLCBgdGhpbmtpbmc6ICR7ZXZlbnQubGV2ZWx9YCk7XG59KTtcbmBgYFxuXG5Vc2UgdGhpcyB0byB1cGRhdGUgZXh0ZW5zaW9uIFVJIHdoZW4gYHBpLnNldFRoaW5raW5nTGV2ZWwoKWAsIG1vZGVsIGNoYW5nZXMsIG9yIGJ1aWx0LWluIHRoaW5raW5nLWxldmVsIGNvbnRyb2xzIGNoYW5nZSB0aGUgYWN0aXZlIHRoaW5raW5nIGxldmVsLlxuXG4jIyMgVG9vbCBFdmVudHNcblxuIyMjIyB0b29sX2NhbGxcblxuRmlyZWQgYWZ0ZXIgYHRvb2xfZXhlY3V0aW9uX3N0YXJ0YCwgYmVmb3JlIHRoZSB0b29sIGV4ZWN1dGVzLiAqKkNhbiBibG9jay4qKiBVc2UgYGlzVG9vbENhbGxFdmVudFR5cGVgIHRvIG5hcnJvdyBhbmQgZ2V0IHR5cGVkIGlucHV0cy5cblxuQmVmb3JlIGB0b29sX2NhbGxgIHJ1bnMsIHBpIHdhaXRzIGZvciBwcmV2aW91c2x5IGVtaXR0ZWQgQWdlbnQgZXZlbnRzIHRvIGZpbmlzaCBkcmFpbmluZyB0aHJvdWdoIGBBZ2VudFNlc3Npb25gLiBUaGlzIG1lYW5zIGBjdHguc2Vzc2lvbk1hbmFnZXJgIGlzIHVwIHRvIGRhdGUgdGhyb3VnaCB0aGUgY3VycmVudCBhc3Npc3RhbnQgdG9vbC1jYWxsaW5nIG1lc3NhZ2UuXG5cbkluIHRoZSBkZWZhdWx0IHBhcmFsbGVsIHRvb2wgZXhlY3V0aW9uIG1vZGUsIHNpYmxpbmcgdG9vbCBjYWxscyBmcm9tIHRoZSBzYW1lIGFzc2lzdGFudCBtZXNzYWdlIGFyZSBwcmVmbGlnaHRlZCBzZXF1ZW50aWFsbHksIHRoZW4gZXhlY3V0ZWQgY29uY3VycmVudGx5LiBgdG9vbF9jYWxsYCBpcyBub3QgZ3VhcmFudGVlZCB0byBzZWUgc2libGluZyB0b29sIHJlc3VsdHMgZnJvbSB0aGF0IHNhbWUgYXNzaXN0YW50IG1lc3NhZ2UgaW4gYGN0eC5zZXNzaW9uTWFuYWdlcmAuXG5cbmBldmVudC5pbnB1dGAgaXMgbXV0YWJsZS4gTXV0YXRlIGl0IGluIHBsYWNlIHRvIHBhdGNoIHRvb2wgYXJndW1lbnRzIGJlZm9yZSBleGVjdXRpb24uXG5cbkJlaGF2aW9yIGd1YXJhbnRlZXM6XG4tIE11dGF0aW9ucyB0byBgZXZlbnQuaW5wdXRgIGFmZmVjdCB0aGUgYWN0dWFsIHRvb2wgZXhlY3V0aW9uXG4tIExhdGVyIGB0b29sX2NhbGxgIGhhbmRsZXJzIHNlZSBtdXRhdGlvbnMgbWFkZSBieSBlYXJsaWVyIGhhbmRsZXJzXG4tIE5vIHJlLXZhbGlkYXRpb24gaXMgcGVyZm9ybWVkIGFmdGVyIHlvdXIgbXV0YXRpb25cbi0gUmV0dXJuIHZhbHVlcyBmcm9tIGB0b29sX2NhbGxgIG9ubHkgY29udHJvbCBibG9ja2luZyB2aWEgYHsgYmxvY2s6IHRydWUsIHJlYXNvbj86IHN0cmluZyB9YFxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBpc1Rvb2xDYWxsRXZlbnRUeXBlIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxucGkub24oXCJ0b29sX2NhbGxcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQudG9vbE5hbWUgLSBcImJhc2hcIiwgXCJyZWFkXCIsIFwid3JpdGVcIiwgXCJlZGl0XCIsIGV0Yy5cbiAgLy8gZXZlbnQudG9vbENhbGxJZFxuICAvLyBldmVudC5pbnB1dCAtIHRvb2wgcGFyYW1ldGVycyAobXV0YWJsZSlcblxuICAvLyBCdWlsdC1pbiB0b29sczogbm8gdHlwZSBwYXJhbXMgbmVlZGVkXG4gIGlmIChpc1Rvb2xDYWxsRXZlbnRUeXBlKFwiYmFzaFwiLCBldmVudCkpIHtcbiAgICAvLyBldmVudC5pbnB1dCBpcyB7IGNvbW1hbmQ6IHN0cmluZzsgdGltZW91dD86IG51bWJlciB9XG4gICAgZXZlbnQuaW5wdXQuY29tbWFuZCA9IGBzb3VyY2Ugfi8ucHJvZmlsZVxcbiR7ZXZlbnQuaW5wdXQuY29tbWFuZH1gO1xuXG4gICAgaWYgKGV2ZW50LmlucHV0LmNvbW1hbmQuaW5jbHVkZXMoXCJybSAtcmZcIikpIHtcbiAgICAgIHJldHVybiB7IGJsb2NrOiB0cnVlLCByZWFzb246IFwiRGFuZ2Vyb3VzIGNvbW1hbmRcIiB9O1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc1Rvb2xDYWxsRXZlbnRUeXBlKFwicmVhZFwiLCBldmVudCkpIHtcbiAgICAvLyBldmVudC5pbnB1dCBpcyB7IHBhdGg6IHN0cmluZzsgb2Zmc2V0PzogbnVtYmVyOyBsaW1pdD86IG51bWJlciB9XG4gICAgY29uc29sZS5sb2coYFJlYWRpbmc6ICR7ZXZlbnQuaW5wdXQucGF0aH1gKTtcbiAgfVxufSk7XG5gYGBcblxuIyMjIyBUeXBpbmcgY3VzdG9tIHRvb2wgaW5wdXRcblxuQ3VzdG9tIHRvb2xzIHNob3VsZCBleHBvcnQgdGhlaXIgaW5wdXQgdHlwZTpcblxuYGBgdHlwZXNjcmlwdFxuLy8gbXktZXh0ZW5zaW9uLnRzXG5leHBvcnQgdHlwZSBNeVRvb2xJbnB1dCA9IFN0YXRpYzx0eXBlb2YgbXlUb29sU2NoZW1hPjtcbmBgYFxuXG5Vc2UgYGlzVG9vbENhbGxFdmVudFR5cGVgIHdpdGggZXhwbGljaXQgdHlwZSBwYXJhbWV0ZXJzOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBpc1Rvb2xDYWxsRXZlbnRUeXBlIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB0eXBlIHsgTXlUb29sSW5wdXQgfSBmcm9tIFwibXktZXh0ZW5zaW9uXCI7XG5cbnBpLm9uKFwidG9vbF9jYWxsXCIsIChldmVudCkgPT4ge1xuICBpZiAoaXNUb29sQ2FsbEV2ZW50VHlwZTxcIm15X3Rvb2xcIiwgTXlUb29sSW5wdXQ+KFwibXlfdG9vbFwiLCBldmVudCkpIHtcbiAgICBldmVudC5pbnB1dC5hY3Rpb247ICAvLyB0eXBlZFxuICB9XG59KTtcbmBgYFxuXG4jIyMjIHRvb2xfcmVzdWx0XG5cbkZpcmVkIGFmdGVyIHRvb2wgZXhlY3V0aW9uIGZpbmlzaGVzIGFuZCBiZWZvcmUgYHRvb2xfZXhlY3V0aW9uX2VuZGAgcGx1cyB0aGUgZmluYWwgdG9vbCByZXN1bHQgbWVzc2FnZSBldmVudHMgYXJlIGVtaXR0ZWQuICoqQ2FuIG1vZGlmeSByZXN1bHQuKipcblxuSW4gcGFyYWxsZWwgdG9vbCBtb2RlLCBgdG9vbF9yZXN1bHRgIGFuZCBgdG9vbF9leGVjdXRpb25fZW5kYCBtYXkgaW50ZXJsZWF2ZSBpbiB0b29sIGNvbXBsZXRpb24gb3JkZXIsIHdoaWxlIGZpbmFsIGB0b29sUmVzdWx0YCBtZXNzYWdlIGV2ZW50cyBhcmUgc3RpbGwgZW1pdHRlZCBsYXRlciBpbiBhc3Npc3RhbnQgc291cmNlIG9yZGVyLlxuXG5gdG9vbF9yZXN1bHRgIGhhbmRsZXJzIGNoYWluIGxpa2UgbWlkZGxld2FyZTpcbi0gSGFuZGxlcnMgcnVuIGluIGV4dGVuc2lvbiBsb2FkIG9yZGVyXG4tIEVhY2ggaGFuZGxlciBzZWVzIHRoZSBsYXRlc3QgcmVzdWx0IGFmdGVyIHByZXZpb3VzIGhhbmRsZXIgY2hhbmdlc1xuLSBIYW5kbGVycyBjYW4gcmV0dXJuIHBhcnRpYWwgcGF0Y2hlcyAoYGNvbnRlbnRgLCBgZGV0YWlsc2AsIG9yIGBpc0Vycm9yYCk7IG9taXR0ZWQgZmllbGRzIGtlZXAgdGhlaXIgY3VycmVudCB2YWx1ZXNcblxuVXNlIGBjdHguc2lnbmFsYCBmb3IgbmVzdGVkIGFzeW5jIHdvcmsgaW5zaWRlIHRoZSBoYW5kbGVyLiBUaGlzIGxldHMgRXNjIGNhbmNlbCBtb2RlbCBjYWxscywgYGZldGNoKClgLCBhbmQgb3RoZXIgYWJvcnQtYXdhcmUgb3BlcmF0aW9ucyBzdGFydGVkIGJ5IHRoZSBleHRlbnNpb24uXG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IGlzQmFzaFRvb2xSZXN1bHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG5waS5vbihcInRvb2xfcmVzdWx0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnRvb2xOYW1lLCBldmVudC50b29sQ2FsbElkLCBldmVudC5pbnB1dFxuICAvLyBldmVudC5jb250ZW50LCBldmVudC5kZXRhaWxzLCBldmVudC5pc0Vycm9yXG5cbiAgaWYgKGlzQmFzaFRvb2xSZXN1bHQoZXZlbnQpKSB7XG4gICAgLy8gZXZlbnQuZGV0YWlscyBpcyB0eXBlZCBhcyBCYXNoVG9vbERldGFpbHNcbiAgfVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXCJodHRwczovL2V4YW1wbGUuY29tL3N1bW1hcml6ZVwiLCB7XG4gICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGNvbnRlbnQ6IGV2ZW50LmNvbnRlbnQgfSksXG4gICAgc2lnbmFsOiBjdHguc2lnbmFsLFxuICB9KTtcblxuICAvLyBNb2RpZnkgcmVzdWx0OlxuICByZXR1cm4geyBjb250ZW50OiBbLi4uXSwgZGV0YWlsczogey4uLn0sIGlzRXJyb3I6IGZhbHNlIH07XG59KTtcbmBgYFxuXG4jIyMgVXNlciBCYXNoIEV2ZW50c1xuXG4jIyMjIHVzZXJfYmFzaFxuXG5GaXJlZCB3aGVuIHVzZXIgZXhlY3V0ZXMgYCFgIG9yIGAhIWAgY29tbWFuZHMuICoqQ2FuIGludGVyY2VwdC4qKlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBjcmVhdGVMb2NhbEJhc2hPcGVyYXRpb25zIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxucGkub24oXCJ1c2VyX2Jhc2hcIiwgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQuY29tbWFuZCAtIHRoZSBiYXNoIGNvbW1hbmRcbiAgLy8gZXZlbnQuZXhjbHVkZUZyb21Db250ZXh0IC0gdHJ1ZSBpZiAhISBwcmVmaXhcbiAgLy8gZXZlbnQuY3dkIC0gd29ya2luZyBkaXJlY3RvcnlcblxuICAvLyBPcHRpb24gMTogUHJvdmlkZSBjdXN0b20gb3BlcmF0aW9ucyAoZS5nLiwgU1NIKVxuICByZXR1cm4geyBvcGVyYXRpb25zOiByZW1vdGVCYXNoT3BzIH07XG5cbiAgLy8gT3B0aW9uIDI6IFdyYXAgcGkncyBidWlsdC1pbiBsb2NhbCBiYXNoIGJhY2tlbmRcbiAgY29uc3QgbG9jYWwgPSBjcmVhdGVMb2NhbEJhc2hPcGVyYXRpb25zKCk7XG4gIHJldHVybiB7XG4gICAgb3BlcmF0aW9uczoge1xuICAgICAgZXhlYyhjb21tYW5kLCBjd2QsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsLmV4ZWMoYHNvdXJjZSB+Ly5wcm9maWxlXFxuJHtjb21tYW5kfWAsIGN3ZCwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8vIE9wdGlvbiAzOiBGdWxsIHJlcGxhY2VtZW50IC0gcmV0dXJuIHJlc3VsdCBkaXJlY3RseVxuICByZXR1cm4geyByZXN1bHQ6IHsgb3V0cHV0OiBcIi4uLlwiLCBleGl0Q29kZTogMCwgY2FuY2VsbGVkOiBmYWxzZSwgdHJ1bmNhdGVkOiBmYWxzZSB9IH07XG59KTtcbmBgYFxuXG4jIyMgSW5wdXQgRXZlbnRzXG5cbiMjIyMgaW5wdXRcblxuRmlyZWQgd2hlbiB1c2VyIGlucHV0IGlzIHJlY2VpdmVkLCBhZnRlciBleHRlbnNpb24gY29tbWFuZHMgYXJlIGNoZWNrZWQgYnV0IGJlZm9yZSBza2lsbCBhbmQgdGVtcGxhdGUgZXhwYW5zaW9uLiBUaGUgZXZlbnQgc2VlcyB0aGUgcmF3IGlucHV0IHRleHQsIHNvIGAvc2tpbGw6Zm9vYCBhbmQgYC90ZW1wbGF0ZWAgYXJlIG5vdCB5ZXQgZXhwYW5kZWQuXG5cbioqUHJvY2Vzc2luZyBvcmRlcjoqKlxuMS4gRXh0ZW5zaW9uIGNvbW1hbmRzIChgL2NtZGApIGNoZWNrZWQgZmlyc3QgLSBpZiBmb3VuZCwgaGFuZGxlciBydW5zIGFuZCBpbnB1dCBldmVudCBpcyBza2lwcGVkXG4yLiBgaW5wdXRgIGV2ZW50IGZpcmVzIC0gY2FuIGludGVyY2VwdCwgdHJhbnNmb3JtLCBvciBoYW5kbGVcbjMuIElmIG5vdCBoYW5kbGVkOiBza2lsbCBjb21tYW5kcyAoYC9za2lsbDpuYW1lYCkgZXhwYW5kZWQgdG8gc2tpbGwgY29udGVudFxuNC4gSWYgbm90IGhhbmRsZWQ6IHByb21wdCB0ZW1wbGF0ZXMgKGAvdGVtcGxhdGVgKSBleHBhbmRlZCB0byB0ZW1wbGF0ZSBjb250ZW50XG41LiBBZ2VudCBwcm9jZXNzaW5nIGJlZ2lucyAoYGJlZm9yZV9hZ2VudF9zdGFydGAsIGV0Yy4pXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwiaW5wdXRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQudGV4dCAtIHJhdyBpbnB1dCAoYmVmb3JlIHNraWxsL3RlbXBsYXRlIGV4cGFuc2lvbilcbiAgLy8gZXZlbnQuaW1hZ2VzIC0gYXR0YWNoZWQgaW1hZ2VzLCBpZiBhbnlcbiAgLy8gZXZlbnQuc291cmNlIC0gXCJpbnRlcmFjdGl2ZVwiICh0eXBlZCksIFwicnBjXCIgKEFQSSksIG9yIFwiZXh0ZW5zaW9uXCIgKHZpYSBzZW5kVXNlck1lc3NhZ2UpXG4gIC8vIGV2ZW50LnN0cmVhbWluZ0JlaGF2aW9yIC0gXCJzdGVlclwiIHwgXCJmb2xsb3dVcFwiIHwgdW5kZWZpbmVkXG4gIC8vICAgdW5kZWZpbmVkIHdoZW4gaWRsZSwgXCJzdGVlclwiIGZvciBtaWQtc3RyZWFtIGludGVycnVwdHMsXG4gIC8vICAgXCJmb2xsb3dVcFwiIGZvciBtZXNzYWdlcyBxdWV1ZWQgdW50aWwgdGhlIGFnZW50IGZpbmlzaGVzXG5cbiAgLy8gVHJhbnNmb3JtOiByZXdyaXRlIGlucHV0IGJlZm9yZSBleHBhbnNpb25cbiAgaWYgKGV2ZW50LnRleHQuc3RhcnRzV2l0aChcIj9xdWljayBcIikpXG4gICAgcmV0dXJuIHsgYWN0aW9uOiBcInRyYW5zZm9ybVwiLCB0ZXh0OiBgUmVzcG9uZCBicmllZmx5OiAke2V2ZW50LnRleHQuc2xpY2UoNyl9YCB9O1xuXG4gIC8vIEhhbmRsZTogcmVzcG9uZCB3aXRob3V0IExMTSAoZXh0ZW5zaW9uIHNob3dzIGl0cyBvd24gZmVlZGJhY2spXG4gIGlmIChldmVudC50ZXh0ID09PSBcInBpbmdcIikge1xuICAgIGN0eC51aS5ub3RpZnkoXCJwb25nXCIsIFwiaW5mb1wiKTtcbiAgICByZXR1cm4geyBhY3Rpb246IFwiaGFuZGxlZFwiIH07XG4gIH1cblxuICAvLyBSb3V0ZSBieSBzb3VyY2U6IHNraXAgcHJvY2Vzc2luZyBmb3IgZXh0ZW5zaW9uLWluamVjdGVkIG1lc3NhZ2VzXG4gIGlmIChldmVudC5zb3VyY2UgPT09IFwiZXh0ZW5zaW9uXCIpIHJldHVybiB7IGFjdGlvbjogXCJjb250aW51ZVwiIH07XG5cbiAgLy8gSW50ZXJjZXB0IHNraWxsIGNvbW1hbmRzIGJlZm9yZSBleHBhbnNpb25cbiAgaWYgKGV2ZW50LnRleHQuc3RhcnRzV2l0aChcIi9za2lsbDpcIikpIHtcbiAgICAvLyBDb3VsZCB0cmFuc2Zvcm0sIGJsb2NrLCBvciBsZXQgcGFzcyB0aHJvdWdoXG4gIH1cblxuICByZXR1cm4geyBhY3Rpb246IFwiY29udGludWVcIiB9OyAgLy8gRGVmYXVsdDogcGFzcyB0aHJvdWdoIHRvIGV4cGFuc2lvblxufSk7XG5gYGBcblxuKipSZXN1bHRzOioqXG4tIGBjb250aW51ZWAgLSBwYXNzIHRocm91Z2ggdW5jaGFuZ2VkIChkZWZhdWx0IGlmIGhhbmRsZXIgcmV0dXJucyBub3RoaW5nKVxuLSBgdHJhbnNmb3JtYCAtIG1vZGlmeSB0ZXh0L2ltYWdlcywgdGhlbiBjb250aW51ZSB0byBleHBhbnNpb25cbi0gYGhhbmRsZWRgIC0gc2tpcCBhZ2VudCBlbnRpcmVseSAoZmlyc3QgaGFuZGxlciB0byByZXR1cm4gdGhpcyB3aW5zKVxuXG5UcmFuc2Zvcm1zIGNoYWluIGFjcm9zcyBoYW5kbGVycy4gU2VlIFtpbnB1dC10cmFuc2Zvcm0udHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvaW5wdXQtdHJhbnNmb3JtLnRzKSBhbmQgW2lucHV0LXRyYW5zZm9ybS1zdHJlYW1pbmcudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvaW5wdXQtdHJhbnNmb3JtLXN0cmVhbWluZy50cykgZm9yIGBzdHJlYW1pbmdCZWhhdmlvcmAtYXdhcmUgcm91dGluZy5cblxuIyMgRXh0ZW5zaW9uQ29udGV4dFxuXG5BbGwgaGFuZGxlcnMgcmVjZWl2ZSBgY3R4OiBFeHRlbnNpb25Db250ZXh0YC5cblxuIyMjIGN0eC51aVxuXG5VSSBtZXRob2RzIGZvciB1c2VyIGludGVyYWN0aW9uLiBTZWUgW0N1c3RvbSBVSV0oI2N1c3RvbS11aSkgZm9yIGZ1bGwgZGV0YWlscy5cblxuIyMjIGN0eC5tb2RlXG5cbkN1cnJlbnQgcnVuIG1vZGU6IGBcInR1aVwiYCwgYFwicnBjXCJgLCBgXCJqc29uXCJgLCBvciBgXCJwcmludFwiYC4gVXNlIGBjdHgubW9kZSA9PT0gXCJ0dWlcImAgdG8gZ3VhcmQgdGVybWluYWwtb25seSBmZWF0dXJlcyBzdWNoIGFzIGBjdXN0b20oKWAsIGNvbXBvbmVudCBmYWN0b3JpZXMsIHRlcm1pbmFsIGlucHV0LCBhbmQgZGlyZWN0IFRVSSByZW5kZXJpbmcuXG5cbiMjIyBjdHguaGFzVUlcblxuYHRydWVgIGluIFRVSSBhbmQgUlBDIG1vZGVzLiBgZmFsc2VgIGluIHByaW50IG1vZGUgKGAtcGApIGFuZCBKU09OIG1vZGUuIFVzZSB0aGlzIHRvIGd1YXJkIGRpYWxvZyBtZXRob2RzIChgc2VsZWN0YCwgYGNvbmZpcm1gLCBgaW5wdXRgLCBgZWRpdG9yYCkgYW5kIGZpcmUtYW5kLWZvcmdldCBtZXRob2RzIChgbm90aWZ5YCwgYHNldFN0YXR1c2AsIGBzZXRXaWRnZXRgLCBgc2V0VGl0bGVgLCBgc2V0RWRpdG9yVGV4dGApIHRoYXQgd29yayBpbiBib3RoIFRVSSBhbmQgUlBDIG1vZGVzLiBJbiBSUEMgbW9kZSwgc29tZSBUVUktc3BlY2lmaWMgbWV0aG9kcyBhcmUgbm8tb3BzIG9yIHJldHVybiBkZWZhdWx0cyAoc2VlIFtycGMubWRdKHJwYy5tZCNleHRlbnNpb24tdWktcHJvdG9jb2wpKS5cblxuIyMjIGN0eC5jd2RcblxuQ3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cblxuVXNlIGBDT05GSUdfRElSX05BTUVgIGluc3RlYWQgb2YgaGFyZGNvZGluZyBgLnBpYCB3aGVuIGNvbnN0cnVjdGluZyBwcm9qZWN0LWxvY2FsIGNvbmZpZyBwYXRocy4gUmVicmFuZGVkIGRpc3RyaWJ1dGlvbnMgY2FuIHVzZSBhIGRpZmZlcmVudCBjb25maWcgZGlyZWN0b3J5IG5hbWUuXG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IENPTkZJR19ESVJfTkFNRSwgdHlwZSBFeHRlbnNpb25BUEkgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBpOiBFeHRlbnNpb25BUEkpIHtcbiAgcGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGNvbnN0IHByb2plY3RDb25maWdQYXRoID0gam9pbihjdHguY3dkLCBDT05GSUdfRElSX05BTUUsIFwibXktZXh0ZW5zaW9uLmpzb25cIik7XG4gICAgLy8gLi4uXG4gIH0pO1xufVxuYGBgXG5cbiMjIyBjdHguaXNQcm9qZWN0VHJ1c3RlZCgpXG5cblJldHVybnMgd2hldGhlciBwcm9qZWN0LWxvY2FsIHRydXN0IGlzIGFjdGl2ZSBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbiBjb250ZXh0LiBUaGlzIGluY2x1ZGVzIHRlbXBvcmFyeSB0cnVzdCBkZWNpc2lvbnMgYW5kIENMSSB0cnVzdCBvdmVycmlkZXMsIG5vdCBqdXN0IHNhdmVkIGRlY2lzaW9ucyBpbiB0aGUgZ2xvYmFsIHRydXN0IHN0b3JlLlxuXG5Vc2UgdGhpcyBiZWZvcmUgcmVhZGluZyBwcm9qZWN0LWxvY2FsIGV4dGVuc2lvbiBjb25maWd1cmF0aW9uIHRoYXQgc2hvdWxkIG9ubHkgYmUgaG9ub3JlZCBmb3IgdHJ1c3RlZCBwcm9qZWN0cy5cblxuIyMjIGN0eC5zZXNzaW9uTWFuYWdlclxuXG5SZWFkLW9ubHkgYWNjZXNzIHRvIHNlc3Npb24gc3RhdGUuIFNlZSBbU2Vzc2lvbiBGb3JtYXRdKHNlc3Npb24tZm9ybWF0Lm1kKSBmb3IgdGhlIGZ1bGwgU2Vzc2lvbk1hbmFnZXIgQVBJIGFuZCBlbnRyeSB0eXBlcy5cblxuRm9yIGB0b29sX2NhbGxgLCB0aGlzIHN0YXRlIGlzIHN5bmNocm9uaXplZCB0aHJvdWdoIHRoZSBjdXJyZW50IGFzc2lzdGFudCBtZXNzYWdlIGJlZm9yZSBoYW5kbGVycyBydW4uIEluIHBhcmFsbGVsIHRvb2wgZXhlY3V0aW9uIG1vZGUgaXQgaXMgc3RpbGwgbm90IGd1YXJhbnRlZWQgdG8gaW5jbHVkZSBzaWJsaW5nIHRvb2wgcmVzdWx0cyBmcm9tIHRoZSBzYW1lIGFzc2lzdGFudCBtZXNzYWdlLlxuXG5gYGB0eXBlc2NyaXB0XG5jdHguc2Vzc2lvbk1hbmFnZXIuZ2V0RW50cmllcygpICAgICAgIC8vIEFsbCBlbnRyaWVzXG5jdHguc2Vzc2lvbk1hbmFnZXIuZ2V0QnJhbmNoKCkgICAgICAgIC8vIEN1cnJlbnQgYnJhbmNoXG5jdHguc2Vzc2lvbk1hbmFnZXIuZ2V0TGVhZklkKCkgICAgICAgIC8vIEN1cnJlbnQgbGVhZiBlbnRyeSBJRFxuYGBgXG5cbiMjIyBjdHgubW9kZWxSZWdpc3RyeSAvIGN0eC5tb2RlbFxuXG5BY2Nlc3MgdG8gbW9kZWxzIGFuZCBBUEkga2V5cy5cblxuIyMjIGN0eC5zaWduYWxcblxuVGhlIGN1cnJlbnQgYWdlbnQgYWJvcnQgc2lnbmFsLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vIGFnZW50IHR1cm4gaXMgYWN0aXZlLlxuXG5Vc2UgdGhpcyBmb3IgYWJvcnQtYXdhcmUgbmVzdGVkIHdvcmsgc3RhcnRlZCBieSBleHRlbnNpb24gaGFuZGxlcnMsIGZvciBleGFtcGxlOlxuLSBgZmV0Y2goLi4uLCB7IHNpZ25hbDogY3R4LnNpZ25hbCB9KWBcbi0gbW9kZWwgY2FsbHMgdGhhdCBhY2NlcHQgYHNpZ25hbGBcbi0gZmlsZSBvciBwcm9jZXNzIGhlbHBlcnMgdGhhdCBhY2NlcHQgYEFib3J0U2lnbmFsYFxuXG5gY3R4LnNpZ25hbGAgaXMgdHlwaWNhbGx5IGRlZmluZWQgZHVyaW5nIGFjdGl2ZSB0dXJuIGV2ZW50cyBzdWNoIGFzIGB0b29sX2NhbGxgLCBgdG9vbF9yZXN1bHRgLCBgbWVzc2FnZV91cGRhdGVgLCBhbmQgYHR1cm5fZW5kYC5cbkl0IGlzIHVzdWFsbHkgYHVuZGVmaW5lZGAgaW4gaWRsZSBvciBub24tdHVybiBjb250ZXh0cyBzdWNoIGFzIHNlc3Npb24gZXZlbnRzLCBleHRlbnNpb24gY29tbWFuZHMsIGFuZCBzaG9ydGN1dHMgZmlyZWQgd2hpbGUgcGkgaXMgaWRsZS5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJ0b29sX3Jlc3VsdFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoZXZlbnQpLFxuICAgIHNpZ25hbDogY3R4LnNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgcmV0dXJuIHsgZGV0YWlsczogZGF0YSB9O1xufSk7XG5gYGBcblxuIyMjIGN0eC5pc0lkbGUoKSAvIGN0eC5hYm9ydCgpIC8gY3R4Lmhhc1BlbmRpbmdNZXNzYWdlcygpXG5cbkNvbnRyb2wgZmxvdyBoZWxwZXJzLlxuXG4jIyMgY3R4LnNodXRkb3duKClcblxuUmVxdWVzdCBhIGdyYWNlZnVsIHNodXRkb3duIG9mIHBpLlxuXG4tICoqSW50ZXJhY3RpdmUgbW9kZToqKiBEZWZlcnJlZCB1bnRpbCB0aGUgYWdlbnQgYmVjb21lcyBpZGxlIChhZnRlciBwcm9jZXNzaW5nIGFsbCBxdWV1ZWQgc3RlZXJpbmcgYW5kIGZvbGxvdy11cCBtZXNzYWdlcykuXG4tICoqUlBDIG1vZGU6KiogRGVmZXJyZWQgdW50aWwgdGhlIG5leHQgaWRsZSBzdGF0ZSAoYWZ0ZXIgY29tcGxldGluZyB0aGUgY3VycmVudCBjb21tYW5kIHJlc3BvbnNlLCB3aGVuIHdhaXRpbmcgZm9yIHRoZSBuZXh0IGNvbW1hbmQpLlxuLSAqKlByaW50IG1vZGU6KiogTm8tb3AuIFRoZSBwcm9jZXNzIGV4aXRzIGF1dG9tYXRpY2FsbHkgd2hlbiBhbGwgcHJvbXB0cyBhcmUgcHJvY2Vzc2VkLlxuXG5FbWl0cyBgc2Vzc2lvbl9zaHV0ZG93bmAgZXZlbnQgdG8gYWxsIGV4dGVuc2lvbnMgYmVmb3JlIGV4aXRpbmcuIEF2YWlsYWJsZSBpbiBhbGwgY29udGV4dHMgKGV2ZW50IGhhbmRsZXJzLCB0b29scywgY29tbWFuZHMsIHNob3J0Y3V0cykuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwidG9vbF9jYWxsXCIsIChldmVudCwgY3R4KSA9PiB7XG4gIGlmIChpc0ZhdGFsKGV2ZW50LmlucHV0KSkge1xuICAgIGN0eC5zaHV0ZG93bigpO1xuICB9XG59KTtcbmBgYFxuXG4jIyMgY3R4LmdldENvbnRleHRVc2FnZSgpXG5cblJldHVybnMgY3VycmVudCBjb250ZXh0IHVzYWdlIGZvciB0aGUgYWN0aXZlIG1vZGVsLiBVc2VzIGxhc3QgYXNzaXN0YW50IHVzYWdlIHdoZW4gYXZhaWxhYmxlLCB0aGVuIGVzdGltYXRlcyB0b2tlbnMgZm9yIHRyYWlsaW5nIG1lc3NhZ2VzLlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCB1c2FnZSA9IGN0eC5nZXRDb250ZXh0VXNhZ2UoKTtcbmlmICh1c2FnZSAmJiB1c2FnZS50b2tlbnMgPiAxMDBfMDAwKSB7XG4gIC8vIC4uLlxufVxuYGBgXG5cbiMjIyBjdHguY29tcGFjdCgpXG5cblRyaWdnZXIgY29tcGFjdGlvbiB3aXRob3V0IGF3YWl0aW5nIGNvbXBsZXRpb24uIFVzZSBgb25Db21wbGV0ZWAgYW5kIGBvbkVycm9yYCBmb3IgZm9sbG93LXVwIGFjdGlvbnMuXG5cbmBgYHR5cGVzY3JpcHRcbmN0eC5jb21wYWN0KHtcbiAgY3VzdG9tSW5zdHJ1Y3Rpb25zOiBcIkZvY3VzIG9uIHJlY2VudCBjaGFuZ2VzXCIsXG4gIG9uQ29tcGxldGU6IChyZXN1bHQpID0+IHtcbiAgICBjdHgudWkubm90aWZ5KFwiQ29tcGFjdGlvbiBjb21wbGV0ZWRcIiwgXCJpbmZvXCIpO1xuICB9LFxuICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICBjdHgudWkubm90aWZ5KGBDb21wYWN0aW9uIGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWAsIFwiZXJyb3JcIik7XG4gIH0sXG59KTtcbmBgYFxuXG4jIyMgY3R4LmdldFN5c3RlbVByb21wdCgpXG5cblJldHVybnMgUGkncyBjdXJyZW50IHN5c3RlbSBwcm9tcHQgc3RyaW5nLlxuXG4tIER1cmluZyBgYmVmb3JlX2FnZW50X3N0YXJ0YCwgdGhpcyByZWZsZWN0cyBjaGFpbmVkIHN5c3RlbS1wcm9tcHQgY2hhbmdlcyBtYWRlIHNvIGZhciBmb3IgdGhlIGN1cnJlbnQgdHVybi5cbi0gSXQgZG9lcyBub3QgaW5jbHVkZSBsYXRlciBgY29udGV4dGAgbWVzc2FnZSBtdXRhdGlvbnMuXG4tIEl0IGRvZXMgbm90IGluY2x1ZGUgYGJlZm9yZV9wcm92aWRlcl9yZXF1ZXN0YCBwYXlsb2FkIHJld3JpdGVzLlxuLSBJZiBsYXRlci1sb2FkZWQgZXh0ZW5zaW9ucyBydW4gYWZ0ZXIgeW91cnMsIHRoZXkgY2FuIHN0aWxsIGNoYW5nZSB3aGF0IGlzIHVsdGltYXRlbHkgc2VudC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJiZWZvcmVfYWdlbnRfc3RhcnRcIiwgKGV2ZW50LCBjdHgpID0+IHtcbiAgY29uc3QgcHJvbXB0ID0gY3R4LmdldFN5c3RlbVByb21wdCgpO1xuICBjb25zb2xlLmxvZyhgU3lzdGVtIHByb21wdCBsZW5ndGg6ICR7cHJvbXB0Lmxlbmd0aH1gKTtcbn0pO1xuYGBgXG5cbiMjIEV4dGVuc2lvbkNvbW1hbmRDb250ZXh0XG5cbkNvbW1hbmQgaGFuZGxlcnMgcmVjZWl2ZSBgRXh0ZW5zaW9uQ29tbWFuZENvbnRleHRgLCB3aGljaCBleHRlbmRzIGBFeHRlbnNpb25Db250ZXh0YCB3aXRoIHNlc3Npb24gY29udHJvbCBtZXRob2RzLiBUaGVzZSBhcmUgb25seSBhdmFpbGFibGUgaW4gY29tbWFuZHMgYmVjYXVzZSB0aGV5IGNhbiBkZWFkbG9jayBpZiBjYWxsZWQgZnJvbSBldmVudCBoYW5kbGVycy5cblxuIyMjIGN0eC5nZXRTeXN0ZW1Qcm9tcHRPcHRpb25zKClcblxuUmV0dXJucyB0aGUgYmFzZSBpbnB1dHMgUGkgY3VycmVudGx5IHVzZXMgdG8gYnVpbGQgdGhlIHN5c3RlbSBwcm9tcHQuXG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IG9wdGlvbnMgPSBjdHguZ2V0U3lzdGVtUHJvbXB0T3B0aW9ucygpO1xuY29uc3QgY29udGV4dFBhdGhzID0gb3B0aW9ucy5jb250ZXh0RmlsZXM/Lm1hcCgoZmlsZSkgPT4gZmlsZS5wYXRoKSA/PyBbXTtcbmBgYFxuXG5UaGlzIGhhcyB0aGUgc2FtZSBzaGFwZSBhbmQgbXV0YWJpbGl0eSBhcyBgYmVmb3JlX2FnZW50X3N0YXJ0YCBgZXZlbnQuc3lzdGVtUHJvbXB0T3B0aW9uc2A6IGN1c3RvbSBwcm9tcHQsIGFjdGl2ZSB0b29scywgdG9vbCBzbmlwcGV0cywgcHJvbXB0IGd1aWRlbGluZXMsIGFwcGVuZGVkIHN5c3RlbSBwcm9tcHQgdGV4dCwgY3dkLCBsb2FkZWQgY29udGV4dCBmaWxlcywgYW5kIGxvYWRlZCBza2lsbHMuIEl0IG1heSBpbmNsdWRlIGZ1bGwgY29udGV4dCBmaWxlIGNvbnRlbnRzLCBzbyB0cmVhdCBpdCBhcyBzZW5zaXRpdmUgZXh0ZW5zaW9uLWxvY2FsIGRhdGEgYW5kIGF2b2lkIGV4cG9zaW5nIGl0IHRocm91Z2ggY29tbWFuZCBsaXN0cywgbG9ncywgb3IgYXV0b2NvbXBsZXRlIG1ldGFkYXRhLlxuXG5UaGlzIHJlcG9ydHMgdGhlIGN1cnJlbnQgYmFzZSBwcm9tcHQgaW5wdXRzLiBJdCBkb2VzIG5vdCBpbmNsdWRlIHBlci10dXJuIGBiZWZvcmVfYWdlbnRfc3RhcnRgIGNoYWluZWQgc3lzdGVtLXByb21wdCBjaGFuZ2VzLCBsYXRlciBgY29udGV4dGAgZXZlbnQgbWVzc2FnZSBtdXRhdGlvbnMsIG9yIGBiZWZvcmVfcHJvdmlkZXJfcmVxdWVzdGAgcGF5bG9hZCByZXdyaXRlcy5cblxuIyMjIGN0eC53YWl0Rm9ySWRsZSgpXG5cbldhaXQgZm9yIHRoZSBhZ2VudCB0byBmaW5pc2ggc3RyZWFtaW5nOlxuXG5gYGB0eXBlc2NyaXB0XG5waS5yZWdpc3RlckNvbW1hbmQoXCJteS1jbWRcIiwge1xuICBoYW5kbGVyOiBhc3luYyAoYXJncywgY3R4KSA9PiB7XG4gICAgYXdhaXQgY3R4LndhaXRGb3JJZGxlKCk7XG4gICAgLy8gQWdlbnQgaXMgbm93IGlkbGUsIHNhZmUgdG8gbW9kaWZ5IHNlc3Npb25cbiAgfSxcbn0pO1xuYGBgXG5cbiMjIyBjdHgubmV3U2Vzc2lvbihvcHRpb25zPylcblxuQ3JlYXRlIGEgbmV3IHNlc3Npb246XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHBhcmVudFNlc3Npb24gPSBjdHguc2Vzc2lvbk1hbmFnZXIuZ2V0U2Vzc2lvbkZpbGUoKTtcbmNvbnN0IGtpY2tvZmYgPSBcIkNvbnRpbnVlIGluIHRoZSByZXBsYWNlbWVudCBzZXNzaW9uXCI7XG5cbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC5uZXdTZXNzaW9uKHtcbiAgcGFyZW50U2Vzc2lvbixcbiAgc2V0dXA6IGFzeW5jIChzbSkgPT4ge1xuICAgIHNtLmFwcGVuZE1lc3NhZ2Uoe1xuICAgICAgcm9sZTogXCJ1c2VyXCIsXG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJDb250ZXh0IGZyb20gcHJldmlvdXMgc2Vzc2lvbi4uLlwiIH1dLFxuICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgIH0pO1xuICB9LFxuICB3aXRoU2Vzc2lvbjogYXN5bmMgKGN0eCkgPT4ge1xuICAgIC8vIFVzZSBvbmx5IHRoZSByZXBsYWNlbWVudC1zZXNzaW9uIGN0eCBoZXJlLlxuICAgIGF3YWl0IGN0eC5zZW5kVXNlck1lc3NhZ2Uoa2lja29mZik7XG4gIH0sXG59KTtcblxuaWYgKHJlc3VsdC5jYW5jZWxsZWQpIHtcbiAgLy8gQW4gZXh0ZW5zaW9uIGNhbmNlbGxlZCB0aGUgbmV3IHNlc3Npb25cbn1cbmBgYFxuXG5PcHRpb25zOlxuLSBgcGFyZW50U2Vzc2lvbmA6IHBhcmVudCBzZXNzaW9uIGZpbGUgdG8gcmVjb3JkIGluIHRoZSBuZXcgc2Vzc2lvbiBoZWFkZXJcbi0gYHNldHVwYDogbXV0YXRlIHRoZSBuZXcgc2Vzc2lvbidzIGBTZXNzaW9uTWFuYWdlcmAgYmVmb3JlIGB3aXRoU2Vzc2lvbmAgcnVuc1xuLSBgd2l0aFNlc3Npb25gOiBydW4gcG9zdC1zd2l0Y2ggd29yayBhZ2FpbnN0IGEgZnJlc2ggcmVwbGFjZW1lbnQtc2Vzc2lvbiBjb250ZXh0LiBEbyBub3QgdXNlIGNhcHR1cmVkIG9sZCBgcGlgIC8gY29tbWFuZCBgY3R4YDsgc2VlIFtTZXNzaW9uIHJlcGxhY2VtZW50IGxpZmVjeWNsZSBhbmQgZm9vdGd1bnNdKCNzZXNzaW9uLXJlcGxhY2VtZW50LWxpZmVjeWNsZS1hbmQtZm9vdGd1bnMpLlxuXG4jIyMgY3R4LmZvcmsoZW50cnlJZCwgb3B0aW9ucz8pXG5cbkZvcmsgZnJvbSBhIHNwZWNpZmljIGVudHJ5LCBjcmVhdGluZyBhIG5ldyBzZXNzaW9uIGZpbGU6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC5mb3JrKFwiZW50cnktaWQtMTIzXCIsIHtcbiAgd2l0aFNlc3Npb246IGFzeW5jIChjdHgpID0+IHtcbiAgICAvLyBVc2Ugb25seSB0aGUgcmVwbGFjZW1lbnQtc2Vzc2lvbiBjdHggaGVyZS5cbiAgICBjdHgudWkubm90aWZ5KFwiTm93IGluIHRoZSBmb3JrZWQgc2Vzc2lvblwiLCBcImluZm9cIik7XG4gIH0sXG59KTtcbmlmIChyZXN1bHQuY2FuY2VsbGVkKSB7XG4gIC8vIEFuIGV4dGVuc2lvbiBjYW5jZWxsZWQgdGhlIGZvcmtcbn1cblxuY29uc3QgY2xvbmVSZXN1bHQgPSBhd2FpdCBjdHguZm9yayhcImVudHJ5LWlkLTQ1NlwiLCB7IHBvc2l0aW9uOiBcImF0XCIgfSk7XG5pZiAoY2xvbmVSZXN1bHQuY2FuY2VsbGVkKSB7XG4gIC8vIEFuIGV4dGVuc2lvbiBjYW5jZWxsZWQgdGhlIGNsb25lXG59XG5gYGBcblxuT3B0aW9uczpcbi0gYHBvc2l0aW9uYDogYFwiYmVmb3JlXCJgIChkZWZhdWx0KSBmb3JrcyBiZWZvcmUgdGhlIHNlbGVjdGVkIHVzZXIgbWVzc2FnZSwgcmVzdG9yaW5nIHRoYXQgcHJvbXB0IGludG8gdGhlIGVkaXRvclxuLSBgcG9zaXRpb25gOiBgXCJhdFwiYCBkdXBsaWNhdGVzIHRoZSBhY3RpdmUgcGF0aCB0aHJvdWdoIHRoZSBzZWxlY3RlZCBlbnRyeSB3aXRob3V0IHJlc3RvcmluZyBlZGl0b3IgdGV4dFxuLSBgd2l0aFNlc3Npb25gOiBydW4gcG9zdC1zd2l0Y2ggd29yayBhZ2FpbnN0IGEgZnJlc2ggcmVwbGFjZW1lbnQtc2Vzc2lvbiBjb250ZXh0LiBEbyBub3QgdXNlIGNhcHR1cmVkIG9sZCBgcGlgIC8gY29tbWFuZCBgY3R4YDsgc2VlIFtTZXNzaW9uIHJlcGxhY2VtZW50IGxpZmVjeWNsZSBhbmQgZm9vdGd1bnNdKCNzZXNzaW9uLXJlcGxhY2VtZW50LWxpZmVjeWNsZS1hbmQtZm9vdGd1bnMpLlxuXG4jIyMgY3R4Lm5hdmlnYXRlVHJlZSh0YXJnZXRJZCwgb3B0aW9ucz8pXG5cbk5hdmlnYXRlIHRvIGEgZGlmZmVyZW50IHBvaW50IGluIHRoZSBzZXNzaW9uIHRyZWU6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC5uYXZpZ2F0ZVRyZWUoXCJlbnRyeS1pZC00NTZcIiwge1xuICBzdW1tYXJpemU6IHRydWUsXG4gIGN1c3RvbUluc3RydWN0aW9uczogXCJGb2N1cyBvbiBlcnJvciBoYW5kbGluZyBjaGFuZ2VzXCIsXG4gIHJlcGxhY2VJbnN0cnVjdGlvbnM6IGZhbHNlLCAvLyB0cnVlID0gcmVwbGFjZSBkZWZhdWx0IHByb21wdCBlbnRpcmVseVxuICBsYWJlbDogXCJyZXZpZXctY2hlY2twb2ludFwiLFxufSk7XG5gYGBcblxuT3B0aW9uczpcbi0gYHN1bW1hcml6ZWA6IFdoZXRoZXIgdG8gZ2VuZXJhdGUgYSBzdW1tYXJ5IG9mIHRoZSBhYmFuZG9uZWQgYnJhbmNoXG4tIGBjdXN0b21JbnN0cnVjdGlvbnNgOiBDdXN0b20gaW5zdHJ1Y3Rpb25zIGZvciB0aGUgc3VtbWFyaXplclxuLSBgcmVwbGFjZUluc3RydWN0aW9uc2A6IElmIHRydWUsIGBjdXN0b21JbnN0cnVjdGlvbnNgIHJlcGxhY2VzIHRoZSBkZWZhdWx0IHByb21wdCBpbnN0ZWFkIG9mIGJlaW5nIGFwcGVuZGVkXG4tIGBsYWJlbGA6IExhYmVsIHRvIGF0dGFjaCB0byB0aGUgYnJhbmNoIHN1bW1hcnkgZW50cnkgKG9yIHRhcmdldCBlbnRyeSBpZiBub3Qgc3VtbWFyaXppbmcpXG5cbiMjIyBjdHguc3dpdGNoU2Vzc2lvbihzZXNzaW9uUGF0aCwgb3B0aW9ucz8pXG5cblN3aXRjaCB0byBhIGRpZmZlcmVudCBzZXNzaW9uIGZpbGU6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC5zd2l0Y2hTZXNzaW9uKFwiL3BhdGgvdG8vc2Vzc2lvbi5qc29ubFwiLCB7XG4gIHdpdGhTZXNzaW9uOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgYXdhaXQgY3R4LnNlbmRVc2VyTWVzc2FnZShcIlJlc3VtZSB3b3JrIGluIHRoZSByZXBsYWNlbWVudCBzZXNzaW9uXCIpO1xuICB9LFxufSk7XG5pZiAocmVzdWx0LmNhbmNlbGxlZCkge1xuICAvLyBBbiBleHRlbnNpb24gY2FuY2VsbGVkIHRoZSBzd2l0Y2ggdmlhIHNlc3Npb25fYmVmb3JlX3N3aXRjaFxufVxuYGBgXG5cbk9wdGlvbnM6XG4tIGB3aXRoU2Vzc2lvbmA6IHJ1biBwb3N0LXN3aXRjaCB3b3JrIGFnYWluc3QgYSBmcmVzaCByZXBsYWNlbWVudC1zZXNzaW9uIGNvbnRleHQuIERvIG5vdCB1c2UgY2FwdHVyZWQgb2xkIGBwaWAgLyBjb21tYW5kIGBjdHhgOyBzZWUgW1Nlc3Npb24gcmVwbGFjZW1lbnQgbGlmZWN5Y2xlIGFuZCBmb290Z3Vuc10oI3Nlc3Npb24tcmVwbGFjZW1lbnQtbGlmZWN5Y2xlLWFuZC1mb290Z3VucykuXG5cblRvIGRpc2NvdmVyIGF2YWlsYWJsZSBzZXNzaW9ucywgdXNlIHRoZSBzdGF0aWMgYFNlc3Npb25NYW5hZ2VyLmxpc3QoKWAgb3IgYFNlc3Npb25NYW5hZ2VyLmxpc3RBbGwoKWAgbWV0aG9kczpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgU2Vzc2lvbk1hbmFnZXIgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG5waS5yZWdpc3RlckNvbW1hbmQoXCJzd2l0Y2hcIiwge1xuICBkZXNjcmlwdGlvbjogXCJTd2l0Y2ggdG8gYW5vdGhlciBzZXNzaW9uXCIsXG4gIGhhbmRsZXI6IGFzeW5jIChhcmdzLCBjdHgpID0+IHtcbiAgICBjb25zdCBzZXNzaW9ucyA9IGF3YWl0IFNlc3Npb25NYW5hZ2VyLmxpc3QoY3R4LmN3ZCk7XG4gICAgaWYgKHNlc3Npb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIGNvbnN0IGNob2ljZSA9IGF3YWl0IGN0eC51aS5zZWxlY3QoXG4gICAgICBcIlBpY2sgc2Vzc2lvbjpcIixcbiAgICAgIHNlc3Npb25zLm1hcChzID0+IHMuZmlsZSksXG4gICAgKTtcbiAgICBpZiAoY2hvaWNlKSB7XG4gICAgICBhd2FpdCBjdHguc3dpdGNoU2Vzc2lvbihjaG9pY2UsIHtcbiAgICAgICAgd2l0aFNlc3Npb246IGFzeW5jIChjdHgpID0+IHtcbiAgICAgICAgICBjdHgudWkubm90aWZ5KFwiU3dpdGNoZWQgc2Vzc2lvblwiLCBcImluZm9cIik7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG59KTtcbmBgYFxuXG4jIyMgU2Vzc2lvbiByZXBsYWNlbWVudCBsaWZlY3ljbGUgYW5kIGZvb3RndW5zXG5cbmB3aXRoU2Vzc2lvbmAgcmVjZWl2ZXMgYSBmcmVzaCBgUmVwbGFjZWRTZXNzaW9uQ29udGV4dGAsIHdoaWNoIGV4dGVuZHMgYEV4dGVuc2lvbkNvbW1hbmRDb250ZXh0YCB3aXRoIGFzeW5jIGBzZW5kTWVzc2FnZSgpYCBhbmQgYHNlbmRVc2VyTWVzc2FnZSgpYCBoZWxwZXJzIGJvdW5kIHRvIHRoZSByZXBsYWNlbWVudCBzZXNzaW9uLlxuXG5MaWZlY3ljbGUgYW5kIGZvb3RndW5zOlxuLSBgd2l0aFNlc3Npb25gIHJ1bnMgb25seSBhZnRlciB0aGUgb2xkIHNlc3Npb24gaGFzIGVtaXR0ZWQgYHNlc3Npb25fc2h1dGRvd25gLCB0aGUgb2xkIHJ1bnRpbWUgaGFzIGJlZW4gdG9ybiBkb3duLCB0aGUgcmVwbGFjZW1lbnQgc2Vzc2lvbiBoYXMgYmVlbiByZWJvdW5kLCBhbmQgdGhlIG5ldyBleHRlbnNpb24gaW5zdGFuY2UgaGFzIGFscmVhZHkgcmVjZWl2ZWQgYHNlc3Npb25fc3RhcnRgLlxuLSBUaGUgY2FsbGJhY2sgc3RpbGwgZXhlY3V0ZXMgaW4gdGhlIG9yaWdpbmFsIGNsb3N1cmUsIG5vdCBpbnNpZGUgdGhlIG5ldyBleHRlbnNpb24gaW5zdGFuY2UuIFRoYXQgbWVhbnMgeW91ciBvbGQgZXh0ZW5zaW9uIGluc3RhbmNlIG1heSBhbHJlYWR5IGhhdmUgcnVuIGl0cyBzaHV0ZG93biBjbGVhbnVwIGJlZm9yZSBgd2l0aFNlc3Npb25gIHN0YXJ0cy5cbi0gQ2FwdHVyZWQgb2xkIGBwaWAgLyBvbGQgY29tbWFuZCBgY3R4YCBzZXNzaW9uLWJvdW5kIG9iamVjdHMgYXJlIHN0YWxlIGFmdGVyIHJlcGxhY2VtZW50IGFuZCB3aWxsIHRocm93IGlmIHVzZWQuIFVzZSBvbmx5IHRoZSBgY3R4YCBwYXNzZWQgdG8gYHdpdGhTZXNzaW9uYCBmb3Igc2Vzc2lvbi1ib3VuZCB3b3JrLlxuLSBQcmV2aW91c2x5IGV4dHJhY3RlZCByYXcgb2JqZWN0cyBhcmUgc3RpbGwgeW91ciByZXNwb25zaWJpbGl0eS4gRm9yIGV4YW1wbGUsIGlmIHlvdSBjYXB0dXJlIGBjb25zdCBzbSA9IGN0eC5zZXNzaW9uTWFuYWdlcmAgYmVmb3JlIHJlcGxhY2VtZW50LCBgc21gIGlzIHN0aWxsIHRoZSBvbGQgYFNlc3Npb25NYW5hZ2VyYCBvYmplY3QuIERvIG5vdCByZXVzZSBpdCBhZnRlciByZXBsYWNlbWVudC5cbi0gQ29kZSBpbiBgd2l0aFNlc3Npb25gIHNob3VsZCBhc3N1bWUgYW55IHN0YXRlIGludmFsaWRhdGVkIGJ5IHlvdXIgYHNlc3Npb25fc2h1dGRvd25gIGhhbmRsZXIgaXMgYWxyZWFkeSBnb25lLiBPbmx5IGNhcHR1cmUgcGxhaW4gZGF0YSB0aGF0IHN1cnZpdmVzIHNodXRkb3duIGNsZWFubHksIHN1Y2ggYXMgc3RyaW5ncywgaWRzLCBhbmQgc2VyaWFsaXplZCBjb25maWcuXG5cblNhZmUgcGF0dGVybjpcblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJDb21tYW5kKFwiaGFuZG9mZlwiLCB7XG4gIGhhbmRsZXI6IGFzeW5jIChfYXJncywgY3R4KSA9PiB7XG4gICAgY29uc3Qga2lja29mZiA9IFwiQ29udGludWUgZnJvbSB0aGUgcmVwbGFjZW1lbnQgc2Vzc2lvblwiO1xuICAgIGF3YWl0IGN0eC5uZXdTZXNzaW9uKHtcbiAgICAgIHdpdGhTZXNzaW9uOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgICAgIGF3YWl0IGN0eC5zZW5kVXNlck1lc3NhZ2Uoa2lja29mZik7XG4gICAgICB9LFxuICAgIH0pO1xuICB9LFxufSk7XG5gYGBcblxuVW5zYWZlIHBhdHRlcm46XG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyQ29tbWFuZChcImhhbmRvZmZcIiwge1xuICBoYW5kbGVyOiBhc3luYyAoX2FyZ3MsIGN0eCkgPT4ge1xuICAgIGNvbnN0IG9sZFNlc3Npb25NYW5hZ2VyID0gY3R4LnNlc3Npb25NYW5hZ2VyO1xuICAgIGF3YWl0IGN0eC5uZXdTZXNzaW9uKHtcbiAgICAgIHdpdGhTZXNzaW9uOiBhc3luYyAoX2N0eCkgPT4ge1xuICAgICAgICAvLyBzdGFsZSBvbGQgb2JqZWN0czogZG8gbm90IGRvIHRoaXNcbiAgICAgICAgb2xkU2Vzc2lvbk1hbmFnZXIuZ2V0U2Vzc2lvbkZpbGUoKTtcbiAgICAgICAgcGkuc2VuZFVzZXJNZXNzYWdlKFwid3JvbmdcIik7XG4gICAgICB9LFxuICAgIH0pO1xuICB9LFxufSk7XG5gYGBcblxuIyMjIGN0eC5yZWxvYWQoKVxuXG5SdW4gdGhlIHNhbWUgcmVsb2FkIGZsb3cgYXMgYC9yZWxvYWRgLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5yZWdpc3RlckNvbW1hbmQoXCJyZWxvYWQtcnVudGltZVwiLCB7XG4gIGRlc2NyaXB0aW9uOiBcIlJlbG9hZCBleHRlbnNpb25zLCBza2lsbHMsIHByb21wdHMsIGFuZCB0aGVtZXNcIixcbiAgaGFuZGxlcjogYXN5bmMgKF9hcmdzLCBjdHgpID0+IHtcbiAgICBhd2FpdCBjdHgucmVsb2FkKCk7XG4gICAgcmV0dXJuO1xuICB9LFxufSk7XG5gYGBcblxuSW1wb3J0YW50IGJlaGF2aW9yOlxuLSBgYXdhaXQgY3R4LnJlbG9hZCgpYCBlbWl0cyBgc2Vzc2lvbl9zaHV0ZG93bmAgZm9yIHRoZSBjdXJyZW50IGV4dGVuc2lvbiBydW50aW1lXG4tIEl0IHRoZW4gcmVsb2FkcyByZXNvdXJjZXMgYW5kIGVtaXRzIGBzZXNzaW9uX3N0YXJ0YCB3aXRoIGByZWFzb246IFwicmVsb2FkXCJgIGFuZCBgcmVzb3VyY2VzX2Rpc2NvdmVyYCB3aXRoIHJlYXNvbiBgXCJyZWxvYWRcImBcbi0gVGhlIGN1cnJlbnRseSBydW5uaW5nIGNvbW1hbmQgaGFuZGxlciBzdGlsbCBjb250aW51ZXMgaW4gdGhlIG9sZCBjYWxsIGZyYW1lXG4tIENvZGUgYWZ0ZXIgYGF3YWl0IGN0eC5yZWxvYWQoKWAgc3RpbGwgcnVucyBmcm9tIHRoZSBwcmUtcmVsb2FkIHZlcnNpb25cbi0gQ29kZSBhZnRlciBgYXdhaXQgY3R4LnJlbG9hZCgpYCBtdXN0IG5vdCBhc3N1bWUgb2xkIGluLW1lbW9yeSBleHRlbnNpb24gc3RhdGUgaXMgc3RpbGwgdmFsaWRcbi0gQWZ0ZXIgdGhlIGhhbmRsZXIgcmV0dXJucywgZnV0dXJlIGNvbW1hbmRzL2V2ZW50cy90b29sIGNhbGxzIHVzZSB0aGUgbmV3IGV4dGVuc2lvbiB2ZXJzaW9uXG5cbkZvciBwcmVkaWN0YWJsZSBiZWhhdmlvciwgdHJlYXQgcmVsb2FkIGFzIHRlcm1pbmFsIGZvciB0aGF0IGhhbmRsZXIgKGBhd2FpdCBjdHgucmVsb2FkKCk7IHJldHVybjtgKS5cblxuVG9vbHMgcnVuIHdpdGggYEV4dGVuc2lvbkNvbnRleHRgLCBzbyB0aGV5IGNhbm5vdCBjYWxsIGBjdHgucmVsb2FkKClgIGRpcmVjdGx5LiBVc2UgYSBjb21tYW5kIGFzIHRoZSByZWxvYWQgZW50cnlwb2ludCwgdGhlbiBleHBvc2UgYSB0b29sIHRoYXQgcXVldWVzIHRoYXQgY29tbWFuZCBhcyBhIGZvbGxvdy11cCB1c2VyIG1lc3NhZ2UuXG5cbkV4YW1wbGUgdG9vbCB0aGUgTExNIGNhbiBjYWxsIHRvIHRyaWdnZXIgcmVsb2FkOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBpOiBFeHRlbnNpb25BUEkpIHtcbiAgcGkucmVnaXN0ZXJDb21tYW5kKFwicmVsb2FkLXJ1bnRpbWVcIiwge1xuICAgIGRlc2NyaXB0aW9uOiBcIlJlbG9hZCBleHRlbnNpb25zLCBza2lsbHMsIHByb21wdHMsIGFuZCB0aGVtZXNcIixcbiAgICBoYW5kbGVyOiBhc3luYyAoX2FyZ3MsIGN0eCkgPT4ge1xuICAgICAgYXdhaXQgY3R4LnJlbG9hZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH0sXG4gIH0pO1xuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJyZWxvYWRfcnVudGltZVwiLFxuICAgIGxhYmVsOiBcIlJlbG9hZCBSdW50aW1lXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVsb2FkIGV4dGVuc2lvbnMsIHNraWxscywgcHJvbXB0cywgYW5kIHRoZW1lc1wiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKCkge1xuICAgICAgcGkuc2VuZFVzZXJNZXNzYWdlKFwiL3JlbG9hZC1ydW50aW1lXCIsIHsgZGVsaXZlckFzOiBcImZvbGxvd1VwXCIgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJRdWV1ZWQgL3JlbG9hZC1ydW50aW1lIGFzIGEgZm9sbG93LXVwIGNvbW1hbmQuXCIgfV0sXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xufVxuYGBgXG5cbiMjIEV4dGVuc2lvbkFQSSBNZXRob2RzXG5cbiMjIyBwaS5vbihldmVudCwgaGFuZGxlcilcblxuU3Vic2NyaWJlIHRvIGV2ZW50cy4gU2VlIFtFdmVudHNdKCNldmVudHMpIGZvciBldmVudCB0eXBlcyBhbmQgcmV0dXJuIHZhbHVlcy5cblxuIyMjIHBpLnJlZ2lzdGVyVG9vbChkZWZpbml0aW9uKVxuXG5SZWdpc3RlciBhIGN1c3RvbSB0b29sIGNhbGxhYmxlIGJ5IHRoZSBMTE0uIFNlZSBbQ3VzdG9tIFRvb2xzXSgjY3VzdG9tLXRvb2xzKSBmb3IgZnVsbCBkZXRhaWxzLlxuXG5gcGkucmVnaXN0ZXJUb29sKClgIHdvcmtzIGJvdGggZHVyaW5nIGV4dGVuc2lvbiBsb2FkIGFuZCBhZnRlciBzdGFydHVwLiBZb3UgY2FuIGNhbGwgaXQgaW5zaWRlIGBzZXNzaW9uX3N0YXJ0YCwgY29tbWFuZCBoYW5kbGVycywgb3Igb3RoZXIgZXZlbnQgaGFuZGxlcnMuIE5ldyB0b29scyBhcmUgcmVmcmVzaGVkIGltbWVkaWF0ZWx5IGluIHRoZSBzYW1lIHNlc3Npb24sIHNvIHRoZXkgYXBwZWFyIGluIGBwaS5nZXRBbGxUb29scygpYCBhbmQgYXJlIGNhbGxhYmxlIGJ5IHRoZSBMTE0gd2l0aG91dCBgL3JlbG9hZGAuXG5cblVzZSBgcGkuc2V0QWN0aXZlVG9vbHMoKWAgdG8gZW5hYmxlIG9yIGRpc2FibGUgdG9vbHMgKGluY2x1ZGluZyBkeW5hbWljYWxseSBhZGRlZCB0b29scykgYXQgcnVudGltZS5cblxuVXNlIGBwcm9tcHRTbmlwcGV0YCB0byBvcHQgYSBjdXN0b20gdG9vbCBpbnRvIGEgb25lLWxpbmUgZW50cnkgaW4gYEF2YWlsYWJsZSB0b29sc2AsIGFuZCBgcHJvbXB0R3VpZGVsaW5lc2AgdG8gYXBwZW5kIHRvb2wtc3BlY2lmaWMgYnVsbGV0cyB0byB0aGUgZGVmYXVsdCBgR3VpZGVsaW5lc2Agc2VjdGlvbiB3aGVuIHRoZSB0b29sIGlzIGFjdGl2ZS5cblxuKipJbXBvcnRhbnQ6KiogYHByb21wdEd1aWRlbGluZXNgIGJ1bGxldHMgYXJlIGFwcGVuZGVkIGZsYXQgdG8gdGhlIGBHdWlkZWxpbmVzYCBzZWN0aW9uIHdpdGggbm8gdG9vbCBuYW1lIHByZWZpeC4gRWFjaCBndWlkZWxpbmUgbXVzdCBuYW1lIHRoZSB0b29sIGl0IHJlZmVycyB0byDigJQgYXZvaWQgXCJVc2UgdGhpcyB0b29sIHdoZW4uLi5cIiBiZWNhdXNlIHRoZSBMTE0gY2Fubm90IHRlbGwgd2hpY2ggdG9vbCBcInRoaXNcIiBtZWFucy4gV3JpdGUgXCJVc2UgbXlfdG9vbCB3aGVuLi4uXCIgaW5zdGVhZC5cblxuU2VlIFtkeW5hbWljLXRvb2xzLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL2R5bmFtaWMtdG9vbHMudHMpIGZvciBhIGZ1bGwgZXhhbXBsZS5cblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5pbXBvcnQgeyBTdHJpbmdFbnVtIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1haVwiO1xuXG5waS5yZWdpc3RlclRvb2woe1xuICBuYW1lOiBcIm15X3Rvb2xcIixcbiAgbGFiZWw6IFwiTXkgVG9vbFwiLFxuICBkZXNjcmlwdGlvbjogXCJXaGF0IHRoaXMgdG9vbCBkb2VzXCIsXG4gIHByb21wdFNuaXBwZXQ6IFwiU3VtbWFyaXplIG9yIHRyYW5zZm9ybSB0ZXh0IGFjY29yZGluZyB0byBhY3Rpb25cIixcbiAgcHJvbXB0R3VpZGVsaW5lczogW1wiVXNlIG15X3Rvb2wgd2hlbiB0aGUgdXNlciBhc2tzIHRvIHN1bW1hcml6ZSBwcmV2aW91c2x5IGdlbmVyYXRlZCB0ZXh0LlwiXSxcbiAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgIGFjdGlvbjogU3RyaW5nRW51bShbXCJsaXN0XCIsIFwiYWRkXCJdIGFzIGNvbnN0KSxcbiAgICB0ZXh0OiBUeXBlLk9wdGlvbmFsKFR5cGUuU3RyaW5nKCkpLFxuICB9KSxcbiAgcHJlcGFyZUFyZ3VtZW50cyhhcmdzKSB7XG4gICAgLy8gT3B0aW9uYWwgY29tcGF0aWJpbGl0eSBzaGltLiBSdW5zIGJlZm9yZSBzY2hlbWEgdmFsaWRhdGlvbi5cbiAgICAvLyBSZXR1cm4gdGhlIGN1cnJlbnQgc2NoZW1hIHNoYXBlLCBmb3IgZXhhbXBsZSB0byBmb2xkIGxlZ2FjeSBmaWVsZHNcbiAgICAvLyBpbnRvIHRoZSBtb2Rlcm4gcGFyYW1ldGVyIG9iamVjdC5cbiAgICByZXR1cm4gYXJncztcbiAgfSxcblxuICBhc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgY3R4KSB7XG4gICAgLy8gU3RyZWFtIHByb2dyZXNzXG4gICAgb25VcGRhdGU/Lih7IGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIldvcmtpbmcuLi5cIiB9XSB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJEb25lXCIgfV0sXG4gICAgICBkZXRhaWxzOiB7IHJlc3VsdDogXCIuLi5cIiB9LFxuICAgIH07XG4gIH0sXG5cbiAgLy8gT3B0aW9uYWw6IEN1c3RvbSByZW5kZXJpbmdcbiAgcmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgY29udGV4dCkgeyAuLi4gfSxcbiAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgb3B0aW9ucywgdGhlbWUsIGNvbnRleHQpIHsgLi4uIH0sXG59KTtcbmBgYFxuXG4jIyMgcGkuc2VuZE1lc3NhZ2UobWVzc2FnZSwgb3B0aW9ucz8pXG5cbkluamVjdCBhIGN1c3RvbSBtZXNzYWdlIGludG8gdGhlIHNlc3Npb24uXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnNlbmRNZXNzYWdlKHtcbiAgY3VzdG9tVHlwZTogXCJteS1leHRlbnNpb25cIixcbiAgY29udGVudDogXCJNZXNzYWdlIHRleHRcIixcbiAgZGlzcGxheTogdHJ1ZSxcbiAgZGV0YWlsczogeyAuLi4gfSxcbn0sIHtcbiAgdHJpZ2dlclR1cm46IHRydWUsXG4gIGRlbGl2ZXJBczogXCJzdGVlclwiLFxufSk7XG5gYGBcblxuKipPcHRpb25zOioqXG4tIGBkZWxpdmVyQXNgIC0gRGVsaXZlcnkgbW9kZTpcbiAgLSBgXCJzdGVlclwiYCAoZGVmYXVsdCkgLSBRdWV1ZXMgdGhlIG1lc3NhZ2Ugd2hpbGUgc3RyZWFtaW5nLiBEZWxpdmVyZWQgYWZ0ZXIgdGhlIGN1cnJlbnQgYXNzaXN0YW50IHR1cm4gZmluaXNoZXMgZXhlY3V0aW5nIGl0cyB0b29sIGNhbGxzLCBiZWZvcmUgdGhlIG5leHQgTExNIGNhbGwuXG4gIC0gYFwiZm9sbG93VXBcImAgLSBXYWl0cyBmb3IgYWdlbnQgdG8gZmluaXNoLiBEZWxpdmVyZWQgb25seSB3aGVuIGFnZW50IGhhcyBubyBtb3JlIHRvb2wgY2FsbHMuXG4gIC0gYFwibmV4dFR1cm5cImAgLSBRdWV1ZWQgZm9yIG5leHQgdXNlciBwcm9tcHQuIERvZXMgbm90IGludGVycnVwdCBvciB0cmlnZ2VyIGFueXRoaW5nLlxuLSBgdHJpZ2dlclR1cm46IHRydWVgIC0gSWYgYWdlbnQgaXMgaWRsZSwgdHJpZ2dlciBhbiBMTE0gcmVzcG9uc2UgaW1tZWRpYXRlbHkuIE9ubHkgYXBwbGllcyB0byBgXCJzdGVlclwiYCBhbmQgYFwiZm9sbG93VXBcImAgbW9kZXMgKGlnbm9yZWQgZm9yIGBcIm5leHRUdXJuXCJgKS5cblxuIyMjIHBpLnNlbmRVc2VyTWVzc2FnZShjb250ZW50LCBvcHRpb25zPylcblxuU2VuZCBhIHVzZXIgbWVzc2FnZSB0byB0aGUgYWdlbnQuIFVubGlrZSBgc2VuZE1lc3NhZ2UoKWAgd2hpY2ggc2VuZHMgY3VzdG9tIG1lc3NhZ2VzLCB0aGlzIHNlbmRzIGFuIGFjdHVhbCB1c2VyIG1lc3NhZ2UgdGhhdCBhcHBlYXJzIGFzIGlmIHR5cGVkIGJ5IHRoZSB1c2VyLiBBbHdheXMgdHJpZ2dlcnMgYSB0dXJuLlxuXG5gYGB0eXBlc2NyaXB0XG4vLyBTaW1wbGUgdGV4dCBtZXNzYWdlXG5waS5zZW5kVXNlck1lc3NhZ2UoXCJXaGF0IGlzIDIrMj9cIik7XG5cbi8vIFdpdGggY29udGVudCBhcnJheSAodGV4dCArIGltYWdlcylcbnBpLnNlbmRVc2VyTWVzc2FnZShbXG4gIHsgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiRGVzY3JpYmUgdGhpcyBpbWFnZTpcIiB9LFxuICB7IHR5cGU6IFwiaW1hZ2VcIiwgc291cmNlOiB7IHR5cGU6IFwiYmFzZTY0XCIsIG1lZGlhVHlwZTogXCJpbWFnZS9wbmdcIiwgZGF0YTogXCIuLi5cIiB9IH0sXG5dKTtcblxuLy8gRHVyaW5nIHN0cmVhbWluZyAtIG11c3Qgc3BlY2lmeSBkZWxpdmVyeSBtb2RlXG5waS5zZW5kVXNlck1lc3NhZ2UoXCJGb2N1cyBvbiBlcnJvciBoYW5kbGluZ1wiLCB7IGRlbGl2ZXJBczogXCJzdGVlclwiIH0pO1xucGkuc2VuZFVzZXJNZXNzYWdlKFwiQW5kIHRoZW4gc3VtbWFyaXplXCIsIHsgZGVsaXZlckFzOiBcImZvbGxvd1VwXCIgfSk7XG5gYGBcblxuKipPcHRpb25zOioqXG4tIGBkZWxpdmVyQXNgIC0gUmVxdWlyZWQgd2hlbiBhZ2VudCBpcyBzdHJlYW1pbmc6XG4gIC0gYFwic3RlZXJcImAgLSBRdWV1ZXMgdGhlIG1lc3NhZ2UgZm9yIGRlbGl2ZXJ5IGFmdGVyIHRoZSBjdXJyZW50IGFzc2lzdGFudCB0dXJuIGZpbmlzaGVzIGV4ZWN1dGluZyBpdHMgdG9vbCBjYWxsc1xuICAtIGBcImZvbGxvd1VwXCJgIC0gV2FpdHMgZm9yIGFnZW50IHRvIGZpbmlzaCBhbGwgdG9vbHNcblxuV2hlbiBub3Qgc3RyZWFtaW5nLCB0aGUgbWVzc2FnZSBpcyBzZW50IGltbWVkaWF0ZWx5IGFuZCB0cmlnZ2VycyBhIG5ldyB0dXJuLiBXaGVuIHN0cmVhbWluZyB3aXRob3V0IGBkZWxpdmVyQXNgLCB0aHJvd3MgYW4gZXJyb3IuXG5cblNlZSBbc2VuZC11c2VyLW1lc3NhZ2UudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvc2VuZC11c2VyLW1lc3NhZ2UudHMpIGZvciBhIGNvbXBsZXRlIGV4YW1wbGUuXG5cbiMjIyBwaS5hcHBlbmRFbnRyeShjdXN0b21UeXBlLCBkYXRhPylcblxuXG5bU2hvd2luZyBsaW5lcyAxLTEzODYgb2YgMjY3NyAoNTAuMEtCIGxpbWl0KS4gVXNlIG9mZnNldD0xMzg3IHRvIGNvbnRpbnVlLl0ifV0sImRldGFpbHMiOnsidHJ1bmNhdGlvbiI6eyJjb250ZW50IjoiPiBwaSBjYW4gY3JlYXRlIGV4dGVuc2lvbnMuIEFzayBpdCB0byBidWlsZCBvbmUgZm9yIHlvdXIgdXNlIGNhc2UuXG5cbiMgRXh0ZW5zaW9uc1xuXG5FeHRlbnNpb25zIGFyZSBUeXBlU2NyaXB0IG1vZHVsZXMgdGhhdCBleHRlbmQgcGkncyBiZWhhdmlvci4gVGhleSBjYW4gc3Vic2NyaWJlIHRvIGxpZmVjeWNsZSBldmVudHMsIHJlZ2lzdGVyIGN1c3RvbSB0b29scyBjYWxsYWJsZSBieSB0aGUgTExNLCBhZGQgY29tbWFuZHMsIGFuZCBtb3JlLlxuXG4+ICoqUGxhY2VtZW50IGZvciAvcmVsb2FkOioqIFB1dCBleHRlbnNpb25zIGluIGB+Ly5waS9hZ2VudC9leHRlbnNpb25zL2AgKGdsb2JhbCkgb3IgYC5waS9leHRlbnNpb25zL2AgKHByb2plY3QtbG9jYWwpIGZvciBhdXRvLWRpc2NvdmVyeS4gVXNlIGBwaSAtZSAuL3BhdGgudHNgIG9ubHkgZm9yIHF1aWNrIHRlc3RzLiBFeHRlbnNpb25zIGluIGF1dG8tZGlzY292ZXJlZCBsb2NhdGlvbnMgY2FuIGJlIGhvdC1yZWxvYWRlZCB3aXRoIGAvcmVsb2FkYC5cblxuKipLZXkgY2FwYWJpbGl0aWVzOioqXG4tICoqQ3VzdG9tIHRvb2xzKiogLSBSZWdpc3RlciB0b29scyB0aGUgTExNIGNhbiBjYWxsIHZpYSBgcGkucmVnaXN0ZXJUb29sKClgXG4tICoqRXZlbnQgaW50ZXJjZXB0aW9uKiogLSBCbG9jayBvciBtb2RpZnkgdG9vbCBjYWxscywgaW5qZWN0IGNvbnRleHQsIGN1c3RvbWl6ZSBjb21wYWN0aW9uXG4tICoqVXNlciBpbnRlcmFjdGlvbioqIC0gUHJvbXB0IHVzZXJzIHZpYSBgY3R4LnVpYCAoc2VsZWN0LCBjb25maXJtLCBpbnB1dCwgbm90aWZ5KVxuLSAqKkN1c3RvbSBVSSBjb21wb25lbnRzKiogLSBGdWxsIFRVSSBjb21wb25lbnRzIHdpdGgga2V5Ym9hcmQgaW5wdXQgdmlhIGBjdHgudWkuY3VzdG9tKClgIGZvciBjb21wbGV4IGludGVyYWN0aW9uc1xuLSAqKkN1c3RvbSBjb21tYW5kcyoqIC0gUmVnaXN0ZXIgY29tbWFuZHMgbGlrZSBgL215Y29tbWFuZGAgdmlhIGBwaS5yZWdpc3RlckNvbW1hbmQoKWBcbi0gKipTZXNzaW9uIHBlcnNpc3RlbmNlKiogLSBTdG9yZSBzdGF0ZSB0aGF0IHN1cnZpdmVzIHJlc3RhcnRzIHZpYSBgcGkuYXBwZW5kRW50cnkoKWBcbi0gKipDdXN0b20gcmVuZGVyaW5nKiogLSBDb250cm9sIGhvdyB0b29sIGNhbGxzL3Jlc3VsdHMgYW5kIG1lc3NhZ2VzIGFwcGVhciBpbiBUVUlcblxuKipFeGFtcGxlIHVzZSBjYXNlczoqKlxuLSBQZXJtaXNzaW9uIGdhdGVzIChjb25maXJtIGJlZm9yZSBgcm0gLXJmYCwgYHN1ZG9gLCBldGMuKVxuLSBHaXQgY2hlY2twb2ludGluZyAoc3Rhc2ggYXQgZWFjaCB0dXJuLCByZXN0b3JlIG9uIGJyYW5jaClcbi0gUGF0aCBwcm90ZWN0aW9uIChibG9jayB3cml0ZXMgdG8gYC5lbnZgLCBgbm9kZV9tb2R1bGVzL2ApXG4tIEN1c3RvbSBjb21wYWN0aW9uIChzdW1tYXJpemUgY29udmVyc2F0aW9uIHlvdXIgd2F5KVxuLSBDb252ZXJzYXRpb24gc3VtbWFyaWVzIChzZWUgYHN1bW1hcml6ZS50c2AgZXhhbXBsZSlcbi0gSW50ZXJhY3RpdmUgdG9vbHMgKHF1ZXN0aW9ucywgd2l6YXJkcywgY3VzdG9tIGRpYWxvZ3MpXG4tIFN0YXRlZnVsIHRvb2xzICh0b2RvIGxpc3RzLCBjb25uZWN0aW9uIHBvb2xzKVxuLSBFeHRlcm5hbCBpbnRlZ3JhdGlvbnMgKGZpbGUgd2F0Y2hlcnMsIHdlYmhvb2tzLCBDSSB0cmlnZ2Vycylcbi0gR2FtZXMgd2hpbGUgeW91IHdhaXQgKHNlZSBgc25ha2UudHNgIGV4YW1wbGUpXG5cblNlZSBbZXhhbXBsZXMvZXh0ZW5zaW9ucy9dKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvKSBmb3Igd29ya2luZyBpbXBsZW1lbnRhdGlvbnMuXG5cbiMjIFRhYmxlIG9mIENvbnRlbnRzXG5cbi0gW1F1aWNrIFN0YXJ0XSgjcXVpY2stc3RhcnQpXG4tIFtFeHRlbnNpb24gTG9jYXRpb25zXSgjZXh0ZW5zaW9uLWxvY2F0aW9ucylcbi0gW0F2YWlsYWJsZSBJbXBvcnRzXSgjYXZhaWxhYmxlLWltcG9ydHMpXG4tIFtXcml0aW5nIGFuIEV4dGVuc2lvbl0oI3dyaXRpbmctYW4tZXh0ZW5zaW9uKVxuICAtIFtFeHRlbnNpb24gU3R5bGVzXSgjZXh0ZW5zaW9uLXN0eWxlcylcbi0gW0V2ZW50c10oI2V2ZW50cylcbiAgLSBbTGlmZWN5Y2xlIE92ZXJ2aWV3XSgjbGlmZWN5Y2xlLW92ZXJ2aWV3KVxuICAtIFtSZXNvdXJjZSBFdmVudHNdKCNyZXNvdXJjZS1ldmVudHMpXG4gIC0gW1Nlc3Npb24gRXZlbnRzXSgjc2Vzc2lvbi1ldmVudHMpXG4gIC0gW0FnZW50IEV2ZW50c10oI2FnZW50LWV2ZW50cylcbiAgLSBbTW9kZWwgRXZlbnRzXSgjbW9kZWwtZXZlbnRzKVxuICAtIFtUb29sIEV2ZW50c10oI3Rvb2wtZXZlbnRzKVxuLSBbRXh0ZW5zaW9uQ29udGV4dF0oI2V4dGVuc2lvbmNvbnRleHQpXG4tIFtFeHRlbnNpb25Db21tYW5kQ29udGV4dF0oI2V4dGVuc2lvbmNvbW1hbmRjb250ZXh0KVxuLSBbRXh0ZW5zaW9uQVBJIE1ldGhvZHNdKCNleHRlbnNpb25hcGktbWV0aG9kcylcbi0gW1N0YXRlIE1hbmFnZW1lbnRdKCNzdGF0ZS1tYW5hZ2VtZW50KVxuLSBbQ3VzdG9tIFRvb2xzXSgjY3VzdG9tLXRvb2xzKVxuLSBbQ3VzdG9tIFVJXSgjY3VzdG9tLXVpKVxuLSBbRXJyb3IgSGFuZGxpbmddKCNlcnJvci1oYW5kbGluZylcbi0gW01vZGUgQmVoYXZpb3JdKCNtb2RlLWJlaGF2aW9yKVxuLSBbRXhhbXBsZXMgUmVmZXJlbmNlXSgjZXhhbXBsZXMtcmVmZXJlbmNlKVxuXG4jIyBRdWljayBTdGFydFxuXG5DcmVhdGUgYH4vLnBpL2FnZW50L2V4dGVuc2lvbnMvbXktZXh0ZW5zaW9uLnRzYDpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEkgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIC8vIFJlYWN0IHRvIGV2ZW50c1xuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgY3R4LnVpLm5vdGlmeShcIkV4dGVuc2lvbiBsb2FkZWQhXCIsIFwiaW5mb1wiKTtcbiAgfSk7XG5cbiAgcGkub24oXCJ0b29sX2NhbGxcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgICBpZiAoZXZlbnQudG9vbE5hbWUgPT09IFwiYmFzaFwiICYmIGV2ZW50LmlucHV0LmNvbW1hbmQ/LmluY2x1ZGVzKFwicm0gLXJmXCIpKSB7XG4gICAgICBjb25zdCBvayA9IGF3YWl0IGN0eC51aS5jb25maXJtKFwiRGFuZ2Vyb3VzIVwiLCBcIkFsbG93IHJtIC1yZj9cIik7XG4gICAgICBpZiAoIW9rKSByZXR1cm4geyBibG9jazogdHJ1ZSwgcmVhc29uOiBcIkJsb2NrZWQgYnkgdXNlclwiIH07XG4gICAgfVxuICB9KTtcblxuICAvLyBSZWdpc3RlciBhIGN1c3RvbSB0b29sXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJncmVldFwiLFxuICAgIGxhYmVsOiBcIkdyZWV0XCIsXG4gICAgZGVzY3JpcHRpb246IFwiR3JlZXQgc29tZW9uZSBieSBuYW1lXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgbmFtZTogVHlwZS5TdHJpbmcoeyBkZXNjcmlwdGlvbjogXCJOYW1lIHRvIGdyZWV0XCIgfSksXG4gICAgfSksXG4gICAgYXN5bmMgZXhlY3V0ZSh0b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUsIGN0eCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IGBIZWxsbywgJHtwYXJhbXMubmFtZX0hYCB9XSxcbiAgICAgICAgZGV0YWlsczoge30sXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIFJlZ2lzdGVyIGEgY29tbWFuZFxuICBwaS5yZWdpc3RlckNvbW1hbmQoXCJoZWxsb1wiLCB7XG4gICAgZGVzY3JpcHRpb246IFwiU2F5IGhlbGxvXCIsXG4gICAgaGFuZGxlcjogYXN5bmMgKGFyZ3MsIGN0eCkgPT4ge1xuICAgICAgY3R4LnVpLm5vdGlmeShgSGVsbG8gJHthcmdzIHx8IFwid29ybGRcIn0hYCwgXCJpbmZvXCIpO1xuICAgIH0sXG4gIH0pO1xufVxuYGBgXG5cblRlc3Qgd2l0aCBgLS1leHRlbnNpb25gIChvciBgLWVgKSBmbGFnOlxuXG5gYGBiYXNoXG5waSAtZSAuL215LWV4dGVuc2lvbi50c1xuYGBgXG5cbiMjIEV4dGVuc2lvbiBMb2NhdGlvbnNcblxuPiAqKlNlY3VyaXR5OioqIEV4dGVuc2lvbnMgcnVuIHdpdGggeW91ciBmdWxsIHN5c3RlbSBwZXJtaXNzaW9ucyBhbmQgY2FuIGV4ZWN1dGUgYXJiaXRyYXJ5IGNvZGUuIE9ubHkgaW5zdGFsbCBmcm9tIHNvdXJjZXMgeW91IHRydXN0LlxuXG5FeHRlbnNpb25zIGFyZSBhdXRvLWRpc2NvdmVyZWQgZnJvbSB0cnVzdGVkIGxvY2F0aW9ucy4gUHJvamVjdC1sb2NhbCBgLnBpL2V4dGVuc2lvbnNgIGVudHJpZXMgbG9hZCBvbmx5IGFmdGVyIHRoZSBwcm9qZWN0IGlzIHRydXN0ZWQuXG5cbnwgTG9jYXRpb24gfCBTY29wZSB8XG58LS0tLS0tLS0tLXwtLS0tLS0tfFxufCBgfi8ucGkvYWdlbnQvZXh0ZW5zaW9ucy8qLnRzYCB8IEdsb2JhbCAoYWxsIHByb2plY3RzKSB8XG58IGB+Ly5waS9hZ2VudC9leHRlbnNpb25zLyovaW5kZXgudHNgIHwgR2xvYmFsIChzdWJkaXJlY3RvcnkpIHxcbnwgYC5waS9leHRlbnNpb25zLyoudHNgIHwgUHJvamVjdC1sb2NhbCB8XG58IGAucGkvZXh0ZW5zaW9ucy8qL2luZGV4LnRzYCB8IFByb2plY3QtbG9jYWwgKHN1YmRpcmVjdG9yeSkgfFxuXG5BZGRpdGlvbmFsIHBhdGhzIHZpYSBgc2V0dGluZ3MuanNvbmA6XG5cbmBgYGpzb25cbntcbiAgXCJwYWNrYWdlc1wiOiBbXG4gICAgXCJucG06QGZvby9iYXJAMS4wLjBcIixcbiAgICBcImdpdDpnaXRodWIuY29tL3VzZXIvcmVwb0B2MVwiXG4gIF0sXG4gIFwiZXh0ZW5zaW9uc1wiOiBbXG4gICAgXCIvcGF0aC90by9sb2NhbC9leHRlbnNpb24udHNcIixcbiAgICBcIi9wYXRoL3RvL2xvY2FsL2V4dGVuc2lvbi9kaXJcIlxuICBdXG59XG5gYGBcblxuVG8gc2hhcmUgZXh0ZW5zaW9ucyB2aWEgbnBtIG9yIGdpdCBhcyBwaSBwYWNrYWdlcywgc2VlIFtwYWNrYWdlcy5tZF0ocGFja2FnZXMubWQpLlxuXG4jIyBBdmFpbGFibGUgSW1wb3J0c1xuXG58IFBhY2thZ2UgfCBQdXJwb3NlIHxcbnwtLS0tLS0tLS18LS0tLS0tLS0tfFxufCBgQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudGAgfCBFeHRlbnNpb24gdHlwZXMgKGBFeHRlbnNpb25BUElgLCBgRXh0ZW5zaW9uQ29udGV4dGAsIGV2ZW50cykgfFxufCBgdHlwZWJveGAgfCBTY2hlbWEgZGVmaW5pdGlvbnMgZm9yIHRvb2wgcGFyYW1ldGVycyB8XG58IGBAZWFyZW5kaWwtd29ya3MvcGktYWlgIHwgQUkgdXRpbGl0aWVzIChgU3RyaW5nRW51bWAgZm9yIEdvb2dsZS1jb21wYXRpYmxlIGVudW1zKSB8XG58IGBAZWFyZW5kaWwtd29ya3MvcGktdHVpYCB8IFRVSSBjb21wb25lbnRzIGZvciBjdXN0b20gcmVuZGVyaW5nIHxcblxubnBtIGRlcGVuZGVuY2llcyB3b3JrIHRvby4gQWRkIGEgYHBhY2thZ2UuanNvbmAgbmV4dCB0byB5b3VyIGV4dGVuc2lvbiAob3IgaW4gYSBwYXJlbnQgZGlyZWN0b3J5KSwgcnVuIGBucG0gaW5zdGFsbGAsIGFuZCBpbXBvcnRzIGZyb20gYG5vZGVfbW9kdWxlcy9gIGFyZSByZXNvbHZlZCBhdXRvbWF0aWNhbGx5LlxuXG5Gb3IgZGlzdHJpYnV0ZWQgcGkgcGFja2FnZXMgaW5zdGFsbGVkIHdpdGggYHBpIGluc3RhbGxgIChucG0gb3IgZ2l0KSwgcnVudGltZSBkZXBzIG11c3QgYmUgaW4gYGRlcGVuZGVuY2llc2AuIFBhY2thZ2UgaW5zdGFsbGF0aW9uIHVzZXMgcHJvZHVjdGlvbiBpbnN0YWxscyAoYG5wbSBpbnN0YWxsIC0tb21pdD1kZXZgKSBieSBkZWZhdWx0LCBzbyBgZGV2RGVwZW5kZW5jaWVzYCBhcmUgbm90IGF2YWlsYWJsZSBhdCBydW50aW1lOyB3aGVuIGBucG1Db21tYW5kYCBpcyBjb25maWd1cmVkLCBnaXQgcGFja2FnZXMgdXNlIHBsYWluIGBpbnN0YWxsYCBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIHdyYXBwZXJzLlxuXG5Ob2RlLmpzIGJ1aWx0LWlucyAoYG5vZGU6ZnNgLCBgbm9kZTpwYXRoYCwgZXRjLikgYXJlIGFsc28gYXZhaWxhYmxlLlxuXG4jIyBXcml0aW5nIGFuIEV4dGVuc2lvblxuXG5BbiBleHRlbnNpb24gZXhwb3J0cyBhIGRlZmF1bHQgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IHJlY2VpdmVzIGBFeHRlbnNpb25BUElgLiBUaGUgZmFjdG9yeSBjYW4gYmUgc3luY2hyb25vdXMgb3IgYXN5bmNocm9ub3VzOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIC8vIFN1YnNjcmliZSB0byBldmVudHNcbiAgcGkub24oXCJldmVudF9uYW1lXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gICAgLy8gY3R4LnVpIGZvciB1c2VyIGludGVyYWN0aW9uXG4gICAgY29uc3Qgb2sgPSBhd2FpdCBjdHgudWkuY29uZmlybShcIlRpdGxlXCIsIFwiQXJlIHlvdSBzdXJlP1wiKTtcbiAgICBjdHgudWkubm90aWZ5KFwiRG9uZSFcIiwgXCJpbmZvXCIpO1xuICAgIGN0eC51aS5zZXRTdGF0dXMoXCJteS1leHRcIiwgXCJQcm9jZXNzaW5nLi4uXCIpOyAgLy8gRm9vdGVyIHN0YXR1c1xuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJteS1leHRcIiwgW1wiTGluZSAxXCIsIFwiTGluZSAyXCJdKTsgIC8vIFdpZGdldCBhYm92ZSBlZGl0b3IgKGRlZmF1bHQpXG4gIH0pO1xuXG4gIC8vIFJlZ2lzdGVyIHRvb2xzLCBjb21tYW5kcywgc2hvcnRjdXRzLCBmbGFnc1xuICBwaS5yZWdpc3RlclRvb2woeyAuLi4gfSk7XG4gIHBpLnJlZ2lzdGVyQ29tbWFuZChcIm5hbWVcIiwgeyAuLi4gfSk7XG4gIHBpLnJlZ2lzdGVyU2hvcnRjdXQoXCJjdHJsK3hcIiwgeyAuLi4gfSk7XG4gIHBpLnJlZ2lzdGVyRmxhZyhcIm15LWZsYWdcIiwgeyAuLi4gfSk7XG59XG5gYGBcblxuRXh0ZW5zaW9ucyBhcmUgbG9hZGVkIHZpYSBbaml0aV0oaHR0cHM6Ly9naXRodWIuY29tL3VuanMvaml0aSksIHNvIFR5cGVTY3JpcHQgd29ya3Mgd2l0aG91dCBjb21waWxhdGlvbi5cblxuSWYgdGhlIGZhY3RvcnkgcmV0dXJucyBhIGBQcm9taXNlYCwgcGkgYXdhaXRzIGl0IGJlZm9yZSBjb250aW51aW5nIHN0YXJ0dXAuIFRoYXQgbWVhbnMgYXN5bmMgaW5pdGlhbGl6YXRpb24gY29tcGxldGVzIGJlZm9yZSBgc2Vzc2lvbl9zdGFydGAsIGJlZm9yZSBgcmVzb3VyY2VzX2Rpc2NvdmVyYCwgYW5kIGJlZm9yZSBwcm92aWRlciByZWdpc3RyYXRpb25zIHF1ZXVlZCB2aWEgYHBpLnJlZ2lzdGVyUHJvdmlkZXIoKWAgYXJlIGZsdXNoZWQuXG5cbiMjIyBBc3luYyBmYWN0b3J5IGZ1bmN0aW9uc1xuXG5Vc2UgYW4gYXN5bmMgZmFjdG9yeSBmb3Igb25lLXRpbWUgc3RhcnR1cCB3b3JrIHN1Y2ggYXMgZmV0Y2hpbmcgcmVtb3RlIGNvbmZpZ3VyYXRpb24gb3IgZHluYW1pY2FsbHkgZGlzY292ZXJpbmcgYXZhaWxhYmxlIG1vZGVscy5cblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEkgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiAocGk6IEV4dGVuc2lvbkFQSSkge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFwiaHR0cDovL2xvY2FsaG9zdDoxMjM0L3YxL21vZGVsc1wiKTtcbiAgY29uc3QgcGF5bG9hZCA9IChhd2FpdCByZXNwb25zZS5qc29uKCkpIGFzIHtcbiAgICBkYXRhOiBBcnJheTx7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgbmFtZT86IHN0cmluZztcbiAgICAgIGNvbnRleHRfd2luZG93PzogbnVtYmVyO1xuICAgICAgbWF4X3Rva2Vucz86IG51bWJlcjtcbiAgICB9PjtcbiAgfTtcblxuICBwaS5yZWdpc3RlclByb3ZpZGVyKFwibG9jYWwtb3BlbmFpXCIsIHtcbiAgICBiYXNlVXJsOiBcImh0dHA6Ly9sb2NhbGhvc3Q6MTIzNC92MVwiLFxuICAgIGFwaUtleTogXCIkTE9DQUxfT1BFTkFJX0FQSV9LRVlcIixcbiAgICBhcGk6IFwib3BlbmFpLWNvbXBsZXRpb25zXCIsXG4gICAgbW9kZWxzOiBwYXlsb2FkLmRhdGEubWFwKChtb2RlbCkgPT4gKHtcbiAgICAgIGlkOiBtb2RlbC5pZCxcbiAgICAgIG5hbWU6IG1vZGVsLm5hbWUgPz8gbW9kZWwuaWQsXG4gICAgICByZWFzb25pbmc6IGZhbHNlLFxuICAgICAgaW5wdXQ6IFtcInRleHRcIl0sXG4gICAgICBjb3N0OiB7IGlucHV0OiAwLCBvdXRwdXQ6IDAsIGNhY2hlUmVhZDogMCwgY2FjaGVXcml0ZTogMCB9LFxuICAgICAgY29udGV4dFdpbmRvdzogbW9kZWwuY29udGV4dF93aW5kb3cgPz8gMTI4MDAwLFxuICAgICAgbWF4VG9rZW5zOiBtb2RlbC5tYXhfdG9rZW5zID8/IDQwOTYsXG4gICAgfSkpLFxuICB9KTtcbn1cbmBgYFxuXG5UaGlzIHBhdHRlcm4gbWFrZXMgdGhlIGZldGNoZWQgbW9kZWxzIGF2YWlsYWJsZSBkdXJpbmcgbm9ybWFsIHN0YXJ0dXAgYW5kIHRvIGBwaSAtLWxpc3QtbW9kZWxzYC5cblxuIyMjIExvbmctbGl2ZWQgcmVzb3VyY2VzIGFuZCBzaHV0ZG93blxuXG5FeHRlbnNpb24gZmFjdG9yaWVzIG1heSBydW4gaW4gaW52b2NhdGlvbnMgdGhhdCBuZXZlciBzdGFydCBhIHNlc3Npb24uIERvIG5vdCBzdGFydCBiYWNrZ3JvdW5kIHJlc291cmNlcyBzdWNoIGFzIHByb2Nlc3Nlcywgc29ja2V0cywgZmlsZSB3YXRjaGVycywgb3IgdGltZXJzIGZyb20gdGhlIGZhY3RvcnkuXG5cbkRlZmVyIGJhY2tncm91bmQgcmVzb3VyY2Ugc3RhcnR1cCB1bnRpbCBgc2Vzc2lvbl9zdGFydGAgb3IgdGhlIGNvbW1hbmQvdG9vbC9ldmVudCB0aGF0IG5lZWRzIHRoZSByZXNvdXJjZS4gUmVnaXN0ZXIgYW4gaWRlbXBvdGVudCBgc2Vzc2lvbl9zaHV0ZG93bmAgaGFuZGxlciB0byBjbG9zZSBhbnkgc2Vzc2lvbi1zY29wZWQgcmVzb3VyY2VzIHlvdSBzdGFydC5cblxuIyMjIEV4dGVuc2lvbiBTdHlsZXNcblxuKipTaW5nbGUgZmlsZSoqIC0gc2ltcGxlc3QsIGZvciBzbWFsbCBleHRlbnNpb25zOlxuXG5gYGBcbn4vLnBpL2FnZW50L2V4dGVuc2lvbnMvXG7ilJTilIDilIAgbXktZXh0ZW5zaW9uLnRzXG5gYGBcblxuKipEaXJlY3Rvcnkgd2l0aCBpbmRleC50cyoqIC0gZm9yIG11bHRpLWZpbGUgZXh0ZW5zaW9uczpcblxuYGBgXG5+Ly5waS9hZ2VudC9leHRlbnNpb25zL1xu4pSU4pSA4pSAIG15LWV4dGVuc2lvbi9cbiAgICDilJzilIDilIAgaW5kZXgudHMgICAgICAgICMgRW50cnkgcG9pbnQgKGV4cG9ydHMgZGVmYXVsdCBmdW5jdGlvbilcbiAgICDilJzilIDilIAgdG9vbHMudHMgICAgICAgICMgSGVscGVyIG1vZHVsZVxuICAgIOKUlOKUgOKUgCB1dGlscy50cyAgICAgICAgIyBIZWxwZXIgbW9kdWxlXG5gYGBcblxuKipQYWNrYWdlIHdpdGggZGVwZW5kZW5jaWVzKiogLSBmb3IgZXh0ZW5zaW9ucyB0aGF0IG5lZWQgbnBtIHBhY2thZ2VzOlxuXG5gYGBcbn4vLnBpL2FnZW50L2V4dGVuc2lvbnMvXG7ilJTilIDilIAgbXktZXh0ZW5zaW9uL1xuICAgIOKUnOKUgOKUgCBwYWNrYWdlLmpzb24gICAgIyBEZWNsYXJlcyBkZXBlbmRlbmNpZXMgYW5kIGVudHJ5IHBvaW50c1xuICAgIOKUnOKUgOKUgCBwYWNrYWdlLWxvY2suanNvblxuICAgIOKUnOKUgOKUgCBub2RlX21vZHVsZXMvICAgIyBBZnRlciBucG0gaW5zdGFsbFxuICAgIOKUlOKUgOKUgCBzcmMvXG4gICAgICAgIOKUlOKUgOKUgCBpbmRleC50c1xuYGBgXG5cbmBgYGpzb25cbi8vIHBhY2thZ2UuanNvblxue1xuICBcIm5hbWVcIjogXCJteS1leHRlbnNpb25cIixcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiem9kXCI6IFwiXjMuMC4wXCIsXG4gICAgXCJjaGFsa1wiOiBcIl41LjAuMFwiXG4gIH0sXG4gIFwicGlcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXCIuL3NyYy9pbmRleC50c1wiXVxuICB9XG59XG5gYGBcblxuUnVuIGBucG0gaW5zdGFsbGAgaW4gdGhlIGV4dGVuc2lvbiBkaXJlY3RvcnksIHRoZW4gaW1wb3J0cyBmcm9tIGBub2RlX21vZHVsZXMvYCB3b3JrIGF1dG9tYXRpY2FsbHkuXG5cbiMjIEV2ZW50c1xuXG4jIyMgTGlmZWN5Y2xlIE92ZXJ2aWV3XG5cbmBgYFxucGkgc3RhcnRzXG4gIOKUglxuICDilJzilIDilrogcHJvamVjdF90cnVzdCAodXNlci9nbG9iYWwgYW5kIENMSSBleHRlbnNpb25zIG9ubHksIGJlZm9yZSBwcm9qZWN0IHJlc291cmNlcyBsb2FkKVxuICDilJzilIDilrogc2Vzc2lvbl9zdGFydCB7IHJlYXNvbjogXCJzdGFydHVwXCIgfVxuICDilJTilIDilrogcmVzb3VyY2VzX2Rpc2NvdmVyIHsgcmVhc29uOiBcInN0YXJ0dXBcIiB9XG4gICAgICDilIJcbiAgICAgIOKWvFxudXNlciBzZW5kcyBwcm9tcHQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQXG4gIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG4gIOKUnOKUgOKWuiAoZXh0ZW5zaW9uIGNvbW1hbmRzIGNoZWNrZWQgZmlyc3QsIGJ5cGFzcyBpZiBmb3VuZCkgIOKUglxuICDilJzilIDilrogaW5wdXQgKGNhbiBpbnRlcmNlcHQsIHRyYW5zZm9ybSwgb3IgaGFuZGxlKSAgICAgICAgICDilIJcbiAg4pSc4pSA4pa6IChza2lsbC90ZW1wbGF0ZSBleHBhbnNpb24gaWYgbm90IGhhbmRsZWQpICAgICAgICAgICAg4pSCXG4gIOKUnOKUgOKWuiBiZWZvcmVfYWdlbnRfc3RhcnQgKGNhbiBpbmplY3QgbWVzc2FnZSwgbW9kaWZ5IHN5c3RlbSBwcm9tcHQpXG4gIOKUnOKUgOKWuiBhZ2VudF9zdGFydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICDilJzilIDilrogbWVzc2FnZV9zdGFydCAvIG1lc3NhZ2VfdXBkYXRlIC8gbWVzc2FnZV9lbmQgICAgICAgICDilIJcbiAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAg4pSCICAg4pSM4pSA4pSA4pSAIHR1cm4gKHJlcGVhdHMgd2hpbGUgTExNIGNhbGxzIHRvb2xzKSDilIDilIDilIDilJAgICAgICAg4pSCXG4gIOKUgiAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilJzilIDilrogdHVybl9zdGFydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUnOKUgOKWuiBjb250ZXh0IChjYW4gbW9kaWZ5IG1lc3NhZ2VzKSAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSc4pSA4pa6IGJlZm9yZV9wcm92aWRlcl9yZXF1ZXN0IChjYW4gaW5zcGVjdCBvciByZXBsYWNlIHBheWxvYWQpXG4gIOKUgiAgIOKUnOKUgOKWuiBhZnRlcl9wcm92aWRlcl9yZXNwb25zZSAoc3RhdHVzICsgaGVhZGVycywgYmVmb3JlIHN0cmVhbSBjb25zdW1lKVxuICDilIIgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSCICAgTExNIHJlc3BvbmRzLCBtYXkgY2FsbCB0b29sczogICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUgiAgICAg4pSc4pSA4pa6IHRvb2xfZXhlY3V0aW9uX3N0YXJ0ICAgICAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilIIgICAgIOKUnOKUgOKWuiB0b29sX2NhbGwgKGNhbiBibG9jaykgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSCICAgICDilJzilIDilrogdG9vbF9leGVjdXRpb25fdXBkYXRlICAgICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUgiAgICAg4pSc4pSA4pa6IHRvb2xfcmVzdWx0IChjYW4gbW9kaWZ5KSAgICAgICAgICAg4pSCICAgICAgIOKUglxuICDilIIgICDilIIgICAgIOKUlOKUgOKWuiB0b29sX2V4ZWN1dGlvbl9lbmQgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAg4pSCXG4gIOKUgiAgIOKUlOKUgOKWuiB0dXJuX2VuZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIJcbiAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAg4pSU4pSA4pa6IGFnZW50X2VuZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxudXNlciBzZW5kcyBhbm90aGVyIHByb21wdCDil4TilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJhcblxuL25ldyAobmV3IHNlc3Npb24pIG9yIC9yZXN1bWUgKHN3aXRjaCBzZXNzaW9uKVxuICDilJzilIDilrogc2Vzc2lvbl9iZWZvcmVfc3dpdGNoIChjYW4gY2FuY2VsKVxuICDilJzilIDilrogc2Vzc2lvbl9zaHV0ZG93blxuICDilJzilIDilrogc2Vzc2lvbl9zdGFydCB7IHJlYXNvbjogXCJuZXdcIiB8IFwicmVzdW1lXCIsIHByZXZpb3VzU2Vzc2lvbkZpbGU/IH1cbiAg4pSU4pSA4pa6IHJlc291cmNlc19kaXNjb3ZlciB7IHJlYXNvbjogXCJzdGFydHVwXCIgfVxuXG4vZm9yayBvciAvY2xvbmVcbiAg4pSc4pSA4pa6IHNlc3Npb25fYmVmb3JlX2ZvcmsgKGNhbiBjYW5jZWwpXG4gIOKUnOKUgOKWuiBzZXNzaW9uX3NodXRkb3duXG4gIOKUnOKUgOKWuiBzZXNzaW9uX3N0YXJ0IHsgcmVhc29uOiBcImZvcmtcIiwgcHJldmlvdXNTZXNzaW9uRmlsZSB9XG4gIOKUlOKUgOKWuiByZXNvdXJjZXNfZGlzY292ZXIgeyByZWFzb246IFwic3RhcnR1cFwiIH1cblxuL2NvbXBhY3Qgb3IgYXV0by1jb21wYWN0aW9uXG4gIOKUnOKUgOKWuiBzZXNzaW9uX2JlZm9yZV9jb21wYWN0IChjYW4gY2FuY2VsIG9yIGN1c3RvbWl6ZSlcbiAg4pSU4pSA4pa6IHNlc3Npb25fY29tcGFjdFxuXG4vdHJlZSBuYXZpZ2F0aW9uXG4gIOKUnOKUgOKWuiBzZXNzaW9uX2JlZm9yZV90cmVlIChjYW4gY2FuY2VsIG9yIGN1c3RvbWl6ZSlcbiAg4pSU4pSA4pa6IHNlc3Npb25fdHJlZVxuXG4vbW9kZWwgb3IgQ3RybCtQIChtb2RlbCBzZWxlY3Rpb24vY3ljbGluZylcbiAg4pSc4pSA4pa6IHRoaW5raW5nX2xldmVsX3NlbGVjdCAoaWYgbW9kZWwgY2hhbmdlIGNoYW5nZXMvY2xhbXBzIHRoaW5raW5nIGxldmVsKVxuICDilJTilIDilrogbW9kZWxfc2VsZWN0XG5cbnRoaW5raW5nIGxldmVsIGNoYW5nZXMgKHNldHRpbmdzLCBrZXliaW5kaW5nLCBwaS5zZXRUaGlua2luZ0xldmVsKCkpXG4gIOKUlOKUgOKWuiB0aGlua2luZ19sZXZlbF9zZWxlY3RcblxuZXhpdCAoQ3RybCtDLCBDdHJsK0QsIFNJR0hVUCwgU0lHVEVSTSlcbiAg4pSU4pSA4pa6IHNlc3Npb25fc2h1dGRvd25cbmBgYFxuXG4jIyMgU3RhcnR1cCBFdmVudHNcblxuIyMjIyBwcm9qZWN0X3RydXN0XG5cbkZpcmVkIGJlZm9yZSBwaSBkZWNpZGVzIHdoZXRoZXIgdG8gdHJ1c3QgYSBwcm9qZWN0IHdpdGggZHluYW1pYyBjb25maWdzIChgLnBpYCBvciBgLmFnZW50cy9za2lsbHNgKS4gSXQgcnVucyBkdXJpbmcgc3RhcnR1cCBhbmQgd2hlbiBzZXNzaW9uIHJlcGxhY2VtZW50IChmb3IgZXhhbXBsZSBgL3Jlc3VtZWApIGVudGVycyBhIGN3ZCB3aG9zZSB0cnVzdCBoYXMgbm90IGJlZW4gcmVzb2x2ZWQgaW4gdGhlIGN1cnJlbnQgcHJvY2Vzcy4gT25seSB1c2VyL2dsb2JhbCBleHRlbnNpb25zIGFuZCBDTEkgYC1lYCBleHRlbnNpb25zIHBhcnRpY2lwYXRlOyBwcm9qZWN0LWxvY2FsIGV4dGVuc2lvbnMgYXJlIG5vdCBsb2FkZWQgdW50aWwgYWZ0ZXIgdHJ1c3QgaXMgcmVzb2x2ZWQuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwicHJvamVjdF90cnVzdFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5jd2QgLSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5XG4gIC8vIGN0eCBoYXMgYSBsaW1pdGVkIHRydXN0IGNvbnRleHQ6IGN3ZCwgbW9kZSwgaGFzVUksIGFuZCBzZWxlY3QvY29uZmlybS9pbnB1dC9ub3RpZnkgVUkgaGVscGVyc1xuICBpZiAoYXdhaXQgY3R4LnVpLmNvbmZpcm0oXCJUcnVzdCBwcm9qZWN0P1wiLCBldmVudC5jd2QpKSB7XG4gICAgcmV0dXJuIHsgdHJ1c3RlZDogXCJ5ZXNcIiwgcmVtZW1iZXI6IHRydWUgfTtcbiAgfVxuICByZXR1cm4geyB0cnVzdGVkOiBcInVuZGVjaWRlZFwiIH07XG59KTtcbmBgYFxuXG5BIGBwcm9qZWN0X3RydXN0YCBoYW5kbGVyIG11c3QgcmV0dXJuIGB7IHRydXN0ZWQ6IFwieWVzXCIgfCBcIm5vXCIgfCBcInVuZGVjaWRlZFwiIH1gLiBBIHVzZXIvZ2xvYmFsIG9yIENMSSBleHRlbnNpb24gdGhhdCByZXR1cm5zIGBcInllc1wiYCBvciBgXCJub1wiYCBvd25zIHRoZSBkZWNpc2lvbjsgdGhlIGZpcnN0IHllcy9ubyBkZWNpc2lvbiB3aW5zIGFuZCBzdXBwcmVzc2VzIHRoZSBidWlsdC1pbiB0cnVzdCBwcm9tcHQuIFVzZSBgcmVtZW1iZXI6IHRydWVgIHRvIHBlcnNpc3QgYSB5ZXMvbm8gZGVjaXNpb247IG90aGVyd2lzZSBpdCBhcHBsaWVzIG9ubHkgdG8gdGhlIGN1cnJlbnQgcHJvY2Vzcy4gUmV0dXJuIGBcInVuZGVjaWRlZFwiYCB0byBsZXQgbGF0ZXIgaGFuZGxlcnMgb3IgdGhlIGJ1aWx0LWluIHRydXN0IGZsb3cgZGVjaWRlLiBDaGVjayBgY3R4Lmhhc1VJYCBiZWZvcmUgcHJvbXB0aW5nLiBJZiBubyBoYW5kbGVyIHJldHVybnMgeWVzL25vLCBub3JtYWwgdHJ1c3QgcmVzb2x1dGlvbiBjb250aW51ZXM6IHNhdmVkIGB0cnVzdC5qc29uYCBkZWNpc2lvbnMgYXBwbHkgZmlyc3QsIHRoZW4gYGRlZmF1bHRQcm9qZWN0VHJ1c3RgIGNvbnRyb2xzIHdoZXRoZXIgcGkgYXNrcywgdHJ1c3RzLCBvciBkZWNsaW5lcyBieSBkZWZhdWx0LlxuXG4jIyMgUmVzb3VyY2UgRXZlbnRzXG5cbiMjIyMgcmVzb3VyY2VzX2Rpc2NvdmVyXG5cbkZpcmVkIGFmdGVyIGBzZXNzaW9uX3N0YXJ0YCBzbyBleHRlbnNpb25zIGNhbiBjb250cmlidXRlIGFkZGl0aW9uYWwgc2tpbGwsIHByb21wdCwgYW5kIHRoZW1lIHBhdGhzLlxuVGhlIHN0YXJ0dXAgcGF0aCB1c2VzIGByZWFzb246IFwic3RhcnR1cFwiYC4gUmVsb2FkIHVzZXMgYHJlYXNvbjogXCJyZWxvYWRcImAuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwicmVzb3VyY2VzX2Rpc2NvdmVyXCIsIGFzeW5jIChldmVudCwgX2N0eCkgPT4ge1xuICAvLyBldmVudC5jd2QgLSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5XG4gIC8vIGV2ZW50LnJlYXNvbiAtIFwic3RhcnR1cFwiIHwgXCJyZWxvYWRcIlxuICByZXR1cm4ge1xuICAgIHNraWxsUGF0aHM6IFtcIi9wYXRoL3RvL3NraWxsc1wiXSxcbiAgICBwcm9tcHRQYXRoczogW1wiL3BhdGgvdG8vcHJvbXB0c1wiXSxcbiAgICB0aGVtZVBhdGhzOiBbXCIvcGF0aC90by90aGVtZXNcIl0sXG4gIH07XG59KTtcbmBgYFxuXG4jIyMgU2Vzc2lvbiBFdmVudHNcblxuU2VlIFtTZXNzaW9uIEZvcm1hdF0oc2Vzc2lvbi1mb3JtYXQubWQpIGZvciBzZXNzaW9uIHN0b3JhZ2UgaW50ZXJuYWxzIGFuZCB0aGUgU2Vzc2lvbk1hbmFnZXIgQVBJLlxuXG4jIyMjIHNlc3Npb25fc3RhcnRcblxuRmlyZWQgd2hlbiBhIHNlc3Npb24gaXMgc3RhcnRlZCwgbG9hZGVkLCBvciByZWxvYWRlZC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnJlYXNvbiAtIFwic3RhcnR1cFwiIHwgXCJyZWxvYWRcIiB8IFwibmV3XCIgfCBcInJlc3VtZVwiIHwgXCJmb3JrXCJcbiAgLy8gZXZlbnQucHJldmlvdXNTZXNzaW9uRmlsZSAtIHByZXNlbnQgZm9yIFwibmV3XCIsIFwicmVzdW1lXCIsIGFuZCBcImZvcmtcIlxuICBjdHgudWkubm90aWZ5KGBTZXNzaW9uOiAke2N0eC5zZXNzaW9uTWFuYWdlci5nZXRTZXNzaW9uRmlsZSgpID8/IFwiZXBoZW1lcmFsXCJ9YCwgXCJpbmZvXCIpO1xufSk7XG5gYGBcblxuIyMjIyBzZXNzaW9uX2JlZm9yZV9zd2l0Y2hcblxuRmlyZWQgYmVmb3JlIHN0YXJ0aW5nIGEgbmV3IHNlc3Npb24gKGAvbmV3YCkgb3Igc3dpdGNoaW5nIHNlc3Npb25zIChgL3Jlc3VtZWApLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInNlc3Npb25fYmVmb3JlX3N3aXRjaFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5yZWFzb24gLSBcIm5ld1wiIG9yIFwicmVzdW1lXCJcbiAgLy8gZXZlbnQudGFyZ2V0U2Vzc2lvbkZpbGUgLSBzZXNzaW9uIHdlJ3JlIHN3aXRjaGluZyB0byAob25seSBmb3IgXCJyZXN1bWVcIilcblxuICBpZiAoZXZlbnQucmVhc29uID09PSBcIm5ld1wiKSB7XG4gICAgY29uc3Qgb2sgPSBhd2FpdCBjdHgudWkuY29uZmlybShcIkNsZWFyP1wiLCBcIkRlbGV0ZSBhbGwgbWVzc2FnZXM/XCIpO1xuICAgIGlmICghb2spIHJldHVybiB7IGNhbmNlbDogdHJ1ZSB9O1xuICB9XG59KTtcbmBgYFxuXG5BZnRlciBhIHN1Y2Nlc3NmdWwgc3dpdGNoIG9yIG5ldy1zZXNzaW9uIGFjdGlvbiwgcGkgZW1pdHMgYHNlc3Npb25fc2h1dGRvd25gIGZvciB0aGUgb2xkIGV4dGVuc2lvbiBpbnN0YW5jZSwgcmVsb2FkcyBhbmQgcmViaW5kcyBleHRlbnNpb25zIGZvciB0aGUgbmV3IHNlc3Npb24sIHRoZW4gZW1pdHMgYHNlc3Npb25fc3RhcnRgIHdpdGggYHJlYXNvbjogXCJuZXdcIiB8IFwicmVzdW1lXCJgIGFuZCBgcHJldmlvdXNTZXNzaW9uRmlsZWAuXG5EbyBjbGVhbnVwIHdvcmsgaW4gYHNlc3Npb25fc2h1dGRvd25gLCB0aGVuIHJlZXN0YWJsaXNoIGFueSBpbi1tZW1vcnkgc3RhdGUgaW4gYHNlc3Npb25fc3RhcnRgLlxuXG4jIyMjIHNlc3Npb25fYmVmb3JlX2ZvcmtcblxuRmlyZWQgd2hlbiBmb3JraW5nIHZpYSBgL2ZvcmtgIG9yIGNsb25pbmcgdmlhIGAvY2xvbmVgLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInNlc3Npb25fYmVmb3JlX2ZvcmtcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQuZW50cnlJZCAtIElEIG9mIHRoZSBzZWxlY3RlZCBlbnRyeVxuICAvLyBldmVudC5wb3NpdGlvbiAtIFwiYmVmb3JlXCIgZm9yIC9mb3JrLCBcImF0XCIgZm9yIC9jbG9uZVxuICByZXR1cm4geyBjYW5jZWw6IHRydWUgfTsgLy8gQ2FuY2VsIGZvcmsvY2xvbmVcbiAgLy8gT1JcbiAgcmV0dXJuIHsgc2tpcENvbnZlcnNhdGlvblJlc3RvcmU6IHRydWUgfTsgLy8gUmVzZXJ2ZWQgZm9yIGZ1dHVyZSBjb252ZXJzYXRpb24gcmVzdG9yZSBjb250cm9sXG59KTtcbmBgYFxuXG5BZnRlciBhIHN1Y2Nlc3NmdWwgZm9yayBvciBjbG9uZSwgcGkgZW1pdHMgYHNlc3Npb25fc2h1dGRvd25gIGZvciB0aGUgb2xkIGV4dGVuc2lvbiBpbnN0YW5jZSwgcmVsb2FkcyBhbmQgcmViaW5kcyBleHRlbnNpb25zIGZvciB0aGUgbmV3IHNlc3Npb24sIHRoZW4gZW1pdHMgYHNlc3Npb25fc3RhcnRgIHdpdGggYHJlYXNvbjogXCJmb3JrXCJgIGFuZCBgcHJldmlvdXNTZXNzaW9uRmlsZWAuXG5EbyBjbGVhbnVwIHdvcmsgaW4gYHNlc3Npb25fc2h1dGRvd25gLCB0aGVuIHJlZXN0YWJsaXNoIGFueSBpbi1tZW1vcnkgc3RhdGUgaW4gYHNlc3Npb25fc3RhcnRgLlxuXG4jIyMjIHNlc3Npb25fYmVmb3JlX2NvbXBhY3QgLyBzZXNzaW9uX2NvbXBhY3RcblxuRmlyZWQgb24gY29tcGFjdGlvbi4gU2VlIFtjb21wYWN0aW9uLm1kXShjb21wYWN0aW9uLm1kKSBmb3IgZGV0YWlscy5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJzZXNzaW9uX2JlZm9yZV9jb21wYWN0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIGNvbnN0IHsgcHJlcGFyYXRpb24sIGJyYW5jaEVudHJpZXMsIGN1c3RvbUluc3RydWN0aW9ucywgc2lnbmFsIH0gPSBldmVudDtcblxuICAvLyBDYW5jZWw6XG4gIHJldHVybiB7IGNhbmNlbDogdHJ1ZSB9O1xuXG4gIC8vIEN1c3RvbSBzdW1tYXJ5OlxuICByZXR1cm4ge1xuICAgIGNvbXBhY3Rpb246IHtcbiAgICAgIHN1bW1hcnk6IFwiLi4uXCIsXG4gICAgICBmaXJzdEtlcHRFbnRyeUlkOiBwcmVwYXJhdGlvbi5maXJzdEtlcHRFbnRyeUlkLFxuICAgICAgdG9rZW5zQmVmb3JlOiBwcmVwYXJhdGlvbi50b2tlbnNCZWZvcmUsXG4gICAgfVxuICB9O1xufSk7XG5cbnBpLm9uKFwic2Vzc2lvbl9jb21wYWN0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LmNvbXBhY3Rpb25FbnRyeSAtIHRoZSBzYXZlZCBjb21wYWN0aW9uXG4gIC8vIGV2ZW50LmZyb21FeHRlbnNpb24gLSB3aGV0aGVyIGV4dGVuc2lvbiBwcm92aWRlZCBpdFxufSk7XG5gYGBcblxuIyMjIyBzZXNzaW9uX2JlZm9yZV90cmVlIC8gc2Vzc2lvbl90cmVlXG5cbkZpcmVkIG9uIGAvdHJlZWAgbmF2aWdhdGlvbi4gU2VlIFtTZXNzaW9uc10oc2Vzc2lvbnMubWQpIGZvciB0cmVlIG5hdmlnYXRpb24gY29uY2VwdHMuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwic2Vzc2lvbl9iZWZvcmVfdHJlZVwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICBjb25zdCB7IHByZXBhcmF0aW9uLCBzaWduYWwgfSA9IGV2ZW50O1xuICByZXR1cm4geyBjYW5jZWw6IHRydWUgfTtcbiAgLy8gT1IgcHJvdmlkZSBjdXN0b20gc3VtbWFyeTpcbiAgcmV0dXJuIHsgc3VtbWFyeTogeyBzdW1tYXJ5OiBcIi4uLlwiLCBkZXRhaWxzOiB7fSB9IH07XG59KTtcblxucGkub24oXCJzZXNzaW9uX3RyZWVcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQubmV3TGVhZklkLCBvbGRMZWFmSWQsIHN1bW1hcnlFbnRyeSwgZnJvbUV4dGVuc2lvblxufSk7XG5gYGBcblxuIyMjIyBzZXNzaW9uX3NodXRkb3duXG5cbkZpcmVkIGJlZm9yZSBhIHN0YXJ0ZWQgc2Vzc2lvbiBydW50aW1lIGlzIHRvcm4gZG93bi4gVXNlIHRoaXMgdG8gY2xlYW4gdXAgcmVzb3VyY2VzIG9wZW5lZCBmcm9tIGBzZXNzaW9uX3N0YXJ0YCBvciBvdGhlciBzZXNzaW9uLXNjb3BlZCBob29rcy5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJzZXNzaW9uX3NodXRkb3duXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnJlYXNvbiAtIFwicXVpdFwiIHwgXCJyZWxvYWRcIiB8IFwibmV3XCIgfCBcInJlc3VtZVwiIHwgXCJmb3JrXCJcbiAgLy8gZXZlbnQudGFyZ2V0U2Vzc2lvbkZpbGUgLSBkZXN0aW5hdGlvbiBzZXNzaW9uIGZvciBzZXNzaW9uIHJlcGxhY2VtZW50IGZsb3dzXG4gIC8vIENsZWFudXAsIHNhdmUgc3RhdGUsIGV0Yy5cbn0pO1xuYGBgXG5cbiMjIyBBZ2VudCBFdmVudHNcblxuIyMjIyBiZWZvcmVfYWdlbnRfc3RhcnRcblxuRmlyZWQgYWZ0ZXIgdXNlciBzdWJtaXRzIHByb21wdCwgYmVmb3JlIGFnZW50IGxvb3AuIENhbiBpbmplY3QgYSBtZXNzYWdlIGFuZC9vciBtb2RpZnkgdGhlIHN5c3RlbSBwcm9tcHQuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnByb21wdCAtIHVzZXIncyBwcm9tcHQgdGV4dFxuICAvLyBldmVudC5pbWFnZXMgLSBhdHRhY2hlZCBpbWFnZXMgKGlmIGFueSlcbiAgLy8gZXZlbnQuc3lzdGVtUHJvbXB0IC0gY3VycmVudCBjaGFpbmVkIHN5c3RlbSBwcm9tcHQgZm9yIHRoaXMgaGFuZGxlclxuICAvLyAgIChpbmNsdWRlcyBjaGFuZ2VzIGZyb20gZWFybGllciBiZWZvcmVfYWdlbnRfc3RhcnQgaGFuZGxlcnMpXG4gIC8vIGV2ZW50LnN5c3RlbVByb21wdE9wdGlvbnMgLSBzdHJ1Y3R1cmVkIG9wdGlvbnMgdXNlZCB0byBidWlsZCB0aGUgc3lzdGVtIHByb21wdFxuICAvLyAgIC5jdXN0b21Qcm9tcHQgLSBhbnkgY3VzdG9tIHN5c3RlbSBwcm9tcHQgKGZyb20gLS1zeXN0ZW0tcHJvbXB0LCBTWVNURU0ubWQsIG9yIGN1c3RvbSB0ZW1wbGF0ZXMpXG4gIC8vICAgLnNlbGVjdGVkVG9vbHMgLSB0b29scyBjdXJyZW50bHkgYWN0aXZlIGluIHRoZSBwcm9tcHRcbiAgLy8gICAudG9vbFNuaXBwZXRzIC0gb25lLWxpbmUgZGVzY3JpcHRpb25zIGZvciBlYWNoIHRvb2xcbiAgLy8gICAucHJvbXB0R3VpZGVsaW5lcyAtIGN1c3RvbSBndWlkZWxpbmUgYnVsbGV0c1xuICAvLyAgIC5hcHBlbmRTeXN0ZW1Qcm9tcHQgLSB0ZXh0IGZyb20gLS1hcHBlbmQtc3lzdGVtLXByb21wdCBmbGFnc1xuICAvLyAgIC5jd2QgLSB3b3JraW5nIGRpcmVjdG9yeVxuICAvLyAgIC5jb250ZXh0RmlsZXMgLSBBR0VOVFMubWQgZmlsZXMgYW5kIG90aGVyIGxvYWRlZCBjb250ZXh0IGZpbGVzXG4gIC8vICAgLnNraWxscyAtIGxvYWRlZCBza2lsbHNcblxuICByZXR1cm4ge1xuICAgIC8vIEluamVjdCBhIHBlcnNpc3RlbnQgbWVzc2FnZSAoc3RvcmVkIGluIHNlc3Npb24sIHNlbnQgdG8gTExNKVxuICAgIG1lc3NhZ2U6IHtcbiAgICAgIGN1c3RvbVR5cGU6IFwibXktZXh0ZW5zaW9uXCIsXG4gICAgICBjb250ZW50OiBcIkFkZGl0aW9uYWwgY29udGV4dCBmb3IgdGhlIExMTVwiLFxuICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICB9LFxuICAgIC8vIFJlcGxhY2UgdGhlIHN5c3RlbSBwcm9tcHQgZm9yIHRoaXMgdHVybiAoY2hhaW5lZCBhY3Jvc3MgZXh0ZW5zaW9ucylcbiAgICBzeXN0ZW1Qcm9tcHQ6IGV2ZW50LnN5c3RlbVByb21wdCArIFwiXFxuXFxuRXh0cmEgaW5zdHJ1Y3Rpb25zIGZvciB0aGlzIHR1cm4uLi5cIixcbiAgfTtcbn0pO1xuYGBgXG5cblRoZSBgc3lzdGVtUHJvbXB0T3B0aW9uc2AgZmllbGQgZ2l2ZXMgZXh0ZW5zaW9ucyBhY2Nlc3MgdG8gdGhlIHNhbWUgc3RydWN0dXJlZCBkYXRhIFBpIHVzZXMgdG8gYnVpbGQgdGhlIHN5c3RlbSBwcm9tcHQuIFRoaXMgbGV0cyB5b3UgaW5zcGVjdCB3aGF0IFBpIGhhcyBsb2FkZWQg4oCUIGN1c3RvbSBwcm9tcHRzLCBndWlkZWxpbmVzLCB0b29sIHNuaXBwZXRzLCBjb250ZXh0IGZpbGVzLCBza2lsbHMg4oCUIHdpdGhvdXQgcmUtZGlzY292ZXJpbmcgcmVzb3VyY2VzIG9yIHJlLXBhcnNpbmcgZmxhZ3MuIFVzZSBpdCB3aGVuIHlvdXIgZXh0ZW5zaW9uIG5lZWRzIHRvIG1ha2UgZGVlcCwgaW5mb3JtZWQgY2hhbmdlcyB0byB0aGUgc3lzdGVtIHByb21wdCB3aGlsZSByZXNwZWN0aW5nIHVzZXItcHJvdmlkZWQgY29uZmlndXJhdGlvbi5cblxuSW5zaWRlIGBiZWZvcmVfYWdlbnRfc3RhcnRgLCBgZXZlbnQuc3lzdGVtUHJvbXB0YCBhbmQgYGN0eC5nZXRTeXN0ZW1Qcm9tcHQoKWAgYm90aCByZWZsZWN0IHRoZSBjaGFpbmVkIHN5c3RlbSBwcm9tcHQgYXMgb2YgdGhlIGN1cnJlbnQgaGFuZGxlci4gTGF0ZXIgYGJlZm9yZV9hZ2VudF9zdGFydGAgaGFuZGxlcnMgY2FuIHN0aWxsIG1vZGlmeSBpdCBhZ2Fpbi5cblxuIyMjIyBhZ2VudF9zdGFydCAvIGFnZW50X2VuZFxuXG5GaXJlZCBvbmNlIHBlciB1c2VyIHByb21wdC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJhZ2VudF9zdGFydFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHt9KTtcblxucGkub24oXCJhZ2VudF9lbmRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQubWVzc2FnZXMgLSBtZXNzYWdlcyBmcm9tIHRoaXMgcHJvbXB0XG59KTtcbmBgYFxuXG4jIyMjIHR1cm5fc3RhcnQgLyB0dXJuX2VuZFxuXG5GaXJlZCBmb3IgZWFjaCB0dXJuIChvbmUgTExNIHJlc3BvbnNlICsgdG9vbCBjYWxscykuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwidHVybl9zdGFydFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC50dXJuSW5kZXgsIGV2ZW50LnRpbWVzdGFtcFxufSk7XG5cbnBpLm9uKFwidHVybl9lbmRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQudHVybkluZGV4LCBldmVudC5tZXNzYWdlLCBldmVudC50b29sUmVzdWx0c1xufSk7XG5gYGBcblxuIyMjIyBtZXNzYWdlX3N0YXJ0IC8gbWVzc2FnZV91cGRhdGUgLyBtZXNzYWdlX2VuZFxuXG5GaXJlZCBmb3IgbWVzc2FnZSBsaWZlY3ljbGUgdXBkYXRlcy5cblxuLSBgbWVzc2FnZV9zdGFydGAgYW5kIGBtZXNzYWdlX2VuZGAgZmlyZSBmb3IgdXNlciwgYXNzaXN0YW50LCBhbmQgdG9vbFJlc3VsdCBtZXNzYWdlcy5cbi0gYG1lc3NhZ2VfdXBkYXRlYCBmaXJlcyBmb3IgYXNzaXN0YW50IHN0cmVhbWluZyB1cGRhdGVzLlxuLSBgbWVzc2FnZV9lbmRgIGhhbmRsZXJzIGNhbiByZXR1cm4gYHsgbWVzc2FnZSB9YCB0byByZXBsYWNlIHRoZSBmaW5hbGl6ZWQgbWVzc2FnZS4gVGhlIHJlcGxhY2VtZW50IG11c3Qga2VlcCB0aGUgc2FtZSBgcm9sZWAuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwibWVzc2FnZV9zdGFydFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5tZXNzYWdlXG59KTtcblxucGkub24oXCJtZXNzYWdlX3VwZGF0ZVwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5tZXNzYWdlXG4gIC8vIGV2ZW50LmFzc2lzdGFudE1lc3NhZ2VFdmVudCAodG9rZW4tYnktdG9rZW4gc3RyZWFtIGV2ZW50KVxufSk7XG5cbnBpLm9uKFwibWVzc2FnZV9lbmRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgaWYgKGV2ZW50Lm1lc3NhZ2Uucm9sZSAhPT0gXCJhc3Npc3RhbnRcIikgcmV0dXJuO1xuXG4gIHJldHVybiB7XG4gICAgbWVzc2FnZToge1xuICAgICAgLi4uZXZlbnQubWVzc2FnZSxcbiAgICAgIHVzYWdlOiB7XG4gICAgICAgIC4uLmV2ZW50Lm1lc3NhZ2UudXNhZ2UsXG4gICAgICAgIGNvc3Q6IHtcbiAgICAgICAgICAuLi5ldmVudC5tZXNzYWdlLnVzYWdlLmNvc3QsXG4gICAgICAgICAgdG90YWw6IDAuMTIzLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufSk7XG5gYGBcblxuIyMjIyB0b29sX2V4ZWN1dGlvbl9zdGFydCAvIHRvb2xfZXhlY3V0aW9uX3VwZGF0ZSAvIHRvb2xfZXhlY3V0aW9uX2VuZFxuXG5GaXJlZCBmb3IgdG9vbCBleGVjdXRpb24gbGlmZWN5Y2xlIHVwZGF0ZXMuXG5cbkluIHBhcmFsbGVsIHRvb2wgbW9kZTpcbi0gYHRvb2xfZXhlY3V0aW9uX3N0YXJ0YCBpcyBlbWl0dGVkIGluIGFzc2lzdGFudCBzb3VyY2Ugb3JkZXIgZHVyaW5nIHRoZSBwcmVmbGlnaHQgcGhhc2Vcbi0gYHRvb2xfZXhlY3V0aW9uX3VwZGF0ZWAgZXZlbnRzIG1heSBpbnRlcmxlYXZlIGFjcm9zcyB0b29sc1xuLSBgdG9vbF9leGVjdXRpb25fZW5kYCBpcyBlbWl0dGVkIGluIHRvb2wgY29tcGxldGlvbiBvcmRlciBhZnRlciBlYWNoIHRvb2wgaXMgZmluYWxpemVkXG4tIGZpbmFsIGB0b29sUmVzdWx0YCBtZXNzYWdlIGV2ZW50cyBhcmUgc3RpbGwgZW1pdHRlZCBsYXRlciBpbiBhc3Npc3RhbnQgc291cmNlIG9yZGVyXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwidG9vbF9leGVjdXRpb25fc3RhcnRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQudG9vbENhbGxJZCwgZXZlbnQudG9vbE5hbWUsIGV2ZW50LmFyZ3Ncbn0pO1xuXG5waS5vbihcInRvb2xfZXhlY3V0aW9uX3VwZGF0ZVwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC50b29sQ2FsbElkLCBldmVudC50b29sTmFtZSwgZXZlbnQuYXJncywgZXZlbnQucGFydGlhbFJlc3VsdFxufSk7XG5cbnBpLm9uKFwidG9vbF9leGVjdXRpb25fZW5kXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnRvb2xDYWxsSWQsIGV2ZW50LnRvb2xOYW1lLCBldmVudC5yZXN1bHQsIGV2ZW50LmlzRXJyb3Jcbn0pO1xuYGBgXG5cbiMjIyMgY29udGV4dFxuXG5GaXJlZCBiZWZvcmUgZWFjaCBMTE0gY2FsbC4gTW9kaWZ5IG1lc3NhZ2VzIG5vbi1kZXN0cnVjdGl2ZWx5LiBTZWUgW1Nlc3Npb24gRm9ybWF0XShzZXNzaW9uLWZvcm1hdC5tZCkgZm9yIG1lc3NhZ2UgdHlwZXMuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwiY29udGV4dFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC5tZXNzYWdlcyAtIGRlZXAgY29weSwgc2FmZSB0byBtb2RpZnlcbiAgY29uc3QgZmlsdGVyZWQgPSBldmVudC5tZXNzYWdlcy5maWx0ZXIobSA9PiAhc2hvdWxkUHJ1bmUobSkpO1xuICByZXR1cm4geyBtZXNzYWdlczogZmlsdGVyZWQgfTtcbn0pO1xuYGBgXG5cbiMjIyMgYmVmb3JlX3Byb3ZpZGVyX3JlcXVlc3RcblxuRmlyZWQgYWZ0ZXIgdGhlIHByb3ZpZGVyLXNwZWNpZmljIHBheWxvYWQgaXMgYnVpbHQsIHJpZ2h0IGJlZm9yZSB0aGUgcmVxdWVzdCBpcyBzZW50LiBIYW5kbGVycyBydW4gaW4gZXh0ZW5zaW9uIGxvYWQgb3JkZXIuIFJldHVybmluZyBgdW5kZWZpbmVkYCBrZWVwcyB0aGUgcGF5bG9hZCB1bmNoYW5nZWQuIFJldHVybmluZyBhbnkgb3RoZXIgdmFsdWUgcmVwbGFjZXMgdGhlIHBheWxvYWQgZm9yIGxhdGVyIGhhbmRsZXJzIGFuZCBmb3IgdGhlIGFjdHVhbCByZXF1ZXN0LlxuXG5UaGlzIGhvb2sgY2FuIHJld3JpdGUgcHJvdmlkZXItbGV2ZWwgc3lzdGVtIGluc3RydWN0aW9ucyBvciByZW1vdmUgdGhlbSBlbnRpcmVseS4gVGhvc2UgcGF5bG9hZC1sZXZlbCBjaGFuZ2VzIGFyZSBub3QgcmVmbGVjdGVkIGJ5IGBjdHguZ2V0U3lzdGVtUHJvbXB0KClgLCB3aGljaCByZXBvcnRzIFBpJ3Mgc3lzdGVtIHByb21wdCBzdHJpbmcgcmF0aGVyIHRoYW4gdGhlIGZpbmFsIHNlcmlhbGl6ZWQgcHJvdmlkZXIgcGF5bG9hZC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJiZWZvcmVfcHJvdmlkZXJfcmVxdWVzdFwiLCAoZXZlbnQsIGN0eCkgPT4ge1xuICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShldmVudC5wYXlsb2FkLCBudWxsLCAyKSk7XG5cbiAgLy8gT3B0aW9uYWw6IHJlcGxhY2UgcGF5bG9hZFxuICAvLyByZXR1cm4geyAuLi5ldmVudC5wYXlsb2FkLCB0ZW1wZXJhdHVyZTogMCB9O1xufSk7XG5gYGBcblxuVGhpcyBpcyBtYWlubHkgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgcHJvdmlkZXIgc2VyaWFsaXphdGlvbiBhbmQgY2FjaGUgYmVoYXZpb3IuXG5cbiMjIyMgYWZ0ZXJfcHJvdmlkZXJfcmVzcG9uc2VcblxuRmlyZWQgYWZ0ZXIgYW4gSFRUUCByZXNwb25zZSBpcyByZWNlaXZlZCBhbmQgYmVmb3JlIGl0cyBzdHJlYW0gYm9keSBpcyBjb25zdW1lZC4gSGFuZGxlcnMgcnVuIGluIGV4dGVuc2lvbiBsb2FkIG9yZGVyLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcImFmdGVyX3Byb3ZpZGVyX3Jlc3BvbnNlXCIsIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnN0YXR1cyAtIEhUVFAgc3RhdHVzIGNvZGVcbiAgLy8gZXZlbnQuaGVhZGVycyAtIG5vcm1hbGl6ZWQgcmVzcG9uc2UgaGVhZGVyc1xuICBpZiAoZXZlbnQuc3RhdHVzID09PSA0MjkpIHtcbiAgICBjb25zb2xlLmxvZyhcInJhdGUgbGltaXRlZFwiLCBldmVudC5oZWFkZXJzW1wicmV0cnktYWZ0ZXJcIl0pO1xuICB9XG59KTtcbmBgYFxuXG5IZWFkZXIgYXZhaWxhYmlsaXR5IGRlcGVuZHMgb24gcHJvdmlkZXIgYW5kIHRyYW5zcG9ydC4gUHJvdmlkZXJzIHRoYXQgYWJzdHJhY3QgSFRUUCByZXNwb25zZXMgbWF5IG5vdCBleHBvc2UgaGVhZGVycy5cblxuIyMjIE1vZGVsIEV2ZW50c1xuXG4jIyMjIG1vZGVsX3NlbGVjdFxuXG5GaXJlZCB3aGVuIHRoZSBtb2RlbCBjaGFuZ2VzIHZpYSBgL21vZGVsYCBjb21tYW5kLCBtb2RlbCBjeWNsaW5nIChgQ3RybCtQYCksIG9yIHNlc3Npb24gcmVzdG9yZS5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJtb2RlbF9zZWxlY3RcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQubW9kZWwgLSBuZXdseSBzZWxlY3RlZCBtb2RlbFxuICAvLyBldmVudC5wcmV2aW91c01vZGVsIC0gcHJldmlvdXMgbW9kZWwgKHVuZGVmaW5lZCBpZiBmaXJzdCBzZWxlY3Rpb24pXG4gIC8vIGV2ZW50LnNvdXJjZSAtIFwic2V0XCIgfCBcImN5Y2xlXCIgfCBcInJlc3RvcmVcIlxuXG4gIGNvbnN0IHByZXYgPSBldmVudC5wcmV2aW91c01vZGVsXG4gICAgPyBgJHtldmVudC5wcmV2aW91c01vZGVsLnByb3ZpZGVyfS8ke2V2ZW50LnByZXZpb3VzTW9kZWwuaWR9YFxuICAgIDogXCJub25lXCI7XG4gIGNvbnN0IG5leHQgPSBgJHtldmVudC5tb2RlbC5wcm92aWRlcn0vJHtldmVudC5tb2RlbC5pZH1gO1xuXG4gIGN0eC51aS5ub3RpZnkoYE1vZGVsIGNoYW5nZWQgKCR7ZXZlbnQuc291cmNlfSk6ICR7cHJldn0gLT4gJHtuZXh0fWAsIFwiaW5mb1wiKTtcbn0pO1xuYGBgXG5cblVzZSB0aGlzIHRvIHVwZGF0ZSBVSSBlbGVtZW50cyAoc3RhdHVzIGJhcnMsIGZvb3RlcnMpIG9yIHBlcmZvcm0gbW9kZWwtc3BlY2lmaWMgaW5pdGlhbGl6YXRpb24gd2hlbiB0aGUgYWN0aXZlIG1vZGVsIGNoYW5nZXMuXG5cbiMjIyMgdGhpbmtpbmdfbGV2ZWxfc2VsZWN0XG5cbkZpcmVkIHdoZW4gdGhlIHRoaW5raW5nIGxldmVsIGNoYW5nZXMuIFRoaXMgaXMgbm90aWZpY2F0aW9uLW9ubHk7IGhhbmRsZXIgcmV0dXJuIHZhbHVlcyBhcmUgaWdub3JlZC5cblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJ0aGlua2luZ19sZXZlbF9zZWxlY3RcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgLy8gZXZlbnQubGV2ZWwgLSBuZXdseSBzZWxlY3RlZCB0aGlua2luZyBsZXZlbFxuICAvLyBldmVudC5wcmV2aW91c0xldmVsIC0gcHJldmlvdXMgdGhpbmtpbmcgbGV2ZWxcblxuICBjdHgudWkuc2V0U3RhdHVzKFwidGhpbmtpbmdcIiwgYHRoaW5raW5nOiAke2V2ZW50LmxldmVsfWApO1xufSk7XG5gYGBcblxuVXNlIHRoaXMgdG8gdXBkYXRlIGV4dGVuc2lvbiBVSSB3aGVuIGBwaS5zZXRUaGlua2luZ0xldmVsKClgLCBtb2RlbCBjaGFuZ2VzLCBvciBidWlsdC1pbiB0aGlua2luZy1sZXZlbCBjb250cm9scyBjaGFuZ2UgdGhlIGFjdGl2ZSB0aGlua2luZyBsZXZlbC5cblxuIyMjIFRvb2wgRXZlbnRzXG5cbiMjIyMgdG9vbF9jYWxsXG5cbkZpcmVkIGFmdGVyIGB0b29sX2V4ZWN1dGlvbl9zdGFydGAsIGJlZm9yZSB0aGUgdG9vbCBleGVjdXRlcy4gKipDYW4gYmxvY2suKiogVXNlIGBpc1Rvb2xDYWxsRXZlbnRUeXBlYCB0byBuYXJyb3cgYW5kIGdldCB0eXBlZCBpbnB1dHMuXG5cbkJlZm9yZSBgdG9vbF9jYWxsYCBydW5zLCBwaSB3YWl0cyBmb3IgcHJldmlvdXNseSBlbWl0dGVkIEFnZW50IGV2ZW50cyB0byBmaW5pc2ggZHJhaW5pbmcgdGhyb3VnaCBgQWdlbnRTZXNzaW9uYC4gVGhpcyBtZWFucyBgY3R4LnNlc3Npb25NYW5hZ2VyYCBpcyB1cCB0byBkYXRlIHRocm91Z2ggdGhlIGN1cnJlbnQgYXNzaXN0YW50IHRvb2wtY2FsbGluZyBtZXNzYWdlLlxuXG5JbiB0aGUgZGVmYXVsdCBwYXJhbGxlbCB0b29sIGV4ZWN1dGlvbiBtb2RlLCBzaWJsaW5nIHRvb2wgY2FsbHMgZnJvbSB0aGUgc2FtZSBhc3Npc3RhbnQgbWVzc2FnZSBhcmUgcHJlZmxpZ2h0ZWQgc2VxdWVudGlhbGx5LCB0aGVuIGV4ZWN1dGVkIGNvbmN1cnJlbnRseS4gYHRvb2xfY2FsbGAgaXMgbm90IGd1YXJhbnRlZWQgdG8gc2VlIHNpYmxpbmcgdG9vbCByZXN1bHRzIGZyb20gdGhhdCBzYW1lIGFzc2lzdGFudCBtZXNzYWdlIGluIGBjdHguc2Vzc2lvbk1hbmFnZXJgLlxuXG5gZXZlbnQuaW5wdXRgIGlzIG11dGFibGUuIE11dGF0ZSBpdCBpbiBwbGFjZSB0byBwYXRjaCB0b29sIGFyZ3VtZW50cyBiZWZvcmUgZXhlY3V0aW9uLlxuXG5CZWhhdmlvciBndWFyYW50ZWVzOlxuLSBNdXRhdGlvbnMgdG8gYGV2ZW50LmlucHV0YCBhZmZlY3QgdGhlIGFjdHVhbCB0b29sIGV4ZWN1dGlvblxuLSBMYXRlciBgdG9vbF9jYWxsYCBoYW5kbGVycyBzZWUgbXV0YXRpb25zIG1hZGUgYnkgZWFybGllciBoYW5kbGVyc1xuLSBObyByZS12YWxpZGF0aW9uIGlzIHBlcmZvcm1lZCBhZnRlciB5b3VyIG11dGF0aW9uXG4tIFJldHVybiB2YWx1ZXMgZnJvbSBgdG9vbF9jYWxsYCBvbmx5IGNvbnRyb2wgYmxvY2tpbmcgdmlhIGB7IGJsb2NrOiB0cnVlLCByZWFzb24/OiBzdHJpbmcgfWBcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgaXNUb29sQ2FsbEV2ZW50VHlwZSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbnBpLm9uKFwidG9vbF9jYWxsXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnRvb2xOYW1lIC0gXCJiYXNoXCIsIFwicmVhZFwiLCBcIndyaXRlXCIsIFwiZWRpdFwiLCBldGMuXG4gIC8vIGV2ZW50LnRvb2xDYWxsSWRcbiAgLy8gZXZlbnQuaW5wdXQgLSB0b29sIHBhcmFtZXRlcnMgKG11dGFibGUpXG5cbiAgLy8gQnVpbHQtaW4gdG9vbHM6IG5vIHR5cGUgcGFyYW1zIG5lZWRlZFxuICBpZiAoaXNUb29sQ2FsbEV2ZW50VHlwZShcImJhc2hcIiwgZXZlbnQpKSB7XG4gICAgLy8gZXZlbnQuaW5wdXQgaXMgeyBjb21tYW5kOiBzdHJpbmc7IHRpbWVvdXQ/OiBudW1iZXIgfVxuICAgIGV2ZW50LmlucHV0LmNvbW1hbmQgPSBgc291cmNlIH4vLnByb2ZpbGVcXG4ke2V2ZW50LmlucHV0LmNvbW1hbmR9YDtcblxuICAgIGlmIChldmVudC5pbnB1dC5jb21tYW5kLmluY2x1ZGVzKFwicm0gLXJmXCIpKSB7XG4gICAgICByZXR1cm4geyBibG9jazogdHJ1ZSwgcmVhc29uOiBcIkRhbmdlcm91cyBjb21tYW5kXCIgfTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXNUb29sQ2FsbEV2ZW50VHlwZShcInJlYWRcIiwgZXZlbnQpKSB7XG4gICAgLy8gZXZlbnQuaW5wdXQgaXMgeyBwYXRoOiBzdHJpbmc7IG9mZnNldD86IG51bWJlcjsgbGltaXQ/OiBudW1iZXIgfVxuICAgIGNvbnNvbGUubG9nKGBSZWFkaW5nOiAke2V2ZW50LmlucHV0LnBhdGh9YCk7XG4gIH1cbn0pO1xuYGBgXG5cbiMjIyMgVHlwaW5nIGN1c3RvbSB0b29sIGlucHV0XG5cbkN1c3RvbSB0b29scyBzaG91bGQgZXhwb3J0IHRoZWlyIGlucHV0IHR5cGU6XG5cbmBgYHR5cGVzY3JpcHRcbi8vIG15LWV4dGVuc2lvbi50c1xuZXhwb3J0IHR5cGUgTXlUb29sSW5wdXQgPSBTdGF0aWM8dHlwZW9mIG15VG9vbFNjaGVtYT47XG5gYGBcblxuVXNlIGBpc1Rvb2xDYWxsRXZlbnRUeXBlYCB3aXRoIGV4cGxpY2l0IHR5cGUgcGFyYW1ldGVyczpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgaXNUb29sQ2FsbEV2ZW50VHlwZSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgdHlwZSB7IE15VG9vbElucHV0IH0gZnJvbSBcIm15LWV4dGVuc2lvblwiO1xuXG5waS5vbihcInRvb2xfY2FsbFwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKGlzVG9vbENhbGxFdmVudFR5cGU8XCJteV90b29sXCIsIE15VG9vbElucHV0PihcIm15X3Rvb2xcIiwgZXZlbnQpKSB7XG4gICAgZXZlbnQuaW5wdXQuYWN0aW9uOyAgLy8gdHlwZWRcbiAgfVxufSk7XG5gYGBcblxuIyMjIyB0b29sX3Jlc3VsdFxuXG5GaXJlZCBhZnRlciB0b29sIGV4ZWN1dGlvbiBmaW5pc2hlcyBhbmQgYmVmb3JlIGB0b29sX2V4ZWN1dGlvbl9lbmRgIHBsdXMgdGhlIGZpbmFsIHRvb2wgcmVzdWx0IG1lc3NhZ2UgZXZlbnRzIGFyZSBlbWl0dGVkLiAqKkNhbiBtb2RpZnkgcmVzdWx0LioqXG5cbkluIHBhcmFsbGVsIHRvb2wgbW9kZSwgYHRvb2xfcmVzdWx0YCBhbmQgYHRvb2xfZXhlY3V0aW9uX2VuZGAgbWF5IGludGVybGVhdmUgaW4gdG9vbCBjb21wbGV0aW9uIG9yZGVyLCB3aGlsZSBmaW5hbCBgdG9vbFJlc3VsdGAgbWVzc2FnZSBldmVudHMgYXJlIHN0aWxsIGVtaXR0ZWQgbGF0ZXIgaW4gYXNzaXN0YW50IHNvdXJjZSBvcmRlci5cblxuYHRvb2xfcmVzdWx0YCBoYW5kbGVycyBjaGFpbiBsaWtlIG1pZGRsZXdhcmU6XG4tIEhhbmRsZXJzIHJ1biBpbiBleHRlbnNpb24gbG9hZCBvcmRlclxuLSBFYWNoIGhhbmRsZXIgc2VlcyB0aGUgbGF0ZXN0IHJlc3VsdCBhZnRlciBwcmV2aW91cyBoYW5kbGVyIGNoYW5nZXNcbi0gSGFuZGxlcnMgY2FuIHJldHVybiBwYXJ0aWFsIHBhdGNoZXMgKGBjb250ZW50YCwgYGRldGFpbHNgLCBvciBgaXNFcnJvcmApOyBvbWl0dGVkIGZpZWxkcyBrZWVwIHRoZWlyIGN1cnJlbnQgdmFsdWVzXG5cblVzZSBgY3R4LnNpZ25hbGAgZm9yIG5lc3RlZCBhc3luYyB3b3JrIGluc2lkZSB0aGUgaGFuZGxlci4gVGhpcyBsZXRzIEVzYyBjYW5jZWwgbW9kZWwgY2FsbHMsIGBmZXRjaCgpYCwgYW5kIG90aGVyIGFib3J0LWF3YXJlIG9wZXJhdGlvbnMgc3RhcnRlZCBieSB0aGUgZXh0ZW5zaW9uLlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBpc0Jhc2hUb29sUmVzdWx0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxucGkub24oXCJ0b29sX3Jlc3VsdFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAvLyBldmVudC50b29sTmFtZSwgZXZlbnQudG9vbENhbGxJZCwgZXZlbnQuaW5wdXRcbiAgLy8gZXZlbnQuY29udGVudCwgZXZlbnQuZGV0YWlscywgZXZlbnQuaXNFcnJvclxuXG4gIGlmIChpc0Jhc2hUb29sUmVzdWx0KGV2ZW50KSkge1xuICAgIC8vIGV2ZW50LmRldGFpbHMgaXMgdHlwZWQgYXMgQmFzaFRvb2xEZXRhaWxzXG4gIH1cblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9zdW1tYXJpemVcIiwge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBjb250ZW50OiBldmVudC5jb250ZW50IH0pLFxuICAgIHNpZ25hbDogY3R4LnNpZ25hbCxcbiAgfSk7XG5cbiAgLy8gTW9kaWZ5IHJlc3VsdDpcbiAgcmV0dXJuIHsgY29udGVudDogWy4uLl0sIGRldGFpbHM6IHsuLi59LCBpc0Vycm9yOiBmYWxzZSB9O1xufSk7XG5gYGBcblxuIyMjIFVzZXIgQmFzaCBFdmVudHNcblxuIyMjIyB1c2VyX2Jhc2hcblxuRmlyZWQgd2hlbiB1c2VyIGV4ZWN1dGVzIGAhYCBvciBgISFgIGNvbW1hbmRzLiAqKkNhbiBpbnRlcmNlcHQuKipcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgY3JlYXRlTG9jYWxCYXNoT3BlcmF0aW9ucyB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbnBpLm9uKFwidXNlcl9iYXNoXCIsIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LmNvbW1hbmQgLSB0aGUgYmFzaCBjb21tYW5kXG4gIC8vIGV2ZW50LmV4Y2x1ZGVGcm9tQ29udGV4dCAtIHRydWUgaWYgISEgcHJlZml4XG4gIC8vIGV2ZW50LmN3ZCAtIHdvcmtpbmcgZGlyZWN0b3J5XG5cbiAgLy8gT3B0aW9uIDE6IFByb3ZpZGUgY3VzdG9tIG9wZXJhdGlvbnMgKGUuZy4sIFNTSClcbiAgcmV0dXJuIHsgb3BlcmF0aW9uczogcmVtb3RlQmFzaE9wcyB9O1xuXG4gIC8vIE9wdGlvbiAyOiBXcmFwIHBpJ3MgYnVpbHQtaW4gbG9jYWwgYmFzaCBiYWNrZW5kXG4gIGNvbnN0IGxvY2FsID0gY3JlYXRlTG9jYWxCYXNoT3BlcmF0aW9ucygpO1xuICByZXR1cm4ge1xuICAgIG9wZXJhdGlvbnM6IHtcbiAgICAgIGV4ZWMoY29tbWFuZCwgY3dkLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBsb2NhbC5leGVjKGBzb3VyY2Ugfi8ucHJvZmlsZVxcbiR7Y29tbWFuZH1gLCBjd2QsIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBPcHRpb24gMzogRnVsbCByZXBsYWNlbWVudCAtIHJldHVybiByZXN1bHQgZGlyZWN0bHlcbiAgcmV0dXJuIHsgcmVzdWx0OiB7IG91dHB1dDogXCIuLi5cIiwgZXhpdENvZGU6IDAsIGNhbmNlbGxlZDogZmFsc2UsIHRydW5jYXRlZDogZmFsc2UgfSB9O1xufSk7XG5gYGBcblxuIyMjIElucHV0IEV2ZW50c1xuXG4jIyMjIGlucHV0XG5cbkZpcmVkIHdoZW4gdXNlciBpbnB1dCBpcyByZWNlaXZlZCwgYWZ0ZXIgZXh0ZW5zaW9uIGNvbW1hbmRzIGFyZSBjaGVja2VkIGJ1dCBiZWZvcmUgc2tpbGwgYW5kIHRlbXBsYXRlIGV4cGFuc2lvbi4gVGhlIGV2ZW50IHNlZXMgdGhlIHJhdyBpbnB1dCB0ZXh0LCBzbyBgL3NraWxsOmZvb2AgYW5kIGAvdGVtcGxhdGVgIGFyZSBub3QgeWV0IGV4cGFuZGVkLlxuXG4qKlByb2Nlc3Npbmcgb3JkZXI6KipcbjEuIEV4dGVuc2lvbiBjb21tYW5kcyAoYC9jbWRgKSBjaGVja2VkIGZpcnN0IC0gaWYgZm91bmQsIGhhbmRsZXIgcnVucyBhbmQgaW5wdXQgZXZlbnQgaXMgc2tpcHBlZFxuMi4gYGlucHV0YCBldmVudCBmaXJlcyAtIGNhbiBpbnRlcmNlcHQsIHRyYW5zZm9ybSwgb3IgaGFuZGxlXG4zLiBJZiBub3QgaGFuZGxlZDogc2tpbGwgY29tbWFuZHMgKGAvc2tpbGw6bmFtZWApIGV4cGFuZGVkIHRvIHNraWxsIGNvbnRlbnRcbjQuIElmIG5vdCBoYW5kbGVkOiBwcm9tcHQgdGVtcGxhdGVzIChgL3RlbXBsYXRlYCkgZXhwYW5kZWQgdG8gdGVtcGxhdGUgY29udGVudFxuNS4gQWdlbnQgcHJvY2Vzc2luZyBiZWdpbnMgKGBiZWZvcmVfYWdlbnRfc3RhcnRgLCBldGMuKVxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcImlucHV0XCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gIC8vIGV2ZW50LnRleHQgLSByYXcgaW5wdXQgKGJlZm9yZSBza2lsbC90ZW1wbGF0ZSBleHBhbnNpb24pXG4gIC8vIGV2ZW50LmltYWdlcyAtIGF0dGFjaGVkIGltYWdlcywgaWYgYW55XG4gIC8vIGV2ZW50LnNvdXJjZSAtIFwiaW50ZXJhY3RpdmVcIiAodHlwZWQpLCBcInJwY1wiIChBUEkpLCBvciBcImV4dGVuc2lvblwiICh2aWEgc2VuZFVzZXJNZXNzYWdlKVxuICAvLyBldmVudC5zdHJlYW1pbmdCZWhhdmlvciAtIFwic3RlZXJcIiB8IFwiZm9sbG93VXBcIiB8IHVuZGVmaW5lZFxuICAvLyAgIHVuZGVmaW5lZCB3aGVuIGlkbGUsIFwic3RlZXJcIiBmb3IgbWlkLXN0cmVhbSBpbnRlcnJ1cHRzLFxuICAvLyAgIFwiZm9sbG93VXBcIiBmb3IgbWVzc2FnZXMgcXVldWVkIHVudGlsIHRoZSBhZ2VudCBmaW5pc2hlc1xuXG4gIC8vIFRyYW5zZm9ybTogcmV3cml0ZSBpbnB1dCBiZWZvcmUgZXhwYW5zaW9uXG4gIGlmIChldmVudC50ZXh0LnN0YXJ0c1dpdGgoXCI/cXVpY2sgXCIpKVxuICAgIHJldHVybiB7IGFjdGlvbjogXCJ0cmFuc2Zvcm1cIiwgdGV4dDogYFJlc3BvbmQgYnJpZWZseTogJHtldmVudC50ZXh0LnNsaWNlKDcpfWAgfTtcblxuICAvLyBIYW5kbGU6IHJlc3BvbmQgd2l0aG91dCBMTE0gKGV4dGVuc2lvbiBzaG93cyBpdHMgb3duIGZlZWRiYWNrKVxuICBpZiAoZXZlbnQudGV4dCA9PT0gXCJwaW5nXCIpIHtcbiAgICBjdHgudWkubm90aWZ5KFwicG9uZ1wiLCBcImluZm9cIik7XG4gICAgcmV0dXJuIHsgYWN0aW9uOiBcImhhbmRsZWRcIiB9O1xuICB9XG5cbiAgLy8gUm91dGUgYnkgc291cmNlOiBza2lwIHByb2Nlc3NpbmcgZm9yIGV4dGVuc2lvbi1pbmplY3RlZCBtZXNzYWdlc1xuICBpZiAoZXZlbnQuc291cmNlID09PSBcImV4dGVuc2lvblwiKSByZXR1cm4geyBhY3Rpb246IFwiY29udGludWVcIiB9O1xuXG4gIC8vIEludGVyY2VwdCBza2lsbCBjb21tYW5kcyBiZWZvcmUgZXhwYW5zaW9uXG4gIGlmIChldmVudC50ZXh0LnN0YXJ0c1dpdGgoXCIvc2tpbGw6XCIpKSB7XG4gICAgLy8gQ291bGQgdHJhbnNmb3JtLCBibG9jaywgb3IgbGV0IHBhc3MgdGhyb3VnaFxuICB9XG5cbiAgcmV0dXJuIHsgYWN0aW9uOiBcImNvbnRpbnVlXCIgfTsgIC8vIERlZmF1bHQ6IHBhc3MgdGhyb3VnaCB0byBleHBhbnNpb25cbn0pO1xuYGBgXG5cbioqUmVzdWx0czoqKlxuLSBgY29udGludWVgIC0gcGFzcyB0aHJvdWdoIHVuY2hhbmdlZCAoZGVmYXVsdCBpZiBoYW5kbGVyIHJldHVybnMgbm90aGluZylcbi0gYHRyYW5zZm9ybWAgLSBtb2RpZnkgdGV4dC9pbWFnZXMsIHRoZW4gY29udGludWUgdG8gZXhwYW5zaW9uXG4tIGBoYW5kbGVkYCAtIHNraXAgYWdlbnQgZW50aXJlbHkgKGZpcnN0IGhhbmRsZXIgdG8gcmV0dXJuIHRoaXMgd2lucylcblxuVHJhbnNmb3JtcyBjaGFpbiBhY3Jvc3MgaGFuZGxlcnMuIFNlZSBbaW5wdXQtdHJhbnNmb3JtLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL2lucHV0LXRyYW5zZm9ybS50cykgYW5kIFtpbnB1dC10cmFuc2Zvcm0tc3RyZWFtaW5nLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL2lucHV0LXRyYW5zZm9ybS1zdHJlYW1pbmcudHMpIGZvciBgc3RyZWFtaW5nQmVoYXZpb3JgLWF3YXJlIHJvdXRpbmcuXG5cbiMjIEV4dGVuc2lvbkNvbnRleHRcblxuQWxsIGhhbmRsZXJzIHJlY2VpdmUgYGN0eDogRXh0ZW5zaW9uQ29udGV4dGAuXG5cbiMjIyBjdHgudWlcblxuVUkgbWV0aG9kcyBmb3IgdXNlciBpbnRlcmFjdGlvbi4gU2VlIFtDdXN0b20gVUldKCNjdXN0b20tdWkpIGZvciBmdWxsIGRldGFpbHMuXG5cbiMjIyBjdHgubW9kZVxuXG5DdXJyZW50IHJ1biBtb2RlOiBgXCJ0dWlcImAsIGBcInJwY1wiYCwgYFwianNvblwiYCwgb3IgYFwicHJpbnRcImAuIFVzZSBgY3R4Lm1vZGUgPT09IFwidHVpXCJgIHRvIGd1YXJkIHRlcm1pbmFsLW9ubHkgZmVhdHVyZXMgc3VjaCBhcyBgY3VzdG9tKClgLCBjb21wb25lbnQgZmFjdG9yaWVzLCB0ZXJtaW5hbCBpbnB1dCwgYW5kIGRpcmVjdCBUVUkgcmVuZGVyaW5nLlxuXG4jIyMgY3R4Lmhhc1VJXG5cbmB0cnVlYCBpbiBUVUkgYW5kIFJQQyBtb2Rlcy4gYGZhbHNlYCBpbiBwcmludCBtb2RlIChgLXBgKSBhbmQgSlNPTiBtb2RlLiBVc2UgdGhpcyB0byBndWFyZCBkaWFsb2cgbWV0aG9kcyAoYHNlbGVjdGAsIGBjb25maXJtYCwgYGlucHV0YCwgYGVkaXRvcmApIGFuZCBmaXJlLWFuZC1mb3JnZXQgbWV0aG9kcyAoYG5vdGlmeWAsIGBzZXRTdGF0dXNgLCBgc2V0V2lkZ2V0YCwgYHNldFRpdGxlYCwgYHNldEVkaXRvclRleHRgKSB0aGF0IHdvcmsgaW4gYm90aCBUVUkgYW5kIFJQQyBtb2Rlcy4gSW4gUlBDIG1vZGUsIHNvbWUgVFVJLXNwZWNpZmljIG1ldGhvZHMgYXJlIG5vLW9wcyBvciByZXR1cm4gZGVmYXVsdHMgKHNlZSBbcnBjLm1kXShycGMubWQjZXh0ZW5zaW9uLXVpLXByb3RvY29sKSkuXG5cbiMjIyBjdHguY3dkXG5cbkN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuXG5cblVzZSBgQ09ORklHX0RJUl9OQU1FYCBpbnN0ZWFkIG9mIGhhcmRjb2RpbmcgYC5waWAgd2hlbiBjb25zdHJ1Y3RpbmcgcHJvamVjdC1sb2NhbCBjb25maWcgcGF0aHMuIFJlYnJhbmRlZCBkaXN0cmlidXRpb25zIGNhbiB1c2UgYSBkaWZmZXJlbnQgY29uZmlnIGRpcmVjdG9yeSBuYW1lLlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBDT05GSUdfRElSX05BTUUsIHR5cGUgRXh0ZW5zaW9uQVBJIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIHBpLm9uKFwic2Vzc2lvbl9zdGFydFwiLCAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICBjb25zdCBwcm9qZWN0Q29uZmlnUGF0aCA9IGpvaW4oY3R4LmN3ZCwgQ09ORklHX0RJUl9OQU1FLCBcIm15LWV4dGVuc2lvbi5qc29uXCIpO1xuICAgIC8vIC4uLlxuICB9KTtcbn1cbmBgYFxuXG4jIyMgY3R4LmlzUHJvamVjdFRydXN0ZWQoKVxuXG5SZXR1cm5zIHdoZXRoZXIgcHJvamVjdC1sb2NhbCB0cnVzdCBpcyBhY3RpdmUgZm9yIHRoZSBjdXJyZW50IHNlc3Npb24gY29udGV4dC4gVGhpcyBpbmNsdWRlcyB0ZW1wb3JhcnkgdHJ1c3QgZGVjaXNpb25zIGFuZCBDTEkgdHJ1c3Qgb3ZlcnJpZGVzLCBub3QganVzdCBzYXZlZCBkZWNpc2lvbnMgaW4gdGhlIGdsb2JhbCB0cnVzdCBzdG9yZS5cblxuVXNlIHRoaXMgYmVmb3JlIHJlYWRpbmcgcHJvamVjdC1sb2NhbCBleHRlbnNpb24gY29uZmlndXJhdGlvbiB0aGF0IHNob3VsZCBvbmx5IGJlIGhvbm9yZWQgZm9yIHRydXN0ZWQgcHJvamVjdHMuXG5cbiMjIyBjdHguc2Vzc2lvbk1hbmFnZXJcblxuUmVhZC1vbmx5IGFjY2VzcyB0byBzZXNzaW9uIHN0YXRlLiBTZWUgW1Nlc3Npb24gRm9ybWF0XShzZXNzaW9uLWZvcm1hdC5tZCkgZm9yIHRoZSBmdWxsIFNlc3Npb25NYW5hZ2VyIEFQSSBhbmQgZW50cnkgdHlwZXMuXG5cbkZvciBgdG9vbF9jYWxsYCwgdGhpcyBzdGF0ZSBpcyBzeW5jaHJvbml6ZWQgdGhyb3VnaCB0aGUgY3VycmVudCBhc3Npc3RhbnQgbWVzc2FnZSBiZWZvcmUgaGFuZGxlcnMgcnVuLiBJbiBwYXJhbGxlbCB0b29sIGV4ZWN1dGlvbiBtb2RlIGl0IGlzIHN0aWxsIG5vdCBndWFyYW50ZWVkIHRvIGluY2x1ZGUgc2libGluZyB0b29sIHJlc3VsdHMgZnJvbSB0aGUgc2FtZSBhc3Npc3RhbnQgbWVzc2FnZS5cblxuYGBgdHlwZXNjcmlwdFxuY3R4LnNlc3Npb25NYW5hZ2VyLmdldEVudHJpZXMoKSAgICAgICAvLyBBbGwgZW50cmllc1xuY3R4LnNlc3Npb25NYW5hZ2VyLmdldEJyYW5jaCgpICAgICAgICAvLyBDdXJyZW50IGJyYW5jaFxuY3R4LnNlc3Npb25NYW5hZ2VyLmdldExlYWZJZCgpICAgICAgICAvLyBDdXJyZW50IGxlYWYgZW50cnkgSURcbmBgYFxuXG4jIyMgY3R4Lm1vZGVsUmVnaXN0cnkgLyBjdHgubW9kZWxcblxuQWNjZXNzIHRvIG1vZGVscyBhbmQgQVBJIGtleXMuXG5cbiMjIyBjdHguc2lnbmFsXG5cblRoZSBjdXJyZW50IGFnZW50IGFib3J0IHNpZ25hbCwgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyBhZ2VudCB0dXJuIGlzIGFjdGl2ZS5cblxuVXNlIHRoaXMgZm9yIGFib3J0LWF3YXJlIG5lc3RlZCB3b3JrIHN0YXJ0ZWQgYnkgZXh0ZW5zaW9uIGhhbmRsZXJzLCBmb3IgZXhhbXBsZTpcbi0gYGZldGNoKC4uLiwgeyBzaWduYWw6IGN0eC5zaWduYWwgfSlgXG4tIG1vZGVsIGNhbGxzIHRoYXQgYWNjZXB0IGBzaWduYWxgXG4tIGZpbGUgb3IgcHJvY2VzcyBoZWxwZXJzIHRoYXQgYWNjZXB0IGBBYm9ydFNpZ25hbGBcblxuYGN0eC5zaWduYWxgIGlzIHR5cGljYWxseSBkZWZpbmVkIGR1cmluZyBhY3RpdmUgdHVybiBldmVudHMgc3VjaCBhcyBgdG9vbF9jYWxsYCwgYHRvb2xfcmVzdWx0YCwgYG1lc3NhZ2VfdXBkYXRlYCwgYW5kIGB0dXJuX2VuZGAuXG5JdCBpcyB1c3VhbGx5IGB1bmRlZmluZWRgIGluIGlkbGUgb3Igbm9uLXR1cm4gY29udGV4dHMgc3VjaCBhcyBzZXNzaW9uIGV2ZW50cywgZXh0ZW5zaW9uIGNvbW1hbmRzLCBhbmQgc2hvcnRjdXRzIGZpcmVkIHdoaWxlIHBpIGlzIGlkbGUuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwidG9vbF9yZXN1bHRcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGV2ZW50KSxcbiAgICBzaWduYWw6IGN0eC5zaWduYWwsXG4gIH0pO1xuXG4gIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gIHJldHVybiB7IGRldGFpbHM6IGRhdGEgfTtcbn0pO1xuYGBgXG5cbiMjIyBjdHguaXNJZGxlKCkgLyBjdHguYWJvcnQoKSAvIGN0eC5oYXNQZW5kaW5nTWVzc2FnZXMoKVxuXG5Db250cm9sIGZsb3cgaGVscGVycy5cblxuIyMjIGN0eC5zaHV0ZG93bigpXG5cblJlcXVlc3QgYSBncmFjZWZ1bCBzaHV0ZG93biBvZiBwaS5cblxuLSAqKkludGVyYWN0aXZlIG1vZGU6KiogRGVmZXJyZWQgdW50aWwgdGhlIGFnZW50IGJlY29tZXMgaWRsZSAoYWZ0ZXIgcHJvY2Vzc2luZyBhbGwgcXVldWVkIHN0ZWVyaW5nIGFuZCBmb2xsb3ctdXAgbWVzc2FnZXMpLlxuLSAqKlJQQyBtb2RlOioqIERlZmVycmVkIHVudGlsIHRoZSBuZXh0IGlkbGUgc3RhdGUgKGFmdGVyIGNvbXBsZXRpbmcgdGhlIGN1cnJlbnQgY29tbWFuZCByZXNwb25zZSwgd2hlbiB3YWl0aW5nIGZvciB0aGUgbmV4dCBjb21tYW5kKS5cbi0gKipQcmludCBtb2RlOioqIE5vLW9wLiBUaGUgcHJvY2VzcyBleGl0cyBhdXRvbWF0aWNhbGx5IHdoZW4gYWxsIHByb21wdHMgYXJlIHByb2Nlc3NlZC5cblxuRW1pdHMgYHNlc3Npb25fc2h1dGRvd25gIGV2ZW50IHRvIGFsbCBleHRlbnNpb25zIGJlZm9yZSBleGl0aW5nLiBBdmFpbGFibGUgaW4gYWxsIGNvbnRleHRzIChldmVudCBoYW5kbGVycywgdG9vbHMsIGNvbW1hbmRzLCBzaG9ydGN1dHMpLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInRvb2xfY2FsbFwiLCAoZXZlbnQsIGN0eCkgPT4ge1xuICBpZiAoaXNGYXRhbChldmVudC5pbnB1dCkpIHtcbiAgICBjdHguc2h1dGRvd24oKTtcbiAgfVxufSk7XG5gYGBcblxuIyMjIGN0eC5nZXRDb250ZXh0VXNhZ2UoKVxuXG5SZXR1cm5zIGN1cnJlbnQgY29udGV4dCB1c2FnZSBmb3IgdGhlIGFjdGl2ZSBtb2RlbC4gVXNlcyBsYXN0IGFzc2lzdGFudCB1c2FnZSB3aGVuIGF2YWlsYWJsZSwgdGhlbiBlc3RpbWF0ZXMgdG9rZW5zIGZvciB0cmFpbGluZyBtZXNzYWdlcy5cblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgdXNhZ2UgPSBjdHguZ2V0Q29udGV4dFVzYWdlKCk7XG5pZiAodXNhZ2UgJiYgdXNhZ2UudG9rZW5zID4gMTAwXzAwMCkge1xuICAvLyAuLi5cbn1cbmBgYFxuXG4jIyMgY3R4LmNvbXBhY3QoKVxuXG5UcmlnZ2VyIGNvbXBhY3Rpb24gd2l0aG91dCBhd2FpdGluZyBjb21wbGV0aW9uLiBVc2UgYG9uQ29tcGxldGVgIGFuZCBgb25FcnJvcmAgZm9yIGZvbGxvdy11cCBhY3Rpb25zLlxuXG5gYGB0eXBlc2NyaXB0XG5jdHguY29tcGFjdCh7XG4gIGN1c3RvbUluc3RydWN0aW9uczogXCJGb2N1cyBvbiByZWNlbnQgY2hhbmdlc1wiLFxuICBvbkNvbXBsZXRlOiAocmVzdWx0KSA9PiB7XG4gICAgY3R4LnVpLm5vdGlmeShcIkNvbXBhY3Rpb24gY29tcGxldGVkXCIsIFwiaW5mb1wiKTtcbiAgfSxcbiAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgY3R4LnVpLm5vdGlmeShgQ29tcGFjdGlvbiBmYWlsZWQ6ICR7ZXJyb3IubWVzc2FnZX1gLCBcImVycm9yXCIpO1xuICB9LFxufSk7XG5gYGBcblxuIyMjIGN0eC5nZXRTeXN0ZW1Qcm9tcHQoKVxuXG5SZXR1cm5zIFBpJ3MgY3VycmVudCBzeXN0ZW0gcHJvbXB0IHN0cmluZy5cblxuLSBEdXJpbmcgYGJlZm9yZV9hZ2VudF9zdGFydGAsIHRoaXMgcmVmbGVjdHMgY2hhaW5lZCBzeXN0ZW0tcHJvbXB0IGNoYW5nZXMgbWFkZSBzbyBmYXIgZm9yIHRoZSBjdXJyZW50IHR1cm4uXG4tIEl0IGRvZXMgbm90IGluY2x1ZGUgbGF0ZXIgYGNvbnRleHRgIG1lc3NhZ2UgbXV0YXRpb25zLlxuLSBJdCBkb2VzIG5vdCBpbmNsdWRlIGBiZWZvcmVfcHJvdmlkZXJfcmVxdWVzdGAgcGF5bG9hZCByZXdyaXRlcy5cbi0gSWYgbGF0ZXItbG9hZGVkIGV4dGVuc2lvbnMgcnVuIGFmdGVyIHlvdXJzLCB0aGV5IGNhbiBzdGlsbCBjaGFuZ2Ugd2hhdCBpcyB1bHRpbWF0ZWx5IHNlbnQuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLm9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIsIChldmVudCwgY3R4KSA9PiB7XG4gIGNvbnN0IHByb21wdCA9IGN0eC5nZXRTeXN0ZW1Qcm9tcHQoKTtcbiAgY29uc29sZS5sb2coYFN5c3RlbSBwcm9tcHQgbGVuZ3RoOiAke3Byb21wdC5sZW5ndGh9YCk7XG59KTtcbmBgYFxuXG4jIyBFeHRlbnNpb25Db21tYW5kQ29udGV4dFxuXG5Db21tYW5kIGhhbmRsZXJzIHJlY2VpdmUgYEV4dGVuc2lvbkNvbW1hbmRDb250ZXh0YCwgd2hpY2ggZXh0ZW5kcyBgRXh0ZW5zaW9uQ29udGV4dGAgd2l0aCBzZXNzaW9uIGNvbnRyb2wgbWV0aG9kcy4gVGhlc2UgYXJlIG9ubHkgYXZhaWxhYmxlIGluIGNvbW1hbmRzIGJlY2F1c2UgdGhleSBjYW4gZGVhZGxvY2sgaWYgY2FsbGVkIGZyb20gZXZlbnQgaGFuZGxlcnMuXG5cbiMjIyBjdHguZ2V0U3lzdGVtUHJvbXB0T3B0aW9ucygpXG5cblJldHVybnMgdGhlIGJhc2UgaW5wdXRzIFBpIGN1cnJlbnRseSB1c2VzIHRvIGJ1aWxkIHRoZSBzeXN0ZW0gcHJvbXB0LlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCBvcHRpb25zID0gY3R4LmdldFN5c3RlbVByb21wdE9wdGlvbnMoKTtcbmNvbnN0IGNvbnRleHRQYXRocyA9IG9wdGlvbnMuY29udGV4dEZpbGVzPy5tYXAoKGZpbGUpID0+IGZpbGUucGF0aCkgPz8gW107XG5gYGBcblxuVGhpcyBoYXMgdGhlIHNhbWUgc2hhcGUgYW5kIG11dGFiaWxpdHkgYXMgYGJlZm9yZV9hZ2VudF9zdGFydGAgYGV2ZW50LnN5c3RlbVByb21wdE9wdGlvbnNgOiBjdXN0b20gcHJvbXB0LCBhY3RpdmUgdG9vbHMsIHRvb2wgc25pcHBldHMsIHByb21wdCBndWlkZWxpbmVzLCBhcHBlbmRlZCBzeXN0ZW0gcHJvbXB0IHRleHQsIGN3ZCwgbG9hZGVkIGNvbnRleHQgZmlsZXMsIGFuZCBsb2FkZWQgc2tpbGxzLiBJdCBtYXkgaW5jbHVkZSBmdWxsIGNvbnRleHQgZmlsZSBjb250ZW50cywgc28gdHJlYXQgaXQgYXMgc2Vuc2l0aXZlIGV4dGVuc2lvbi1sb2NhbCBkYXRhIGFuZCBhdm9pZCBleHBvc2luZyBpdCB0aHJvdWdoIGNvbW1hbmQgbGlzdHMsIGxvZ3MsIG9yIGF1dG9jb21wbGV0ZSBtZXRhZGF0YS5cblxuVGhpcyByZXBvcnRzIHRoZSBjdXJyZW50IGJhc2UgcHJvbXB0IGlucHV0cy4gSXQgZG9lcyBub3QgaW5jbHVkZSBwZXItdHVybiBgYmVmb3JlX2FnZW50X3N0YXJ0YCBjaGFpbmVkIHN5c3RlbS1wcm9tcHQgY2hhbmdlcywgbGF0ZXIgYGNvbnRleHRgIGV2ZW50IG1lc3NhZ2UgbXV0YXRpb25zLCBvciBgYmVmb3JlX3Byb3ZpZGVyX3JlcXVlc3RgIHBheWxvYWQgcmV3cml0ZXMuXG5cbiMjIyBjdHgud2FpdEZvcklkbGUoKVxuXG5XYWl0IGZvciB0aGUgYWdlbnQgdG8gZmluaXNoIHN0cmVhbWluZzpcblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJDb21tYW5kKFwibXktY21kXCIsIHtcbiAgaGFuZGxlcjogYXN5bmMgKGFyZ3MsIGN0eCkgPT4ge1xuICAgIGF3YWl0IGN0eC53YWl0Rm9ySWRsZSgpO1xuICAgIC8vIEFnZW50IGlzIG5vdyBpZGxlLCBzYWZlIHRvIG1vZGlmeSBzZXNzaW9uXG4gIH0sXG59KTtcbmBgYFxuXG4jIyMgY3R4Lm5ld1Nlc3Npb24ob3B0aW9ucz8pXG5cbkNyZWF0ZSBhIG5ldyBzZXNzaW9uOlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCBwYXJlbnRTZXNzaW9uID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldFNlc3Npb25GaWxlKCk7XG5jb25zdCBraWNrb2ZmID0gXCJDb250aW51ZSBpbiB0aGUgcmVwbGFjZW1lbnQgc2Vzc2lvblwiO1xuXG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHgubmV3U2Vzc2lvbih7XG4gIHBhcmVudFNlc3Npb24sXG4gIHNldHVwOiBhc3luYyAoc20pID0+IHtcbiAgICBzbS5hcHBlbmRNZXNzYWdlKHtcbiAgICAgIHJvbGU6IFwidXNlclwiLFxuICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiQ29udGV4dCBmcm9tIHByZXZpb3VzIHNlc3Npb24uLi5cIiB9XSxcbiAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICB9KTtcbiAgfSxcbiAgd2l0aFNlc3Npb246IGFzeW5jIChjdHgpID0+IHtcbiAgICAvLyBVc2Ugb25seSB0aGUgcmVwbGFjZW1lbnQtc2Vzc2lvbiBjdHggaGVyZS5cbiAgICBhd2FpdCBjdHguc2VuZFVzZXJNZXNzYWdlKGtpY2tvZmYpO1xuICB9LFxufSk7XG5cbmlmIChyZXN1bHQuY2FuY2VsbGVkKSB7XG4gIC8vIEFuIGV4dGVuc2lvbiBjYW5jZWxsZWQgdGhlIG5ldyBzZXNzaW9uXG59XG5gYGBcblxuT3B0aW9uczpcbi0gYHBhcmVudFNlc3Npb25gOiBwYXJlbnQgc2Vzc2lvbiBmaWxlIHRvIHJlY29yZCBpbiB0aGUgbmV3IHNlc3Npb24gaGVhZGVyXG4tIGBzZXR1cGA6IG11dGF0ZSB0aGUgbmV3IHNlc3Npb24ncyBgU2Vzc2lvbk1hbmFnZXJgIGJlZm9yZSBgd2l0aFNlc3Npb25gIHJ1bnNcbi0gYHdpdGhTZXNzaW9uYDogcnVuIHBvc3Qtc3dpdGNoIHdvcmsgYWdhaW5zdCBhIGZyZXNoIHJlcGxhY2VtZW50LXNlc3Npb24gY29udGV4dC4gRG8gbm90IHVzZSBjYXB0dXJlZCBvbGQgYHBpYCAvIGNvbW1hbmQgYGN0eGA7IHNlZSBbU2Vzc2lvbiByZXBsYWNlbWVudCBsaWZlY3ljbGUgYW5kIGZvb3RndW5zXSgjc2Vzc2lvbi1yZXBsYWNlbWVudC1saWZlY3ljbGUtYW5kLWZvb3RndW5zKS5cblxuIyMjIGN0eC5mb3JrKGVudHJ5SWQsIG9wdGlvbnM/KVxuXG5Gb3JrIGZyb20gYSBzcGVjaWZpYyBlbnRyeSwgY3JlYXRpbmcgYSBuZXcgc2Vzc2lvbiBmaWxlOlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHguZm9yayhcImVudHJ5LWlkLTEyM1wiLCB7XG4gIHdpdGhTZXNzaW9uOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgLy8gVXNlIG9ubHkgdGhlIHJlcGxhY2VtZW50LXNlc3Npb24gY3R4IGhlcmUuXG4gICAgY3R4LnVpLm5vdGlmeShcIk5vdyBpbiB0aGUgZm9ya2VkIHNlc3Npb25cIiwgXCJpbmZvXCIpO1xuICB9LFxufSk7XG5pZiAocmVzdWx0LmNhbmNlbGxlZCkge1xuICAvLyBBbiBleHRlbnNpb24gY2FuY2VsbGVkIHRoZSBmb3JrXG59XG5cbmNvbnN0IGNsb25lUmVzdWx0ID0gYXdhaXQgY3R4LmZvcmsoXCJlbnRyeS1pZC00NTZcIiwgeyBwb3NpdGlvbjogXCJhdFwiIH0pO1xuaWYgKGNsb25lUmVzdWx0LmNhbmNlbGxlZCkge1xuICAvLyBBbiBleHRlbnNpb24gY2FuY2VsbGVkIHRoZSBjbG9uZVxufVxuYGBgXG5cbk9wdGlvbnM6XG4tIGBwb3NpdGlvbmA6IGBcImJlZm9yZVwiYCAoZGVmYXVsdCkgZm9ya3MgYmVmb3JlIHRoZSBzZWxlY3RlZCB1c2VyIG1lc3NhZ2UsIHJlc3RvcmluZyB0aGF0IHByb21wdCBpbnRvIHRoZSBlZGl0b3Jcbi0gYHBvc2l0aW9uYDogYFwiYXRcImAgZHVwbGljYXRlcyB0aGUgYWN0aXZlIHBhdGggdGhyb3VnaCB0aGUgc2VsZWN0ZWQgZW50cnkgd2l0aG91dCByZXN0b3JpbmcgZWRpdG9yIHRleHRcbi0gYHdpdGhTZXNzaW9uYDogcnVuIHBvc3Qtc3dpdGNoIHdvcmsgYWdhaW5zdCBhIGZyZXNoIHJlcGxhY2VtZW50LXNlc3Npb24gY29udGV4dC4gRG8gbm90IHVzZSBjYXB0dXJlZCBvbGQgYHBpYCAvIGNvbW1hbmQgYGN0eGA7IHNlZSBbU2Vzc2lvbiByZXBsYWNlbWVudCBsaWZlY3ljbGUgYW5kIGZvb3RndW5zXSgjc2Vzc2lvbi1yZXBsYWNlbWVudC1saWZlY3ljbGUtYW5kLWZvb3RndW5zKS5cblxuIyMjIGN0eC5uYXZpZ2F0ZVRyZWUodGFyZ2V0SWQsIG9wdGlvbnM/KVxuXG5OYXZpZ2F0ZSB0byBhIGRpZmZlcmVudCBwb2ludCBpbiB0aGUgc2Vzc2lvbiB0cmVlOlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHgubmF2aWdhdGVUcmVlKFwiZW50cnktaWQtNDU2XCIsIHtcbiAgc3VtbWFyaXplOiB0cnVlLFxuICBjdXN0b21JbnN0cnVjdGlvbnM6IFwiRm9jdXMgb24gZXJyb3IgaGFuZGxpbmcgY2hhbmdlc1wiLFxuICByZXBsYWNlSW5zdHJ1Y3Rpb25zOiBmYWxzZSwgLy8gdHJ1ZSA9IHJlcGxhY2UgZGVmYXVsdCBwcm9tcHQgZW50aXJlbHlcbiAgbGFiZWw6IFwicmV2aWV3LWNoZWNrcG9pbnRcIixcbn0pO1xuYGBgXG5cbk9wdGlvbnM6XG4tIGBzdW1tYXJpemVgOiBXaGV0aGVyIHRvIGdlbmVyYXRlIGEgc3VtbWFyeSBvZiB0aGUgYWJhbmRvbmVkIGJyYW5jaFxuLSBgY3VzdG9tSW5zdHJ1Y3Rpb25zYDogQ3VzdG9tIGluc3RydWN0aW9ucyBmb3IgdGhlIHN1bW1hcml6ZXJcbi0gYHJlcGxhY2VJbnN0cnVjdGlvbnNgOiBJZiB0cnVlLCBgY3VzdG9tSW5zdHJ1Y3Rpb25zYCByZXBsYWNlcyB0aGUgZGVmYXVsdCBwcm9tcHQgaW5zdGVhZCBvZiBiZWluZyBhcHBlbmRlZFxuLSBgbGFiZWxgOiBMYWJlbCB0byBhdHRhY2ggdG8gdGhlIGJyYW5jaCBzdW1tYXJ5IGVudHJ5IChvciB0YXJnZXQgZW50cnkgaWYgbm90IHN1bW1hcml6aW5nKVxuXG4jIyMgY3R4LnN3aXRjaFNlc3Npb24oc2Vzc2lvblBhdGgsIG9wdGlvbnM/KVxuXG5Td2l0Y2ggdG8gYSBkaWZmZXJlbnQgc2Vzc2lvbiBmaWxlOlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHguc3dpdGNoU2Vzc2lvbihcIi9wYXRoL3RvL3Nlc3Npb24uanNvbmxcIiwge1xuICB3aXRoU2Vzc2lvbjogYXN5bmMgKGN0eCkgPT4ge1xuICAgIGF3YWl0IGN0eC5zZW5kVXNlck1lc3NhZ2UoXCJSZXN1bWUgd29yayBpbiB0aGUgcmVwbGFjZW1lbnQgc2Vzc2lvblwiKTtcbiAgfSxcbn0pO1xuaWYgKHJlc3VsdC5jYW5jZWxsZWQpIHtcbiAgLy8gQW4gZXh0ZW5zaW9uIGNhbmNlbGxlZCB0aGUgc3dpdGNoIHZpYSBzZXNzaW9uX2JlZm9yZV9zd2l0Y2hcbn1cbmBgYFxuXG5PcHRpb25zOlxuLSBgd2l0aFNlc3Npb25gOiBydW4gcG9zdC1zd2l0Y2ggd29yayBhZ2FpbnN0IGEgZnJlc2ggcmVwbGFjZW1lbnQtc2Vzc2lvbiBjb250ZXh0LiBEbyBub3QgdXNlIGNhcHR1cmVkIG9sZCBgcGlgIC8gY29tbWFuZCBgY3R4YDsgc2VlIFtTZXNzaW9uIHJlcGxhY2VtZW50IGxpZmVjeWNsZSBhbmQgZm9vdGd1bnNdKCNzZXNzaW9uLXJlcGxhY2VtZW50LWxpZmVjeWNsZS1hbmQtZm9vdGd1bnMpLlxuXG5UbyBkaXNjb3ZlciBhdmFpbGFibGUgc2Vzc2lvbnMsIHVzZSB0aGUgc3RhdGljIGBTZXNzaW9uTWFuYWdlci5saXN0KClgIG9yIGBTZXNzaW9uTWFuYWdlci5saXN0QWxsKClgIG1ldGhvZHM6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IFNlc3Npb25NYW5hZ2VyIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxucGkucmVnaXN0ZXJDb21tYW5kKFwic3dpdGNoXCIsIHtcbiAgZGVzY3JpcHRpb246IFwiU3dpdGNoIHRvIGFub3RoZXIgc2Vzc2lvblwiLFxuICBoYW5kbGVyOiBhc3luYyAoYXJncywgY3R4KSA9PiB7XG4gICAgY29uc3Qgc2Vzc2lvbnMgPSBhd2FpdCBTZXNzaW9uTWFuYWdlci5saXN0KGN0eC5jd2QpO1xuICAgIGlmIChzZXNzaW9ucy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCBjaG9pY2UgPSBhd2FpdCBjdHgudWkuc2VsZWN0KFxuICAgICAgXCJQaWNrIHNlc3Npb246XCIsXG4gICAgICBzZXNzaW9ucy5tYXAocyA9PiBzLmZpbGUpLFxuICAgICk7XG4gICAgaWYgKGNob2ljZSkge1xuICAgICAgYXdhaXQgY3R4LnN3aXRjaFNlc3Npb24oY2hvaWNlLCB7XG4gICAgICAgIHdpdGhTZXNzaW9uOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgICAgICAgY3R4LnVpLm5vdGlmeShcIlN3aXRjaGVkIHNlc3Npb25cIiwgXCJpbmZvXCIpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuICB9LFxufSk7XG5gYGBcblxuIyMjIFNlc3Npb24gcmVwbGFjZW1lbnQgbGlmZWN5Y2xlIGFuZCBmb290Z3Vuc1xuXG5gd2l0aFNlc3Npb25gIHJlY2VpdmVzIGEgZnJlc2ggYFJlcGxhY2VkU2Vzc2lvbkNvbnRleHRgLCB3aGljaCBleHRlbmRzIGBFeHRlbnNpb25Db21tYW5kQ29udGV4dGAgd2l0aCBhc3luYyBgc2VuZE1lc3NhZ2UoKWAgYW5kIGBzZW5kVXNlck1lc3NhZ2UoKWAgaGVscGVycyBib3VuZCB0byB0aGUgcmVwbGFjZW1lbnQgc2Vzc2lvbi5cblxuTGlmZWN5Y2xlIGFuZCBmb290Z3Vuczpcbi0gYHdpdGhTZXNzaW9uYCBydW5zIG9ubHkgYWZ0ZXIgdGhlIG9sZCBzZXNzaW9uIGhhcyBlbWl0dGVkIGBzZXNzaW9uX3NodXRkb3duYCwgdGhlIG9sZCBydW50aW1lIGhhcyBiZWVuIHRvcm4gZG93biwgdGhlIHJlcGxhY2VtZW50IHNlc3Npb24gaGFzIGJlZW4gcmVib3VuZCwgYW5kIHRoZSBuZXcgZXh0ZW5zaW9uIGluc3RhbmNlIGhhcyBhbHJlYWR5IHJlY2VpdmVkIGBzZXNzaW9uX3N0YXJ0YC5cbi0gVGhlIGNhbGxiYWNrIHN0aWxsIGV4ZWN1dGVzIGluIHRoZSBvcmlnaW5hbCBjbG9zdXJlLCBub3QgaW5zaWRlIHRoZSBuZXcgZXh0ZW5zaW9uIGluc3RhbmNlLiBUaGF0IG1lYW5zIHlvdXIgb2xkIGV4dGVuc2lvbiBpbnN0YW5jZSBtYXkgYWxyZWFkeSBoYXZlIHJ1biBpdHMgc2h1dGRvd24gY2xlYW51cCBiZWZvcmUgYHdpdGhTZXNzaW9uYCBzdGFydHMuXG4tIENhcHR1cmVkIG9sZCBgcGlgIC8gb2xkIGNvbW1hbmQgYGN0eGAgc2Vzc2lvbi1ib3VuZCBvYmplY3RzIGFyZSBzdGFsZSBhZnRlciByZXBsYWNlbWVudCBhbmQgd2lsbCB0aHJvdyBpZiB1c2VkLiBVc2Ugb25seSB0aGUgYGN0eGAgcGFzc2VkIHRvIGB3aXRoU2Vzc2lvbmAgZm9yIHNlc3Npb24tYm91bmQgd29yay5cbi0gUHJldmlvdXNseSBleHRyYWN0ZWQgcmF3IG9iamVjdHMgYXJlIHN0aWxsIHlvdXIgcmVzcG9uc2liaWxpdHkuIEZvciBleGFtcGxlLCBpZiB5b3UgY2FwdHVyZSBgY29uc3Qgc20gPSBjdHguc2Vzc2lvbk1hbmFnZXJgIGJlZm9yZSByZXBsYWNlbWVudCwgYHNtYCBpcyBzdGlsbCB0aGUgb2xkIGBTZXNzaW9uTWFuYWdlcmAgb2JqZWN0LiBEbyBub3QgcmV1c2UgaXQgYWZ0ZXIgcmVwbGFjZW1lbnQuXG4tIENvZGUgaW4gYHdpdGhTZXNzaW9uYCBzaG91bGQgYXNzdW1lIGFueSBzdGF0ZSBpbnZhbGlkYXRlZCBieSB5b3VyIGBzZXNzaW9uX3NodXRkb3duYCBoYW5kbGVyIGlzIGFscmVhZHkgZ29uZS4gT25seSBjYXB0dXJlIHBsYWluIGRhdGEgdGhhdCBzdXJ2aXZlcyBzaHV0ZG93biBjbGVhbmx5LCBzdWNoIGFzIHN0cmluZ3MsIGlkcywgYW5kIHNlcmlhbGl6ZWQgY29uZmlnLlxuXG5TYWZlIHBhdHRlcm46XG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyQ29tbWFuZChcImhhbmRvZmZcIiwge1xuICBoYW5kbGVyOiBhc3luYyAoX2FyZ3MsIGN0eCkgPT4ge1xuICAgIGNvbnN0IGtpY2tvZmYgPSBcIkNvbnRpbnVlIGZyb20gdGhlIHJlcGxhY2VtZW50IHNlc3Npb25cIjtcbiAgICBhd2FpdCBjdHgubmV3U2Vzc2lvbih7XG4gICAgICB3aXRoU2Vzc2lvbjogYXN5bmMgKGN0eCkgPT4ge1xuICAgICAgICBhd2FpdCBjdHguc2VuZFVzZXJNZXNzYWdlKGtpY2tvZmYpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfSxcbn0pO1xuYGBgXG5cblVuc2FmZSBwYXR0ZXJuOlxuXG5gYGB0eXBlc2NyaXB0XG5waS5yZWdpc3RlckNvbW1hbmQoXCJoYW5kb2ZmXCIsIHtcbiAgaGFuZGxlcjogYXN5bmMgKF9hcmdzLCBjdHgpID0+IHtcbiAgICBjb25zdCBvbGRTZXNzaW9uTWFuYWdlciA9IGN0eC5zZXNzaW9uTWFuYWdlcjtcbiAgICBhd2FpdCBjdHgubmV3U2Vzc2lvbih7XG4gICAgICB3aXRoU2Vzc2lvbjogYXN5bmMgKF9jdHgpID0+IHtcbiAgICAgICAgLy8gc3RhbGUgb2xkIG9iamVjdHM6IGRvIG5vdCBkbyB0aGlzXG4gICAgICAgIG9sZFNlc3Npb25NYW5hZ2VyLmdldFNlc3Npb25GaWxlKCk7XG4gICAgICAgIHBpLnNlbmRVc2VyTWVzc2FnZShcIndyb25nXCIpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfSxcbn0pO1xuYGBgXG5cbiMjIyBjdHgucmVsb2FkKClcblxuUnVuIHRoZSBzYW1lIHJlbG9hZCBmbG93IGFzIGAvcmVsb2FkYC5cblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJDb21tYW5kKFwicmVsb2FkLXJ1bnRpbWVcIiwge1xuICBkZXNjcmlwdGlvbjogXCJSZWxvYWQgZXh0ZW5zaW9ucywgc2tpbGxzLCBwcm9tcHRzLCBhbmQgdGhlbWVzXCIsXG4gIGhhbmRsZXI6IGFzeW5jIChfYXJncywgY3R4KSA9PiB7XG4gICAgYXdhaXQgY3R4LnJlbG9hZCgpO1xuICAgIHJldHVybjtcbiAgfSxcbn0pO1xuYGBgXG5cbkltcG9ydGFudCBiZWhhdmlvcjpcbi0gYGF3YWl0IGN0eC5yZWxvYWQoKWAgZW1pdHMgYHNlc3Npb25fc2h1dGRvd25gIGZvciB0aGUgY3VycmVudCBleHRlbnNpb24gcnVudGltZVxuLSBJdCB0aGVuIHJlbG9hZHMgcmVzb3VyY2VzIGFuZCBlbWl0cyBgc2Vzc2lvbl9zdGFydGAgd2l0aCBgcmVhc29uOiBcInJlbG9hZFwiYCBhbmQgYHJlc291cmNlc19kaXNjb3ZlcmAgd2l0aCByZWFzb24gYFwicmVsb2FkXCJgXG4tIFRoZSBjdXJyZW50bHkgcnVubmluZyBjb21tYW5kIGhhbmRsZXIgc3RpbGwgY29udGludWVzIGluIHRoZSBvbGQgY2FsbCBmcmFtZVxuLSBDb2RlIGFmdGVyIGBhd2FpdCBjdHgucmVsb2FkKClgIHN0aWxsIHJ1bnMgZnJvbSB0aGUgcHJlLXJlbG9hZCB2ZXJzaW9uXG4tIENvZGUgYWZ0ZXIgYGF3YWl0IGN0eC5yZWxvYWQoKWAgbXVzdCBub3QgYXNzdW1lIG9sZCBpbi1tZW1vcnkgZXh0ZW5zaW9uIHN0YXRlIGlzIHN0aWxsIHZhbGlkXG4tIEFmdGVyIHRoZSBoYW5kbGVyIHJldHVybnMsIGZ1dHVyZSBjb21tYW5kcy9ldmVudHMvdG9vbCBjYWxscyB1c2UgdGhlIG5ldyBleHRlbnNpb24gdmVyc2lvblxuXG5Gb3IgcHJlZGljdGFibGUgYmVoYXZpb3IsIHRyZWF0IHJlbG9hZCBhcyB0ZXJtaW5hbCBmb3IgdGhhdCBoYW5kbGVyIChgYXdhaXQgY3R4LnJlbG9hZCgpOyByZXR1cm47YCkuXG5cblRvb2xzIHJ1biB3aXRoIGBFeHRlbnNpb25Db250ZXh0YCwgc28gdGhleSBjYW5ub3QgY2FsbCBgY3R4LnJlbG9hZCgpYCBkaXJlY3RseS4gVXNlIGEgY29tbWFuZCBhcyB0aGUgcmVsb2FkIGVudHJ5cG9pbnQsIHRoZW4gZXhwb3NlIGEgdG9vbCB0aGF0IHF1ZXVlcyB0aGF0IGNvbW1hbmQgYXMgYSBmb2xsb3ctdXAgdXNlciBtZXNzYWdlLlxuXG5FeGFtcGxlIHRvb2wgdGhlIExMTSBjYW4gY2FsbCB0byB0cmlnZ2VyIHJlbG9hZDpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEkgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIHBpLnJlZ2lzdGVyQ29tbWFuZChcInJlbG9hZC1ydW50aW1lXCIsIHtcbiAgICBkZXNjcmlwdGlvbjogXCJSZWxvYWQgZXh0ZW5zaW9ucywgc2tpbGxzLCBwcm9tcHRzLCBhbmQgdGhlbWVzXCIsXG4gICAgaGFuZGxlcjogYXN5bmMgKF9hcmdzLCBjdHgpID0+IHtcbiAgICAgIGF3YWl0IGN0eC5yZWxvYWQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9LFxuICB9KTtcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwicmVsb2FkX3J1bnRpbWVcIixcbiAgICBsYWJlbDogXCJSZWxvYWQgUnVudGltZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlJlbG9hZCBleHRlbnNpb25zLCBza2lsbHMsIHByb21wdHMsIGFuZCB0aGVtZXNcIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICAgIHBpLnNlbmRVc2VyTWVzc2FnZShcIi9yZWxvYWQtcnVudGltZVwiLCB7IGRlbGl2ZXJBczogXCJmb2xsb3dVcFwiIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiUXVldWVkIC9yZWxvYWQtcnVudGltZSBhcyBhIGZvbGxvdy11cCBjb21tYW5kLlwiIH1dLFxuICAgICAgfTtcbiAgICB9LFxuICB9KTtcbn1cbmBgYFxuXG4jIyBFeHRlbnNpb25BUEkgTWV0aG9kc1xuXG4jIyMgcGkub24oZXZlbnQsIGhhbmRsZXIpXG5cblN1YnNjcmliZSB0byBldmVudHMuIFNlZSBbRXZlbnRzXSgjZXZlbnRzKSBmb3IgZXZlbnQgdHlwZXMgYW5kIHJldHVybiB2YWx1ZXMuXG5cbiMjIyBwaS5yZWdpc3RlclRvb2woZGVmaW5pdGlvbilcblxuUmVnaXN0ZXIgYSBjdXN0b20gdG9vbCBjYWxsYWJsZSBieSB0aGUgTExNLiBTZWUgW0N1c3RvbSBUb29sc10oI2N1c3RvbS10b29scykgZm9yIGZ1bGwgZGV0YWlscy5cblxuYHBpLnJlZ2lzdGVyVG9vbCgpYCB3b3JrcyBib3RoIGR1cmluZyBleHRlbnNpb24gbG9hZCBhbmQgYWZ0ZXIgc3RhcnR1cC4gWW91IGNhbiBjYWxsIGl0IGluc2lkZSBgc2Vzc2lvbl9zdGFydGAsIGNvbW1hbmQgaGFuZGxlcnMsIG9yIG90aGVyIGV2ZW50IGhhbmRsZXJzLiBOZXcgdG9vbHMgYXJlIHJlZnJlc2hlZCBpbW1lZGlhdGVseSBpbiB0aGUgc2FtZSBzZXNzaW9uLCBzbyB0aGV5IGFwcGVhciBpbiBgcGkuZ2V0QWxsVG9vbHMoKWAgYW5kIGFyZSBjYWxsYWJsZSBieSB0aGUgTExNIHdpdGhvdXQgYC9yZWxvYWRgLlxuXG5Vc2UgYHBpLnNldEFjdGl2ZVRvb2xzKClgIHRvIGVuYWJsZSBvciBkaXNhYmxlIHRvb2xzIChpbmNsdWRpbmcgZHluYW1pY2FsbHkgYWRkZWQgdG9vbHMpIGF0IHJ1bnRpbWUuXG5cblVzZSBgcHJvbXB0U25pcHBldGAgdG8gb3B0IGEgY3VzdG9tIHRvb2wgaW50byBhIG9uZS1saW5lIGVudHJ5IGluIGBBdmFpbGFibGUgdG9vbHNgLCBhbmQgYHByb21wdEd1aWRlbGluZXNgIHRvIGFwcGVuZCB0b29sLXNwZWNpZmljIGJ1bGxldHMgdG8gdGhlIGRlZmF1bHQgYEd1aWRlbGluZXNgIHNlY3Rpb24gd2hlbiB0aGUgdG9vbCBpcyBhY3RpdmUuXG5cbioqSW1wb3J0YW50OioqIGBwcm9tcHRHdWlkZWxpbmVzYCBidWxsZXRzIGFyZSBhcHBlbmRlZCBmbGF0IHRvIHRoZSBgR3VpZGVsaW5lc2Agc2VjdGlvbiB3aXRoIG5vIHRvb2wgbmFtZSBwcmVmaXguIEVhY2ggZ3VpZGVsaW5lIG11c3QgbmFtZSB0aGUgdG9vbCBpdCByZWZlcnMgdG8g4oCUIGF2b2lkIFwiVXNlIHRoaXMgdG9vbCB3aGVuLi4uXCIgYmVjYXVzZSB0aGUgTExNIGNhbm5vdCB0ZWxsIHdoaWNoIHRvb2wgXCJ0aGlzXCIgbWVhbnMuIFdyaXRlIFwiVXNlIG15X3Rvb2wgd2hlbi4uLlwiIGluc3RlYWQuXG5cblNlZSBbZHluYW1pYy10b29scy50c10oLi4vZXhhbXBsZXMvZXh0ZW5zaW9ucy9keW5hbWljLXRvb2xzLnRzKSBmb3IgYSBmdWxsIGV4YW1wbGUuXG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwidHlwZWJveFwiO1xuaW1wb3J0IHsgU3RyaW5nRW51bSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktYWlcIjtcblxucGkucmVnaXN0ZXJUb29sKHtcbiAgbmFtZTogXCJteV90b29sXCIsXG4gIGxhYmVsOiBcIk15IFRvb2xcIixcbiAgZGVzY3JpcHRpb246IFwiV2hhdCB0aGlzIHRvb2wgZG9lc1wiLFxuICBwcm9tcHRTbmlwcGV0OiBcIlN1bW1hcml6ZSBvciB0cmFuc2Zvcm0gdGV4dCBhY2NvcmRpbmcgdG8gYWN0aW9uXCIsXG4gIHByb21wdEd1aWRlbGluZXM6IFtcIlVzZSBteV90b29sIHdoZW4gdGhlIHVzZXIgYXNrcyB0byBzdW1tYXJpemUgcHJldmlvdXNseSBnZW5lcmF0ZWQgdGV4dC5cIl0sXG4gIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHtcbiAgICBhY3Rpb246IFN0cmluZ0VudW0oW1wibGlzdFwiLCBcImFkZFwiXSBhcyBjb25zdCksXG4gICAgdGV4dDogVHlwZS5PcHRpb25hbChUeXBlLlN0cmluZygpKSxcbiAgfSksXG4gIHByZXBhcmVBcmd1bWVudHMoYXJncykge1xuICAgIC8vIE9wdGlvbmFsIGNvbXBhdGliaWxpdHkgc2hpbS4gUnVucyBiZWZvcmUgc2NoZW1hIHZhbGlkYXRpb24uXG4gICAgLy8gUmV0dXJuIHRoZSBjdXJyZW50IHNjaGVtYSBzaGFwZSwgZm9yIGV4YW1wbGUgdG8gZm9sZCBsZWdhY3kgZmllbGRzXG4gICAgLy8gaW50byB0aGUgbW9kZXJuIHBhcmFtZXRlciBvYmplY3QuXG4gICAgcmV0dXJuIGFyZ3M7XG4gIH0sXG5cbiAgYXN5bmMgZXhlY3V0ZSh0b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUsIGN0eCkge1xuICAgIC8vIFN0cmVhbSBwcm9ncmVzc1xuICAgIG9uVXBkYXRlPy4oeyBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJXb3JraW5nLi4uXCIgfV0gfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiRG9uZVwiIH1dLFxuICAgICAgZGV0YWlsczogeyByZXN1bHQ6IFwiLi4uXCIgfSxcbiAgICB9O1xuICB9LFxuXG4gIC8vIE9wdGlvbmFsOiBDdXN0b20gcmVuZGVyaW5nXG4gIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIGNvbnRleHQpIHsgLi4uIH0sXG4gIHJlbmRlclJlc3VsdChyZXN1bHQsIG9wdGlvbnMsIHRoZW1lLCBjb250ZXh0KSB7IC4uLiB9LFxufSk7XG5gYGBcblxuIyMjIHBpLnNlbmRNZXNzYWdlKG1lc3NhZ2UsIG9wdGlvbnM/KVxuXG5JbmplY3QgYSBjdXN0b20gbWVzc2FnZSBpbnRvIHRoZSBzZXNzaW9uLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5zZW5kTWVzc2FnZSh7XG4gIGN1c3RvbVR5cGU6IFwibXktZXh0ZW5zaW9uXCIsXG4gIGNvbnRlbnQ6IFwiTWVzc2FnZSB0ZXh0XCIsXG4gIGRpc3BsYXk6IHRydWUsXG4gIGRldGFpbHM6IHsgLi4uIH0sXG59LCB7XG4gIHRyaWdnZXJUdXJuOiB0cnVlLFxuICBkZWxpdmVyQXM6IFwic3RlZXJcIixcbn0pO1xuYGBgXG5cbioqT3B0aW9uczoqKlxuLSBgZGVsaXZlckFzYCAtIERlbGl2ZXJ5IG1vZGU6XG4gIC0gYFwic3RlZXJcImAgKGRlZmF1bHQpIC0gUXVldWVzIHRoZSBtZXNzYWdlIHdoaWxlIHN0cmVhbWluZy4gRGVsaXZlcmVkIGFmdGVyIHRoZSBjdXJyZW50IGFzc2lzdGFudCB0dXJuIGZpbmlzaGVzIGV4ZWN1dGluZyBpdHMgdG9vbCBjYWxscywgYmVmb3JlIHRoZSBuZXh0IExMTSBjYWxsLlxuICAtIGBcImZvbGxvd1VwXCJgIC0gV2FpdHMgZm9yIGFnZW50IHRvIGZpbmlzaC4gRGVsaXZlcmVkIG9ubHkgd2hlbiBhZ2VudCBoYXMgbm8gbW9yZSB0b29sIGNhbGxzLlxuICAtIGBcIm5leHRUdXJuXCJgIC0gUXVldWVkIGZvciBuZXh0IHVzZXIgcHJvbXB0LiBEb2VzIG5vdCBpbnRlcnJ1cHQgb3IgdHJpZ2dlciBhbnl0aGluZy5cbi0gYHRyaWdnZXJUdXJuOiB0cnVlYCAtIElmIGFnZW50IGlzIGlkbGUsIHRyaWdnZXIgYW4gTExNIHJlc3BvbnNlIGltbWVkaWF0ZWx5LiBPbmx5IGFwcGxpZXMgdG8gYFwic3RlZXJcImAgYW5kIGBcImZvbGxvd1VwXCJgIG1vZGVzIChpZ25vcmVkIGZvciBgXCJuZXh0VHVyblwiYCkuXG5cbiMjIyBwaS5zZW5kVXNlck1lc3NhZ2UoY29udGVudCwgb3B0aW9ucz8pXG5cblNlbmQgYSB1c2VyIG1lc3NhZ2UgdG8gdGhlIGFnZW50LiBVbmxpa2UgYHNlbmRNZXNzYWdlKClgIHdoaWNoIHNlbmRzIGN1c3RvbSBtZXNzYWdlcywgdGhpcyBzZW5kcyBhbiBhY3R1YWwgdXNlciBtZXNzYWdlIHRoYXQgYXBwZWFycyBhcyBpZiB0eXBlZCBieSB0aGUgdXNlci4gQWx3YXlzIHRyaWdnZXJzIGEgdHVybi5cblxuYGBgdHlwZXNjcmlwdFxuLy8gU2ltcGxlIHRleHQgbWVzc2FnZVxucGkuc2VuZFVzZXJNZXNzYWdlKFwiV2hhdCBpcyAyKzI/XCIpO1xuXG4vLyBXaXRoIGNvbnRlbnQgYXJyYXkgKHRleHQgKyBpbWFnZXMpXG5waS5zZW5kVXNlck1lc3NhZ2UoW1xuICB7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIkRlc2NyaWJlIHRoaXMgaW1hZ2U6XCIgfSxcbiAgeyB0eXBlOiBcImltYWdlXCIsIHNvdXJjZTogeyB0eXBlOiBcImJhc2U2NFwiLCBtZWRpYVR5cGU6IFwiaW1hZ2UvcG5nXCIsIGRhdGE6IFwiLi4uXCIgfSB9LFxuXSk7XG5cbi8vIER1cmluZyBzdHJlYW1pbmcgLSBtdXN0IHNwZWNpZnkgZGVsaXZlcnkgbW9kZVxucGkuc2VuZFVzZXJNZXNzYWdlKFwiRm9jdXMgb24gZXJyb3IgaGFuZGxpbmdcIiwgeyBkZWxpdmVyQXM6IFwic3RlZXJcIiB9KTtcbnBpLnNlbmRVc2VyTWVzc2FnZShcIkFuZCB0aGVuIHN1bW1hcml6ZVwiLCB7IGRlbGl2ZXJBczogXCJmb2xsb3dVcFwiIH0pO1xuYGBgXG5cbioqT3B0aW9uczoqKlxuLSBgZGVsaXZlckFzYCAtIFJlcXVpcmVkIHdoZW4gYWdlbnQgaXMgc3RyZWFtaW5nOlxuICAtIGBcInN0ZWVyXCJgIC0gUXVldWVzIHRoZSBtZXNzYWdlIGZvciBkZWxpdmVyeSBhZnRlciB0aGUgY3VycmVudCBhc3Npc3RhbnQgdHVybiBmaW5pc2hlcyBleGVjdXRpbmcgaXRzIHRvb2wgY2FsbHNcbiAgLSBgXCJmb2xsb3dVcFwiYCAtIFdhaXRzIGZvciBhZ2VudCB0byBmaW5pc2ggYWxsIHRvb2xzXG5cbldoZW4gbm90IHN0cmVhbWluZywgdGhlIG1lc3NhZ2UgaXMgc2VudCBpbW1lZGlhdGVseSBhbmQgdHJpZ2dlcnMgYSBuZXcgdHVybi4gV2hlbiBzdHJlYW1pbmcgd2l0aG91dCBgZGVsaXZlckFzYCwgdGhyb3dzIGFuIGVycm9yLlxuXG5TZWUgW3NlbmQtdXNlci1tZXNzYWdlLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL3NlbmQtdXNlci1tZXNzYWdlLnRzKSBmb3IgYSBjb21wbGV0ZSBleGFtcGxlLlxuXG4jIyMgcGkuYXBwZW5kRW50cnkoY3VzdG9tVHlwZSwgZGF0YT8pXG4iLCJ0cnVuY2F0ZWQiOnRydWUsInRydW5jYXRlZEJ5IjoiYnl0ZXMiLCJ0b3RhbExpbmVzIjoyNjc2LCJ0b3RhbEJ5dGVzIjoxMDMzNTAsIm91dHB1dExpbmVzIjoxMzg2LCJvdXRwdXRCeXRlcyI6NTExNzYsImxhc3RMaW5lUGFydGlhbCI6ZmFsc2UsImZpcnN0TGluZUV4Y2VlZHNMaW1pdCI6ZmFsc2UsIm1heExpbmVzIjoyMDAwLCJtYXhCeXRlcyI6NTEyMDB9fSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODIxMzA0Mn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjE4ODUyZmVlIiwicGFyZW50SWQiOiIyMjdmZWMyMSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTA6MTMuMDQzWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiT1lMSWZLQjJRYVo0QXFDMVNUeURrVlY2cHI0Q0FidVEiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJtaXNlLnRvbWxcbnBhY2thZ2UuanNvblxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MjEzMDQzfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYzZmNmQxYTIiLCJwYXJlbnRJZCI6IjE4ODUyZmVlIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MDo0Mi44OTFaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJMZXQgbWUgcmVhZCB0aGUgZXh0ZW5zaW9ucyBkb2NzIGZ1cnRoZXIgYW5kIGxvb2sgYXQgdGhlIGV4YW1wbGVzLCBhbmQgYWxzbyBjaGVjayB0aGUgY3VycmVudCBwcm9qZWN0IHN0cnVjdHVyZS5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkxldCBtZSByZWFkIHRoZSByZXN0IG9mIHRoZSBleHRlbnNpb25zIGRvY3MgYW5kIGNoZWNrIHRoZSBwcm9qZWN0IHN0cnVjdHVyZTpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6Im9yaHhWRkl3WFByMXpLZ3FFSGxkdXVMb09xTk94ajk0IiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2RvY3MvZXh0ZW5zaW9ucy5tZCIsIm9mZnNldCI6MTM4N319LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJOS3dRM0d6VGd6dllqc3ZaQWhVODVLY29neE1LdGZOYSIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9wYWNrYWdlLmpzb24ifX0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6InRYSng3T3BwTGczT3F5T2JaWkQ1d2gxQXJwZm5NZmNtIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL21pc2UudG9tbCJ9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiQTVNbzN5aHdnOHBYOXlYSTYyUVIwRXpwdnVqMEVHU0EiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoibHMgL1VzZXJzL3dpbGxlbS8ubG9jYWwvc2hhcmUvbWlzZS9pbnN0YWxscy9ub2RlLzI0LjAuMS9saWIvbm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnQvZXhhbXBsZXMvZXh0ZW5zaW9ucy8ifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjIwNDg5LCJvdXRwdXQiOjI1NywiY2FjaGVSZWFkIjoxOTU1LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MjI3MDEsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODIxMzA0MywicmVzcG9uc2VJZCI6ImNoYXRjbXBsLWZBckVGRXFsd3U2dVFZN1FUZnNxdVJmTGhGYTJKSFpPIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjgwNzljMzYyIiwicGFyZW50SWQiOiJjNmY2ZDFhMiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTA6NDIuOTA1WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoib3JoeFZGSXdYUHIxektncUVIbGR1dUxvT3FOT3hqOTQiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJQZXJzaXN0IGV4dGVuc2lvbiBzdGF0ZSAoZG9lcyBOT1QgcGFydGljaXBhdGUgaW4gTExNIGNvbnRleHQpLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5hcHBlbmRFbnRyeShcIm15LXN0YXRlXCIsIHsgY291bnQ6IDQyIH0pO1xuXG4vLyBSZXN0b3JlIG9uIHJlbG9hZFxucGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGN0eC5zZXNzaW9uTWFuYWdlci5nZXRFbnRyaWVzKCkpIHtcbiAgICBpZiAoZW50cnkudHlwZSA9PT0gXCJjdXN0b21cIiAmJiBlbnRyeS5jdXN0b21UeXBlID09PSBcIm15LXN0YXRlXCIpIHtcbiAgICAgIC8vIFJlY29uc3RydWN0IGZyb20gZW50cnkuZGF0YVxuICAgIH1cbiAgfVxufSk7XG5gYGBcblxuIyMjIHBpLnNldFNlc3Npb25OYW1lKG5hbWUpXG5cblNldCB0aGUgc2Vzc2lvbiBkaXNwbGF5IG5hbWUgKHNob3duIGluIHNlc3Npb24gc2VsZWN0b3IgaW5zdGVhZCBvZiBmaXJzdCBtZXNzYWdlKS5cblxuYGBgdHlwZXNjcmlwdFxucGkuc2V0U2Vzc2lvbk5hbWUoXCJSZWZhY3RvciBhdXRoIG1vZHVsZVwiKTtcbmBgYFxuXG4jIyMgcGkuZ2V0U2Vzc2lvbk5hbWUoKVxuXG5HZXQgdGhlIGN1cnJlbnQgc2Vzc2lvbiBuYW1lLCBpZiBzZXQuXG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IG5hbWUgPSBwaS5nZXRTZXNzaW9uTmFtZSgpO1xuaWYgKG5hbWUpIHtcbiAgY29uc29sZS5sb2coYFNlc3Npb246ICR7bmFtZX1gKTtcbn1cbmBgYFxuXG4jIyMgcGkuc2V0TGFiZWwoZW50cnlJZCwgbGFiZWwpXG5cblNldCBvciBjbGVhciBhIGxhYmVsIG9uIGFuIGVudHJ5LiBMYWJlbHMgYXJlIHVzZXItZGVmaW5lZCBtYXJrZXJzIGZvciBib29rbWFya2luZyBhbmQgbmF2aWdhdGlvbiAoc2hvd24gaW4gYC90cmVlYCBzZWxlY3RvcikuXG5cbmBgYHR5cGVzY3JpcHRcbi8vIFNldCBhIGxhYmVsXG5waS5zZXRMYWJlbChlbnRyeUlkLCBcImNoZWNrcG9pbnQtYmVmb3JlLXJlZmFjdG9yXCIpO1xuXG4vLyBDbGVhciBhIGxhYmVsXG5waS5zZXRMYWJlbChlbnRyeUlkLCB1bmRlZmluZWQpO1xuXG4vLyBSZWFkIGxhYmVscyB2aWEgc2Vzc2lvbk1hbmFnZXJcbmNvbnN0IGxhYmVsID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldExhYmVsKGVudHJ5SWQpO1xuYGBgXG5cbkxhYmVscyBwZXJzaXN0IGluIHRoZSBzZXNzaW9uIGFuZCBzdXJ2aXZlIHJlc3RhcnRzLiBVc2UgdGhlbSB0byBtYXJrIGltcG9ydGFudCBwb2ludHMgKHR1cm5zLCBjaGVja3BvaW50cykgaW4gdGhlIGNvbnZlcnNhdGlvbiB0cmVlLlxuXG4jIyMgcGkucmVnaXN0ZXJDb21tYW5kKG5hbWUsIG9wdGlvbnMpXG5cblJlZ2lzdGVyIGEgY29tbWFuZC5cblxuSWYgbXVsdGlwbGUgZXh0ZW5zaW9ucyByZWdpc3RlciB0aGUgc2FtZSBjb21tYW5kIG5hbWUsIHBpIGtlZXBzIHRoZW0gYWxsIGFuZCBhc3NpZ25zIG51bWVyaWMgaW52b2NhdGlvbiBzdWZmaXhlcyBpbiBsb2FkIG9yZGVyLCBmb3IgZXhhbXBsZSBgL3JldmlldzoxYCBhbmQgYC9yZXZpZXc6MmAuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyQ29tbWFuZChcInN0YXRzXCIsIHtcbiAgZGVzY3JpcHRpb246IFwiU2hvdyBzZXNzaW9uIHN0YXRpc3RpY3NcIixcbiAgaGFuZGxlcjogYXN5bmMgKGFyZ3MsIGN0eCkgPT4ge1xuICAgIGNvbnN0IGNvdW50ID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldEVudHJpZXMoKS5sZW5ndGg7XG4gICAgY3R4LnVpLm5vdGlmeShgJHtjb3VudH0gZW50cmllc2AsIFwiaW5mb1wiKTtcbiAgfVxufSk7XG5gYGBcblxuT3B0aW9uYWw6IGFkZCBhcmd1bWVudCBhdXRvLWNvbXBsZXRpb24gZm9yIGAvY29tbWFuZCAuLi5gOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgdHlwZSB7IEF1dG9jb21wbGV0ZUl0ZW0gfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuXG5waS5yZWdpc3RlckNvbW1hbmQoXCJkZXBsb3lcIiwge1xuICBkZXNjcmlwdGlvbjogXCJEZXBsb3kgdG8gYW4gZW52aXJvbm1lbnRcIixcbiAgZ2V0QXJndW1lbnRDb21wbGV0aW9uczogKHByZWZpeDogc3RyaW5nKTogQXV0b2NvbXBsZXRlSXRlbVtdIHwgbnVsbCA9PiB7XG4gICAgY29uc3QgZW52cyA9IFtcImRldlwiLCBcInN0YWdpbmdcIiwgXCJwcm9kXCJdO1xuICAgIGNvbnN0IGl0ZW1zID0gZW52cy5tYXAoKGUpID0+ICh7IHZhbHVlOiBlLCBsYWJlbDogZSB9KSk7XG4gICAgY29uc3QgZmlsdGVyZWQgPSBpdGVtcy5maWx0ZXIoKGkpID0+IGkudmFsdWUuc3RhcnRzV2l0aChwcmVmaXgpKTtcbiAgICByZXR1cm4gZmlsdGVyZWQubGVuZ3RoID4gMCA/IGZpbHRlcmVkIDogbnVsbDtcbiAgfSxcbiAgaGFuZGxlcjogYXN5bmMgKGFyZ3MsIGN0eCkgPT4ge1xuICAgIGN0eC51aS5ub3RpZnkoYERlcGxveWluZzogJHthcmdzfWAsIFwiaW5mb1wiKTtcbiAgfSxcbn0pO1xuYGBgXG5cbiMjIyBwaS5nZXRDb21tYW5kcygpXG5cbkdldCB0aGUgc2xhc2ggY29tbWFuZHMgYXZhaWxhYmxlIGZvciBpbnZvY2F0aW9uIHZpYSBgcHJvbXB0YCBpbiB0aGUgY3VycmVudCBzZXNzaW9uLiBJbmNsdWRlcyBleHRlbnNpb24gY29tbWFuZHMsIHByb21wdCB0ZW1wbGF0ZXMsIGFuZCBza2lsbCBjb21tYW5kcy5cblRoZSBsaXN0IG1hdGNoZXMgdGhlIFJQQyBgZ2V0X2NvbW1hbmRzYCBvcmRlcmluZzogZXh0ZW5zaW9ucyBmaXJzdCwgdGhlbiB0ZW1wbGF0ZXMsIHRoZW4gc2tpbGxzLlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCBjb21tYW5kcyA9IHBpLmdldENvbW1hbmRzKCk7XG5jb25zdCBieVNvdXJjZSA9IGNvbW1hbmRzLmZpbHRlcigoY29tbWFuZCkgPT4gY29tbWFuZC5zb3VyY2UgPT09IFwiZXh0ZW5zaW9uXCIpO1xuY29uc3QgdXNlclNjb3BlZCA9IGNvbW1hbmRzLmZpbHRlcigoY29tbWFuZCkgPT4gY29tbWFuZC5zb3VyY2VJbmZvLnNjb3BlID09PSBcInVzZXJcIik7XG5gYGBcblxuRWFjaCBlbnRyeSBoYXMgdGhpcyBzaGFwZTpcblxuYGBgdHlwZXNjcmlwdFxue1xuICBuYW1lOiBzdHJpbmc7IC8vIEludm9rYWJsZSBjb21tYW5kIG5hbWUgd2l0aG91dCB0aGUgbGVhZGluZyBzbGFzaC4gTWF5IGJlIHN1ZmZpeGVkIGxpa2UgXCJyZXZpZXc6MVwiXG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBzb3VyY2U6IFwiZXh0ZW5zaW9uXCIgfCBcInByb21wdFwiIHwgXCJza2lsbFwiO1xuICBzb3VyY2VJbmZvOiB7XG4gICAgcGF0aDogc3RyaW5nO1xuICAgIHNvdXJjZTogc3RyaW5nO1xuICAgIHNjb3BlOiBcInVzZXJcIiB8IFwicHJvamVjdFwiIHwgXCJ0ZW1wb3JhcnlcIjtcbiAgICBvcmlnaW46IFwicGFja2FnZVwiIHwgXCJ0b3AtbGV2ZWxcIjtcbiAgICBiYXNlRGlyPzogc3RyaW5nO1xuICB9O1xufVxuYGBgXG5cblVzZSBgc291cmNlSW5mb2AgYXMgdGhlIGNhbm9uaWNhbCBwcm92ZW5hbmNlIGZpZWxkLiBEbyBub3QgaW5mZXIgb3duZXJzaGlwIGZyb20gY29tbWFuZCBuYW1lcyBvciBmcm9tIGFkIGhvYyBwYXRoIHBhcnNpbmcuXG5cbkJ1aWx0LWluIGludGVyYWN0aXZlIGNvbW1hbmRzIChsaWtlIGAvbW9kZWxgIGFuZCBgL3NldHRpbmdzYCkgYXJlIG5vdCBpbmNsdWRlZCBoZXJlLiBUaGV5IGFyZSBoYW5kbGVkIG9ubHkgaW4gaW50ZXJhY3RpdmVcbm1vZGUgYW5kIHdvdWxkIG5vdCBleGVjdXRlIGlmIHNlbnQgdmlhIGBwcm9tcHRgLlxuXG4jIyMgcGkucmVnaXN0ZXJNZXNzYWdlUmVuZGVyZXIoY3VzdG9tVHlwZSwgcmVuZGVyZXIpXG5cblJlZ2lzdGVyIGEgY3VzdG9tIFRVSSByZW5kZXJlciBmb3IgbWVzc2FnZXMgd2l0aCB5b3VyIGBjdXN0b21UeXBlYC4gU2VlIFtDdXN0b20gVUldKCNjdXN0b20tdWkpLlxuXG4jIyMgcGkucmVnaXN0ZXJTaG9ydGN1dChzaG9ydGN1dCwgb3B0aW9ucylcblxuUmVnaXN0ZXIgYSBrZXlib2FyZCBzaG9ydGN1dC4gU2VlIFtrZXliaW5kaW5ncy5tZF0oa2V5YmluZGluZ3MubWQpIGZvciB0aGUgc2hvcnRjdXQgZm9ybWF0IGFuZCBidWlsdC1pbiBrZXliaW5kaW5ncy5cblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJTaG9ydGN1dChcImN0cmwrc2hpZnQrcFwiLCB7XG4gIGRlc2NyaXB0aW9uOiBcIlRvZ2dsZSBwbGFuIG1vZGVcIixcbiAgaGFuZGxlcjogYXN5bmMgKGN0eCkgPT4ge1xuICAgIGN0eC51aS5ub3RpZnkoXCJUb2dnbGVkIVwiKTtcbiAgfSxcbn0pO1xuYGBgXG5cbiMjIyBwaS5yZWdpc3RlckZsYWcobmFtZSwgb3B0aW9ucylcblxuUmVnaXN0ZXIgYSBDTEkgZmxhZy5cblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJGbGFnKFwicGxhblwiLCB7XG4gIGRlc2NyaXB0aW9uOiBcIlN0YXJ0IGluIHBsYW4gbW9kZVwiLFxuICB0eXBlOiBcImJvb2xlYW5cIixcbiAgZGVmYXVsdDogZmFsc2UsXG59KTtcblxuLy8gQ2hlY2sgdmFsdWVcbmlmIChwaS5nZXRGbGFnKFwicGxhblwiKSkge1xuICAvLyBQbGFuIG1vZGUgZW5hYmxlZFxufVxuYGBgXG5cbiMjIyBwaS5leGVjKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnM/KVxuXG5FeGVjdXRlIGEgc2hlbGwgY29tbWFuZC5cblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImdpdFwiLCBbXCJzdGF0dXNcIl0sIHsgc2lnbmFsLCB0aW1lb3V0OiA1MDAwIH0pO1xuLy8gcmVzdWx0LnN0ZG91dCwgcmVzdWx0LnN0ZGVyciwgcmVzdWx0LmNvZGUsIHJlc3VsdC5raWxsZWRcbmBgYFxuXG4jIyMgcGkuZ2V0QWN0aXZlVG9vbHMoKSAvIHBpLmdldEFsbFRvb2xzKCkgLyBwaS5zZXRBY3RpdmVUb29scyhuYW1lcylcblxuTWFuYWdlIGFjdGl2ZSB0b29scy4gVGhpcyB3b3JrcyBmb3IgYm90aCBidWlsdC1pbiB0b29scyBhbmQgZHluYW1pY2FsbHkgcmVnaXN0ZXJlZCB0b29scy4gYHBpLmdldEFjdGl2ZVRvb2xzKClgIHJldHVybnMgdGhlIGFjdGl2ZSB0b29sIG5hbWVzIGFzIGBzdHJpbmdbXWA7IGBwaS5nZXRBbGxUb29scygpYCByZXR1cm5zIG1ldGFkYXRhIGZvciBhbGwgY29uZmlndXJlZCB0b29scy5cblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgYWN0aXZlID0gcGkuZ2V0QWN0aXZlVG9vbHMoKTsgLy8gW1wicmVhZFwiLCBcImJhc2hcIiwgLi4uXVxuY29uc3QgYWxsID0gcGkuZ2V0QWxsVG9vbHMoKTtcbi8vIGFsbCA9IFt7XG4vLyAgIG5hbWU6IFwicmVhZFwiLFxuLy8gICBkZXNjcmlwdGlvbjogXCJSZWFkIGZpbGUgY29udGVudHMuLi5cIixcbi8vICAgcGFyYW1ldGVyczogLi4uLFxuLy8gICBwcm9tcHRHdWlkZWxpbmVzOiBbXCJVc2UgcmVhZCB0byBleGFtaW5lIGZpbGVzIGluc3RlYWQgb2YgY2F0IG9yIHNlZC5cIl0sXG4vLyAgIHNvdXJjZUluZm86IHsgcGF0aDogXCI8YnVpbHRpbjpyZWFkPlwiLCBzb3VyY2U6IFwiYnVpbHRpblwiLCBzY29wZTogXCJ0ZW1wb3JhcnlcIiwgb3JpZ2luOiBcInRvcC1sZXZlbFwiIH1cbi8vIH0sIC4uLl1cbmNvbnN0IGJ1aWx0aW5Ub29scyA9IGFsbC5maWx0ZXIoKHQpID0+IHQuc291cmNlSW5mby5zb3VyY2UgPT09IFwiYnVpbHRpblwiKTtcbmNvbnN0IGV4dGVuc2lvblRvb2xzID0gYWxsLmZpbHRlcigodCkgPT4gdC5zb3VyY2VJbmZvLnNvdXJjZSAhPT0gXCJidWlsdGluXCIgJiYgdC5zb3VyY2VJbmZvLnNvdXJjZSAhPT0gXCJzZGtcIik7XG5waS5zZXRBY3RpdmVUb29scyhbLi4ubmV3IFNldChbLi4uYWN0aXZlLCBcIm15X2N1c3RvbV90b29sXCJdKV0pOyAvLyBLZWVwIGN1cnJlbnQgdG9vbHMgYW5kIGVuYWJsZSBteV9jdXN0b21fdG9vbFxucGkuc2V0QWN0aXZlVG9vbHMoW1wicmVhZFwiLCBcImJhc2hcIl0pOyAvLyBTd2l0Y2ggdG8gcmVhZC1vbmx5XG5gYGBcblxuYHBpLmdldEFsbFRvb2xzKClgIHJldHVybnMgYG5hbWVgLCBgZGVzY3JpcHRpb25gLCBgcGFyYW1ldGVyc2AsIGBwcm9tcHRHdWlkZWxpbmVzYCwgYW5kIGBzb3VyY2VJbmZvYC5cblxuVHlwaWNhbCBgc291cmNlSW5mby5zb3VyY2VgIHZhbHVlczpcbi0gYGJ1aWx0aW5gIGZvciBidWlsdC1pbiB0b29sc1xuLSBgc2RrYCBmb3IgdG9vbHMgcGFzc2VkIHZpYSBgY3JlYXRlQWdlbnRTZXNzaW9uKHsgY3VzdG9tVG9vbHMgfSlgXG4tIGV4dGVuc2lvbiBzb3VyY2UgbWV0YWRhdGEgZm9yIHRvb2xzIHJlZ2lzdGVyZWQgYnkgZXh0ZW5zaW9uc1xuXG4jIyMgcGkuc2V0TW9kZWwobW9kZWwpXG5cblNldCB0aGUgY3VycmVudCBtb2RlbC4gUmV0dXJucyBgZmFsc2VgIGlmIG5vIEFQSSBrZXkgaXMgYXZhaWxhYmxlIGZvciB0aGUgbW9kZWwuIFNlZSBbbW9kZWxzLm1kXShtb2RlbHMubWQpIGZvciBjb25maWd1cmluZyBjdXN0b20gbW9kZWxzLlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCBtb2RlbCA9IGN0eC5tb2RlbFJlZ2lzdHJ5LmZpbmQoXCJhbnRocm9waWNcIiwgXCJjbGF1ZGUtc29ubmV0LTQtNVwiKTtcbmlmIChtb2RlbCkge1xuICBjb25zdCBzdWNjZXNzID0gYXdhaXQgcGkuc2V0TW9kZWwobW9kZWwpO1xuICBpZiAoIXN1Y2Nlc3MpIHtcbiAgICBjdHgudWkubm90aWZ5KFwiTm8gQVBJIGtleSBmb3IgdGhpcyBtb2RlbFwiLCBcImVycm9yXCIpO1xuICB9XG59XG5gYGBcblxuIyMjIHBpLmdldFRoaW5raW5nTGV2ZWwoKSAvIHBpLnNldFRoaW5raW5nTGV2ZWwobGV2ZWwpXG5cbkdldCBvciBzZXQgdGhlIHRoaW5raW5nIGxldmVsLiBMZXZlbCBpcyBjbGFtcGVkIHRvIG1vZGVsIGNhcGFiaWxpdGllcyAobm9uLXJlYXNvbmluZyBtb2RlbHMgYWx3YXlzIHVzZSBcIm9mZlwiKS4gQ2hhbmdlcyBlbWl0IGB0aGlua2luZ19sZXZlbF9zZWxlY3RgLlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCBjdXJyZW50ID0gcGkuZ2V0VGhpbmtpbmdMZXZlbCgpOyAgLy8gXCJvZmZcIiB8IFwibWluaW1hbFwiIHwgXCJsb3dcIiB8IFwibWVkaXVtXCIgfCBcImhpZ2hcIiB8IFwieGhpZ2hcIlxucGkuc2V0VGhpbmtpbmdMZXZlbChcImhpZ2hcIik7XG5gYGBcblxuIyMjIHBpLmV2ZW50c1xuXG5TaGFyZWQgZXZlbnQgYnVzIGZvciBjb21tdW5pY2F0aW9uIGJldHdlZW4gZXh0ZW5zaW9uczpcblxuYGBgdHlwZXNjcmlwdFxucGkuZXZlbnRzLm9uKFwibXk6ZXZlbnRcIiwgKGRhdGEpID0+IHsgLi4uIH0pO1xucGkuZXZlbnRzLmVtaXQoXCJteTpldmVudFwiLCB7IC4uLiB9KTtcbmBgYFxuXG4jIyMgcGkucmVnaXN0ZXJQcm92aWRlcihuYW1lLCBjb25maWcpXG5cblJlZ2lzdGVyIG9yIG92ZXJyaWRlIGEgbW9kZWwgcHJvdmlkZXIgZHluYW1pY2FsbHkuIFVzZWZ1bCBmb3IgcHJveGllcywgY3VzdG9tIGVuZHBvaW50cywgb3IgdGVhbS13aWRlIG1vZGVsIGNvbmZpZ3VyYXRpb25zLlxuXG5DYWxscyBtYWRlIGR1cmluZyB0aGUgZXh0ZW5zaW9uIGZhY3RvcnkgZnVuY3Rpb24gYXJlIHF1ZXVlZCBhbmQgYXBwbGllZCBvbmNlIHRoZSBydW5uZXIgaW5pdGlhbGlzZXMuIENhbGxzIG1hZGUgYWZ0ZXIgdGhhdCDigJQgZm9yIGV4YW1wbGUgZnJvbSBhIGNvbW1hbmQgaGFuZGxlciBmb2xsb3dpbmcgYSB1c2VyIHNldHVwIGZsb3cg4oCUIHRha2UgZWZmZWN0IGltbWVkaWF0ZWx5IHdpdGhvdXQgcmVxdWlyaW5nIGEgYC9yZWxvYWRgLlxuXG5JZiB5b3UgbmVlZCB0byBkaXNjb3ZlciBtb2RlbHMgZnJvbSBhIHJlbW90ZSBlbmRwb2ludCwgcHJlZmVyIGFuIGFzeW5jIGV4dGVuc2lvbiBmYWN0b3J5IG92ZXIgZGVmZXJyaW5nIHRoZSBmZXRjaCB0byBgc2Vzc2lvbl9zdGFydGAuIHBpIHdhaXRzIGZvciB0aGUgZmFjdG9yeSBiZWZvcmUgc3RhcnR1cCBjb250aW51ZXMsIHNvIHRoZSByZWdpc3RlcmVkIG1vZGVscyBhcmUgYXZhaWxhYmxlIGltbWVkaWF0ZWx5LCBpbmNsdWRpbmcgdG8gYHBpIC0tbGlzdC1tb2RlbHNgLlxuXG5gYGB0eXBlc2NyaXB0XG4vLyBSZWdpc3RlciBhIG5ldyBwcm92aWRlciB3aXRoIGN1c3RvbSBtb2RlbHNcbnBpLnJlZ2lzdGVyUHJvdmlkZXIoXCJteS1wcm94eVwiLCB7XG4gIG5hbWU6IFwiTXkgUHJveHlcIixcbiAgYmFzZVVybDogXCJodHRwczovL3Byb3h5LmV4YW1wbGUuY29tXCIsXG4gIGFwaUtleTogXCIkUFJPWFlfQVBJX0tFWVwiLCAgLy8gZW52IHZhciByZWZlcmVuY2VcbiAgYXBpOiBcImFudGhyb3BpYy1tZXNzYWdlc1wiLFxuICBtb2RlbHM6IFtcbiAgICB7XG4gICAgICBpZDogXCJjbGF1ZGUtc29ubmV0LTQtMjAyNTA1MTRcIixcbiAgICAgIG5hbWU6IFwiQ2xhdWRlIDQgU29ubmV0IChwcm94eSlcIixcbiAgICAgIHJlYXNvbmluZzogZmFsc2UsXG4gICAgICBpbnB1dDogW1widGV4dFwiLCBcImltYWdlXCJdLFxuICAgICAgY29zdDogeyBpbnB1dDogMCwgb3V0cHV0OiAwLCBjYWNoZVJlYWQ6IDAsIGNhY2hlV3JpdGU6IDAgfSxcbiAgICAgIGNvbnRleHRXaW5kb3c6IDIwMDAwMCxcbiAgICAgIG1heFRva2VuczogMTYzODRcbiAgICB9XG4gIF1cbn0pO1xuXG4vLyBPdmVycmlkZSBiYXNlVXJsIGZvciBhbiBleGlzdGluZyBwcm92aWRlciAoa2VlcHMgYWxsIG1vZGVscylcbnBpLnJlZ2lzdGVyUHJvdmlkZXIoXCJhbnRocm9waWNcIiwge1xuICBiYXNlVXJsOiBcImh0dHBzOi8vcHJveHkuZXhhbXBsZS5jb21cIlxufSk7XG5cbi8vIFJlZ2lzdGVyIHByb3ZpZGVyIHdpdGggT0F1dGggc3VwcG9ydCBmb3IgL2xvZ2luXG5waS5yZWdpc3RlclByb3ZpZGVyKFwiY29ycG9yYXRlLWFpXCIsIHtcbiAgYmFzZVVybDogXCJodHRwczovL2FpLmNvcnAuY29tXCIsXG4gIGFwaTogXCJvcGVuYWktcmVzcG9uc2VzXCIsXG4gIG1vZGVsczogWy4uLl0sXG4gIG9hdXRoOiB7XG4gICAgbmFtZTogXCJDb3Jwb3JhdGUgQUkgKFNTTylcIixcbiAgICBhc3luYyBsb2dpbihjYWxsYmFja3MpIHtcbiAgICAgIC8vIEN1c3RvbSBPQXV0aCBmbG93XG4gICAgICBjYWxsYmFja3Mub25BdXRoKHsgdXJsOiBcImh0dHBzOi8vc3NvLmNvcnAuY29tLy4uLlwiIH0pO1xuICAgICAgY29uc3QgY29kZSA9IGF3YWl0IGNhbGxiYWNrcy5vblByb21wdCh7IG1lc3NhZ2U6IFwiRW50ZXIgY29kZTpcIiB9KTtcbiAgICAgIHJldHVybiB7IHJlZnJlc2g6IGNvZGUsIGFjY2VzczogY29kZSwgZXhwaXJlczogRGF0ZS5ub3coKSArIDM2MDAwMDAgfTtcbiAgICB9LFxuICAgIGFzeW5jIHJlZnJlc2hUb2tlbihjcmVkZW50aWFscykge1xuICAgICAgLy8gUmVmcmVzaCBsb2dpY1xuICAgICAgcmV0dXJuIGNyZWRlbnRpYWxzO1xuICAgIH0sXG4gICAgZ2V0QXBpS2V5KGNyZWRlbnRpYWxzKSB7XG4gICAgICByZXR1cm4gY3JlZGVudGlhbHMuYWNjZXNzO1xuICAgIH1cbiAgfVxufSk7XG5gYGBcblxuKipDb25maWcgb3B0aW9uczoqKlxuLSBgbmFtZWAgLSBEaXNwbGF5IG5hbWUgZm9yIHRoZSBwcm92aWRlciBpbiBVSSBzdWNoIGFzIGAvbG9naW5gLlxuLSBgYmFzZVVybGAgLSBBUEkgZW5kcG9pbnQgVVJMLiBSZXF1aXJlZCB3aGVuIGRlZmluaW5nIG1vZGVscy5cbi0gYGFwaUtleWAgLSBBUEkga2V5IGxpdGVyYWwsIGVudmlyb25tZW50IGludGVycG9sYXRpb24gKGAkRU5WX1ZBUmAgb3IgYCR7RU5WX1ZBUn1gKSwgb3IgbGVhZGluZyBgIWNvbW1hbmRgLiBSZXF1aXJlZCB3aGVuIGRlZmluaW5nIG1vZGVscyAodW5sZXNzIGBvYXV0aGAgcHJvdmlkZWQpLiBgJCRgIGVzY2FwZXMgYCRgLCBhbmQgYCQhYCBlc2NhcGVzIGEgbGl0ZXJhbCBgIWAgd2l0aG91dCB0cmlnZ2VyaW5nIGNvbW1hbmQgZXhlY3V0aW9uLlxuLSBgYXBpYCAtIEFQSSB0eXBlOiBgXCJhbnRocm9waWMtbWVzc2FnZXNcImAsIGBcIm9wZW5haS1jb21wbGV0aW9uc1wiYCwgYFwib3BlbmFpLXJlc3BvbnNlc1wiYCwgZXRjLlxuLSBgaGVhZGVyc2AgLSBDdXN0b20gaGVhZGVycyB0byBpbmNsdWRlIGluIHJlcXVlc3RzLlxuLSBgYXV0aEhlYWRlcmAgLSBJZiB0cnVlLCBhZGRzIGBBdXRob3JpemF0aW9uOiBCZWFyZXJgIGhlYWRlciBhdXRvbWF0aWNhbGx5LlxuLSBgbW9kZWxzYCAtIEFycmF5IG9mIG1vZGVsIGRlZmluaXRpb25zLiBJZiBwcm92aWRlZCwgcmVwbGFjZXMgYWxsIGV4aXN0aW5nIG1vZGVscyBmb3IgdGhpcyBwcm92aWRlci4gTW9kZWwgZGVmaW5pdGlvbnMgY2FuIHNldCBgYmFzZVVybGAgdG8gb3ZlcnJpZGUgdGhlIHByb3ZpZGVyIGVuZHBvaW50IGZvciB0aGF0IG1vZGVsLlxuLSBgb2F1dGhgIC0gT0F1dGggcHJvdmlkZXIgY29uZmlnIGZvciBgL2xvZ2luYCBzdXBwb3J0LiBXaGVuIHByb3ZpZGVkLCB0aGUgcHJvdmlkZXIgYXBwZWFycyBpbiB0aGUgbG9naW4gbWVudS5cbi0gYHN0cmVhbVNpbXBsZWAgLSBDdXN0b20gc3RyZWFtaW5nIGltcGxlbWVudGF0aW9uIGZvciBub24tc3RhbmRhcmQgQVBJcy5cblxuU2VlIFtjdXN0b20tcHJvdmlkZXIubWRdKGN1c3RvbS1wcm92aWRlci5tZCkgZm9yIGFkdmFuY2VkIHRvcGljczogY3VzdG9tIHN0cmVhbWluZyBBUElzLCBPQXV0aCBkZXRhaWxzLCBtb2RlbCBkZWZpbml0aW9uIHJlZmVyZW5jZS5cblxuIyMjIHBpLnVucmVnaXN0ZXJQcm92aWRlcihuYW1lKVxuXG5SZW1vdmUgYSBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgcHJvdmlkZXIgYW5kIGl0cyBtb2RlbHMuIEJ1aWx0LWluIG1vZGVscyB0aGF0IHdlcmUgb3ZlcnJpZGRlbiBieSB0aGUgcHJvdmlkZXIgYXJlIHJlc3RvcmVkLiBIYXMgbm8gZWZmZWN0IGlmIHRoZSBwcm92aWRlciB3YXMgbm90IHJlZ2lzdGVyZWQuXG5cbkxpa2UgYHJlZ2lzdGVyUHJvdmlkZXJgLCB0aGlzIHRha2VzIGVmZmVjdCBpbW1lZGlhdGVseSB3aGVuIGNhbGxlZCBhZnRlciB0aGUgaW5pdGlhbCBsb2FkIHBoYXNlLCBzbyBhIGAvcmVsb2FkYCBpcyBub3QgcmVxdWlyZWQuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyQ29tbWFuZChcIm15LXNldHVwLXRlYXJkb3duXCIsIHtcbiAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIHRoZSBjdXN0b20gcHJveHkgcHJvdmlkZXJcIixcbiAgaGFuZGxlcjogYXN5bmMgKF9hcmdzLCBfY3R4KSA9PiB7XG4gICAgcGkudW5yZWdpc3RlclByb3ZpZGVyKFwibXktcHJveHlcIik7XG4gIH0sXG59KTtcbmBgYFxuXG4jIyBTdGF0ZSBNYW5hZ2VtZW50XG5cbkV4dGVuc2lvbnMgd2l0aCBzdGF0ZSBzaG91bGQgc3RvcmUgaXQgaW4gdG9vbCByZXN1bHQgYGRldGFpbHNgIGZvciBwcm9wZXIgYnJhbmNoaW5nIHN1cHBvcnQ6XG5cbmBgYHR5cGVzY3JpcHRcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIGxldCBpdGVtczogc3RyaW5nW10gPSBbXTtcblxuICAvLyBSZWNvbnN0cnVjdCBzdGF0ZSBmcm9tIHNlc3Npb25cbiAgcGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGl0ZW1zID0gW107XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBjdHguc2Vzc2lvbk1hbmFnZXIuZ2V0QnJhbmNoKCkpIHtcbiAgICAgIGlmIChlbnRyeS50eXBlID09PSBcIm1lc3NhZ2VcIiAmJiBlbnRyeS5tZXNzYWdlLnJvbGUgPT09IFwidG9vbFJlc3VsdFwiKSB7XG4gICAgICAgIGlmIChlbnRyeS5tZXNzYWdlLnRvb2xOYW1lID09PSBcIm15X3Rvb2xcIikge1xuICAgICAgICAgIGl0ZW1zID0gZW50cnkubWVzc2FnZS5kZXRhaWxzPy5pdGVtcyA/PyBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcIm15X3Rvb2xcIixcbiAgICAvLyAuLi5cbiAgICBhc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgY3R4KSB7XG4gICAgICBpdGVtcy5wdXNoKFwibmV3IGl0ZW1cIik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJBZGRlZFwiIH1dLFxuICAgICAgICBkZXRhaWxzOiB7IGl0ZW1zOiBbLi4uaXRlbXNdIH0sICAvLyBTdG9yZSBmb3IgcmVjb25zdHJ1Y3Rpb25cbiAgICAgIH07XG4gICAgfSxcbiAgfSk7XG59XG5gYGBcblxuIyMgQ3VzdG9tIFRvb2xzXG5cblJlZ2lzdGVyIHRvb2xzIHRoZSBMTE0gY2FuIGNhbGwgdmlhIGBwaS5yZWdpc3RlclRvb2woKWAuIFRvb2xzIGFwcGVhciBpbiB0aGUgc3lzdGVtIHByb21wdCBhbmQgY2FuIGhhdmUgY3VzdG9tIHJlbmRlcmluZy5cblxuVXNlIGBwcm9tcHRTbmlwcGV0YCBmb3IgYSBzaG9ydCBvbmUtbGluZSBlbnRyeSBpbiB0aGUgYEF2YWlsYWJsZSB0b29sc2Agc2VjdGlvbiBpbiB0aGUgZGVmYXVsdCBzeXN0ZW0gcHJvbXB0LiBJZiBvbWl0dGVkLCBjdXN0b20gdG9vbHMgYXJlIGxlZnQgb3V0IG9mIHRoYXQgc2VjdGlvbi5cblxuVXNlIGBwcm9tcHRHdWlkZWxpbmVzYCB0byBhZGQgdG9vbC1zcGVjaWZpYyBidWxsZXRzIHRvIHRoZSBkZWZhdWx0IHN5c3RlbSBwcm9tcHQgYEd1aWRlbGluZXNgIHNlY3Rpb24uIFRoZXNlIGJ1bGxldHMgYXJlIGluY2x1ZGVkIG9ubHkgd2hpbGUgdGhlIHRvb2wgaXMgYWN0aXZlIChmb3IgZXhhbXBsZSwgYWZ0ZXIgYHBpLnNldEFjdGl2ZVRvb2xzKFsuLi5dKWApLlxuXG4qKkltcG9ydGFudDoqKiBgcHJvbXB0R3VpZGVsaW5lc2AgYnVsbGV0cyBhcmUgYXBwZW5kZWQgZmxhdCB0byB0aGUgYEd1aWRlbGluZXNgIHNlY3Rpb24gd2l0aCBubyB0b29sIG5hbWUgcHJlZml4IG9yIGdyb3VwaW5nLiBFYWNoIGd1aWRlbGluZSBtdXN0IG5hbWUgdGhlIHRvb2wgaXQgcmVmZXJzIHRvIOKAlCBhdm9pZCBcIlVzZSB0aGlzIHRvb2wgd2hlbi4uLlwiIGJlY2F1c2UgdGhlIExMTSBjYW5ub3QgdGVsbCB3aGljaCB0b29sIFwidGhpc1wiIG1lYW5zLiBXcml0ZSBcIlVzZSBteV90b29sIHdoZW4uLi5cIiBpbnN0ZWFkLlxuXG5Ob3RlOiBTb21lIG1vZGVscyBhcmUgaWRpb3RzIGFuZCBpbmNsdWRlIHRoZSBAIHByZWZpeCBpbiB0b29sIHBhdGggYXJndW1lbnRzLiBCdWlsdC1pbiB0b29scyBzdHJpcCBhIGxlYWRpbmcgQCBiZWZvcmUgcmVzb2x2aW5nIHBhdGhzLiBJZiB5b3VyIGN1c3RvbSB0b29sIGFjY2VwdHMgYSBwYXRoLCBub3JtYWxpemUgYSBsZWFkaW5nIEAgYXMgd2VsbC5cblxuSWYgeW91ciBjdXN0b20gdG9vbCBtdXRhdGVzIGZpbGVzLCB1c2UgYHdpdGhGaWxlTXV0YXRpb25RdWV1ZSgpYCBzbyBpdCBwYXJ0aWNpcGF0ZXMgaW4gdGhlIHNhbWUgcGVyLWZpbGUgcXVldWUgYXMgYnVpbHQtaW4gYGVkaXRgIGFuZCBgd3JpdGVgLiBUaGlzIG1hdHRlcnMgYmVjYXVzZSB0b29sIGNhbGxzIHJ1biBpbiBwYXJhbGxlbCBieSBkZWZhdWx0LiBXaXRob3V0IHRoZSBxdWV1ZSwgdHdvIHRvb2xzIGNhbiByZWFkIHRoZSBzYW1lIG9sZCBmaWxlIGNvbnRlbnRzLCBjb21wdXRlIGRpZmZlcmVudCB1cGRhdGVzLCBhbmQgdGhlbiB3aGljaGV2ZXIgd3JpdGUgbGFuZHMgbGFzdCBvdmVyd3JpdGVzIHRoZSBvdGhlci5cblxuRXhhbXBsZSBmYWlsdXJlIGNhc2U6IHlvdXIgY3VzdG9tIHRvb2wgZWRpdHMgYGZvby50c2Agd2hpbGUgYnVpbHQtaW4gYGVkaXRgIGFsc28gY2hhbmdlcyBgZm9vLnRzYCBpbiB0aGUgc2FtZSBhc3Npc3RhbnQgdHVybi4gSWYgeW91ciB0b29sIGRvZXMgbm90IHBhcnRpY2lwYXRlIGluIHRoZSBxdWV1ZSwgYm90aCBjYW4gcmVhZCB0aGUgb3JpZ2luYWwgYGZvby50c2AsIGFwcGx5IHNlcGFyYXRlIGNoYW5nZXMsIGFuZCBvbmUgb2YgdGhvc2UgY2hhbmdlcyBpcyBsb3N0LlxuXG5QYXNzIHRoZSByZWFsIHRhcmdldCBmaWxlIHBhdGggdG8gYHdpdGhGaWxlTXV0YXRpb25RdWV1ZSgpYCwgbm90IHRoZSByYXcgdXNlciBhcmd1bWVudC4gUmVzb2x2ZSBpdCB0byBhbiBhYnNvbHV0ZSBwYXRoIGZpcnN0LCByZWxhdGl2ZSB0byBgY3R4LmN3ZGAgb3IgeW91ciB0b29sJ3Mgd29ya2luZyBkaXJlY3RvcnkuIEZvciBleGlzdGluZyBmaWxlcywgdGhlIGhlbHBlciBjYW5vbmljYWxpemVzIHRocm91Z2ggYHJlYWxwYXRoKClgLCBzbyBzeW1saW5rIGFsaWFzZXMgZm9yIHRoZSBzYW1lIGZpbGUgc2hhcmUgb25lIHF1ZXVlLiBGb3IgbmV3IGZpbGVzLCBpdCBmYWxscyBiYWNrIHRvIHRoZSByZXNvbHZlZCBhYnNvbHV0ZSBwYXRoIGJlY2F1c2UgdGhlcmUgaXMgbm90aGluZyB0byBgcmVhbHBhdGgoKWAgeWV0LlxuXG5RdWV1ZSB0aGUgZW50aXJlIG11dGF0aW9uIHdpbmRvdyBvbiB0aGF0IHRhcmdldCBwYXRoLiBUaGF0IGluY2x1ZGVzIHJlYWQtbW9kaWZ5LXdyaXRlIGxvZ2ljLCBub3QganVzdCB0aGUgZmluYWwgd3JpdGUuXG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IHdpdGhGaWxlTXV0YXRpb25RdWV1ZSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBta2RpciwgcmVhZEZpbGUsIHdyaXRlRmlsZSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgeyBkaXJuYW1lLCByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5hc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gIGNvbnN0IGFic29sdXRlUGF0aCA9IHJlc29sdmUoY3R4LmN3ZCwgcGFyYW1zLnBhdGgpO1xuXG4gIHJldHVybiB3aXRoRmlsZU11dGF0aW9uUXVldWUoYWJzb2x1dGVQYXRoLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgbWtkaXIoZGlybmFtZShhYnNvbHV0ZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgcmVhZEZpbGUoYWJzb2x1dGVQYXRoLCBcInV0ZjhcIik7XG4gICAgY29uc3QgbmV4dCA9IGN1cnJlbnQucmVwbGFjZShwYXJhbXMub2xkVGV4dCwgcGFyYW1zLm5ld1RleHQpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShhYnNvbHV0ZVBhdGgsIG5leHQsIFwidXRmOFwiKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogYFVwZGF0ZWQgJHtwYXJhbXMucGF0aH1gIH1dLFxuICAgICAgZGV0YWlsczoge30sXG4gICAgfTtcbiAgfSk7XG59XG5gYGBcblxuIyMjIFRvb2wgRGVmaW5pdGlvblxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcbmltcG9ydCB7IFN0cmluZ0VudW0gfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWFpXCI7XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxucGkucmVnaXN0ZXJUb29sKHtcbiAgbmFtZTogXCJteV90b29sXCIsXG4gIGxhYmVsOiBcIk15IFRvb2xcIixcbiAgZGVzY3JpcHRpb246IFwiV2hhdCB0aGlzIHRvb2wgZG9lcyAoc2hvd24gdG8gTExNKVwiLFxuICBwcm9tcHRTbmlwcGV0OiBcIkxpc3Qgb3IgYWRkIGl0ZW1zIGluIHRoZSBwcm9qZWN0IHRvZG8gbGlzdFwiLFxuICBwcm9tcHRHdWlkZWxpbmVzOiBbXG4gICAgXCJVc2UgbXlfdG9vbCBmb3IgdG9kbyBwbGFubmluZyBpbnN0ZWFkIG9mIGRpcmVjdCBmaWxlIGVkaXRzIHdoZW4gdGhlIHVzZXIgYXNrcyBmb3IgYSB0YXNrIGxpc3QuXCJcbiAgXSxcbiAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgIGFjdGlvbjogU3RyaW5nRW51bShbXCJsaXN0XCIsIFwiYWRkXCJdIGFzIGNvbnN0KSwgIC8vIFVzZSBTdHJpbmdFbnVtIGZvciBHb29nbGUgY29tcGF0aWJpbGl0eVxuICAgIHRleHQ6IFR5cGUuT3B0aW9uYWwoVHlwZS5TdHJpbmcoKSksXG4gIH0pLFxuICBwcmVwYXJlQXJndW1lbnRzKGFyZ3MpIHtcbiAgICBpZiAoIWFyZ3MgfHwgdHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIpIHJldHVybiBhcmdzO1xuICAgIGNvbnN0IGlucHV0ID0gYXJncyBhcyB7IGFjdGlvbj86IHN0cmluZzsgb2xkQWN0aW9uPzogc3RyaW5nIH07XG4gICAgaWYgKHR5cGVvZiBpbnB1dC5vbGRBY3Rpb24gPT09IFwic3RyaW5nXCIgJiYgaW5wdXQuYWN0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB7IC4uLmlucHV0LCBhY3Rpb246IGlucHV0Lm9sZEFjdGlvbiB9O1xuICAgIH1cbiAgICByZXR1cm4gYXJncztcbiAgfSxcblxuICBhc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgY3R4KSB7XG4gICAgLy8gQ2hlY2sgZm9yIGNhbmNlbGxhdGlvblxuICAgIGlmIChzaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgIHJldHVybiB7IGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIkNhbmNlbGxlZFwiIH1dIH07XG4gICAgfVxuXG4gICAgLy8gU3RyZWFtIHByb2dyZXNzIHVwZGF0ZXNcbiAgICBvblVwZGF0ZT8uKHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIldvcmtpbmcuLi5cIiB9XSxcbiAgICAgIGRldGFpbHM6IHsgcHJvZ3Jlc3M6IDUwIH0sXG4gICAgfSk7XG5cbiAgICAvLyBSdW4gY29tbWFuZHMgdmlhIHBpLmV4ZWMgKGNhcHR1cmVkIGZyb20gZXh0ZW5zaW9uIGNsb3N1cmUpXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcInNvbWUtY29tbWFuZFwiLCBbXSwgeyBzaWduYWwgfSk7XG5cbiAgICAvLyBSZXR1cm4gcmVzdWx0XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIkRvbmVcIiB9XSwgIC8vIFNlbnQgdG8gTExNXG4gICAgICBkZXRhaWxzOiB7IGRhdGE6IHJlc3VsdCB9LCAgICAgICAgICAgICAgICAgICAvLyBGb3IgcmVuZGVyaW5nICYgc3RhdGVcbiAgICAgIC8vIE9wdGlvbmFsOiBzdG9wIGFmdGVyIHRoaXMgdG9vbCBiYXRjaCB3aGVuIGV2ZXJ5IGZpbmFsaXplZCB0b29sIHJlc3VsdFxuICAgICAgLy8gaW4gdGhlIGJhdGNoIGFsc28gcmV0dXJucyB0ZXJtaW5hdGU6IHRydWUuXG4gICAgICB0ZXJtaW5hdGU6IHRydWUsXG4gICAgfTtcbiAgfSxcblxuICAvLyBPcHRpb25hbDogQ3VzdG9tIHJlbmRlcmluZ1xuICByZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBjb250ZXh0KSB7IC4uLiB9LFxuICByZW5kZXJSZXN1bHQocmVzdWx0LCBvcHRpb25zLCB0aGVtZSwgY29udGV4dCkgeyAuLi4gfSxcbn0pO1xuYGBgXG5cbioqU2lnbmFsaW5nIGVycm9yczoqKiBUbyBtYXJrIGEgdG9vbCBleGVjdXRpb24gYXMgZmFpbGVkIChzZXRzIGBpc0Vycm9yOiB0cnVlYCBvbiB0aGUgcmVzdWx0IGFuZCByZXBvcnRzIGl0IHRvIHRoZSBMTE0pLCB0aHJvdyBhbiBlcnJvciBmcm9tIGBleGVjdXRlYC4gUmV0dXJuaW5nIGEgdmFsdWUgbmV2ZXIgc2V0cyB0aGUgZXJyb3IgZmxhZyByZWdhcmRsZXNzIG9mIHdoYXQgcHJvcGVydGllcyB5b3UgaW5jbHVkZSBpbiB0aGUgcmV0dXJuIG9iamVjdC5cblxuKipFYXJseSB0ZXJtaW5hdGlvbjoqKiBSZXR1cm4gYHRlcm1pbmF0ZTogdHJ1ZWAgZnJvbSBgZXhlY3V0ZSgpYCB0byBoaW50IHRoYXQgdGhlIGF1dG9tYXRpYyBmb2xsb3ctdXAgTExNIGNhbGwgc2hvdWxkIGJlIHNraXBwZWQgYWZ0ZXIgdGhlIGN1cnJlbnQgdG9vbCBiYXRjaC4gVGhpcyBvbmx5IHRha2VzIGVmZmVjdCB3aGVuIGV2ZXJ5IGZpbmFsaXplZCB0b29sIHJlc3VsdCBpbiB0aGF0IGJhdGNoIGlzIHRlcm1pbmF0aW5nLiBTZWUgW2V4YW1wbGVzL2V4dGVuc2lvbnMvc3RydWN0dXJlZC1vdXRwdXQudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvc3RydWN0dXJlZC1vdXRwdXQudHMpIGZvciBhIG1pbmltYWwgZXhhbXBsZSB3aGVyZSB0aGUgYWdlbnQgZW5kcyBvbiBhIGZpbmFsIHN0cnVjdHVyZWQtb3V0cHV0IHRvb2wgY2FsbC5cblxuYGBgdHlwZXNjcmlwdFxuLy8gQ29ycmVjdDogdGhyb3cgdG8gc2lnbmFsIGFuIGVycm9yXG5hc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcykge1xuICBpZiAoIWlzVmFsaWQocGFyYW1zLmlucHV0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbnB1dDogJHtwYXJhbXMuaW5wdXR9YCk7XG4gIH1cbiAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiT0tcIiB9XSwgZGV0YWlsczoge30gfTtcbn1cbmBgYFxuXG4qKkltcG9ydGFudDoqKiBVc2UgYFN0cmluZ0VudW1gIGZyb20gYEBlYXJlbmRpbC13b3Jrcy9waS1haWAgZm9yIHN0cmluZyBlbnVtcy4gYFR5cGUuVW5pb25gL2BUeXBlLkxpdGVyYWxgIGRvZXNuJ3Qgd29yayB3aXRoIEdvb2dsZSdzIEFQSS5cblxuKipBcmd1bWVudCBwcmVwYXJhdGlvbjoqKiBgcHJlcGFyZUFyZ3VtZW50cyhhcmdzKWAgaXMgb3B0aW9uYWwuIElmIGRlZmluZWQsIGl0IHJ1bnMgYmVmb3JlIHNjaGVtYSB2YWxpZGF0aW9uIGFuZCBiZWZvcmUgYGV4ZWN1dGUoKWAuIFVzZSBpdCB0byBtaW1pYyBhbiBvbGRlciBhY2NlcHRlZCBpbnB1dCBzaGFwZSB3aGVuIHBpIHJlc3VtZXMgYW4gb2xkZXIgc2Vzc2lvbiB3aG9zZSBzdG9yZWQgdG9vbCBjYWxsIGFyZ3VtZW50cyBubyBsb25nZXIgbWF0Y2ggdGhlIGN1cnJlbnQgc2NoZW1hLiBSZXR1cm4gdGhlIG9iamVjdCB5b3Ugd2FudCB2YWxpZGF0ZWQgYWdhaW5zdCBgcGFyYW1ldGVyc2AuIEtlZXAgdGhlIHB1YmxpYyBzY2hlbWEgc3RyaWN0LiBEbyBub3QgYWRkIGRlcHJlY2F0ZWQgY29tcGF0aWJpbGl0eSBmaWVsZHMgdG8gYHBhcmFtZXRlcnNgIGp1c3QgdG8ga2VlcCBvbGQgcmVzdW1lZCBzZXNzaW9ucyB3b3JraW5nLlxuXG5FeGFtcGxlOiBhbiBvbGRlciBzZXNzaW9uIG1heSBjb250YWluIGFuIGBlZGl0YCB0b29sIGNhbGwgd2l0aCB0b3AtbGV2ZWwgYG9sZFRleHRgIGFuZCBgbmV3VGV4dGAsIHdoaWxlIHRoZSBjdXJyZW50IHNjaGVtYSBvbmx5IGFjY2VwdHMgYGVkaXRzOiBbeyBvbGRUZXh0LCBuZXdUZXh0IH1dYC5cblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJUb29sKHtcbiAgbmFtZTogXCJlZGl0XCIsXG4gIGxhYmVsOiBcIkVkaXRcIixcbiAgZGVzY3JpcHRpb246IFwiRWRpdCBhIHNpbmdsZSBmaWxlIHVzaW5nIGV4YWN0IHRleHQgcmVwbGFjZW1lbnRcIixcbiAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgIHBhdGg6IFR5cGUuU3RyaW5nKCksXG4gICAgZWRpdHM6IFR5cGUuQXJyYXkoXG4gICAgICBUeXBlLk9iamVjdCh7XG4gICAgICAgIG9sZFRleHQ6IFR5cGUuU3RyaW5nKCksXG4gICAgICAgIG5ld1RleHQ6IFR5cGUuU3RyaW5nKCksXG4gICAgICB9KSxcbiAgICApLFxuICB9KSxcbiAgcHJlcGFyZUFyZ3VtZW50cyhhcmdzKSB7XG4gICAgaWYgKCFhcmdzIHx8IHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiKSByZXR1cm4gYXJncztcblxuICAgIGNvbnN0IGlucHV0ID0gYXJncyBhcyB7XG4gICAgICBwYXRoPzogc3RyaW5nO1xuICAgICAgZWRpdHM/OiBBcnJheTx7IG9sZFRleHQ6IHN0cmluZzsgbmV3VGV4dDogc3RyaW5nIH0+O1xuICAgICAgb2xkVGV4dD86IHVua25vd247XG4gICAgICBuZXdUZXh0PzogdW5rbm93bjtcbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBpbnB1dC5vbGRUZXh0ICE9PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBpbnB1dC5uZXdUZXh0ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gYXJncztcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uaW5wdXQsXG4gICAgICBlZGl0czogWy4uLihpbnB1dC5lZGl0cyA/PyBbXSksIHsgb2xkVGV4dDogaW5wdXQub2xkVGV4dCwgbmV3VGV4dDogaW5wdXQubmV3VGV4dCB9XSxcbiAgICB9O1xuICB9LFxuICBhc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgY3R4KSB7XG4gICAgLy8gcGFyYW1zIG5vdyBtYXRjaGVzIHRoZSBjdXJyZW50IHNjaGVtYVxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogYEFwcGx5aW5nICR7cGFyYW1zLmVkaXRzLmxlbmd0aH0gZWRpdCBibG9jayhzKWAgfV0sXG4gICAgICBkZXRhaWxzOiB7fSxcbiAgICB9O1xuICB9LFxufSk7XG5gYGBcblxuIyMjIE92ZXJyaWRpbmcgQnVpbHQtaW4gVG9vbHNcblxuRXh0ZW5zaW9ucyBjYW4gb3ZlcnJpZGUgYnVpbHQtaW4gdG9vbHMgKGByZWFkYCwgYGJhc2hgLCBgZWRpdGAsIGB3cml0ZWAsIGBncmVwYCwgYGZpbmRgLCBgbHNgKSBieSByZWdpc3RlcmluZyBhIHRvb2wgd2l0aCB0aGUgc2FtZSBuYW1lLiBJbnRlcmFjdGl2ZSBtb2RlIGRpc3BsYXlzIGEgd2FybmluZyB3aGVuIHRoaXMgaGFwcGVucy5cblxuYGBgYmFzaFxuIyBFeHRlbnNpb24ncyByZWFkIHRvb2wgcmVwbGFjZXMgYnVpbHQtaW4gcmVhZFxucGkgLWUgLi90b29sLW92ZXJyaWRlLnRzXG5gYGBcblxuQWx0ZXJuYXRpdmVseSwgdXNlIGAtLW5vLWJ1aWx0aW4tdG9vbHNgIHRvIHN0YXJ0IHdpdGhvdXQgYW55IGJ1aWx0LWluIHRvb2xzIHdoaWxlIGtlZXBpbmcgZXh0ZW5zaW9uIHRvb2xzIGVuYWJsZWQ6XG5gYGBiYXNoXG4jIE5vIGJ1aWx0LWluIHRvb2xzLCBvbmx5IGV4dGVuc2lvbiB0b29sc1xucGkgLS1uby1idWlsdGluLXRvb2xzIC1lIC4vbXktZXh0ZW5zaW9uLnRzXG5gYGBcblxuU2VlIFtleGFtcGxlcy9leHRlbnNpb25zL3Rvb2wtb3ZlcnJpZGUudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvdG9vbC1vdmVycmlkZS50cykgZm9yIGEgY29tcGxldGUgZXhhbXBsZSB0aGF0IG92ZXJyaWRlcyBgcmVhZGAgd2l0aCBsb2dnaW5nIGFuZCBhY2Nlc3MgY29udHJvbC5cblxuKipSZW5kZXJpbmc6KiogQnVpbHQtaW4gcmVuZGVyZXIgaW5oZXJpdGFuY2UgaXMgcmVzb2x2ZWQgcGVyIHNsb3QuIEV4ZWN1dGlvbiBvdmVycmlkZSBhbmQgcmVuZGVyaW5nIG92ZXJyaWRlIGFyZSBpbmRlcGVuZGVudC4gSWYgeW91ciBvdmVycmlkZSBvbWl0cyBgcmVuZGVyQ2FsbGAsIHRoZSBidWlsdC1pbiBgcmVuZGVyQ2FsbGAgaXMgdXNlZC4gSWYgeW91ciBvdmVycmlkZSBvbWl0cyBgcmVuZGVyUmVzdWx0YCwgdGhlIGJ1aWx0LWluIGByZW5kZXJSZXN1bHRgIGlzIHVzZWQuIElmIHlvdXIgb3ZlcnJpZGUgb21pdHMgYm90aCwgdGhlIGJ1aWx0LWluIHJlbmRlcmVyIGlzIHVzZWQgYXV0b21hdGljYWxseSAoc3ludGF4IGhpZ2hsaWdodGluZywgZGlmZnMsIGV0Yy4pLiBUaGlzIGxldHMgeW91IHdyYXAgYnVpbHQtaW4gdG9vbHMgZm9yIGxvZ2dpbmcgb3IgYWNjZXNzIGNvbnRyb2wgd2l0aG91dCByZWltcGxlbWVudGluZyB0aGUgVUkuXG5cbioqUHJvbXB0IG1ldGFkYXRhOioqIGBwcm9tcHRTbmlwcGV0YCBhbmQgYHByb21wdEd1aWRlbGluZXNgIGFyZSBub3QgaW5oZXJpdGVkIGZyb20gdGhlIGJ1aWx0LWluIHRvb2wuIElmIHlvdXIgb3ZlcnJpZGUgc2hvdWxkIGtlZXAgdGhvc2UgcHJvbXB0IGluc3RydWN0aW9ucywgZGVmaW5lIHRoZW0gb24gdGhlIG92ZXJyaWRlIGV4cGxpY2l0bHkuXG5cbioqWW91ciBpbXBsZW1lbnRhdGlvbiBtdXN0IG1hdGNoIHRoZSBleGFjdCByZXN1bHQgc2hhcGUqKiwgaW5jbHVkaW5nIHRoZSBgZGV0YWlsc2AgdHlwZS4gVGhlIFVJIGFuZCBzZXNzaW9uIGxvZ2ljIGRlcGVuZCBvbiB0aGVzZSBzaGFwZXMgZm9yIHJlbmRlcmluZyBhbmQgc3RhdGUgdHJhY2tpbmcuXG5cbkJ1aWx0LWluIHRvb2wgaW1wbGVtZW50YXRpb25zOlxuLSBbcmVhZC50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvY29yZS90b29scy9yZWFkLnRzKSAtIGBSZWFkVG9vbERldGFpbHNgXG4tIFtiYXNoLnRzXShodHRwczovL2dpdGh1Yi5jb20vZWFyZW5kaWwtd29ya3MvcGktbW9uby9ibG9iL21haW4vcGFja2FnZXMvY29kaW5nLWFnZW50L3NyYy9jb3JlL3Rvb2xzL2Jhc2gudHMpIC0gYEJhc2hUb29sRGV0YWlsc2Bcbi0gW2VkaXQudHNdKGh0dHBzOi8vZ2l0aHViLmNvbS9lYXJlbmRpbC13b3Jrcy9waS1tb25vL2Jsb2IvbWFpbi9wYWNrYWdlcy9jb2RpbmctYWdlbnQvc3JjL2NvcmUvdG9vbHMvZWRpdC50cylcbi0gW3dyaXRlLnRzXShodHRwczovL2dpdGh1Yi5jb20vZWFyZW5kaWwtd29ya3MvcGktbW9uby9ibG9iL21haW4vcGFja2FnZXMvY29kaW5nLWFnZW50L3NyYy9jb3JlL3Rvb2xzL3dyaXRlLnRzKVxuLSBbZ3JlcC50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvY29yZS90b29scy9ncmVwLnRzKSAtIGBHcmVwVG9vbERldGFpbHNgXG4tIFtmaW5kLnRzXShodHRwczovL2dpdGh1Yi5jb20vZWFyZW5kaWwtd29ya3MvcGktbW9uby9ibG9iL21haW4vcGFja2FnZXMvY29kaW5nLWFnZW50L3NyYy9jb3JlL3Rvb2xzL2ZpbmQudHMpIC0gYEZpbmRUb29sRGV0YWlsc2Bcbi0gW2xzLnRzXShodHRwczovL2dpdGh1Yi5jb20vZWFyZW5kaWwtd29ya3MvcGktbW9uby9ibG9iL21haW4vcGFja2FnZXMvY29kaW5nLWFnZW50L3NyYy9jb3JlL3Rvb2xzL2xzLnRzKSAtIGBMc1Rvb2xEZXRhaWxzYFxuXG4jIyMgUmVtb3RlIEV4ZWN1dGlvblxuXG5CdWlsdC1pbiB0b29scyBzdXBwb3J0IHBsdWdnYWJsZSBvcGVyYXRpb25zIGZvciBkZWxlZ2F0aW5nIHRvIHJlbW90ZSBzeXN0ZW1zIChTU0gsIGNvbnRhaW5lcnMsIGV0Yy4pOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBjcmVhdGVSZWFkVG9vbCwgY3JlYXRlQmFzaFRvb2wsIHR5cGUgUmVhZE9wZXJhdGlvbnMgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG4vLyBDcmVhdGUgdG9vbCB3aXRoIGN1c3RvbSBvcGVyYXRpb25zXG5jb25zdCByZW1vdGVSZWFkID0gY3JlYXRlUmVhZFRvb2woY3dkLCB7XG4gIG9wZXJhdGlvbnM6IHtcbiAgICByZWFkRmlsZTogKHBhdGgpID0+IHNzaEV4ZWMocmVtb3RlLCBgY2F0ICR7cGF0aH1gKSxcbiAgICBhY2Nlc3M6IChwYXRoKSA9PiBzc2hFeGVjKHJlbW90ZSwgYHRlc3QgLXIgJHtwYXRofWApLnRoZW4oKCkgPT4ge30pLFxuICB9XG59KTtcblxuLy8gUmVnaXN0ZXIsIGNoZWNraW5nIGZsYWcgYXQgZXhlY3V0aW9uIHRpbWVcbnBpLnJlZ2lzdGVyVG9vbCh7XG4gIC4uLnJlbW90ZVJlYWQsXG4gIGFzeW5jIGV4ZWN1dGUoaWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgX2N0eCkge1xuICAgIGNvbnN0IHNzaCA9IGdldFNzaENvbmZpZygpO1xuICAgIGlmIChzc2gpIHtcbiAgICAgIGNvbnN0IHRvb2wgPSBjcmVhdGVSZWFkVG9vbChjd2QsIHsgb3BlcmF0aW9uczogY3JlYXRlUmVtb3RlT3BzKHNzaCkgfSk7XG4gICAgICByZXR1cm4gdG9vbC5leGVjdXRlKGlkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUpO1xuICAgIH1cbiAgICByZXR1cm4gbG9jYWxSZWFkLmV4ZWN1dGUoaWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSk7XG4gIH0sXG59KTtcbmBgYFxuXG4qKk9wZXJhdGlvbnMgaW50ZXJmYWNlczoqKiBgUmVhZE9wZXJhdGlvbnNgLCBgV3JpdGVPcGVyYXRpb25zYCwgYEVkaXRPcGVyYXRpb25zYCwgYEJhc2hPcGVyYXRpb25zYCwgYExzT3BlcmF0aW9uc2AsIGBHcmVwT3BlcmF0aW9uc2AsIGBGaW5kT3BlcmF0aW9uc2BcblxuRm9yIGB1c2VyX2Jhc2hgLCBleHRlbnNpb25zIGNhbiByZXVzZSBwaSdzIGxvY2FsIHNoZWxsIGJhY2tlbmQgdmlhIGBjcmVhdGVMb2NhbEJhc2hPcGVyYXRpb25zKClgIGluc3RlYWQgb2YgcmVpbXBsZW1lbnRpbmcgbG9jYWwgcHJvY2VzcyBzcGF3bmluZywgc2hlbGwgcmVzb2x1dGlvbiwgYW5kIHByb2Nlc3MtdHJlZSB0ZXJtaW5hdGlvbi5cblxuVGhlIGJhc2ggdG9vbCBhbHNvIHN1cHBvcnRzIGEgc3Bhd24gaG9vayB0byBhZGp1c3QgdGhlIGNvbW1hbmQsIGN3ZCwgb3IgZW52IGJlZm9yZSBleGVjdXRpb246XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IGNyZWF0ZUJhc2hUb29sIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxuY29uc3QgYmFzaFRvb2wgPSBjcmVhdGVCYXNoVG9vbChjd2QsIHtcbiAgc3Bhd25Ib29rOiAoeyBjb21tYW5kLCBjd2QsIGVudiB9KSA9PiAoe1xuICAgIGNvbW1hbmQ6IGBzb3VyY2Ugfi8ucHJvZmlsZVxcbiR7Y29tbWFuZH1gLFxuICAgIGN3ZDogYC9tbnQvc2FuZGJveCR7Y3dkfWAsXG4gICAgZW52OiB7IC4uLmVudiwgQ0k6IFwiMVwiIH0sXG4gIH0pLFxufSk7XG5gYGBcblxuU2VlIFtleGFtcGxlcy9leHRlbnNpb25zL3NzaC50c10oLi4vZXhhbXBsZXMvZXh0ZW5zaW9ucy9zc2gudHMpIGZvciBhIGNvbXBsZXRlIFNTSCBleGFtcGxlIHdpdGggYC0tc3NoYCBmbGFnLlxuXG4jIyMgT3V0cHV0IFRydW5jYXRpb25cblxuKipUb29scyBNVVNUIHRydW5jYXRlIHRoZWlyIG91dHB1dCoqIHRvIGF2b2lkIG92ZXJ3aGVsbWluZyB0aGUgTExNIGNvbnRleHQuIExhcmdlIG91dHB1dHMgY2FuIGNhdXNlOlxuLSBDb250ZXh0IG92ZXJmbG93IGVycm9ycyAocHJvbXB0IHRvbyBsb25nKVxuLSBDb21wYWN0aW9uIGZhaWx1cmVzXG4tIERlZ3JhZGVkIG1vZGVsIHBlcmZvcm1hbmNlXG5cblRoZSBidWlsdC1pbiBsaW1pdCBpcyAqKjUwS0IqKiAofjEwayB0b2tlbnMpIGFuZCAqKjIwMDAgbGluZXMqKiwgd2hpY2hldmVyIGlzIGhpdCBmaXJzdC4gVXNlIHRoZSBleHBvcnRlZCB0cnVuY2F0aW9uIHV0aWxpdGllczpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHtcbiAgdHJ1bmNhdGVIZWFkLCAgICAgIC8vIEtlZXAgZmlyc3QgTiBsaW5lcy9ieXRlcyAoZ29vZCBmb3IgZmlsZSByZWFkcywgc2VhcmNoIHJlc3VsdHMpXG4gIHRydW5jYXRlVGFpbCwgICAgICAvLyBLZWVwIGxhc3QgTiBsaW5lcy9ieXRlcyAoZ29vZCBmb3IgbG9ncywgY29tbWFuZCBvdXRwdXQpXG4gIHRydW5jYXRlTGluZSwgICAgICAvLyBUcnVuY2F0ZSBhIHNpbmdsZSBsaW5lIHRvIG1heEJ5dGVzIHdpdGggZWxsaXBzaXNcbiAgZm9ybWF0U2l6ZSwgICAgICAgIC8vIEh1bWFuLXJlYWRhYmxlIHNpemUgKGUuZy4sIFwiNTBLQlwiLCBcIjEuNU1CXCIpXG4gIERFRkFVTFRfTUFYX0JZVEVTLCAvLyA1MEtCXG4gIERFRkFVTFRfTUFYX0xJTkVTLCAvLyAyMDAwXG59IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbmFzeW5jIGV4ZWN1dGUodG9vbENhbGxJZCwgcGFyYW1zLCBzaWduYWwsIG9uVXBkYXRlLCBjdHgpIHtcbiAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgcnVuQ29tbWFuZCgpO1xuXG4gIC8vIEFwcGx5IHRydW5jYXRpb25cbiAgY29uc3QgdHJ1bmNhdGlvbiA9IHRydW5jYXRlSGVhZChvdXRwdXQsIHtcbiAgICBtYXhMaW5lczogREVGQVVMVF9NQVhfTElORVMsXG4gICAgbWF4Qnl0ZXM6IERFRkFVTFRfTUFYX0JZVEVTLFxuICB9KTtcblxuICBsZXQgcmVzdWx0ID0gdHJ1bmNhdGlvbi5jb250ZW50O1xuXG4gIGlmICh0cnVuY2F0aW9uLnRydW5jYXRlZCkge1xuICAgIC8vIFdyaXRlIGZ1bGwgb3V0cHV0IHRvIHRlbXAgZmlsZVxuICAgIGNvbnN0IHRlbXBGaWxlID0gd3JpdGVUZW1wRmlsZShvdXRwdXQpO1xuXG4gICAgLy8gSW5mb3JtIHRoZSBMTE0gd2hlcmUgdG8gZmluZCBjb21wbGV0ZSBvdXRwdXRcbiAgICByZXN1bHQgKz0gYFxcblxcbltPdXRwdXQgdHJ1bmNhdGVkOiAke3RydW5jYXRpb24ub3V0cHV0TGluZXN9IG9mICR7dHJ1bmNhdGlvbi50b3RhbExpbmVzfSBsaW5lc2A7XG4gICAgcmVzdWx0ICs9IGAgKCR7Zm9ybWF0U2l6ZSh0cnVuY2F0aW9uLm91dHB1dEJ5dGVzKX0gb2YgJHtmb3JtYXRTaXplKHRydW5jYXRpb24udG90YWxCeXRlcyl9KS5gO1xuICAgIHJlc3VsdCArPSBgIEZ1bGwgb3V0cHV0IHNhdmVkIHRvOiAke3RlbXBGaWxlfV1gO1xuICB9XG5cbiAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IHJlc3VsdCB9XSB9O1xufVxuYGBgXG5cbioqS2V5IHBvaW50czoqKlxuLSBVc2UgYHRydW5jYXRlSGVhZGAgZm9yIGNvbnRlbnQgd2hlcmUgdGhlIGJlZ2lubmluZyBtYXR0ZXJzIChzZWFyY2ggcmVzdWx0cywgZmlsZSByZWFkcylcbi0gVXNlIGB0cnVuY2F0ZVRhaWxgIGZvciBjb250ZW50IHdoZXJlIHRoZSBlbmQgbWF0dGVycyAobG9ncywgY29tbWFuZCBvdXRwdXQpXG4tIEFsd2F5cyBpbmZvcm0gdGhlIExMTSB3aGVuIG91dHB1dCBpcyB0cnVuY2F0ZWQgYW5kIHdoZXJlIHRvIGZpbmQgdGhlIGZ1bGwgdmVyc2lvblxuLSBEb2N1bWVudCB0aGUgdHJ1bmNhdGlvbiBsaW1pdHMgaW4geW91ciB0b29sJ3MgZGVzY3JpcHRpb25cblxuU2VlIFtleGFtcGxlcy9leHRlbnNpb25zL3RydW5jYXRlZC10b29sLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL3RydW5jYXRlZC10b29sLnRzKSBmb3IgYSBjb21wbGV0ZSBleGFtcGxlIHdyYXBwaW5nIGByZ2AgKHJpcGdyZXApIHdpdGggcHJvcGVyIHRydW5jYXRpb24uXG5cbiMjIyBNdWx0aXBsZSBUb29sc1xuXG5PbmUgZXh0ZW5zaW9uIGNhbiByZWdpc3RlciBtdWx0aXBsZSB0b29scyB3aXRoIHNoYXJlZCBzdGF0ZTpcblxuYGBgdHlwZXNjcmlwdFxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBpOiBFeHRlbnNpb25BUEkpIHtcbiAgbGV0IGNvbm5lY3Rpb24gPSBudWxsO1xuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7IG5hbWU6IFwiZGJfY29ubmVjdFwiLCAuLi4gfSk7XG4gIHBpLnJlZ2lzdGVyVG9vbCh7IG5hbWU6IFwiZGJfcXVlcnlcIiwgLi4uIH0pO1xuICBwaS5yZWdpc3RlclRvb2woeyBuYW1lOiBcImRiX2Nsb3NlXCIsIC4uLiB9KTtcblxuICBwaS5vbihcInNlc3Npb25fc2h1dGRvd25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbm5lY3Rpb24/LmNsb3NlKCk7XG4gIH0pO1xufVxuYGBgXG5cbiMjIyBDdXN0b20gUmVuZGVyaW5nXG5cblRvb2xzIGNhbiBwcm92aWRlIGByZW5kZXJDYWxsYCBhbmQgYHJlbmRlclJlc3VsdGAgZm9yIGN1c3RvbSBUVUkgZGlzcGxheS4gU2VlIFt0dWkubWRdKHR1aS5tZCkgZm9yIHRoZSBmdWxsIGNvbXBvbmVudCBBUEkgYW5kIFt0b29sLWV4ZWN1dGlvbi50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvbW9kZXMvaW50ZXJhY3RpdmUvY29tcG9uZW50cy90b29sLWV4ZWN1dGlvbi50cykgZm9yIGhvdyB0b29sIHJvd3MgYXJlIGNvbXBvc2VkLlxuXG5CeSBkZWZhdWx0LCB0b29sIG91dHB1dCBpcyB3cmFwcGVkIGluIGEgYEJveGAgdGhhdCBoYW5kbGVzIHBhZGRpbmcgYW5kIGJhY2tncm91bmQuIEEgZGVmaW5lZCBgcmVuZGVyQ2FsbGAgb3IgYHJlbmRlclJlc3VsdGAgbXVzdCByZXR1cm4gYSBgQ29tcG9uZW50YC4gSWYgYSBzbG90IHJlbmRlcmVyIGlzIG5vdCBkZWZpbmVkLCBgdG9vbC1leGVjdXRpb24udHNgIHVzZXMgZmFsbGJhY2sgcmVuZGVyaW5nIGZvciB0aGF0IHNsb3QuXG5cblNldCBgcmVuZGVyU2hlbGw6IFwic2VsZlwiYCB3aGVuIHRoZSB0b29sIHNob3VsZCByZW5kZXIgaXRzIG93biBzaGVsbCBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBkZWZhdWx0IGBCb3hgLiBUaGlzIGlzIHVzZWZ1bCBmb3IgdG9vbHMgdGhhdCBuZWVkIGNvbXBsZXRlIGNvbnRyb2wgb3ZlciBmcmFtaW5nIG9yIGJhY2tncm91bmQgYmVoYXZpb3IsIGZvciBleGFtcGxlIGxhcmdlIHByZXZpZXdzIHRoYXQgbXVzdCBzdGF5IHZpc3VhbGx5IHN0YWJsZSBhZnRlciB0aGUgdG9vbCBzZXR0bGVzLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5yZWdpc3RlclRvb2woe1xuICBuYW1lOiBcIm15X3Rvb2xcIixcbiAgbGFiZWw6IFwiTXkgVG9vbFwiLFxuICBkZXNjcmlwdGlvbjogXCJDdXN0b20gc2hlbGwgZXhhbXBsZVwiLFxuICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gIHJlbmRlclNoZWxsOiBcInNlbGZcIixcbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICByZXR1cm4geyBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJva1wiIH1dLCBkZXRhaWxzOiB1bmRlZmluZWQgfTtcbiAgfSxcbiAgcmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgY29udGV4dCkge1xuICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcImFjY2VudFwiLCBcIm15IGN1c3RvbSBzaGVsbFwiKSwgMCwgMCk7XG4gIH0sXG59KTtcbmBgYFxuXG5gcmVuZGVyQ2FsbGAgYW5kIGByZW5kZXJSZXN1bHRgIGVhY2ggcmVjZWl2ZSBhIGBjb250ZXh0YCBvYmplY3Qgd2l0aDpcbi0gYGFyZ3NgIC0gdGhlIGN1cnJlbnQgdG9vbCBjYWxsIGFyZ3VtZW50c1xuLSBgc3RhdGVgIC0gc2hhcmVkIHJvdy1sb2NhbCBzdGF0ZSBhY3Jvc3MgYHJlbmRlckNhbGxgIGFuZCBgcmVuZGVyUmVzdWx0YFxuLSBgbGFzdENvbXBvbmVudGAgLSB0aGUgcHJldmlvdXNseSByZXR1cm5lZCBjb21wb25lbnQgZm9yIHRoYXQgc2xvdCwgaWYgYW55XG4tIGBpbnZhbGlkYXRlKClgIC0gcmVxdWVzdCBhIHJlcmVuZGVyIG9mIHRoaXMgdG9vbCByb3dcbi0gYHRvb2xDYWxsSWRgLCBgY3dkYCwgYGV4ZWN1dGlvblN0YXJ0ZWRgLCBgYXJnc0NvbXBsZXRlYCwgYGlzUGFydGlhbGAsIGBleHBhbmRlZGAsIGBzaG93SW1hZ2VzYCwgYGlzRXJyb3JgXG5cblVzZSBgY29udGV4dC5zdGF0ZWAgZm9yIGNyb3NzLXNsb3Qgc2hhcmVkIHN0YXRlLiBLZWVwIHNsb3QtbG9jYWwgY2FjaGVzIG9uIHRoZSByZXR1cm5lZCBjb21wb25lbnQgaW5zdGFuY2Ugd2hlbiB5b3Ugd2FudCB0byByZXVzZSBhbmQgbXV0YXRlIHRoZSBzYW1lIGNvbXBvbmVudCBhY3Jvc3MgcmVuZGVycy5cblxuIyMjIyByZW5kZXJDYWxsXG5cblJlbmRlcnMgdGhlIHRvb2wgY2FsbCBvciBoZWFkZXI6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuXG5yZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBjb250ZXh0KSB7XG4gIGNvbnN0IHRleHQgPSAoY29udGV4dC5sYXN0Q29tcG9uZW50IGFzIFRleHQgfCB1bmRlZmluZWQpID8/IG5ldyBUZXh0KFwiXCIsIDAsIDApO1xuICBsZXQgY29udGVudCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJteV90b29sIFwiKSk7XG4gIGNvbnRlbnQgKz0gdGhlbWUuZmcoXCJtdXRlZFwiLCBhcmdzLmFjdGlvbik7XG4gIGlmIChhcmdzLnRleHQpIHtcbiAgICBjb250ZW50ICs9IFwiIFwiICsgdGhlbWUuZmcoXCJkaW1cIiwgYFwiJHthcmdzLnRleHR9XCJgKTtcbiAgfVxuICB0ZXh0LnNldFRleHQoY29udGVudCk7XG4gIHJldHVybiB0ZXh0O1xufVxuYGBgXG5cbiMjIyMgcmVuZGVyUmVzdWx0XG5cblJlbmRlcnMgdGhlIHRvb2wgcmVzdWx0IG9yIG91dHB1dDpcblxuYGBgdHlwZXNjcmlwdFxucmVuZGVyUmVzdWx0KHJlc3VsdCwgeyBleHBhbmRlZCwgaXNQYXJ0aWFsIH0sIHRoZW1lLCBjb250ZXh0KSB7XG4gIGlmIChpc1BhcnRpYWwpIHtcbiAgICByZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJ3YXJuaW5nXCIsIFwiUHJvY2Vzc2luZy4uLlwiKSwgMCwgMCk7XG4gIH1cblxuICBpZiAocmVzdWx0LmRldGFpbHM/LmVycm9yKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwiZXJyb3JcIiwgYEVycm9yOiAke3Jlc3VsdC5kZXRhaWxzLmVycm9yfWApLCAwLCAwKTtcbiAgfVxuXG4gIGxldCB0ZXh0ID0gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIFwi4pyTIERvbmVcIik7XG4gIGlmIChleHBhbmRlZCAmJiByZXN1bHQuZGV0YWlscz8uaXRlbXMpIHtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgcmVzdWx0LmRldGFpbHMuaXRlbXMpIHtcbiAgICAgIHRleHQgKz0gXCJcXG4gIFwiICsgdGhlbWUuZmcoXCJkaW1cIiwgaXRlbSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbn1cbmBgYFxuXG5JZiBhIHNsb3QgaW50ZW50aW9uYWxseSBoYXMgbm8gdmlzaWJsZSBjb250ZW50LCByZXR1cm4gYW4gZW1wdHkgYENvbXBvbmVudGAgc3VjaCBhcyBhbiBlbXB0eSBgQ29udGFpbmVyYC5cblxuIyMjIyBLZXliaW5kaW5nIEhpbnRzXG5cblVzZSBga2V5SGludCgpYCB0byBkaXNwbGF5IGtleWJpbmRpbmcgaGludHMgdGhhdCByZXNwZWN0IHRoZSBhY3RpdmUga2V5YmluZGluZyBjb25maWd1cmF0aW9uOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBrZXlIaW50IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxucmVuZGVyUmVzdWx0KHJlc3VsdCwgeyBleHBhbmRlZCB9LCB0aGVtZSwgY29udGV4dCkge1xuICBsZXQgdGV4dCA9IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKckyBEb25lXCIpO1xuICBpZiAoIWV4cGFuZGVkKSB7XG4gICAgdGV4dCArPSBgICgke2tleUhpbnQoXCJhcHAudG9vbHMuZXhwYW5kXCIsIFwidG8gZXhwYW5kXCIpfSlgO1xuICB9XG4gIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbn1cbmBgYFxuXG5BdmFpbGFibGUgZnVuY3Rpb25zOlxuLSBga2V5SGludChrZXliaW5kaW5nLCBkZXNjcmlwdGlvbilgIC0gRm9ybWF0cyBhIGNvbmZpZ3VyZWQga2V5YmluZGluZyBpZCBzdWNoIGFzIGBcImFwcC50b29scy5leHBhbmRcImAgb3IgYFwidHVpLnNlbGVjdC5jb25maXJtXCJgXG4tIGBrZXlUZXh0KGtleWJpbmRpbmcpYCAtIFJldHVybnMgdGhlIHJhdyBjb25maWd1cmVkIGtleSB0ZXh0IGZvciBhIGtleWJpbmRpbmcgaWRcbi0gYHJhd0tleUhpbnQoa2V5LCBkZXNjcmlwdGlvbilgIC0gRm9ybWF0IGEgcmF3IGtleSBzdHJpbmdcblxuVXNlIG5hbWVzcGFjZWQga2V5YmluZGluZyBpZHM6XG4tIENvZGluZy1hZ2VudCBpZHMgdXNlIHRoZSBgYXBwLipgIG5hbWVzcGFjZSwgZm9yIGV4YW1wbGUgYGFwcC50b29scy5leHBhbmRgLCBgYXBwLmVkaXRvci5leHRlcm5hbGAsIGBhcHAuc2Vzc2lvbi5yZW5hbWVgXG4tIFNoYXJlZCBUVUkgaWRzIHVzZSB0aGUgYHR1aS4qYCBuYW1lc3BhY2UsIGZvciBleGFtcGxlIGB0dWkuc2VsZWN0LmNvbmZpcm1gLCBgdHVpLnNlbGVjdC5jYW5jZWxgLCBgdHVpLmlucHV0LnRhYmBcblxuRm9yIHRoZSBleGhhdXN0aXZlIGxpc3Qgb2Yga2V5YmluZGluZyBpZHMgYW5kIGRlZmF1bHRzLCBzZWUgW2tleWJpbmRpbmdzLm1kXShrZXliaW5kaW5ncy5tZCkuIGBrZXliaW5kaW5ncy5qc29uYCB1c2VzIHRob3NlIHNhbWUgbmFtZXNwYWNlZCBpZHMuXG5cbkN1c3RvbSBlZGl0b3JzIGFuZCBgY3R4LnVpLmN1c3RvbSgpYCBjb21wb25lbnRzIHJlY2VpdmUgYGtleWJpbmRpbmdzOiBLZXliaW5kaW5nc01hbmFnZXJgIGFzIGFuIGluamVjdGVkIGFyZ3VtZW50LiBUaGV5IHNob3VsZCB1c2UgdGhhdCBpbmplY3RlZCBtYW5hZ2VyIGRpcmVjdGx5IGluc3RlYWQgb2YgY2FsbGluZyBgZ2V0S2V5YmluZGluZ3MoKWAgb3IgYHNldEtleWJpbmRpbmdzKClgLlxuXG4jIyMjIEJlc3QgUHJhY3RpY2VzXG5cbi0gVXNlIGBUZXh0YCB3aXRoIHBhZGRpbmcgYCgwLCAwKWAuIFRoZSBkZWZhdWx0IEJveCBoYW5kbGVzIHBhZGRpbmcuXG4tIFVzZSBgXFxuYCBmb3IgbXVsdGktbGluZSBjb250ZW50LlxuLSBIYW5kbGUgYGlzUGFydGlhbGAgZm9yIHN0cmVhbWluZyBwcm9ncmVzcy5cbi0gU3VwcG9ydCBgZXhwYW5kZWRgIGZvciBkZXRhaWwgb24gZGVtYW5kLlxuLSBLZWVwIGRlZmF1bHQgdmlldyBjb21wYWN0LlxuLSBSZWFkIGBjb250ZXh0LmFyZ3NgIGluIGByZW5kZXJSZXN1bHRgIGluc3RlYWQgb2YgY29weWluZyBhcmdzIGludG8gYGNvbnRleHQuc3RhdGVgLlxuLSBVc2UgYGNvbnRleHQuc3RhdGVgIG9ubHkgZm9yIGRhdGEgdGhhdCBtdXN0IGJlIHNoYXJlZCBhY3Jvc3MgY2FsbCBhbmQgcmVzdWx0IHNsb3RzLlxuLSBSZXVzZSBgY29udGV4dC5sYXN0Q29tcG9uZW50YCB3aGVuIHRoZSBzYW1lIGNvbXBvbmVudCBpbnN0YW5jZSBjYW4gYmUgdXBkYXRlZCBpbiBwbGFjZS5cbi0gVXNlIGByZW5kZXJTaGVsbDogXCJzZWxmXCJgIG9ubHkgd2hlbiB0aGUgZGVmYXVsdCBib3hlZCBzaGVsbCBnZXRzIGluIHRoZSB3YXkuIEluIHNlbGYtc2hlbGwgbW9kZSB0aGUgdG9vbCBpcyByZXNwb25zaWJsZSBmb3IgaXRzIG93biBmcmFtaW5nLCBwYWRkaW5nLCBhbmQgYmFja2dyb3VuZC5cblxuIyMjIyBGYWxsYmFja1xuXG5JZiBhIHNsb3QgcmVuZGVyZXIgaXMgbm90IGRlZmluZWQgb3IgdGhyb3dzOlxuLSBgcmVuZGVyQ2FsbGA6IFNob3dzIHRoZSB0b29sIG5hbWVcbi0gYHJlbmRlclJlc3VsdGA6IFNob3dzIHJhdyB0ZXh0IGZyb20gYGNvbnRlbnRgXG5cbiMjIEN1c3RvbSBVSVxuXG5FeHRlbnNpb25zIGNhbiBpbnRlcmFjdCB3aXRoIHVzZXJzIHZpYSBgY3R4LnVpYCBtZXRob2RzIGFuZCBjdXN0b21pemUgaG93IG1lc3NhZ2VzL3Rvb2xzIHJlbmRlci5cblxuKipGb3IgY3VzdG9tIGNvbXBvbmVudHMsIHNlZSBbdHVpLm1kXSh0dWkubWQpKiogd2hpY2ggaGFzIGNvcHktcGFzdGUgcGF0dGVybnMgZm9yOlxuLSBTZWxlY3Rpb24gZGlhbG9ncyAoU2VsZWN0TGlzdClcbi0gQXN5bmMgb3BlcmF0aW9ucyB3aXRoIGNhbmNlbCAoQm9yZGVyZWRMb2FkZXIpXG4tIFNldHRpbmdzIHRvZ2dsZXMgKFNldHRpbmdzTGlzdClcbi0gU3RhdHVzIGluZGljYXRvcnMgKHNldFN0YXR1cylcbi0gV29ya2luZyBtZXNzYWdlLCB2aXNpYmlsaXR5LCBhbmQgaW5kaWNhdG9yIGR1cmluZyBzdHJlYW1pbmcgKGBzZXRXb3JraW5nTWVzc2FnZWAsIGBzZXRXb3JraW5nVmlzaWJsZWAsIGBzZXRXb3JraW5nSW5kaWNhdG9yYClcbi0gV2lkZ2V0cyBhYm92ZS9iZWxvdyBlZGl0b3IgKHNldFdpZGdldClcbi0gQXV0b2NvbXBsZXRlIHByb3ZpZGVycyBsYXllcmVkIG9uIHRvcCBvZiBidWlsdC1pbiBzbGFzaC9wYXRoIGNvbXBsZXRpb24gKGFkZEF1dG9jb21wbGV0ZVByb3ZpZGVyKVxuLSBDdXN0b20gZm9vdGVycyAoc2V0Rm9vdGVyKVxuXG4jIyMgRGlhbG9nc1xuXG5gYGB0eXBlc2NyaXB0XG4vLyBTZWxlY3QgZnJvbSBvcHRpb25zXG5jb25zdCBjaG9pY2UgPSBhd2FpdCBjdHgudWkuc2VsZWN0KFwiUGljayBvbmU6XCIsIFtcIkFcIiwgXCJCXCIsIFwiQ1wiXSk7XG5cbi8vIENvbmZpcm0gZGlhbG9nXG5jb25zdCBvayA9IGF3YWl0IGN0eC51aS5jb25maXJtKFwiRGVsZXRlP1wiLCBcIlRoaXMgY2Fubm90IGJlIHVuZG9uZVwiKTtcblxuLy8gVGV4dCBpbnB1dFxuY29uc3QgbmFtZSA9IGF3YWl0IGN0eC51aS5pbnB1dChcIk5hbWU6XCIsIFwicGxhY2Vob2xkZXJcIik7XG5cbi8vIE11bHRpLWxpbmUgZWRpdG9yXG5jb25zdCB0ZXh0ID0gYXdhaXQgY3R4LnVpLmVkaXRvcihcIkVkaXQ6XCIsIFwicHJlZmlsbGVkIHRleHRcIik7XG5cbi8vIE5vdGlmaWNhdGlvbiAobm9uLWJsb2NraW5nKVxuY3R4LnVpLm5vdGlmeShcIkRvbmUhXCIsIFwiaW5mb1wiKTsgIC8vIFwiaW5mb1wiIHwgXCJ3YXJuaW5nXCIgfCBcImVycm9yXCJcbmBgYFxuXG4jIyMjIFRpbWVkIERpYWxvZ3Mgd2l0aCBDb3VudGRvd25cblxuRGlhbG9ncyBzdXBwb3J0IGEgYHRpbWVvdXRgIG9wdGlvbiB0aGF0IGF1dG8tZGlzbWlzc2VzIHdpdGggYSBsaXZlIGNvdW50ZG93biBkaXNwbGF5OlxuXG5gYGB0eXBlc2NyaXB0XG4vLyBEaWFsb2cgc2hvd3MgXCJUaXRsZSAoNXMpXCIg4oaSIFwiVGl0bGUgKDRzKVwiIOKGkiAuLi4g4oaSIGF1dG8tZGlzbWlzc2VzIGF0IDBcbmNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IGN0eC51aS5jb25maXJtKFxuICBcIlRpbWVkIENvbmZpcm1hdGlvblwiLFxuICBcIlRoaXMgZGlhbG9nIHdpbGwgYXV0by1jYW5jZWwgaW4gNSBzZWNvbmRzLiBDb25maXJtP1wiLFxuICB7IHRpbWVvdXQ6IDUwMDAgfVxuKTtcblxuaWYgKGNvbmZpcm1lZCkge1xuICAvLyBVc2VyIGNvbmZpcm1lZFxufSBlbHNlIHtcbiAgLy8gVXNlciBjYW5jZWxsZWQgb3IgdGltZWQgb3V0XG59XG5gYGBcblxuKipSZXR1cm4gdmFsdWVzIG9uIHRpbWVvdXQ6Kipcbi0gYHNlbGVjdCgpYCByZXR1cm5zIGB1bmRlZmluZWRgXG4tIGBjb25maXJtKClgIHJldHVybnMgYGZhbHNlYFxuLSBgaW5wdXQoKWAgcmV0dXJucyBgdW5kZWZpbmVkYFxuXG4jIyMjIE1hbnVhbCBEaXNtaXNzYWwgd2l0aCBBYm9ydFNpZ25hbFxuXG5Gb3IgbW9yZSBjb250cm9sIChlLmcuLCB0byBkaXN0aW5ndWlzaCB0aW1lb3V0IGZyb20gdXNlciBjYW5jZWwpLCB1c2UgYEFib3J0U2lnbmFsYDpcblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbmNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCA1MDAwKTtcblxuY29uc3QgY29uZmlybWVkID0gYXdhaXQgY3R4LnVpLmNvbmZpcm0oXG4gIFwiVGltZWQgQ29uZmlybWF0aW9uXCIsXG4gIFwiVGhpcyBkaWFsb2cgd2lsbCBhdXRvLWNhbmNlbCBpbiA1IHNlY29uZHMuIENvbmZpcm0/XCIsXG4gIHsgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCB9XG4pO1xuXG5jbGVhclRpbWVvdXQodGltZW91dElkKTtcblxuaWYgKGNvbmZpcm1lZCkge1xuICAvLyBVc2VyIGNvbmZpcm1lZFxufSBlbHNlIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSB7XG4gIC8vIERpYWxvZyB0aW1lZCBvdXRcbn0gZWxzZSB7XG4gIC8vIFVzZXIgY2FuY2VsbGVkIChwcmVzc2VkIEVzY2FwZSBvciBzZWxlY3RlZCBcIk5vXCIpXG59XG5gYGBcblxuU2VlIFtleGFtcGxlcy9leHRlbnNpb25zL3RpbWVkLWNvbmZpcm0udHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvdGltZWQtY29uZmlybS50cykgZm9yIGNvbXBsZXRlIGV4YW1wbGVzLlxuXG4jIyMgV2lkZ2V0cywgU3RhdHVzLCBhbmQgRm9vdGVyXG5cbmBgYHR5cGVzY3JpcHRcbi8vIFN0YXR1cyBpbiBmb290ZXIgKHBlcnNpc3RlbnQgdW50aWwgY2xlYXJlZClcbmN0eC51aS5zZXRTdGF0dXMoXCJteS1leHRcIiwgXCJQcm9jZXNzaW5nLi4uXCIpO1xuY3R4LnVpLnNldFN0YXR1cyhcIm15LWV4dFwiLCB1bmRlZmluZWQpOyAgLy8gQ2xlYXJcblxuLy8gV29ya2luZyBsb2FkZXIgKHNob3duIGR1cmluZyBzdHJlYW1pbmcpXG5jdHgudWkuc2V0V29ya2luZ01lc3NhZ2UoXCJUaGlua2luZyBkZWVwbHkuLi5cIik7XG5jdHgudWkuc2V0V29ya2luZ01lc3NhZ2UoKTsgIC8vIFJlc3RvcmUgZGVmYXVsdFxuY3R4LnVpLnNldFdvcmtpbmdWaXNpYmxlKGZhbHNlKTsgIC8vIEhpZGUgdGhlIGJ1aWx0LWluIHdvcmtpbmcgbG9hZGVyIHJvdyBlbnRpcmVseVxuY3R4LnVpLnNldFdvcmtpbmdWaXNpYmxlKHRydWUpOyAgIC8vIFNob3cgdGhlIGJ1aWx0LWluIHdvcmtpbmcgbG9hZGVyIHJvd1xuXG4vLyBXb3JraW5nIGluZGljYXRvciAoc2hvd24gZHVyaW5nIHN0cmVhbWluZylcbmN0eC51aS5zZXRXb3JraW5nSW5kaWNhdG9yKHsgZnJhbWVzOiBbY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIFwi4pePXCIpXSB9KTsgIC8vIFN0YXRpYyBkb3RcbmN0eC51aS5zZXRXb3JraW5nSW5kaWNhdG9yKHtcbiAgZnJhbWVzOiBbXG4gICAgY3R4LnVpLnRoZW1lLmZnKFwiZGltXCIsIFwiwrdcIiksXG4gICAgY3R4LnVpLnRoZW1lLmZnKFwibXV0ZWRcIiwgXCLigKJcIiksXG4gICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIFwi4pePXCIpLFxuICAgIGN0eC51aS50aGVtZS5mZyhcIm11dGVkXCIsIFwi4oCiXCIpLFxuICBdLFxuICBpbnRlcnZhbE1zOiAxMjAsXG59KTtcbmN0eC51aS5zZXRXb3JraW5nSW5kaWNhdG9yKHsgZnJhbWVzOiBbXSB9KTsgIC8vIEhpZGUgaW5kaWNhdG9yXG5jdHgudWkuc2V0V29ya2luZ0luZGljYXRvcigpOyAgLy8gUmVzdG9yZSBkZWZhdWx0IHNwaW5uZXJcblxuLy8gV2lkZ2V0IGFib3ZlIGVkaXRvciAoZGVmYXVsdClcbmN0eC51aS5zZXRXaWRnZXQoXCJteS13aWRnZXRcIiwgW1wiTGluZSAxXCIsIFwiTGluZSAyXCJdKTtcbi8vIFdpZGdldCBiZWxvdyBlZGl0b3JcbmN0eC51aS5zZXRXaWRnZXQoXCJteS13aWRnZXRcIiwgW1wiTGluZSAxXCIsIFwiTGluZSAyXCJdLCB7IHBsYWNlbWVudDogXCJiZWxvd0VkaXRvclwiIH0pO1xuY3R4LnVpLnNldFdpZGdldChcIm15LXdpZGdldFwiLCAodHVpLCB0aGVtZSkgPT4gbmV3IFRleHQodGhlbWUuZmcoXCJhY2NlbnRcIiwgXCJDdXN0b21cIiksIDAsIDApKTtcbmN0eC51aS5zZXRXaWRnZXQoXCJteS13aWRnZXRcIiwgdW5kZWZpbmVkKTsgIC8vIENsZWFyXG5cbi8vIEN1c3RvbSBmb290ZXIgKHJlcGxhY2VzIGJ1aWx0LWluIGZvb3RlciBlbnRpcmVseSlcbmN0eC51aS5zZXRGb290ZXIoKHR1aSwgdGhlbWUpID0+ICh7XG4gIHJlbmRlcih3aWR0aCkgeyByZXR1cm4gW3RoZW1lLmZnKFwiZGltXCIsIFwiQ3VzdG9tIGZvb3RlclwiKV07IH0sXG4gIGludmFsaWRhdGUoKSB7fSxcbn0pKTtcbmN0eC51aS5zZXRGb290ZXIodW5kZWZpbmVkKTsgIC8vIFJlc3RvcmUgYnVpbHQtaW4gZm9vdGVyXG5cbi8vIFRlcm1pbmFsIHRpdGxlXG5jdHgudWkuc2V0VGl0bGUoXCJwaSAtIG15LXByb2plY3RcIik7XG5cbi8vIEVkaXRvciB0ZXh0XG5jdHgudWkuc2V0RWRpdG9yVGV4dChcIlByZWZpbGwgdGV4dFwiKTtcbmNvbnN0IGN1cnJlbnQgPSBjdHgudWkuZ2V0RWRpdG9yVGV4dCgpO1xuXG4vLyBQYXN0ZSBpbnRvIGVkaXRvciAodHJpZ2dlcnMgcGFzdGUgaGFuZGxpbmcsIGluY2x1ZGluZyBjb2xsYXBzZSBmb3IgbGFyZ2UgY29udGVudClcbmN0eC51aS5wYXN0ZVRvRWRpdG9yKFwicGFzdGVkIGNvbnRlbnRcIik7XG5cbi8vIFN0YWNrIGN1c3RvbSBhdXRvY29tcGxldGUgYmVoYXZpb3Igb24gdG9wIG9mIHRoZSBidWlsdC1pbiBwcm92aWRlclxuY3R4LnVpLmFkZEF1dG9jb21wbGV0ZVByb3ZpZGVyKChjdXJyZW50KSA9PiAoe1xuICB0cmlnZ2VyQ2hhcmFjdGVyczogW1wiI1wiXSxcbiAgYXN5bmMgZ2V0U3VnZ2VzdGlvbnMobGluZXMsIGxpbmUsIGNvbCwgb3B0aW9ucykge1xuICAgIGNvbnN0IGJlZm9yZUN1cnNvciA9IChsaW5lc1tsaW5lXSA/PyBcIlwiKS5zbGljZSgwLCBjb2wpO1xuICAgIGNvbnN0IG1hdGNoID0gYmVmb3JlQ3Vyc29yLm1hdGNoKC8oPzpefFsgXFx0XSkjKFteXFxzI10qKSQvKTtcbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICByZXR1cm4gY3VycmVudC5nZXRTdWdnZXN0aW9ucyhsaW5lcywgbGluZSwgY29sLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJlZml4OiBgIyR7bWF0Y2hbMV0gPz8gXCJcIn1gLFxuICAgICAgaXRlbXM6IFt7IHZhbHVlOiBcIiMyOTgzXCIsIGxhYmVsOiBcIiMyOTgzXCIsIGRlc2NyaXB0aW9uOiBcIkV4dGVuc2lvbiBBUEkgZm9yIGF1dG9jb21wbGV0ZVwiIH1dLFxuICAgIH07XG4gIH0sXG4gIGFwcGx5Q29tcGxldGlvbihsaW5lcywgbGluZSwgY29sLCBpdGVtLCBwcmVmaXgpIHtcbiAgICByZXR1cm4gY3VycmVudC5hcHBseUNvbXBsZXRpb24obGluZXMsIGxpbmUsIGNvbCwgaXRlbSwgcHJlZml4KTtcbiAgfSxcbiAgc2hvdWxkVHJpZ2dlckZpbGVDb21wbGV0aW9uKGxpbmVzLCBsaW5lLCBjb2wpIHtcbiAgICByZXR1cm4gY3VycmVudC5zaG91bGRUcmlnZ2VyRmlsZUNvbXBsZXRpb24/LihsaW5lcywgbGluZSwgY29sKSA/PyB0cnVlO1xuICB9LFxufSkpO1xuXG4vLyBUb29sIG91dHB1dCBleHBhbnNpb25cbmNvbnN0IHdhc0V4cGFuZGVkID0gY3R4LnVpLmdldFRvb2xzRXhwYW5kZWQoKTtcbmN0eC51aS5zZXRUb29sc0V4cGFuZGVkKHRydWUpO1xuY3R4LnVpLnNldFRvb2xzRXhwYW5kZWQod2FzRXhwYW5kZWQpO1xuXG4vLyBDdXN0b20gZWRpdG9yICh2aW0gbW9kZSwgZW1hY3MgbW9kZSwgZXRjLilcbmN0eC51aS5zZXRFZGl0b3JDb21wb25lbnQoKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzKSA9PiBuZXcgVmltRWRpdG9yKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzKSk7XG5jb25zdCBjdXJyZW50RWRpdG9yID0gY3R4LnVpLmdldEVkaXRvckNvbXBvbmVudCgpO1xuY3R4LnVpLnNldEVkaXRvckNvbXBvbmVudCgodHVpLCB0aGVtZSwga2V5YmluZGluZ3MpID0+XG4gIG5ldyBXcmFwcGVkRWRpdG9yKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzLCBjdXJyZW50RWRpdG9yPy4odHVpLCB0aGVtZSwga2V5YmluZGluZ3MpKVxuKTtcbmN0eC51aS5zZXRFZGl0b3JDb21wb25lbnQodW5kZWZpbmVkKTsgIC8vIFJlc3RvcmUgZGVmYXVsdCBlZGl0b3JcblxuLy8gVGhlbWUgbWFuYWdlbWVudCAoc2VlIHRoZW1lcy5tZCBmb3IgY3JlYXRpbmcgdGhlbWVzKVxuY29uc3QgdGhlbWVzID0gY3R4LnVpLmdldEFsbFRoZW1lcygpOyAgLy8gW3sgbmFtZTogXCJkYXJrXCIsIHBhdGg6IFwiLy4uLlwiIHwgdW5kZWZpbmVkIH0sIC4uLl1cbmNvbnN0IGxpZ2h0VGhlbWUgPSBjdHgudWkuZ2V0VGhlbWUoXCJsaWdodFwiKTsgIC8vIExvYWQgd2l0aG91dCBzd2l0Y2hpbmdcbmNvbnN0IHJlc3VsdCA9IGN0eC51aS5zZXRUaGVtZShcImxpZ2h0XCIpOyAgLy8gU3dpdGNoIGJ5IG5hbWVcbmlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgY3R4LnVpLm5vdGlmeShgRmFpbGVkOiAke3Jlc3VsdC5lcnJvcn1gLCBcImVycm9yXCIpO1xufVxuY3R4LnVpLnNldFRoZW1lKGxpZ2h0VGhlbWUhKTsgIC8vIE9yIHN3aXRjaCBieSBUaGVtZSBvYmplY3RcbmN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBcInN0eWxlZCB0ZXh0XCIpOyAgLy8gQWNjZXNzIGN1cnJlbnQgdGhlbWVcbmBgYFxuXG5DdXN0b20gd29ya2luZy1pbmRpY2F0b3IgZnJhbWVzIGFyZSByZW5kZXJlZCB2ZXJiYXRpbS4gSWYgeW91IHdhbnQgY29sb3JzLCBhZGQgdGhlbSB0byB0aGUgZnJhbWUgc3RyaW5ncyB5b3Vyc2VsZiwgZm9yIGV4YW1wbGUgd2l0aCBgY3R4LnVpLnRoZW1lLmZnKC4uLilgLlxuXG4jIyMgQXV0b2NvbXBsZXRlIFByb3ZpZGVyc1xuXG5Vc2UgYGN0eC51aS5hZGRBdXRvY29tcGxldGVQcm92aWRlcigpYCB0byBzdGFjayBjdXN0b20gYXV0b2NvbXBsZXRlIGxvZ2ljIG9uIHRvcCBvZiB0aGUgYnVpbHQtaW4gc2xhc2gtY29tbWFuZCBhbmQgcGF0aCBwcm92aWRlci4gU2V0IGB0cmlnZ2VyQ2hhcmFjdGVyc2AgZm9yIGN1c3RvbSBuYXR1cmFsIHRyaWdnZXJzIHN1Y2ggYXMgYCRgLlxuXG5UeXBpY2FsIHBhdHRlcm46XG5cbi0gaW5zcGVjdCB0aGUgdGV4dCBiZWZvcmUgdGhlIGN1cnNvclxuLSByZXR1cm4geW91ciBvd24gc3VnZ2VzdGlvbnMgd2hlbiB5b3VyIGV4dGVuc2lvbi1zcGVjaWZpYyBzeW50YXggbWF0Y2hlc1xuLSBvdGhlcndpc2UgZGVsZWdhdGUgdG8gYGN1cnJlbnQuZ2V0U3VnZ2VzdGlvbnMoLi4uKWBcbi0gZGVsZWdhdGUgYGFwcGx5Q29tcGxldGlvbiguLi4pYCB1bmxlc3MgeW91IG5lZWQgY3VzdG9tIGluc2VydGlvbiBiZWhhdmlvclxuXG5gYGB0eXBlc2NyaXB0XG5waS5vbihcInNlc3Npb25fc3RhcnRcIiwgKF9ldmVudCwgY3R4KSA9PiB7XG4gIGN0eC51aS5hZGRBdXRvY29tcGxldGVQcm92aWRlcigoY3VycmVudCkgPT4gKHtcbiAgICB0cmlnZ2VyQ2hhcmFjdGVyczogW1wiI1wiXSxcbiAgICBhc3luYyBnZXRTdWdnZXN0aW9ucyhsaW5lcywgY3Vyc29yTGluZSwgY3Vyc29yQ29sLCBvcHRpb25zKSB7XG4gICAgICBjb25zdCBsaW5lID0gbGluZXNbY3Vyc29yTGluZV0gPz8gXCJcIjtcbiAgICAgIGNvbnN0IGJlZm9yZUN1cnNvciA9IGxpbmUuc2xpY2UoMCwgY3Vyc29yQ29sKTtcbiAgICAgIGNvbnN0IG1hdGNoID0gYmVmb3JlQ3Vyc29yLm1hdGNoKC8oPzpefFsgXFx0XSkjKFteXFxzI10qKSQvKTtcbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQuZ2V0U3VnZ2VzdGlvbnMobGluZXMsIGN1cnNvckxpbmUsIGN1cnNvckNvbCwgb3B0aW9ucyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByZWZpeDogYCMke21hdGNoWzFdID8/IFwiXCJ9YCxcbiAgICAgICAgaXRlbXM6IFtcbiAgICAgICAgICB7IHZhbHVlOiBcIiMyOTgzXCIsIGxhYmVsOiBcIiMyOTgzXCIsIGRlc2NyaXB0aW9uOiBcIkV4dGVuc2lvbiBBUEkgZm9yIHJlZ2lzdGVyaW5nIGN1c3RvbSBAIGF1dG9jb21wbGV0ZSBwcm92aWRlcnNcIiB9LFxuICAgICAgICAgIHsgdmFsdWU6IFwiIzI3NTNcIiwgbGFiZWw6IFwiIzI3NTNcIiwgZGVzY3JpcHRpb246IFwiUmVsb2FkIHN0YWxlIHJlc291cmNlIHNldHRpbmdzXCIgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIGFwcGx5Q29tcGxldGlvbihsaW5lcywgY3Vyc29yTGluZSwgY3Vyc29yQ29sLCBpdGVtLCBwcmVmaXgpIHtcbiAgICAgIHJldHVybiBjdXJyZW50LmFwcGx5Q29tcGxldGlvbihsaW5lcywgY3Vyc29yTGluZSwgY3Vyc29yQ29sLCBpdGVtLCBwcmVmaXgpO1xuICAgIH0sXG5cbiAgICBzaG91bGRUcmlnZ2VyRmlsZUNvbXBsZXRpb24obGluZXMsIGN1cnNvckxpbmUsIGN1cnNvckNvbCkge1xuICAgICAgcmV0dXJuIGN1cnJlbnQuc2hvdWxkVHJpZ2dlckZpbGVDb21wbGV0aW9uPy4obGluZXMsIGN1cnNvckxpbmUsIGN1cnNvckNvbCkgPz8gdHJ1ZTtcbiAgICB9LFxuICB9KSk7XG59KTtcbmBgYFxuXG5TZWUgW2dpdGh1Yi1pc3N1ZS1hdXRvY29tcGxldGUudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvZ2l0aHViLWlzc3VlLWF1dG9jb21wbGV0ZS50cykgZm9yIGEgY29tcGxldGUgZXhhbXBsZSB0aGF0IHByZWxvYWRzIHRoZSBsYXRlc3Qgb3BlbiBHaXRIdWIgaXNzdWVzIHdpdGggYGdoIGlzc3VlIGxpc3RgIGFuZCBmaWx0ZXJzIHRoZW0gbG9jYWxseSBmb3IgZmFzdCBgIy4uLmAgY29tcGxldGlvbi4gSXQgcmVxdWlyZXMgR2l0SHViIENMSSAoYGdoYCkgYW5kIGEgR2l0SHViIHJlcG9zaXRvcnkgY2hlY2tvdXQuXG5cbiMjIyBDdXN0b20gQ29tcG9uZW50c1xuXG5Gb3IgY29tcGxleCBVSSwgdXNlIGBjdHgudWkuY3VzdG9tKClgLiBUaGlzIHRlbXBvcmFyaWx5IHJlcGxhY2VzIHRoZSBlZGl0b3Igd2l0aCB5b3VyIGNvbXBvbmVudCB1bnRpbCBgZG9uZSgpYCBpcyBjYWxsZWQ6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IFRleHQsIENvbXBvbmVudCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5cbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC51aS5jdXN0b208Ym9vbGVhbj4oKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzLCBkb25lKSA9PiB7XG4gIGNvbnN0IHRleHQgPSBuZXcgVGV4dChcIlByZXNzIEVudGVyIHRvIGNvbmZpcm0sIEVzY2FwZSB0byBjYW5jZWxcIiwgMSwgMSk7XG5cbiAgdGV4dC5vbktleSA9IChrZXkpID0+IHtcbiAgICBpZiAoa2V5ID09PSBcInJldHVyblwiKSBkb25lKHRydWUpO1xuICAgIGlmIChrZXkgPT09IFwiZXNjYXBlXCIpIGRvbmUoZmFsc2UpO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHJldHVybiB0ZXh0O1xufSk7XG5cbmlmIChyZXN1bHQpIHtcbiAgLy8gVXNlciBwcmVzc2VkIEVudGVyXG59XG5gYGBcblxuVGhlIGNhbGxiYWNrIHJlY2VpdmVzOlxuLSBgdHVpYCAtIFRVSSBpbnN0YW5jZSAoZm9yIHNjcmVlbiBkaW1lbnNpb25zLCBmb2N1cyBtYW5hZ2VtZW50KVxuLSBgdGhlbWVgIC0gQ3VycmVudCB0aGVtZSBmb3Igc3R5bGluZ1xuLSBga2V5YmluZGluZ3NgIC0gQXBwIGtleWJpbmRpbmcgbWFuYWdlciAoZm9yIGNoZWNraW5nIHNob3J0Y3V0cylcbi0gYGRvbmUodmFsdWUpYCAtIENhbGwgdG8gY2xvc2UgY29tcG9uZW50IGFuZCByZXR1cm4gdmFsdWVcblxuU2VlIFt0dWkubWRdKHR1aS5tZCkgZm9yIHRoZSBmdWxsIGNvbXBvbmVudCBBUEkuXG5cbiMjIyMgT3ZlcmxheSBNb2RlIChFeHBlcmltZW50YWwpXG5cblBhc3MgYHsgb3ZlcmxheTogdHJ1ZSB9YCB0byByZW5kZXIgdGhlIGNvbXBvbmVudCBhcyBhIGZsb2F0aW5nIG1vZGFsIG9uIHRvcCBvZiBleGlzdGluZyBjb250ZW50LCB3aXRob3V0IGNsZWFyaW5nIHRoZSBzY3JlZW46XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC51aS5jdXN0b208c3RyaW5nIHwgbnVsbD4oXG4gICh0dWksIHRoZW1lLCBrZXliaW5kaW5ncywgZG9uZSkgPT4gbmV3IE15T3ZlcmxheUNvbXBvbmVudCh7IG9uQ2xvc2U6IGRvbmUgfSksXG4gIHsgb3ZlcmxheTogdHJ1ZSB9XG4pO1xuYGBgXG5cbkZvciBhZHZhbmNlZCBwb3NpdGlvbmluZyAoYW5jaG9ycywgbWFyZ2lucywgcGVyY2VudGFnZXMsIHJlc3BvbnNpdmUgdmlzaWJpbGl0eSksIHBhc3MgYG92ZXJsYXlPcHRpb25zYC4gVXNlIGBvbkhhbmRsZWAgdG8gY29udHJvbCBmb2N1cyBvciB2aXNpYmlsaXR5IHByb2dyYW1tYXRpY2FsbHk6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC51aS5jdXN0b208c3RyaW5nIHwgbnVsbD4oXG4gICh0dWksIHRoZW1lLCBrZXliaW5kaW5ncywgZG9uZSkgPT4gbmV3IE15T3ZlcmxheUNvbXBvbmVudCh7IG9uQ2xvc2U6IGRvbmUgfSksXG4gIHtcbiAgICBvdmVybGF5OiB0cnVlLFxuICAgIG92ZXJsYXlPcHRpb25zOiB7IGFuY2hvcjogXCJ0b3AtcmlnaHRcIiwgd2lkdGg6IFwiNTAlXCIsIG1hcmdpbjogMiB9LFxuICAgIG9uSGFuZGxlOiAoaGFuZGxlKSA9PiB7XG4gICAgICBoYW5kbGUuZm9jdXMoKTsgLy8gZm9jdXMgdGhpcyBvdmVybGF5IGFuZCBicmluZyBpdCB0byB0aGUgdmlzdWFsIGZyb250XG4gICAgICAvLyBoYW5kbGUudW5mb2N1cyh7IHRhcmdldDogZWRpdG9yQ29tcG9uZW50IH0pOyAvLyByZWxlYXNlIGlucHV0IHRvIGEgc3BlY2lmaWMgY29tcG9uZW50XG4gICAgICAvLyBoYW5kbGUuc2V0SGlkZGVuKHRydWUvZmFsc2UpOyAvLyB0b2dnbGUgdmlzaWJpbGl0eVxuICAgICAgLy8gaGFuZGxlLmhpZGUoKTsgLy8gcGVybWFuZW50bHkgcmVtb3ZlXG4gICAgfVxuICB9XG4pO1xuYGBgXG5cbkEgZm9jdXNlZCB2aXNpYmxlIG92ZXJsYXkgY2FuIHJlY2xhaW0gaW5wdXQgYWZ0ZXIgdGVtcG9yYXJ5IG5vbi1vdmVybGF5IGN1c3RvbSBVSSBjbG9zZXMuIElmIHlvdSBpbnRlbnRpb25hbGx5IHdhbnQgYW5vdGhlciBjb21wb25lbnQgdG8ga2VlcCBpbnB1dCB3aGlsZSB0aGUgb3ZlcmxheSBzdGF5cyB2aXNpYmxlLCBjYWxsIGBoYW5kbGUudW5mb2N1cyh7IHRhcmdldCB9KWAuIFBhc3NpbmcgYHsgdGFyZ2V0OiBudWxsIH1gIHJlbGVhc2VzIHRoZSBvdmVybGF5IHdpdGhvdXQgZm9jdXNpbmcgYW5vdGhlciBjb21wb25lbnQuXG5cblNlZSBbdHVpLm1kXSh0dWkubWQpIGZvciB0aGUgZnVsbCBgT3ZlcmxheU9wdGlvbnNgIGFuZCBgT3ZlcmxheUhhbmRsZWAgQVBJIGFuZCBbb3ZlcmxheS1xYS10ZXN0cy50c10oLi4vZXhhbXBsZXMvZXh0ZW5zaW9ucy9vdmVybGF5LXFhLXRlc3RzLnRzKSBmb3IgZXhhbXBsZXMuXG5cbiMjIyBDdXN0b20gRWRpdG9yXG5cblJlcGxhY2UgdGhlIG1haW4gaW5wdXQgZWRpdG9yIHdpdGggYSBjdXN0b20gaW1wbGVtZW50YXRpb24gKHZpbSBtb2RlLCBlbWFjcyBtb2RlLCBldGMuKTpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgQ3VzdG9tRWRpdG9yLCB0eXBlIEV4dGVuc2lvbkFQSSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBtYXRjaGVzS2V5IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxuY2xhc3MgVmltRWRpdG9yIGV4dGVuZHMgQ3VzdG9tRWRpdG9yIHtcbiAgcHJpdmF0ZSBtb2RlOiBcIm5vcm1hbFwiIHwgXCJpbnNlcnRcIiA9IFwiaW5zZXJ0XCI7XG5cbiAgaGFuZGxlSW5wdXQoZGF0YTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgXCJlc2NhcGVcIikgJiYgdGhpcy5tb2RlID09PSBcImluc2VydFwiKSB7XG4gICAgICB0aGlzLm1vZGUgPSBcIm5vcm1hbFwiO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5tb2RlID09PSBcIm5vcm1hbFwiICYmIGRhdGEgPT09IFwiaVwiKSB7XG4gICAgICB0aGlzLm1vZGUgPSBcImluc2VydFwiO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci5oYW5kbGVJbnB1dChkYXRhKTsgIC8vIEFwcCBrZXliaW5kaW5ncyArIHRleHQgZWRpdGluZ1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIHBpLm9uKFwic2Vzc2lvbl9zdGFydFwiLCAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICBjdHgudWkuc2V0RWRpdG9yQ29tcG9uZW50KChfdHVpLCB0aGVtZSwga2V5YmluZGluZ3MpID0+XG4gICAgICBuZXcgVmltRWRpdG9yKHRoZW1lLCBrZXliaW5kaW5ncylcbiAgICApO1xuICB9KTtcbn1cbmBgYFxuXG4qKktleSBwb2ludHM6Kipcbi0gRXh0ZW5kIGBDdXN0b21FZGl0b3JgIChub3QgYmFzZSBgRWRpdG9yYCkgdG8gZ2V0IGFwcCBrZXliaW5kaW5ncyAoZXNjYXBlIHRvIGFib3J0LCBjdHJsK2QsIG1vZGVsIHN3aXRjaGluZylcbi0gQ2FsbCBgc3VwZXIuaGFuZGxlSW5wdXQoZGF0YSlgIGZvciBrZXlzIHlvdSBkb24ndCBoYW5kbGVcbi0gRmFjdG9yeSByZWNlaXZlcyBgdGhlbWVgIGFuZCBga2V5YmluZGluZ3NgIGZyb20gdGhlIGFwcFxuLSBVc2UgYGN0eC51aS5nZXRFZGl0b3JDb21wb25lbnQoKWAgYmVmb3JlIGBzZXRFZGl0b3JDb21wb25lbnQoKWAgdG8gd3JhcCB0aGUgcHJldmlvdXNseSBjb25maWd1cmVkIGN1c3RvbSBlZGl0b3Jcbi0gUGFzcyBgdW5kZWZpbmVkYCB0byByZXN0b3JlIGRlZmF1bHQ6IGBjdHgudWkuc2V0RWRpdG9yQ29tcG9uZW50KHVuZGVmaW5lZClgXG5cblRvIGNvbXBvc2Ugd2l0aCBhbm90aGVyIGV4dGVuc2lvbiB0aGF0IGFscmVhZHkgcmVwbGFjZWQgdGhlIGVkaXRvciwgY2FwdHVyZSB0aGUgcHJldmlvdXMgZmFjdG9yeSBiZWZvcmUgc2V0dGluZyB5b3VyczpcblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgcHJldmlvdXMgPSBjdHgudWkuZ2V0RWRpdG9yQ29tcG9uZW50KCk7XG5jdHgudWkuc2V0RWRpdG9yQ29tcG9uZW50KCh0dWksIHRoZW1lLCBrZXliaW5kaW5ncykgPT5cbiAgbmV3IE15RWRpdG9yKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzLCB7IGJhc2U6IHByZXZpb3VzPy4odHVpLCB0aGVtZSwga2V5YmluZGluZ3MpIH0pXG4pO1xuYGBgXG5cblNlZSBbdHVpLm1kXSh0dWkubWQpIFBhdHRlcm4gNyBmb3IgYSBjb21wbGV0ZSBleGFtcGxlIHdpdGggbW9kZSBpbmRpY2F0b3IuXG5cbiMjIyBNZXNzYWdlIFJlbmRlcmluZ1xuXG5SZWdpc3RlciBhIGN1c3RvbSByZW5kZXJlciBmb3IgbWVzc2FnZXMgd2l0aCB5b3VyIGBjdXN0b21UeXBlYDpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5cbnBpLnJlZ2lzdGVyTWVzc2FnZVJlbmRlcmVyKFwibXktZXh0ZW5zaW9uXCIsIChtZXNzYWdlLCBvcHRpb25zLCB0aGVtZSkgPT4ge1xuICBjb25zdCB7IGV4cGFuZGVkIH0gPSBvcHRpb25zO1xuICBsZXQgdGV4dCA9IHRoZW1lLmZnKFwiYWNjZW50XCIsIGBbJHttZXNzYWdlLmN1c3RvbVR5cGV9XSBgKTtcbiAgdGV4dCArPSBtZXNzYWdlLmNvbnRlbnQ7XG5cbiAgaWYgKGV4cGFuZGVkICYmIG1lc3NhZ2UuZGV0YWlscykge1xuICAgIHRleHQgKz0gXCJcXG5cIiArIHRoZW1lLmZnKFwiZGltXCIsIEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UuZGV0YWlscywgbnVsbCwgMikpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xufSk7XG5gYGBcblxuTWVzc2FnZXMgYXJlIHNlbnQgdmlhIGBwaS5zZW5kTWVzc2FnZSgpYDpcblxuYGBgdHlwZXNjcmlwdFxucGkuc2VuZE1lc3NhZ2Uoe1xuICBjdXN0b21UeXBlOiBcIm15LWV4dGVuc2lvblwiLCAgLy8gTWF0Y2hlcyByZWdpc3Rlck1lc3NhZ2VSZW5kZXJlclxuICBjb250ZW50OiBcIlN0YXR1cyB1cGRhdGVcIixcbiAgZGlzcGxheTogdHJ1ZSwgICAgICAgICAgICAgICAvLyBTaG93IGluIFRVSVxuICBkZXRhaWxzOiB7IC4uLiB9LCAgICAgICAgICAgIC8vIEF2YWlsYWJsZSBpbiByZW5kZXJlclxufSk7XG5gYGBcblxuIyMjIFRoZW1lIENvbG9yc1xuXG5BbGwgcmVuZGVyIGZ1bmN0aW9ucyByZWNlaXZlIGEgYHRoZW1lYCBvYmplY3QuIFNlZSBbdGhlbWVzLm1kXSh0aGVtZXMubWQpIGZvciBjcmVhdGluZyBjdXN0b20gdGhlbWVzIGFuZCB0aGUgZnVsbCBjb2xvciBwYWxldHRlLlxuXG5gYGB0eXBlc2NyaXB0XG4vLyBGb3JlZ3JvdW5kIGNvbG9yc1xudGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGV4dCkgICAvLyBUb29sIG5hbWVzXG50aGVtZS5mZyhcImFjY2VudFwiLCB0ZXh0KSAgICAgIC8vIEhpZ2hsaWdodHNcbnRoZW1lLmZnKFwic3VjY2Vzc1wiLCB0ZXh0KSAgICAgLy8gU3VjY2VzcyAoZ3JlZW4pXG50aGVtZS5mZyhcImVycm9yXCIsIHRleHQpICAgICAgIC8vIEVycm9ycyAocmVkKVxudGhlbWUuZmcoXCJ3YXJuaW5nXCIsIHRleHQpICAgICAvLyBXYXJuaW5ncyAoeWVsbG93KVxudGhlbWUuZmcoXCJtdXRlZFwiLCB0ZXh0KSAgICAgICAvLyBTZWNvbmRhcnkgdGV4dFxudGhlbWUuZmcoXCJkaW1cIiwgdGV4dCkgICAgICAgICAvLyBUZXJ0aWFyeSB0ZXh0XG5cbi8vIFRleHQgc3R5bGVzXG50aGVtZS5ib2xkKHRleHQpXG50aGVtZS5pdGFsaWModGV4dClcbnRoZW1lLnN0cmlrZXRocm91Z2godGV4dClcbmBgYFxuXG5Gb3Igc3ludGF4IGhpZ2hsaWdodGluZyBpbiBjdXN0b20gdG9vbCByZW5kZXJlcnM6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IGhpZ2hsaWdodENvZGUsIGdldExhbmd1YWdlRnJvbVBhdGggfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG4vLyBIaWdobGlnaHQgY29kZSB3aXRoIGV4cGxpY2l0IGxhbmd1YWdlXG5jb25zdCBoaWdobGlnaHRlZCA9IGhpZ2hsaWdodENvZGUoXCJjb25zdCB4ID0gMTtcIiwgXCJ0eXBlc2NyaXB0XCIsIHRoZW1lKTtcblxuLy8gQXV0by1kZXRlY3QgbGFuZ3VhZ2UgZnJvbSBmaWxlIHBhdGhcbmNvbnN0IGxhbmcgPSBnZXRMYW5ndWFnZUZyb21QYXRoKFwiL3BhdGgvdG8vZmlsZS5yc1wiKTsgIC8vIFwicnVzdFwiXG5jb25zdCBoaWdobGlnaHRlZCA9IGhpZ2hsaWdodENvZGUoY29kZSwgbGFuZywgdGhlbWUpO1xuYGBgXG5cbiMjIEVycm9yIEhhbmRsaW5nXG5cbi0gRXh0ZW5zaW9uIGVycm9ycyBhcmUgbG9nZ2VkLCBhZ2VudCBjb250aW51ZXNcbi0gYHRvb2xfY2FsbGAgZXJyb3JzIGJsb2NrIHRoZSB0b29sIChmYWlsLXNhZmUpXG4tIFRvb2wgYGV4ZWN1dGVgIGVycm9ycyBtdXN0IGJlIHNpZ25hbGVkIGJ5IHRocm93aW5nOyB0aGUgdGhyb3duIGVycm9yIGlzIGNhdWdodCwgcmVwb3J0ZWQgdG8gdGhlIExMTSB3aXRoIGBpc0Vycm9yOiB0cnVlYCwgYW5kIGV4ZWN1dGlvbiBjb250aW51ZXNcblxuIyMgTW9kZSBCZWhhdmlvclxuXG58IE1vZGUgfCBgY3R4Lm1vZGVgIHwgYGN0eC5oYXNVSWAgfCBOb3RlcyB8XG58LS0tLS0tfC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tfC0tLS0tLS18XG58IEludGVyYWN0aXZlIHwgYFwidHVpXCJgIHwgYHRydWVgIHwgRnVsbCBUVUkgd2l0aCB0ZXJtaW5hbCByZW5kZXJpbmcgfFxufCBSUEMgKGAtLW1vZGUgcnBjYCkgfCBgXCJycGNcImAgfCBgdHJ1ZWAgfCBEaWFsb2dzIGFuZCBub3RpZmljYXRpb25zIHZpYSBKU09OIHByb3RvY29sOyBgY3VzdG9tKClgIHJldHVybnMgYHVuZGVmaW5lZGAuIFNlZSBbcnBjLm1kXShycGMubWQpIHxcbnwgSlNPTiAoYC0tbW9kZSBqc29uYCkgfCBgXCJqc29uXCJgIHwgYGZhbHNlYCB8IEV2ZW50IHN0cmVhbSB0byBzdGRvdXQ7IFVJIG1ldGhvZHMgYXJlIG5vLW9wcyB8XG58IFByaW50IChgLXBgKSB8IGBcInByaW50XCJgIHwgYGZhbHNlYCB8IEV4dGVuc2lvbnMgcnVuIGJ1dCBjYW4ndCBwcm9tcHQgfFxuXG5Vc2UgYGN0eC5tb2RlID09PSBcInR1aVwiYCBiZWZvcmUgVFVJLXNwZWNpZmljIGZlYXR1cmVzIChgY3VzdG9tKClgLCBjb21wb25lbnQgZmFjdG9yaWVzLCB0ZXJtaW5hbCBpbnB1dCkuIFVzZSBgY3R4Lmhhc1VJYCBiZWZvcmUgZGlhbG9nIGFuZCBub3RpZmljYXRpb24gbWV0aG9kcyB0aGF0IHdvcmsgaW4gYm90aCBUVUkgYW5kIFJQQyBtb2Rlcy5cblxuIyMgRXhhbXBsZXMgUmVmZXJlbmNlXG5cbkFsbCBleGFtcGxlcyBpbiBbZXhhbXBsZXMvZXh0ZW5zaW9ucy9dKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvKS5cblxufCBFeGFtcGxlIHwgRGVzY3JpcHRpb24gfCBLZXkgQVBJcyB8XG58LS0tLS0tLS0tfC0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLXxcbnwgKipUb29scyoqIHx8fFxufCBgaGVsbG8udHNgIHwgTWluaW1hbCB0b29sIHJlZ2lzdHJhdGlvbiB8IGByZWdpc3RlclRvb2xgIHxcbnwgYHF1ZXN0aW9uLnRzYCB8IFRvb2wgd2l0aCB1c2VyIGludGVyYWN0aW9uIHwgYHJlZ2lzdGVyVG9vbGAsIGB1aS5zZWxlY3RgIHxcbnwgYHF1ZXN0aW9ubmFpcmUudHNgIHwgTXVsdGktc3RlcCB3aXphcmQgdG9vbCB8IGByZWdpc3RlclRvb2xgLCBgdWkuY3VzdG9tYCB8XG58IGB0b2RvLnRzYCB8IFN0YXRlZnVsIHRvb2wgd2l0aCBwZXJzaXN0ZW5jZSB8IGByZWdpc3RlclRvb2xgLCBgYXBwZW5kRW50cnlgLCBgcmVuZGVyUmVzdWx0YCwgc2Vzc2lvbiBldmVudHMgfFxufCBgZHluYW1pYy10b29scy50c2AgfCBSZWdpc3RlciB0b29scyBhZnRlciBzdGFydHVwIGFuZCBkdXJpbmcgY29tbWFuZHMgfCBgcmVnaXN0ZXJUb29sYCwgYHNlc3Npb25fc3RhcnRgLCBgcmVnaXN0ZXJDb21tYW5kYCB8XG58IGBzdHJ1Y3R1cmVkLW91dHB1dC50c2AgfCBGaW5hbCBzdHJ1Y3R1cmVkLW91dHB1dCB0b29sIHdpdGggYHRlcm1pbmF0ZTogdHJ1ZWAgfCBgcmVnaXN0ZXJUb29sYCwgdGVybWluYXRpbmcgdG9vbCByZXN1bHRzIHxcbnwgYHRydW5jYXRlZC10b29sLnRzYCB8IE91dHB1dCB0cnVuY2F0aW9uIGV4YW1wbGUgfCBgcmVnaXN0ZXJUb29sYCwgYHRydW5jYXRlSGVhZGAgfFxufCBgdG9vbC1vdmVycmlkZS50c2AgfCBPdmVycmlkZSBidWlsdC1pbiByZWFkIHRvb2wgfCBgcmVnaXN0ZXJUb29sYCAoc2FtZSBuYW1lIGFzIGJ1aWx0LWluKSB8XG58ICoqQ29tbWFuZHMqKiB8fHxcbnwgYHBpcmF0ZS50c2AgfCBNb2RpZnkgc3lzdGVtIHByb21wdCBwZXItdHVybiB8IGByZWdpc3RlckNvbW1hbmRgLCBgYmVmb3JlX2FnZW50X3N0YXJ0YCB8XG58IGBzdW1tYXJpemUudHNgIHwgQ29udmVyc2F0aW9uIHN1bW1hcnkgY29tbWFuZCB8IGByZWdpc3RlckNvbW1hbmRgLCBgdWkuY3VzdG9tYCB8XG58IGBoYW5kb2ZmLnRzYCB8IENyb3NzLXByb3ZpZGVyIG1vZGVsIGhhbmRvZmYgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHVpLmVkaXRvcmAsIGB1aS5jdXN0b21gIHxcbnwgYHFuYS50c2AgfCBRJkEgd2l0aCBjdXN0b20gVUkgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHVpLmN1c3RvbWAsIGBzZXRFZGl0b3JUZXh0YCB8XG58IGBzZW5kLXVzZXItbWVzc2FnZS50c2AgfCBJbmplY3QgdXNlciBtZXNzYWdlcyB8IGByZWdpc3RlckNvbW1hbmRgLCBgc2VuZFVzZXJNZXNzYWdlYCB8XG58IGByZWxvYWQtcnVudGltZS50c2AgfCBSZWxvYWQgY29tbWFuZCBhbmQgTExNIHRvb2wgaGFuZG9mZiB8IGByZWdpc3RlckNvbW1hbmRgLCBgY3R4LnJlbG9hZCgpYCwgYHNlbmRVc2VyTWVzc2FnZWAgfFxufCBgc2h1dGRvd24tY29tbWFuZC50c2AgfCBHcmFjZWZ1bCBzaHV0ZG93biBjb21tYW5kIHwgYHJlZ2lzdGVyQ29tbWFuZGAsIGBzaHV0ZG93bigpYCB8XG58ICoqRXZlbnRzICYgR2F0ZXMqKiB8fHxcbnwgYHBlcm1pc3Npb24tZ2F0ZS50c2AgfCBCbG9jayBkYW5nZXJvdXMgY29tbWFuZHMgfCBgb24oXCJ0b29sX2NhbGxcIilgLCBgdWkuY29uZmlybWAgfFxufCBgcHJvamVjdC10cnVzdC50c2AgfCBEZWNpZGUgb3IgZGVmZXIgcHJvamVjdCB0cnVzdCBmcm9tIGEgdXNlci9nbG9iYWwgb3IgQ0xJIGV4dGVuc2lvbiB8IGBvbihcInByb2plY3RfdHJ1c3RcIilgLCB0cnVzdCBVSSwgcmVxdWlyZWQgdHJ1c3QgcmVzdWx0IHxcbnwgYHByb3RlY3RlZC1wYXRocy50c2AgfCBCbG9jayB3cml0ZXMgdG8gc3BlY2lmaWMgcGF0aHMgfCBgb24oXCJ0b29sX2NhbGxcIilgIHxcbnwgYGNvbmZpcm0tZGVzdHJ1Y3RpdmUudHNgIHwgQ29uZmlybSBzZXNzaW9uIGNoYW5nZXMgfCBgb24oXCJzZXNzaW9uX2JlZm9yZV9zd2l0Y2hcIilgLCBgb24oXCJzZXNzaW9uX2JlZm9yZV9mb3JrXCIpYCB8XG58IGBkaXJ0eS1yZXBvLWd1YXJkLnRzYCB8IFdhcm4gb24gZGlydHkgZ2l0IHJlcG8gfCBgb24oXCJzZXNzaW9uX2JlZm9yZV8qXCIpYCwgYGV4ZWNgIHxcbnwgYGlucHV0LXRyYW5zZm9ybS50c2AgfCBUcmFuc2Zvcm0gdXNlciBpbnB1dCB8IGBvbihcImlucHV0XCIpYCB8XG58IGBpbnB1dC10cmFuc2Zvcm0tc3RyZWFtaW5nLnRzYCB8IFN0cmVhbWluZy1hd2FyZSBpbnB1dCB0cmFuc2Zvcm0gfCBgb24oXCJpbnB1dFwiKWAsIGBzdHJlYW1pbmdCZWhhdmlvcmAgfFxufCBgbW9kZWwtc3RhdHVzLnRzYCB8IFJlYWN0IHRvIG1vZGVsIGNoYW5nZXMgfCBgb24oXCJtb2RlbF9zZWxlY3RcIilgLCBgc2V0U3RhdHVzYCB8XG58IGBwcm92aWRlci1wYXlsb2FkLnRzYCB8IEluc3BlY3QgcGF5bG9hZHMgYW5kIHByb3ZpZGVyIHJlc3BvbnNlIGhlYWRlcnMgfCBgb24oXCJiZWZvcmVfcHJvdmlkZXJfcmVxdWVzdFwiKWAsIGBvbihcImFmdGVyX3Byb3ZpZGVyX3Jlc3BvbnNlXCIpYCB8XG58IGBzeXN0ZW0tcHJvbXB0LWhlYWRlci50c2AgfCBEaXNwbGF5IHN5c3RlbSBwcm9tcHQgaW5mbyB8IGBvbihcImFnZW50X3N0YXJ0XCIpYCwgYGdldFN5c3RlbVByb21wdGAgfFxufCBgY2xhdWRlLXJ1bGVzLnRzYCB8IExvYWQgcnVsZXMgZnJvbSBmaWxlcyB8IGBvbihcInNlc3Npb25fc3RhcnRcIilgLCBgb24oXCJiZWZvcmVfYWdlbnRfc3RhcnRcIilgIHxcbnwgYHByb21wdC1jdXN0b21pemVyLnRzYCB8IEFkZCBjb250ZXh0LWF3YXJlIHRvb2wgZ3VpZGFuY2UgdXNpbmcgYHN5c3RlbVByb21wdE9wdGlvbnNgIHwgYG9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIpYCwgYEJ1aWxkU3lzdGVtUHJvbXB0T3B0aW9uc2AgfFxufCBgZmlsZS10cmlnZ2VyLnRzYCB8IEZpbGUgd2F0Y2hlciB0cmlnZ2VycyBtZXNzYWdlcyB8IGBzZW5kTWVzc2FnZWAgfFxufCAqKkNvbXBhY3Rpb24gJiBTZXNzaW9ucyoqIHx8fFxufCBgY3VzdG9tLWNvbXBhY3Rpb24udHNgIHwgQ3VzdG9tIGNvbXBhY3Rpb24gc3VtbWFyeSB8IGBvbihcInNlc3Npb25fYmVmb3JlX2NvbXBhY3RcIilgIHxcbnwgYHRyaWdnZXItY29tcGFjdC50c2AgfCBUcmlnZ2VyIGNvbXBhY3Rpb24gbWFudWFsbHkgfCBgY29tcGFjdCgpYCB8XG58IGBnaXQtY2hlY2twb2ludC50c2AgfCBHaXQgc3Rhc2ggb24gdHVybnMgfCBgb24oXCJ0dXJuX3N0YXJ0XCIpYCwgYG9uKFwic2Vzc2lvbl9iZWZvcmVfZm9ya1wiKWAsIGBleGVjYCB8XG58IGBnaXQtbWVyZ2UtYW5kLXJlc29sdmUudHNgIHwgRmV0Y2gsIG1lcmdlLCBhbmQgcmVzb2x2ZSBjb25mbGljdHMgfCBgb24oXCJhZ2VudF9lbmRcIilgLCBgZXhlY2AsIGBzZW5kVXNlck1lc3NhZ2VgIHxcbnwgYGF1dG8tY29tbWl0LW9uLWV4aXQudHNgIHwgQ29tbWl0IG9uIHNodXRkb3duIHwgYG9uKFwic2Vzc2lvbl9zaHV0ZG93blwiKWAsIGBleGVjYCB8XG58ICoqVUkgQ29tcG9uZW50cyoqIHx8fFxufCBgc3RhdHVzLWxpbmUudHNgIHwgRm9vdGVyIHN0YXR1cyBpbmRpY2F0b3IgfCBgc2V0U3RhdHVzYCwgc2Vzc2lvbiBldmVudHMgfFxufCBgd29ya2luZy1pbmRpY2F0b3IudHNgIHwgQ3VzdG9taXplIHRoZSBzdHJlYW1pbmcgd29ya2luZyBpbmRpY2F0b3IgfCBgc2V0V29ya2luZ0luZGljYXRvcmAsIGByZWdpc3RlckNvbW1hbmRgIHxcbnwgYGdpdGh1Yi1pc3N1ZS1hdXRvY29tcGxldGUudHNgIHwgQWRkIGAjMTIzNGAgaXNzdWUgY29tcGxldGlvbnMgb24gdG9wIG9mIGJ1aWx0LWluIGF1dG9jb21wbGV0ZSBieSBwcmVsb2FkaW5nIHJlY2VudCBvcGVuIGlzc3VlcyBmcm9tIGBnaCBpc3N1ZSBsaXN0YCB8IGBhZGRBdXRvY29tcGxldGVQcm92aWRlcmAsIGBvbihcInNlc3Npb25fc3RhcnRcIilgLCBgZXhlY2AgfFxufCBgY3VzdG9tLWZvb3Rlci50c2AgfCBSZXBsYWNlIGZvb3RlciBlbnRpcmVseSB8IGByZWdpc3RlckNvbW1hbmRgLCBgc2V0Rm9vdGVyYCB8XG58IGBjdXN0b20taGVhZGVyLnRzYCB8IFJlcGxhY2Ugc3RhcnR1cCBoZWFkZXIgfCBgb24oXCJzZXNzaW9uX3N0YXJ0XCIpYCwgYHNldEhlYWRlcmAgfFxufCBgbW9kYWwtZWRpdG9yLnRzYCB8IFZpbS1zdHlsZSBtb2RhbCBlZGl0b3IgfCBgc2V0RWRpdG9yQ29tcG9uZW50YCwgYEN1c3RvbUVkaXRvcmAgfFxufCBgcmFpbmJvdy1lZGl0b3IudHNgIHwgQ3VzdG9tIGVkaXRvciBzdHlsaW5nIHwgYHNldEVkaXRvckNvbXBvbmVudGAgfFxufCBgd2lkZ2V0LXBsYWNlbWVudC50c2AgfCBXaWRnZXQgYWJvdmUvYmVsb3cgZWRpdG9yIHwgYHNldFdpZGdldGAgfFxufCBgb3ZlcmxheS10ZXN0LnRzYCB8IE92ZXJsYXkgY29tcG9uZW50cyB8IGB1aS5jdXN0b21gIHdpdGggb3ZlcmxheSBvcHRpb25zIHxcbnwgYG92ZXJsYXktcWEtdGVzdHMudHNgIHwgQ29tcHJlaGVuc2l2ZSBvdmVybGF5IHRlc3RzIHwgYHVpLmN1c3RvbWAsIGFsbCBvdmVybGF5IG9wdGlvbnMgfFxufCBgbm90aWZ5LnRzYCB8IFNpbXBsZSBub3RpZmljYXRpb25zIHwgYHVpLm5vdGlmeWAgfFxufCBgdGltZWQtY29uZmlybS50c2AgfCBEaWFsb2dzIHdpdGggdGltZW91dCB8IGB1aS5jb25maXJtYCB3aXRoIHRpbWVvdXQvc2lnbmFsIHxcbnwgYG1hYy1zeXN0ZW0tdGhlbWUudHNgIHwgQXV0by1zd2l0Y2ggdGhlbWUgfCBgc2V0VGhlbWVgLCBgZXhlY2AgfFxufCAqKkNvbXBsZXggRXh0ZW5zaW9ucyoqIHx8fFxufCBgcGxhbi1tb2RlL2AgfCBGdWxsIHBsYW4gbW9kZSBpbXBsZW1lbnRhdGlvbiB8IEFsbCBldmVudCB0eXBlcywgYHJlZ2lzdGVyQ29tbWFuZGAsIGByZWdpc3RlclNob3J0Y3V0YCwgYHJlZ2lzdGVyRmxhZ2AsIGBzZXRTdGF0dXNgLCBgc2V0V2lkZ2V0YCwgYHNlbmRNZXNzYWdlYCwgYHNldEFjdGl2ZVRvb2xzYCB8XG58IGBwcmVzZXQudHNgIHwgU2F2ZWFibGUgcHJlc2V0cyAobW9kZWwsIHRvb2xzLCB0aGlua2luZykgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHJlZ2lzdGVyU2hvcnRjdXRgLCBgcmVnaXN0ZXJGbGFnYCwgYHNldE1vZGVsYCwgYHNldEFjdGl2ZVRvb2xzYCwgYHNldFRoaW5raW5nTGV2ZWxgLCBgYXBwZW5kRW50cnlgIHxcbnwgYHRvb2xzLnRzYCB8IFRvZ2dsZSB0b29scyBvbi9vZmYgVUkgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHNldEFjdGl2ZVRvb2xzYCwgYFNldHRpbmdzTGlzdGAsIHNlc3Npb24gZXZlbnRzIHxcbnwgKipSZW1vdGUgJiBTYW5kYm94KiogfHx8XG58IGBzc2gudHNgIHwgU1NIIHJlbW90ZSBleGVjdXRpb24gfCBgcmVnaXN0ZXJGbGFnYCwgYG9uKFwidXNlcl9iYXNoXCIpYCwgYG9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIpYCwgdG9vbCBvcGVyYXRpb25zIHxcbnwgYGludGVyYWN0aXZlLXNoZWxsLnRzYCB8IFBlcnNpc3RlbnQgc2hlbGwgc2Vzc2lvbiB8IGBvbihcInVzZXJfYmFzaFwiKWAgfFxufCBgc2FuZGJveC9gIHwgU2FuZGJveGVkIHRvb2wgZXhlY3V0aW9uIHwgVG9vbCBvcGVyYXRpb25zIHxcbnwgYGdvbmRvbGluL2AgfCBSb3V0ZSBidWlsdC1pbiB0b29scyBhbmQgYCFgIGNvbW1hbmRzIGludG8gYSBHb25kb2xpbiBtaWNyby1WTSB8IFRvb2wgb3BlcmF0aW9ucywgYnVpbHQtaW4gdG9vbCBvdmVycmlkZXMsIGBvbihcInVzZXJfYmFzaFwiKWAgfFxufCBgc3ViYWdlbnQvYCB8IFNwYXduIHN1Yi1hZ2VudHMgfCBgcmVnaXN0ZXJUb29sYCwgYGV4ZWNgIHxcbnwgKipHYW1lcyoqIHx8fFxufCBgc25ha2UudHNgIHwgU25ha2UgZ2FtZSB8IGByZWdpc3RlckNvbW1hbmRgLCBgdWkuY3VzdG9tYCwga2V5Ym9hcmQgaGFuZGxpbmcgfFxuXG5bU2hvd2luZyBsaW5lcyAxMzg3LTI2NjEgb2YgMjY3NyAoNTAuMEtCIGxpbWl0KS4gVXNlIG9mZnNldD0yNjYyIHRvIGNvbnRpbnVlLl0ifV0sImRldGFpbHMiOnsidHJ1bmNhdGlvbiI6eyJjb250ZW50IjoiUGVyc2lzdCBleHRlbnNpb24gc3RhdGUgKGRvZXMgTk9UIHBhcnRpY2lwYXRlIGluIExMTSBjb250ZXh0KS5cblxuYGBgdHlwZXNjcmlwdFxucGkuYXBwZW5kRW50cnkoXCJteS1zdGF0ZVwiLCB7IGNvdW50OiA0MiB9KTtcblxuLy8gUmVzdG9yZSBvbiByZWxvYWRcbnBpLm9uKFwic2Vzc2lvbl9zdGFydFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHtcbiAgZm9yIChjb25zdCBlbnRyeSBvZiBjdHguc2Vzc2lvbk1hbmFnZXIuZ2V0RW50cmllcygpKSB7XG4gICAgaWYgKGVudHJ5LnR5cGUgPT09IFwiY3VzdG9tXCIgJiYgZW50cnkuY3VzdG9tVHlwZSA9PT0gXCJteS1zdGF0ZVwiKSB7XG4gICAgICAvLyBSZWNvbnN0cnVjdCBmcm9tIGVudHJ5LmRhdGFcbiAgICB9XG4gIH1cbn0pO1xuYGBgXG5cbiMjIyBwaS5zZXRTZXNzaW9uTmFtZShuYW1lKVxuXG5TZXQgdGhlIHNlc3Npb24gZGlzcGxheSBuYW1lIChzaG93biBpbiBzZXNzaW9uIHNlbGVjdG9yIGluc3RlYWQgb2YgZmlyc3QgbWVzc2FnZSkuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnNldFNlc3Npb25OYW1lKFwiUmVmYWN0b3IgYXV0aCBtb2R1bGVcIik7XG5gYGBcblxuIyMjIHBpLmdldFNlc3Npb25OYW1lKClcblxuR2V0IHRoZSBjdXJyZW50IHNlc3Npb24gbmFtZSwgaWYgc2V0LlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCBuYW1lID0gcGkuZ2V0U2Vzc2lvbk5hbWUoKTtcbmlmIChuYW1lKSB7XG4gIGNvbnNvbGUubG9nKGBTZXNzaW9uOiAke25hbWV9YCk7XG59XG5gYGBcblxuIyMjIHBpLnNldExhYmVsKGVudHJ5SWQsIGxhYmVsKVxuXG5TZXQgb3IgY2xlYXIgYSBsYWJlbCBvbiBhbiBlbnRyeS4gTGFiZWxzIGFyZSB1c2VyLWRlZmluZWQgbWFya2VycyBmb3IgYm9va21hcmtpbmcgYW5kIG5hdmlnYXRpb24gKHNob3duIGluIGAvdHJlZWAgc2VsZWN0b3IpLlxuXG5gYGB0eXBlc2NyaXB0XG4vLyBTZXQgYSBsYWJlbFxucGkuc2V0TGFiZWwoZW50cnlJZCwgXCJjaGVja3BvaW50LWJlZm9yZS1yZWZhY3RvclwiKTtcblxuLy8gQ2xlYXIgYSBsYWJlbFxucGkuc2V0TGFiZWwoZW50cnlJZCwgdW5kZWZpbmVkKTtcblxuLy8gUmVhZCBsYWJlbHMgdmlhIHNlc3Npb25NYW5hZ2VyXG5jb25zdCBsYWJlbCA9IGN0eC5zZXNzaW9uTWFuYWdlci5nZXRMYWJlbChlbnRyeUlkKTtcbmBgYFxuXG5MYWJlbHMgcGVyc2lzdCBpbiB0aGUgc2Vzc2lvbiBhbmQgc3Vydml2ZSByZXN0YXJ0cy4gVXNlIHRoZW0gdG8gbWFyayBpbXBvcnRhbnQgcG9pbnRzICh0dXJucywgY2hlY2twb2ludHMpIGluIHRoZSBjb252ZXJzYXRpb24gdHJlZS5cblxuIyMjIHBpLnJlZ2lzdGVyQ29tbWFuZChuYW1lLCBvcHRpb25zKVxuXG5SZWdpc3RlciBhIGNvbW1hbmQuXG5cbklmIG11bHRpcGxlIGV4dGVuc2lvbnMgcmVnaXN0ZXIgdGhlIHNhbWUgY29tbWFuZCBuYW1lLCBwaSBrZWVwcyB0aGVtIGFsbCBhbmQgYXNzaWducyBudW1lcmljIGludm9jYXRpb24gc3VmZml4ZXMgaW4gbG9hZCBvcmRlciwgZm9yIGV4YW1wbGUgYC9yZXZpZXc6MWAgYW5kIGAvcmV2aWV3OjJgLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5yZWdpc3RlckNvbW1hbmQoXCJzdGF0c1wiLCB7XG4gIGRlc2NyaXB0aW9uOiBcIlNob3cgc2Vzc2lvbiBzdGF0aXN0aWNzXCIsXG4gIGhhbmRsZXI6IGFzeW5jIChhcmdzLCBjdHgpID0+IHtcbiAgICBjb25zdCBjb3VudCA9IGN0eC5zZXNzaW9uTWFuYWdlci5nZXRFbnRyaWVzKCkubGVuZ3RoO1xuICAgIGN0eC51aS5ub3RpZnkoYCR7Y291bnR9IGVudHJpZXNgLCBcImluZm9cIik7XG4gIH1cbn0pO1xuYGBgXG5cbk9wdGlvbmFsOiBhZGQgYXJndW1lbnQgYXV0by1jb21wbGV0aW9uIGZvciBgL2NvbW1hbmQgLi4uYDpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHR5cGUgeyBBdXRvY29tcGxldGVJdGVtIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxucGkucmVnaXN0ZXJDb21tYW5kKFwiZGVwbG95XCIsIHtcbiAgZGVzY3JpcHRpb246IFwiRGVwbG95IHRvIGFuIGVudmlyb25tZW50XCIsXG4gIGdldEFyZ3VtZW50Q29tcGxldGlvbnM6IChwcmVmaXg6IHN0cmluZyk6IEF1dG9jb21wbGV0ZUl0ZW1bXSB8IG51bGwgPT4ge1xuICAgIGNvbnN0IGVudnMgPSBbXCJkZXZcIiwgXCJzdGFnaW5nXCIsIFwicHJvZFwiXTtcbiAgICBjb25zdCBpdGVtcyA9IGVudnMubWFwKChlKSA9PiAoeyB2YWx1ZTogZSwgbGFiZWw6IGUgfSkpO1xuICAgIGNvbnN0IGZpbHRlcmVkID0gaXRlbXMuZmlsdGVyKChpKSA9PiBpLnZhbHVlLnN0YXJ0c1dpdGgocHJlZml4KSk7XG4gICAgcmV0dXJuIGZpbHRlcmVkLmxlbmd0aCA+IDAgPyBmaWx0ZXJlZCA6IG51bGw7XG4gIH0sXG4gIGhhbmRsZXI6IGFzeW5jIChhcmdzLCBjdHgpID0+IHtcbiAgICBjdHgudWkubm90aWZ5KGBEZXBsb3lpbmc6ICR7YXJnc31gLCBcImluZm9cIik7XG4gIH0sXG59KTtcbmBgYFxuXG4jIyMgcGkuZ2V0Q29tbWFuZHMoKVxuXG5HZXQgdGhlIHNsYXNoIGNvbW1hbmRzIGF2YWlsYWJsZSBmb3IgaW52b2NhdGlvbiB2aWEgYHByb21wdGAgaW4gdGhlIGN1cnJlbnQgc2Vzc2lvbi4gSW5jbHVkZXMgZXh0ZW5zaW9uIGNvbW1hbmRzLCBwcm9tcHQgdGVtcGxhdGVzLCBhbmQgc2tpbGwgY29tbWFuZHMuXG5UaGUgbGlzdCBtYXRjaGVzIHRoZSBSUEMgYGdldF9jb21tYW5kc2Agb3JkZXJpbmc6IGV4dGVuc2lvbnMgZmlyc3QsIHRoZW4gdGVtcGxhdGVzLCB0aGVuIHNraWxscy5cblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgY29tbWFuZHMgPSBwaS5nZXRDb21tYW5kcygpO1xuY29uc3QgYnlTb3VyY2UgPSBjb21tYW5kcy5maWx0ZXIoKGNvbW1hbmQpID0+IGNvbW1hbmQuc291cmNlID09PSBcImV4dGVuc2lvblwiKTtcbmNvbnN0IHVzZXJTY29wZWQgPSBjb21tYW5kcy5maWx0ZXIoKGNvbW1hbmQpID0+IGNvbW1hbmQuc291cmNlSW5mby5zY29wZSA9PT0gXCJ1c2VyXCIpO1xuYGBgXG5cbkVhY2ggZW50cnkgaGFzIHRoaXMgc2hhcGU6XG5cbmBgYHR5cGVzY3JpcHRcbntcbiAgbmFtZTogc3RyaW5nOyAvLyBJbnZva2FibGUgY29tbWFuZCBuYW1lIHdpdGhvdXQgdGhlIGxlYWRpbmcgc2xhc2guIE1heSBiZSBzdWZmaXhlZCBsaWtlIFwicmV2aWV3OjFcIlxuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgc291cmNlOiBcImV4dGVuc2lvblwiIHwgXCJwcm9tcHRcIiB8IFwic2tpbGxcIjtcbiAgc291cmNlSW5mbzoge1xuICAgIHBhdGg6IHN0cmluZztcbiAgICBzb3VyY2U6IHN0cmluZztcbiAgICBzY29wZTogXCJ1c2VyXCIgfCBcInByb2plY3RcIiB8IFwidGVtcG9yYXJ5XCI7XG4gICAgb3JpZ2luOiBcInBhY2thZ2VcIiB8IFwidG9wLWxldmVsXCI7XG4gICAgYmFzZURpcj86IHN0cmluZztcbiAgfTtcbn1cbmBgYFxuXG5Vc2UgYHNvdXJjZUluZm9gIGFzIHRoZSBjYW5vbmljYWwgcHJvdmVuYW5jZSBmaWVsZC4gRG8gbm90IGluZmVyIG93bmVyc2hpcCBmcm9tIGNvbW1hbmQgbmFtZXMgb3IgZnJvbSBhZCBob2MgcGF0aCBwYXJzaW5nLlxuXG5CdWlsdC1pbiBpbnRlcmFjdGl2ZSBjb21tYW5kcyAobGlrZSBgL21vZGVsYCBhbmQgYC9zZXR0aW5nc2ApIGFyZSBub3QgaW5jbHVkZWQgaGVyZS4gVGhleSBhcmUgaGFuZGxlZCBvbmx5IGluIGludGVyYWN0aXZlXG5tb2RlIGFuZCB3b3VsZCBub3QgZXhlY3V0ZSBpZiBzZW50IHZpYSBgcHJvbXB0YC5cblxuIyMjIHBpLnJlZ2lzdGVyTWVzc2FnZVJlbmRlcmVyKGN1c3RvbVR5cGUsIHJlbmRlcmVyKVxuXG5SZWdpc3RlciBhIGN1c3RvbSBUVUkgcmVuZGVyZXIgZm9yIG1lc3NhZ2VzIHdpdGggeW91ciBgY3VzdG9tVHlwZWAuIFNlZSBbQ3VzdG9tIFVJXSgjY3VzdG9tLXVpKS5cblxuIyMjIHBpLnJlZ2lzdGVyU2hvcnRjdXQoc2hvcnRjdXQsIG9wdGlvbnMpXG5cblJlZ2lzdGVyIGEga2V5Ym9hcmQgc2hvcnRjdXQuIFNlZSBba2V5YmluZGluZ3MubWRdKGtleWJpbmRpbmdzLm1kKSBmb3IgdGhlIHNob3J0Y3V0IGZvcm1hdCBhbmQgYnVpbHQtaW4ga2V5YmluZGluZ3MuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyU2hvcnRjdXQoXCJjdHJsK3NoaWZ0K3BcIiwge1xuICBkZXNjcmlwdGlvbjogXCJUb2dnbGUgcGxhbiBtb2RlXCIsXG4gIGhhbmRsZXI6IGFzeW5jIChjdHgpID0+IHtcbiAgICBjdHgudWkubm90aWZ5KFwiVG9nZ2xlZCFcIik7XG4gIH0sXG59KTtcbmBgYFxuXG4jIyMgcGkucmVnaXN0ZXJGbGFnKG5hbWUsIG9wdGlvbnMpXG5cblJlZ2lzdGVyIGEgQ0xJIGZsYWcuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyRmxhZyhcInBsYW5cIiwge1xuICBkZXNjcmlwdGlvbjogXCJTdGFydCBpbiBwbGFuIG1vZGVcIixcbiAgdHlwZTogXCJib29sZWFuXCIsXG4gIGRlZmF1bHQ6IGZhbHNlLFxufSk7XG5cbi8vIENoZWNrIHZhbHVlXG5pZiAocGkuZ2V0RmxhZyhcInBsYW5cIikpIHtcbiAgLy8gUGxhbiBtb2RlIGVuYWJsZWRcbn1cbmBgYFxuXG4jIyMgcGkuZXhlYyhjb21tYW5kLCBhcmdzLCBvcHRpb25zPylcblxuRXhlY3V0ZSBhIHNoZWxsIGNvbW1hbmQuXG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJnaXRcIiwgW1wic3RhdHVzXCJdLCB7IHNpZ25hbCwgdGltZW91dDogNTAwMCB9KTtcbi8vIHJlc3VsdC5zdGRvdXQsIHJlc3VsdC5zdGRlcnIsIHJlc3VsdC5jb2RlLCByZXN1bHQua2lsbGVkXG5gYGBcblxuIyMjIHBpLmdldEFjdGl2ZVRvb2xzKCkgLyBwaS5nZXRBbGxUb29scygpIC8gcGkuc2V0QWN0aXZlVG9vbHMobmFtZXMpXG5cbk1hbmFnZSBhY3RpdmUgdG9vbHMuIFRoaXMgd29ya3MgZm9yIGJvdGggYnVpbHQtaW4gdG9vbHMgYW5kIGR5bmFtaWNhbGx5IHJlZ2lzdGVyZWQgdG9vbHMuIGBwaS5nZXRBY3RpdmVUb29scygpYCByZXR1cm5zIHRoZSBhY3RpdmUgdG9vbCBuYW1lcyBhcyBgc3RyaW5nW11gOyBgcGkuZ2V0QWxsVG9vbHMoKWAgcmV0dXJucyBtZXRhZGF0YSBmb3IgYWxsIGNvbmZpZ3VyZWQgdG9vbHMuXG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IGFjdGl2ZSA9IHBpLmdldEFjdGl2ZVRvb2xzKCk7IC8vIFtcInJlYWRcIiwgXCJiYXNoXCIsIC4uLl1cbmNvbnN0IGFsbCA9IHBpLmdldEFsbFRvb2xzKCk7XG4vLyBhbGwgPSBbe1xuLy8gICBuYW1lOiBcInJlYWRcIixcbi8vICAgZGVzY3JpcHRpb246IFwiUmVhZCBmaWxlIGNvbnRlbnRzLi4uXCIsXG4vLyAgIHBhcmFtZXRlcnM6IC4uLixcbi8vICAgcHJvbXB0R3VpZGVsaW5lczogW1wiVXNlIHJlYWQgdG8gZXhhbWluZSBmaWxlcyBpbnN0ZWFkIG9mIGNhdCBvciBzZWQuXCJdLFxuLy8gICBzb3VyY2VJbmZvOiB7IHBhdGg6IFwiPGJ1aWx0aW46cmVhZD5cIiwgc291cmNlOiBcImJ1aWx0aW5cIiwgc2NvcGU6IFwidGVtcG9yYXJ5XCIsIG9yaWdpbjogXCJ0b3AtbGV2ZWxcIiB9XG4vLyB9LCAuLi5dXG5jb25zdCBidWlsdGluVG9vbHMgPSBhbGwuZmlsdGVyKCh0KSA9PiB0LnNvdXJjZUluZm8uc291cmNlID09PSBcImJ1aWx0aW5cIik7XG5jb25zdCBleHRlbnNpb25Ub29scyA9IGFsbC5maWx0ZXIoKHQpID0+IHQuc291cmNlSW5mby5zb3VyY2UgIT09IFwiYnVpbHRpblwiICYmIHQuc291cmNlSW5mby5zb3VyY2UgIT09IFwic2RrXCIpO1xucGkuc2V0QWN0aXZlVG9vbHMoWy4uLm5ldyBTZXQoWy4uLmFjdGl2ZSwgXCJteV9jdXN0b21fdG9vbFwiXSldKTsgLy8gS2VlcCBjdXJyZW50IHRvb2xzIGFuZCBlbmFibGUgbXlfY3VzdG9tX3Rvb2xcbnBpLnNldEFjdGl2ZVRvb2xzKFtcInJlYWRcIiwgXCJiYXNoXCJdKTsgLy8gU3dpdGNoIHRvIHJlYWQtb25seVxuYGBgXG5cbmBwaS5nZXRBbGxUb29scygpYCByZXR1cm5zIGBuYW1lYCwgYGRlc2NyaXB0aW9uYCwgYHBhcmFtZXRlcnNgLCBgcHJvbXB0R3VpZGVsaW5lc2AsIGFuZCBgc291cmNlSW5mb2AuXG5cblR5cGljYWwgYHNvdXJjZUluZm8uc291cmNlYCB2YWx1ZXM6XG4tIGBidWlsdGluYCBmb3IgYnVpbHQtaW4gdG9vbHNcbi0gYHNka2AgZm9yIHRvb2xzIHBhc3NlZCB2aWEgYGNyZWF0ZUFnZW50U2Vzc2lvbih7IGN1c3RvbVRvb2xzIH0pYFxuLSBleHRlbnNpb24gc291cmNlIG1ldGFkYXRhIGZvciB0b29scyByZWdpc3RlcmVkIGJ5IGV4dGVuc2lvbnNcblxuIyMjIHBpLnNldE1vZGVsKG1vZGVsKVxuXG5TZXQgdGhlIGN1cnJlbnQgbW9kZWwuIFJldHVybnMgYGZhbHNlYCBpZiBubyBBUEkga2V5IGlzIGF2YWlsYWJsZSBmb3IgdGhlIG1vZGVsLiBTZWUgW21vZGVscy5tZF0obW9kZWxzLm1kKSBmb3IgY29uZmlndXJpbmcgY3VzdG9tIG1vZGVscy5cblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgbW9kZWwgPSBjdHgubW9kZWxSZWdpc3RyeS5maW5kKFwiYW50aHJvcGljXCIsIFwiY2xhdWRlLXNvbm5ldC00LTVcIik7XG5pZiAobW9kZWwpIHtcbiAgY29uc3Qgc3VjY2VzcyA9IGF3YWl0IHBpLnNldE1vZGVsKG1vZGVsKTtcbiAgaWYgKCFzdWNjZXNzKSB7XG4gICAgY3R4LnVpLm5vdGlmeShcIk5vIEFQSSBrZXkgZm9yIHRoaXMgbW9kZWxcIiwgXCJlcnJvclwiKTtcbiAgfVxufVxuYGBgXG5cbiMjIyBwaS5nZXRUaGlua2luZ0xldmVsKCkgLyBwaS5zZXRUaGlua2luZ0xldmVsKGxldmVsKVxuXG5HZXQgb3Igc2V0IHRoZSB0aGlua2luZyBsZXZlbC4gTGV2ZWwgaXMgY2xhbXBlZCB0byBtb2RlbCBjYXBhYmlsaXRpZXMgKG5vbi1yZWFzb25pbmcgbW9kZWxzIGFsd2F5cyB1c2UgXCJvZmZcIikuIENoYW5nZXMgZW1pdCBgdGhpbmtpbmdfbGV2ZWxfc2VsZWN0YC5cblxuYGBgdHlwZXNjcmlwdFxuY29uc3QgY3VycmVudCA9IHBpLmdldFRoaW5raW5nTGV2ZWwoKTsgIC8vIFwib2ZmXCIgfCBcIm1pbmltYWxcIiB8IFwibG93XCIgfCBcIm1lZGl1bVwiIHwgXCJoaWdoXCIgfCBcInhoaWdoXCJcbnBpLnNldFRoaW5raW5nTGV2ZWwoXCJoaWdoXCIpO1xuYGBgXG5cbiMjIyBwaS5ldmVudHNcblxuU2hhcmVkIGV2ZW50IGJ1cyBmb3IgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIGV4dGVuc2lvbnM6XG5cbmBgYHR5cGVzY3JpcHRcbnBpLmV2ZW50cy5vbihcIm15OmV2ZW50XCIsIChkYXRhKSA9PiB7IC4uLiB9KTtcbnBpLmV2ZW50cy5lbWl0KFwibXk6ZXZlbnRcIiwgeyAuLi4gfSk7XG5gYGBcblxuIyMjIHBpLnJlZ2lzdGVyUHJvdmlkZXIobmFtZSwgY29uZmlnKVxuXG5SZWdpc3RlciBvciBvdmVycmlkZSBhIG1vZGVsIHByb3ZpZGVyIGR5bmFtaWNhbGx5LiBVc2VmdWwgZm9yIHByb3hpZXMsIGN1c3RvbSBlbmRwb2ludHMsIG9yIHRlYW0td2lkZSBtb2RlbCBjb25maWd1cmF0aW9ucy5cblxuQ2FsbHMgbWFkZSBkdXJpbmcgdGhlIGV4dGVuc2lvbiBmYWN0b3J5IGZ1bmN0aW9uIGFyZSBxdWV1ZWQgYW5kIGFwcGxpZWQgb25jZSB0aGUgcnVubmVyIGluaXRpYWxpc2VzLiBDYWxscyBtYWRlIGFmdGVyIHRoYXQg4oCUIGZvciBleGFtcGxlIGZyb20gYSBjb21tYW5kIGhhbmRsZXIgZm9sbG93aW5nIGEgdXNlciBzZXR1cCBmbG93IOKAlCB0YWtlIGVmZmVjdCBpbW1lZGlhdGVseSB3aXRob3V0IHJlcXVpcmluZyBhIGAvcmVsb2FkYC5cblxuSWYgeW91IG5lZWQgdG8gZGlzY292ZXIgbW9kZWxzIGZyb20gYSByZW1vdGUgZW5kcG9pbnQsIHByZWZlciBhbiBhc3luYyBleHRlbnNpb24gZmFjdG9yeSBvdmVyIGRlZmVycmluZyB0aGUgZmV0Y2ggdG8gYHNlc3Npb25fc3RhcnRgLiBwaSB3YWl0cyBmb3IgdGhlIGZhY3RvcnkgYmVmb3JlIHN0YXJ0dXAgY29udGludWVzLCBzbyB0aGUgcmVnaXN0ZXJlZCBtb2RlbHMgYXJlIGF2YWlsYWJsZSBpbW1lZGlhdGVseSwgaW5jbHVkaW5nIHRvIGBwaSAtLWxpc3QtbW9kZWxzYC5cblxuYGBgdHlwZXNjcmlwdFxuLy8gUmVnaXN0ZXIgYSBuZXcgcHJvdmlkZXIgd2l0aCBjdXN0b20gbW9kZWxzXG5waS5yZWdpc3RlclByb3ZpZGVyKFwibXktcHJveHlcIiwge1xuICBuYW1lOiBcIk15IFByb3h5XCIsXG4gIGJhc2VVcmw6IFwiaHR0cHM6Ly9wcm94eS5leGFtcGxlLmNvbVwiLFxuICBhcGlLZXk6IFwiJFBST1hZX0FQSV9LRVlcIiwgIC8vIGVudiB2YXIgcmVmZXJlbmNlXG4gIGFwaTogXCJhbnRocm9waWMtbWVzc2FnZXNcIixcbiAgbW9kZWxzOiBbXG4gICAge1xuICAgICAgaWQ6IFwiY2xhdWRlLXNvbm5ldC00LTIwMjUwNTE0XCIsXG4gICAgICBuYW1lOiBcIkNsYXVkZSA0IFNvbm5ldCAocHJveHkpXCIsXG4gICAgICByZWFzb25pbmc6IGZhbHNlLFxuICAgICAgaW5wdXQ6IFtcInRleHRcIiwgXCJpbWFnZVwiXSxcbiAgICAgIGNvc3Q6IHsgaW5wdXQ6IDAsIG91dHB1dDogMCwgY2FjaGVSZWFkOiAwLCBjYWNoZVdyaXRlOiAwIH0sXG4gICAgICBjb250ZXh0V2luZG93OiAyMDAwMDAsXG4gICAgICBtYXhUb2tlbnM6IDE2Mzg0XG4gICAgfVxuICBdXG59KTtcblxuLy8gT3ZlcnJpZGUgYmFzZVVybCBmb3IgYW4gZXhpc3RpbmcgcHJvdmlkZXIgKGtlZXBzIGFsbCBtb2RlbHMpXG5waS5yZWdpc3RlclByb3ZpZGVyKFwiYW50aHJvcGljXCIsIHtcbiAgYmFzZVVybDogXCJodHRwczovL3Byb3h5LmV4YW1wbGUuY29tXCJcbn0pO1xuXG4vLyBSZWdpc3RlciBwcm92aWRlciB3aXRoIE9BdXRoIHN1cHBvcnQgZm9yIC9sb2dpblxucGkucmVnaXN0ZXJQcm92aWRlcihcImNvcnBvcmF0ZS1haVwiLCB7XG4gIGJhc2VVcmw6IFwiaHR0cHM6Ly9haS5jb3JwLmNvbVwiLFxuICBhcGk6IFwib3BlbmFpLXJlc3BvbnNlc1wiLFxuICBtb2RlbHM6IFsuLi5dLFxuICBvYXV0aDoge1xuICAgIG5hbWU6IFwiQ29ycG9yYXRlIEFJIChTU08pXCIsXG4gICAgYXN5bmMgbG9naW4oY2FsbGJhY2tzKSB7XG4gICAgICAvLyBDdXN0b20gT0F1dGggZmxvd1xuICAgICAgY2FsbGJhY2tzLm9uQXV0aCh7IHVybDogXCJodHRwczovL3Nzby5jb3JwLmNvbS8uLi5cIiB9KTtcbiAgICAgIGNvbnN0IGNvZGUgPSBhd2FpdCBjYWxsYmFja3Mub25Qcm9tcHQoeyBtZXNzYWdlOiBcIkVudGVyIGNvZGU6XCIgfSk7XG4gICAgICByZXR1cm4geyByZWZyZXNoOiBjb2RlLCBhY2Nlc3M6IGNvZGUsIGV4cGlyZXM6IERhdGUubm93KCkgKyAzNjAwMDAwIH07XG4gICAgfSxcbiAgICBhc3luYyByZWZyZXNoVG9rZW4oY3JlZGVudGlhbHMpIHtcbiAgICAgIC8vIFJlZnJlc2ggbG9naWNcbiAgICAgIHJldHVybiBjcmVkZW50aWFscztcbiAgICB9LFxuICAgIGdldEFwaUtleShjcmVkZW50aWFscykge1xuICAgICAgcmV0dXJuIGNyZWRlbnRpYWxzLmFjY2VzcztcbiAgICB9XG4gIH1cbn0pO1xuYGBgXG5cbioqQ29uZmlnIG9wdGlvbnM6Kipcbi0gYG5hbWVgIC0gRGlzcGxheSBuYW1lIGZvciB0aGUgcHJvdmlkZXIgaW4gVUkgc3VjaCBhcyBgL2xvZ2luYC5cbi0gYGJhc2VVcmxgIC0gQVBJIGVuZHBvaW50IFVSTC4gUmVxdWlyZWQgd2hlbiBkZWZpbmluZyBtb2RlbHMuXG4tIGBhcGlLZXlgIC0gQVBJIGtleSBsaXRlcmFsLCBlbnZpcm9ubWVudCBpbnRlcnBvbGF0aW9uIChgJEVOVl9WQVJgIG9yIGAke0VOVl9WQVJ9YCksIG9yIGxlYWRpbmcgYCFjb21tYW5kYC4gUmVxdWlyZWQgd2hlbiBkZWZpbmluZyBtb2RlbHMgKHVubGVzcyBgb2F1dGhgIHByb3ZpZGVkKS4gYCQkYCBlc2NhcGVzIGAkYCwgYW5kIGAkIWAgZXNjYXBlcyBhIGxpdGVyYWwgYCFgIHdpdGhvdXQgdHJpZ2dlcmluZyBjb21tYW5kIGV4ZWN1dGlvbi5cbi0gYGFwaWAgLSBBUEkgdHlwZTogYFwiYW50aHJvcGljLW1lc3NhZ2VzXCJgLCBgXCJvcGVuYWktY29tcGxldGlvbnNcImAsIGBcIm9wZW5haS1yZXNwb25zZXNcImAsIGV0Yy5cbi0gYGhlYWRlcnNgIC0gQ3VzdG9tIGhlYWRlcnMgdG8gaW5jbHVkZSBpbiByZXF1ZXN0cy5cbi0gYGF1dGhIZWFkZXJgIC0gSWYgdHJ1ZSwgYWRkcyBgQXV0aG9yaXphdGlvbjogQmVhcmVyYCBoZWFkZXIgYXV0b21hdGljYWxseS5cbi0gYG1vZGVsc2AgLSBBcnJheSBvZiBtb2RlbCBkZWZpbml0aW9ucy4gSWYgcHJvdmlkZWQsIHJlcGxhY2VzIGFsbCBleGlzdGluZyBtb2RlbHMgZm9yIHRoaXMgcHJvdmlkZXIuIE1vZGVsIGRlZmluaXRpb25zIGNhbiBzZXQgYGJhc2VVcmxgIHRvIG92ZXJyaWRlIHRoZSBwcm92aWRlciBlbmRwb2ludCBmb3IgdGhhdCBtb2RlbC5cbi0gYG9hdXRoYCAtIE9BdXRoIHByb3ZpZGVyIGNvbmZpZyBmb3IgYC9sb2dpbmAgc3VwcG9ydC4gV2hlbiBwcm92aWRlZCwgdGhlIHByb3ZpZGVyIGFwcGVhcnMgaW4gdGhlIGxvZ2luIG1lbnUuXG4tIGBzdHJlYW1TaW1wbGVgIC0gQ3VzdG9tIHN0cmVhbWluZyBpbXBsZW1lbnRhdGlvbiBmb3Igbm9uLXN0YW5kYXJkIEFQSXMuXG5cblNlZSBbY3VzdG9tLXByb3ZpZGVyLm1kXShjdXN0b20tcHJvdmlkZXIubWQpIGZvciBhZHZhbmNlZCB0b3BpY3M6IGN1c3RvbSBzdHJlYW1pbmcgQVBJcywgT0F1dGggZGV0YWlscywgbW9kZWwgZGVmaW5pdGlvbiByZWZlcmVuY2UuXG5cbiMjIyBwaS51bnJlZ2lzdGVyUHJvdmlkZXIobmFtZSlcblxuUmVtb3ZlIGEgcHJldmlvdXNseSByZWdpc3RlcmVkIHByb3ZpZGVyIGFuZCBpdHMgbW9kZWxzLiBCdWlsdC1pbiBtb2RlbHMgdGhhdCB3ZXJlIG92ZXJyaWRkZW4gYnkgdGhlIHByb3ZpZGVyIGFyZSByZXN0b3JlZC4gSGFzIG5vIGVmZmVjdCBpZiB0aGUgcHJvdmlkZXIgd2FzIG5vdCByZWdpc3RlcmVkLlxuXG5MaWtlIGByZWdpc3RlclByb3ZpZGVyYCwgdGhpcyB0YWtlcyBlZmZlY3QgaW1tZWRpYXRlbHkgd2hlbiBjYWxsZWQgYWZ0ZXIgdGhlIGluaXRpYWwgbG9hZCBwaGFzZSwgc28gYSBgL3JlbG9hZGAgaXMgbm90IHJlcXVpcmVkLlxuXG5gYGB0eXBlc2NyaXB0XG5waS5yZWdpc3RlckNvbW1hbmQoXCJteS1zZXR1cC10ZWFyZG93blwiLCB7XG4gIGRlc2NyaXB0aW9uOiBcIlJlbW92ZSB0aGUgY3VzdG9tIHByb3h5IHByb3ZpZGVyXCIsXG4gIGhhbmRsZXI6IGFzeW5jIChfYXJncywgX2N0eCkgPT4ge1xuICAgIHBpLnVucmVnaXN0ZXJQcm92aWRlcihcIm15LXByb3h5XCIpO1xuICB9LFxufSk7XG5gYGBcblxuIyMgU3RhdGUgTWFuYWdlbWVudFxuXG5FeHRlbnNpb25zIHdpdGggc3RhdGUgc2hvdWxkIHN0b3JlIGl0IGluIHRvb2wgcmVzdWx0IGBkZXRhaWxzYCBmb3IgcHJvcGVyIGJyYW5jaGluZyBzdXBwb3J0OlxuXG5gYGB0eXBlc2NyaXB0XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAocGk6IEV4dGVuc2lvbkFQSSkge1xuICBsZXQgaXRlbXM6IHN0cmluZ1tdID0gW107XG5cbiAgLy8gUmVjb25zdHJ1Y3Qgc3RhdGUgZnJvbSBzZXNzaW9uXG4gIHBpLm9uKFwic2Vzc2lvbl9zdGFydFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICBpdGVtcyA9IFtdO1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgY3R4LnNlc3Npb25NYW5hZ2VyLmdldEJyYW5jaCgpKSB7XG4gICAgICBpZiAoZW50cnkudHlwZSA9PT0gXCJtZXNzYWdlXCIgJiYgZW50cnkubWVzc2FnZS5yb2xlID09PSBcInRvb2xSZXN1bHRcIikge1xuICAgICAgICBpZiAoZW50cnkubWVzc2FnZS50b29sTmFtZSA9PT0gXCJteV90b29sXCIpIHtcbiAgICAgICAgICBpdGVtcyA9IGVudHJ5Lm1lc3NhZ2UuZGV0YWlscz8uaXRlbXMgPz8gW107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJteV90b29sXCIsXG4gICAgLy8gLi4uXG4gICAgYXN5bmMgZXhlY3V0ZSh0b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUsIGN0eCkge1xuICAgICAgaXRlbXMucHVzaChcIm5ldyBpdGVtXCIpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiQWRkZWRcIiB9XSxcbiAgICAgICAgZGV0YWlsczogeyBpdGVtczogWy4uLml0ZW1zXSB9LCAgLy8gU3RvcmUgZm9yIHJlY29uc3RydWN0aW9uXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xufVxuYGBgXG5cbiMjIEN1c3RvbSBUb29sc1xuXG5SZWdpc3RlciB0b29scyB0aGUgTExNIGNhbiBjYWxsIHZpYSBgcGkucmVnaXN0ZXJUb29sKClgLiBUb29scyBhcHBlYXIgaW4gdGhlIHN5c3RlbSBwcm9tcHQgYW5kIGNhbiBoYXZlIGN1c3RvbSByZW5kZXJpbmcuXG5cblVzZSBgcHJvbXB0U25pcHBldGAgZm9yIGEgc2hvcnQgb25lLWxpbmUgZW50cnkgaW4gdGhlIGBBdmFpbGFibGUgdG9vbHNgIHNlY3Rpb24gaW4gdGhlIGRlZmF1bHQgc3lzdGVtIHByb21wdC4gSWYgb21pdHRlZCwgY3VzdG9tIHRvb2xzIGFyZSBsZWZ0IG91dCBvZiB0aGF0IHNlY3Rpb24uXG5cblVzZSBgcHJvbXB0R3VpZGVsaW5lc2AgdG8gYWRkIHRvb2wtc3BlY2lmaWMgYnVsbGV0cyB0byB0aGUgZGVmYXVsdCBzeXN0ZW0gcHJvbXB0IGBHdWlkZWxpbmVzYCBzZWN0aW9uLiBUaGVzZSBidWxsZXRzIGFyZSBpbmNsdWRlZCBvbmx5IHdoaWxlIHRoZSB0b29sIGlzIGFjdGl2ZSAoZm9yIGV4YW1wbGUsIGFmdGVyIGBwaS5zZXRBY3RpdmVUb29scyhbLi4uXSlgKS5cblxuKipJbXBvcnRhbnQ6KiogYHByb21wdEd1aWRlbGluZXNgIGJ1bGxldHMgYXJlIGFwcGVuZGVkIGZsYXQgdG8gdGhlIGBHdWlkZWxpbmVzYCBzZWN0aW9uIHdpdGggbm8gdG9vbCBuYW1lIHByZWZpeCBvciBncm91cGluZy4gRWFjaCBndWlkZWxpbmUgbXVzdCBuYW1lIHRoZSB0b29sIGl0IHJlZmVycyB0byDigJQgYXZvaWQgXCJVc2UgdGhpcyB0b29sIHdoZW4uLi5cIiBiZWNhdXNlIHRoZSBMTE0gY2Fubm90IHRlbGwgd2hpY2ggdG9vbCBcInRoaXNcIiBtZWFucy4gV3JpdGUgXCJVc2UgbXlfdG9vbCB3aGVuLi4uXCIgaW5zdGVhZC5cblxuTm90ZTogU29tZSBtb2RlbHMgYXJlIGlkaW90cyBhbmQgaW5jbHVkZSB0aGUgQCBwcmVmaXggaW4gdG9vbCBwYXRoIGFyZ3VtZW50cy4gQnVpbHQtaW4gdG9vbHMgc3RyaXAgYSBsZWFkaW5nIEAgYmVmb3JlIHJlc29sdmluZyBwYXRocy4gSWYgeW91ciBjdXN0b20gdG9vbCBhY2NlcHRzIGEgcGF0aCwgbm9ybWFsaXplIGEgbGVhZGluZyBAIGFzIHdlbGwuXG5cbklmIHlvdXIgY3VzdG9tIHRvb2wgbXV0YXRlcyBmaWxlcywgdXNlIGB3aXRoRmlsZU11dGF0aW9uUXVldWUoKWAgc28gaXQgcGFydGljaXBhdGVzIGluIHRoZSBzYW1lIHBlci1maWxlIHF1ZXVlIGFzIGJ1aWx0LWluIGBlZGl0YCBhbmQgYHdyaXRlYC4gVGhpcyBtYXR0ZXJzIGJlY2F1c2UgdG9vbCBjYWxscyBydW4gaW4gcGFyYWxsZWwgYnkgZGVmYXVsdC4gV2l0aG91dCB0aGUgcXVldWUsIHR3byB0b29scyBjYW4gcmVhZCB0aGUgc2FtZSBvbGQgZmlsZSBjb250ZW50cywgY29tcHV0ZSBkaWZmZXJlbnQgdXBkYXRlcywgYW5kIHRoZW4gd2hpY2hldmVyIHdyaXRlIGxhbmRzIGxhc3Qgb3ZlcndyaXRlcyB0aGUgb3RoZXIuXG5cbkV4YW1wbGUgZmFpbHVyZSBjYXNlOiB5b3VyIGN1c3RvbSB0b29sIGVkaXRzIGBmb28udHNgIHdoaWxlIGJ1aWx0LWluIGBlZGl0YCBhbHNvIGNoYW5nZXMgYGZvby50c2AgaW4gdGhlIHNhbWUgYXNzaXN0YW50IHR1cm4uIElmIHlvdXIgdG9vbCBkb2VzIG5vdCBwYXJ0aWNpcGF0ZSBpbiB0aGUgcXVldWUsIGJvdGggY2FuIHJlYWQgdGhlIG9yaWdpbmFsIGBmb28udHNgLCBhcHBseSBzZXBhcmF0ZSBjaGFuZ2VzLCBhbmQgb25lIG9mIHRob3NlIGNoYW5nZXMgaXMgbG9zdC5cblxuUGFzcyB0aGUgcmVhbCB0YXJnZXQgZmlsZSBwYXRoIHRvIGB3aXRoRmlsZU11dGF0aW9uUXVldWUoKWAsIG5vdCB0aGUgcmF3IHVzZXIgYXJndW1lbnQuIFJlc29sdmUgaXQgdG8gYW4gYWJzb2x1dGUgcGF0aCBmaXJzdCwgcmVsYXRpdmUgdG8gYGN0eC5jd2RgIG9yIHlvdXIgdG9vbCdzIHdvcmtpbmcgZGlyZWN0b3J5LiBGb3IgZXhpc3RpbmcgZmlsZXMsIHRoZSBoZWxwZXIgY2Fub25pY2FsaXplcyB0aHJvdWdoIGByZWFscGF0aCgpYCwgc28gc3ltbGluayBhbGlhc2VzIGZvciB0aGUgc2FtZSBmaWxlIHNoYXJlIG9uZSBxdWV1ZS4gRm9yIG5ldyBmaWxlcywgaXQgZmFsbHMgYmFjayB0byB0aGUgcmVzb2x2ZWQgYWJzb2x1dGUgcGF0aCBiZWNhdXNlIHRoZXJlIGlzIG5vdGhpbmcgdG8gYHJlYWxwYXRoKClgIHlldC5cblxuUXVldWUgdGhlIGVudGlyZSBtdXRhdGlvbiB3aW5kb3cgb24gdGhhdCB0YXJnZXQgcGF0aC4gVGhhdCBpbmNsdWRlcyByZWFkLW1vZGlmeS13cml0ZSBsb2dpYywgbm90IGp1c3QgdGhlIGZpbmFsIHdyaXRlLlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyB3aXRoRmlsZU11dGF0aW9uUXVldWUgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgbWtkaXIsIHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgZGlybmFtZSwgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcblxuYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICBjb25zdCBhYnNvbHV0ZVBhdGggPSByZXNvbHZlKGN0eC5jd2QsIHBhcmFtcy5wYXRoKTtcblxuICByZXR1cm4gd2l0aEZpbGVNdXRhdGlvblF1ZXVlKGFic29sdXRlUGF0aCwgYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IG1rZGlyKGRpcm5hbWUoYWJzb2x1dGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgY29uc3QgY3VycmVudCA9IGF3YWl0IHJlYWRGaWxlKGFic29sdXRlUGF0aCwgXCJ1dGY4XCIpO1xuICAgIGNvbnN0IG5leHQgPSBjdXJyZW50LnJlcGxhY2UocGFyYW1zLm9sZFRleHQsIHBhcmFtcy5uZXdUZXh0KTtcbiAgICBhd2FpdCB3cml0ZUZpbGUoYWJzb2x1dGVQYXRoLCBuZXh0LCBcInV0ZjhcIik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IGBVcGRhdGVkICR7cGFyYW1zLnBhdGh9YCB9XSxcbiAgICAgIGRldGFpbHM6IHt9LFxuICAgIH07XG4gIH0pO1xufVxuYGBgXG5cbiMjIyBUb29sIERlZmluaXRpb25cblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5pbXBvcnQgeyBTdHJpbmdFbnVtIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1haVwiO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5cbnBpLnJlZ2lzdGVyVG9vbCh7XG4gIG5hbWU6IFwibXlfdG9vbFwiLFxuICBsYWJlbDogXCJNeSBUb29sXCIsXG4gIGRlc2NyaXB0aW9uOiBcIldoYXQgdGhpcyB0b29sIGRvZXMgKHNob3duIHRvIExMTSlcIixcbiAgcHJvbXB0U25pcHBldDogXCJMaXN0IG9yIGFkZCBpdGVtcyBpbiB0aGUgcHJvamVjdCB0b2RvIGxpc3RcIixcbiAgcHJvbXB0R3VpZGVsaW5lczogW1xuICAgIFwiVXNlIG15X3Rvb2wgZm9yIHRvZG8gcGxhbm5pbmcgaW5zdGVhZCBvZiBkaXJlY3QgZmlsZSBlZGl0cyB3aGVuIHRoZSB1c2VyIGFza3MgZm9yIGEgdGFzayBsaXN0LlwiXG4gIF0sXG4gIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHtcbiAgICBhY3Rpb246IFN0cmluZ0VudW0oW1wibGlzdFwiLCBcImFkZFwiXSBhcyBjb25zdCksICAvLyBVc2UgU3RyaW5nRW51bSBmb3IgR29vZ2xlIGNvbXBhdGliaWxpdHlcbiAgICB0ZXh0OiBUeXBlLk9wdGlvbmFsKFR5cGUuU3RyaW5nKCkpLFxuICB9KSxcbiAgcHJlcGFyZUFyZ3VtZW50cyhhcmdzKSB7XG4gICAgaWYgKCFhcmdzIHx8IHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiKSByZXR1cm4gYXJncztcbiAgICBjb25zdCBpbnB1dCA9IGFyZ3MgYXMgeyBhY3Rpb24/OiBzdHJpbmc7IG9sZEFjdGlvbj86IHN0cmluZyB9O1xuICAgIGlmICh0eXBlb2YgaW5wdXQub2xkQWN0aW9uID09PSBcInN0cmluZ1wiICYmIGlucHV0LmFjdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4geyAuLi5pbnB1dCwgYWN0aW9uOiBpbnB1dC5vbGRBY3Rpb24gfTtcbiAgICB9XG4gICAgcmV0dXJuIGFyZ3M7XG4gIH0sXG5cbiAgYXN5bmMgZXhlY3V0ZSh0b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUsIGN0eCkge1xuICAgIC8vIENoZWNrIGZvciBjYW5jZWxsYXRpb25cbiAgICBpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICByZXR1cm4geyBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJDYW5jZWxsZWRcIiB9XSB9O1xuICAgIH1cblxuICAgIC8vIFN0cmVhbSBwcm9ncmVzcyB1cGRhdGVzXG4gICAgb25VcGRhdGU/Lih7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJXb3JraW5nLi4uXCIgfV0sXG4gICAgICBkZXRhaWxzOiB7IHByb2dyZXNzOiA1MCB9LFxuICAgIH0pO1xuXG4gICAgLy8gUnVuIGNvbW1hbmRzIHZpYSBwaS5leGVjIChjYXB0dXJlZCBmcm9tIGV4dGVuc2lvbiBjbG9zdXJlKVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJzb21lLWNvbW1hbmRcIiwgW10sIHsgc2lnbmFsIH0pO1xuXG4gICAgLy8gUmV0dXJuIHJlc3VsdFxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJEb25lXCIgfV0sICAvLyBTZW50IHRvIExMTVxuICAgICAgZGV0YWlsczogeyBkYXRhOiByZXN1bHQgfSwgICAgICAgICAgICAgICAgICAgLy8gRm9yIHJlbmRlcmluZyAmIHN0YXRlXG4gICAgICAvLyBPcHRpb25hbDogc3RvcCBhZnRlciB0aGlzIHRvb2wgYmF0Y2ggd2hlbiBldmVyeSBmaW5hbGl6ZWQgdG9vbCByZXN1bHRcbiAgICAgIC8vIGluIHRoZSBiYXRjaCBhbHNvIHJldHVybnMgdGVybWluYXRlOiB0cnVlLlxuICAgICAgdGVybWluYXRlOiB0cnVlLFxuICAgIH07XG4gIH0sXG5cbiAgLy8gT3B0aW9uYWw6IEN1c3RvbSByZW5kZXJpbmdcbiAgcmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgY29udGV4dCkgeyAuLi4gfSxcbiAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgb3B0aW9ucywgdGhlbWUsIGNvbnRleHQpIHsgLi4uIH0sXG59KTtcbmBgYFxuXG4qKlNpZ25hbGluZyBlcnJvcnM6KiogVG8gbWFyayBhIHRvb2wgZXhlY3V0aW9uIGFzIGZhaWxlZCAoc2V0cyBgaXNFcnJvcjogdHJ1ZWAgb24gdGhlIHJlc3VsdCBhbmQgcmVwb3J0cyBpdCB0byB0aGUgTExNKSwgdGhyb3cgYW4gZXJyb3IgZnJvbSBgZXhlY3V0ZWAuIFJldHVybmluZyBhIHZhbHVlIG5ldmVyIHNldHMgdGhlIGVycm9yIGZsYWcgcmVnYXJkbGVzcyBvZiB3aGF0IHByb3BlcnRpZXMgeW91IGluY2x1ZGUgaW4gdGhlIHJldHVybiBvYmplY3QuXG5cbioqRWFybHkgdGVybWluYXRpb246KiogUmV0dXJuIGB0ZXJtaW5hdGU6IHRydWVgIGZyb20gYGV4ZWN1dGUoKWAgdG8gaGludCB0aGF0IHRoZSBhdXRvbWF0aWMgZm9sbG93LXVwIExMTSBjYWxsIHNob3VsZCBiZSBza2lwcGVkIGFmdGVyIHRoZSBjdXJyZW50IHRvb2wgYmF0Y2guIFRoaXMgb25seSB0YWtlcyBlZmZlY3Qgd2hlbiBldmVyeSBmaW5hbGl6ZWQgdG9vbCByZXN1bHQgaW4gdGhhdCBiYXRjaCBpcyB0ZXJtaW5hdGluZy4gU2VlIFtleGFtcGxlcy9leHRlbnNpb25zL3N0cnVjdHVyZWQtb3V0cHV0LnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL3N0cnVjdHVyZWQtb3V0cHV0LnRzKSBmb3IgYSBtaW5pbWFsIGV4YW1wbGUgd2hlcmUgdGhlIGFnZW50IGVuZHMgb24gYSBmaW5hbCBzdHJ1Y3R1cmVkLW91dHB1dCB0b29sIGNhbGwuXG5cbmBgYHR5cGVzY3JpcHRcbi8vIENvcnJlY3Q6IHRocm93IHRvIHNpZ25hbCBhbiBlcnJvclxuYXN5bmMgZXhlY3V0ZSh0b29sQ2FsbElkLCBwYXJhbXMpIHtcbiAgaWYgKCFpc1ZhbGlkKHBhcmFtcy5pbnB1dCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaW5wdXQ6ICR7cGFyYW1zLmlucHV0fWApO1xuICB9XG4gIHJldHVybiB7IGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIk9LXCIgfV0sIGRldGFpbHM6IHt9IH07XG59XG5gYGBcblxuKipJbXBvcnRhbnQ6KiogVXNlIGBTdHJpbmdFbnVtYCBmcm9tIGBAZWFyZW5kaWwtd29ya3MvcGktYWlgIGZvciBzdHJpbmcgZW51bXMuIGBUeXBlLlVuaW9uYC9gVHlwZS5MaXRlcmFsYCBkb2Vzbid0IHdvcmsgd2l0aCBHb29nbGUncyBBUEkuXG5cbioqQXJndW1lbnQgcHJlcGFyYXRpb246KiogYHByZXBhcmVBcmd1bWVudHMoYXJncylgIGlzIG9wdGlvbmFsLiBJZiBkZWZpbmVkLCBpdCBydW5zIGJlZm9yZSBzY2hlbWEgdmFsaWRhdGlvbiBhbmQgYmVmb3JlIGBleGVjdXRlKClgLiBVc2UgaXQgdG8gbWltaWMgYW4gb2xkZXIgYWNjZXB0ZWQgaW5wdXQgc2hhcGUgd2hlbiBwaSByZXN1bWVzIGFuIG9sZGVyIHNlc3Npb24gd2hvc2Ugc3RvcmVkIHRvb2wgY2FsbCBhcmd1bWVudHMgbm8gbG9uZ2VyIG1hdGNoIHRoZSBjdXJyZW50IHNjaGVtYS4gUmV0dXJuIHRoZSBvYmplY3QgeW91IHdhbnQgdmFsaWRhdGVkIGFnYWluc3QgYHBhcmFtZXRlcnNgLiBLZWVwIHRoZSBwdWJsaWMgc2NoZW1hIHN0cmljdC4gRG8gbm90IGFkZCBkZXByZWNhdGVkIGNvbXBhdGliaWxpdHkgZmllbGRzIHRvIGBwYXJhbWV0ZXJzYCBqdXN0IHRvIGtlZXAgb2xkIHJlc3VtZWQgc2Vzc2lvbnMgd29ya2luZy5cblxuRXhhbXBsZTogYW4gb2xkZXIgc2Vzc2lvbiBtYXkgY29udGFpbiBhbiBgZWRpdGAgdG9vbCBjYWxsIHdpdGggdG9wLWxldmVsIGBvbGRUZXh0YCBhbmQgYG5ld1RleHRgLCB3aGlsZSB0aGUgY3VycmVudCBzY2hlbWEgb25seSBhY2NlcHRzIGBlZGl0czogW3sgb2xkVGV4dCwgbmV3VGV4dCB9XWAuXG5cbmBgYHR5cGVzY3JpcHRcbnBpLnJlZ2lzdGVyVG9vbCh7XG4gIG5hbWU6IFwiZWRpdFwiLFxuICBsYWJlbDogXCJFZGl0XCIsXG4gIGRlc2NyaXB0aW9uOiBcIkVkaXQgYSBzaW5nbGUgZmlsZSB1c2luZyBleGFjdCB0ZXh0IHJlcGxhY2VtZW50XCIsXG4gIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHtcbiAgICBwYXRoOiBUeXBlLlN0cmluZygpLFxuICAgIGVkaXRzOiBUeXBlLkFycmF5KFxuICAgICAgVHlwZS5PYmplY3Qoe1xuICAgICAgICBvbGRUZXh0OiBUeXBlLlN0cmluZygpLFxuICAgICAgICBuZXdUZXh0OiBUeXBlLlN0cmluZygpLFxuICAgICAgfSksXG4gICAgKSxcbiAgfSksXG4gIHByZXBhcmVBcmd1bWVudHMoYXJncykge1xuICAgIGlmICghYXJncyB8fCB0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIGFyZ3M7XG5cbiAgICBjb25zdCBpbnB1dCA9IGFyZ3MgYXMge1xuICAgICAgcGF0aD86IHN0cmluZztcbiAgICAgIGVkaXRzPzogQXJyYXk8eyBvbGRUZXh0OiBzdHJpbmc7IG5ld1RleHQ6IHN0cmluZyB9PjtcbiAgICAgIG9sZFRleHQ/OiB1bmtub3duO1xuICAgICAgbmV3VGV4dD86IHVua25vd247XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2YgaW5wdXQub2xkVGV4dCAhPT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgaW5wdXQubmV3VGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIGFyZ3M7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmlucHV0LFxuICAgICAgZWRpdHM6IFsuLi4oaW5wdXQuZWRpdHMgPz8gW10pLCB7IG9sZFRleHQ6IGlucHV0Lm9sZFRleHQsIG5ld1RleHQ6IGlucHV0Lm5ld1RleHQgfV0sXG4gICAgfTtcbiAgfSxcbiAgYXN5bmMgZXhlY3V0ZSh0b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUsIGN0eCkge1xuICAgIC8vIHBhcmFtcyBub3cgbWF0Y2hlcyB0aGUgY3VycmVudCBzY2hlbWFcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IGBBcHBseWluZyAke3BhcmFtcy5lZGl0cy5sZW5ndGh9IGVkaXQgYmxvY2socylgIH1dLFxuICAgICAgZGV0YWlsczoge30sXG4gICAgfTtcbiAgfSxcbn0pO1xuYGBgXG5cbiMjIyBPdmVycmlkaW5nIEJ1aWx0LWluIFRvb2xzXG5cbkV4dGVuc2lvbnMgY2FuIG92ZXJyaWRlIGJ1aWx0LWluIHRvb2xzIChgcmVhZGAsIGBiYXNoYCwgYGVkaXRgLCBgd3JpdGVgLCBgZ3JlcGAsIGBmaW5kYCwgYGxzYCkgYnkgcmVnaXN0ZXJpbmcgYSB0b29sIHdpdGggdGhlIHNhbWUgbmFtZS4gSW50ZXJhY3RpdmUgbW9kZSBkaXNwbGF5cyBhIHdhcm5pbmcgd2hlbiB0aGlzIGhhcHBlbnMuXG5cbmBgYGJhc2hcbiMgRXh0ZW5zaW9uJ3MgcmVhZCB0b29sIHJlcGxhY2VzIGJ1aWx0LWluIHJlYWRcbnBpIC1lIC4vdG9vbC1vdmVycmlkZS50c1xuYGBgXG5cbkFsdGVybmF0aXZlbHksIHVzZSBgLS1uby1idWlsdGluLXRvb2xzYCB0byBzdGFydCB3aXRob3V0IGFueSBidWlsdC1pbiB0b29scyB3aGlsZSBrZWVwaW5nIGV4dGVuc2lvbiB0b29scyBlbmFibGVkOlxuYGBgYmFzaFxuIyBObyBidWlsdC1pbiB0b29scywgb25seSBleHRlbnNpb24gdG9vbHNcbnBpIC0tbm8tYnVpbHRpbi10b29scyAtZSAuL215LWV4dGVuc2lvbi50c1xuYGBgXG5cblNlZSBbZXhhbXBsZXMvZXh0ZW5zaW9ucy90b29sLW92ZXJyaWRlLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL3Rvb2wtb3ZlcnJpZGUudHMpIGZvciBhIGNvbXBsZXRlIGV4YW1wbGUgdGhhdCBvdmVycmlkZXMgYHJlYWRgIHdpdGggbG9nZ2luZyBhbmQgYWNjZXNzIGNvbnRyb2wuXG5cbioqUmVuZGVyaW5nOioqIEJ1aWx0LWluIHJlbmRlcmVyIGluaGVyaXRhbmNlIGlzIHJlc29sdmVkIHBlciBzbG90LiBFeGVjdXRpb24gb3ZlcnJpZGUgYW5kIHJlbmRlcmluZyBvdmVycmlkZSBhcmUgaW5kZXBlbmRlbnQuIElmIHlvdXIgb3ZlcnJpZGUgb21pdHMgYHJlbmRlckNhbGxgLCB0aGUgYnVpbHQtaW4gYHJlbmRlckNhbGxgIGlzIHVzZWQuIElmIHlvdXIgb3ZlcnJpZGUgb21pdHMgYHJlbmRlclJlc3VsdGAsIHRoZSBidWlsdC1pbiBgcmVuZGVyUmVzdWx0YCBpcyB1c2VkLiBJZiB5b3VyIG92ZXJyaWRlIG9taXRzIGJvdGgsIHRoZSBidWlsdC1pbiByZW5kZXJlciBpcyB1c2VkIGF1dG9tYXRpY2FsbHkgKHN5bnRheCBoaWdobGlnaHRpbmcsIGRpZmZzLCBldGMuKS4gVGhpcyBsZXRzIHlvdSB3cmFwIGJ1aWx0LWluIHRvb2xzIGZvciBsb2dnaW5nIG9yIGFjY2VzcyBjb250cm9sIHdpdGhvdXQgcmVpbXBsZW1lbnRpbmcgdGhlIFVJLlxuXG4qKlByb21wdCBtZXRhZGF0YToqKiBgcHJvbXB0U25pcHBldGAgYW5kIGBwcm9tcHRHdWlkZWxpbmVzYCBhcmUgbm90IGluaGVyaXRlZCBmcm9tIHRoZSBidWlsdC1pbiB0b29sLiBJZiB5b3VyIG92ZXJyaWRlIHNob3VsZCBrZWVwIHRob3NlIHByb21wdCBpbnN0cnVjdGlvbnMsIGRlZmluZSB0aGVtIG9uIHRoZSBvdmVycmlkZSBleHBsaWNpdGx5LlxuXG4qKllvdXIgaW1wbGVtZW50YXRpb24gbXVzdCBtYXRjaCB0aGUgZXhhY3QgcmVzdWx0IHNoYXBlKiosIGluY2x1ZGluZyB0aGUgYGRldGFpbHNgIHR5cGUuIFRoZSBVSSBhbmQgc2Vzc2lvbiBsb2dpYyBkZXBlbmQgb24gdGhlc2Ugc2hhcGVzIGZvciByZW5kZXJpbmcgYW5kIHN0YXRlIHRyYWNraW5nLlxuXG5CdWlsdC1pbiB0b29sIGltcGxlbWVudGF0aW9uczpcbi0gW3JlYWQudHNdKGh0dHBzOi8vZ2l0aHViLmNvbS9lYXJlbmRpbC13b3Jrcy9waS1tb25vL2Jsb2IvbWFpbi9wYWNrYWdlcy9jb2RpbmctYWdlbnQvc3JjL2NvcmUvdG9vbHMvcmVhZC50cykgLSBgUmVhZFRvb2xEZXRhaWxzYFxuLSBbYmFzaC50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvY29yZS90b29scy9iYXNoLnRzKSAtIGBCYXNoVG9vbERldGFpbHNgXG4tIFtlZGl0LnRzXShodHRwczovL2dpdGh1Yi5jb20vZWFyZW5kaWwtd29ya3MvcGktbW9uby9ibG9iL21haW4vcGFja2FnZXMvY29kaW5nLWFnZW50L3NyYy9jb3JlL3Rvb2xzL2VkaXQudHMpXG4tIFt3cml0ZS50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvY29yZS90b29scy93cml0ZS50cylcbi0gW2dyZXAudHNdKGh0dHBzOi8vZ2l0aHViLmNvbS9lYXJlbmRpbC13b3Jrcy9waS1tb25vL2Jsb2IvbWFpbi9wYWNrYWdlcy9jb2RpbmctYWdlbnQvc3JjL2NvcmUvdG9vbHMvZ3JlcC50cykgLSBgR3JlcFRvb2xEZXRhaWxzYFxuLSBbZmluZC50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvY29yZS90b29scy9maW5kLnRzKSAtIGBGaW5kVG9vbERldGFpbHNgXG4tIFtscy50c10oaHR0cHM6Ly9naXRodWIuY29tL2VhcmVuZGlsLXdvcmtzL3BpLW1vbm8vYmxvYi9tYWluL3BhY2thZ2VzL2NvZGluZy1hZ2VudC9zcmMvY29yZS90b29scy9scy50cykgLSBgTHNUb29sRGV0YWlsc2BcblxuIyMjIFJlbW90ZSBFeGVjdXRpb25cblxuQnVpbHQtaW4gdG9vbHMgc3VwcG9ydCBwbHVnZ2FibGUgb3BlcmF0aW9ucyBmb3IgZGVsZWdhdGluZyB0byByZW1vdGUgc3lzdGVtcyAoU1NILCBjb250YWluZXJzLCBldGMuKTpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsgY3JlYXRlUmVhZFRvb2wsIGNyZWF0ZUJhc2hUb29sLCB0eXBlIFJlYWRPcGVyYXRpb25zIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxuLy8gQ3JlYXRlIHRvb2wgd2l0aCBjdXN0b20gb3BlcmF0aW9uc1xuY29uc3QgcmVtb3RlUmVhZCA9IGNyZWF0ZVJlYWRUb29sKGN3ZCwge1xuICBvcGVyYXRpb25zOiB7XG4gICAgcmVhZEZpbGU6IChwYXRoKSA9PiBzc2hFeGVjKHJlbW90ZSwgYGNhdCAke3BhdGh9YCksXG4gICAgYWNjZXNzOiAocGF0aCkgPT4gc3NoRXhlYyhyZW1vdGUsIGB0ZXN0IC1yICR7cGF0aH1gKS50aGVuKCgpID0+IHt9KSxcbiAgfVxufSk7XG5cbi8vIFJlZ2lzdGVyLCBjaGVja2luZyBmbGFnIGF0IGV4ZWN1dGlvbiB0aW1lXG5waS5yZWdpc3RlclRvb2woe1xuICAuLi5yZW1vdGVSZWFkLFxuICBhc3luYyBleGVjdXRlKGlkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUsIF9jdHgpIHtcbiAgICBjb25zdCBzc2ggPSBnZXRTc2hDb25maWcoKTtcbiAgICBpZiAoc3NoKSB7XG4gICAgICBjb25zdCB0b29sID0gY3JlYXRlUmVhZFRvb2woY3dkLCB7IG9wZXJhdGlvbnM6IGNyZWF0ZVJlbW90ZU9wcyhzc2gpIH0pO1xuICAgICAgcmV0dXJuIHRvb2wuZXhlY3V0ZShpZCwgcGFyYW1zLCBzaWduYWwsIG9uVXBkYXRlKTtcbiAgICB9XG4gICAgcmV0dXJuIGxvY2FsUmVhZC5leGVjdXRlKGlkLCBwYXJhbXMsIHNpZ25hbCwgb25VcGRhdGUpO1xuICB9LFxufSk7XG5gYGBcblxuKipPcGVyYXRpb25zIGludGVyZmFjZXM6KiogYFJlYWRPcGVyYXRpb25zYCwgYFdyaXRlT3BlcmF0aW9uc2AsIGBFZGl0T3BlcmF0aW9uc2AsIGBCYXNoT3BlcmF0aW9uc2AsIGBMc09wZXJhdGlvbnNgLCBgR3JlcE9wZXJhdGlvbnNgLCBgRmluZE9wZXJhdGlvbnNgXG5cbkZvciBgdXNlcl9iYXNoYCwgZXh0ZW5zaW9ucyBjYW4gcmV1c2UgcGkncyBsb2NhbCBzaGVsbCBiYWNrZW5kIHZpYSBgY3JlYXRlTG9jYWxCYXNoT3BlcmF0aW9ucygpYCBpbnN0ZWFkIG9mIHJlaW1wbGVtZW50aW5nIGxvY2FsIHByb2Nlc3Mgc3Bhd25pbmcsIHNoZWxsIHJlc29sdXRpb24sIGFuZCBwcm9jZXNzLXRyZWUgdGVybWluYXRpb24uXG5cblRoZSBiYXNoIHRvb2wgYWxzbyBzdXBwb3J0cyBhIHNwYXduIGhvb2sgdG8gYWRqdXN0IHRoZSBjb21tYW5kLCBjd2QsIG9yIGVudiBiZWZvcmUgZXhlY3V0aW9uOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBjcmVhdGVCYXNoVG9vbCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbmNvbnN0IGJhc2hUb29sID0gY3JlYXRlQmFzaFRvb2woY3dkLCB7XG4gIHNwYXduSG9vazogKHsgY29tbWFuZCwgY3dkLCBlbnYgfSkgPT4gKHtcbiAgICBjb21tYW5kOiBgc291cmNlIH4vLnByb2ZpbGVcXG4ke2NvbW1hbmR9YCxcbiAgICBjd2Q6IGAvbW50L3NhbmRib3gke2N3ZH1gLFxuICAgIGVudjogeyAuLi5lbnYsIENJOiBcIjFcIiB9LFxuICB9KSxcbn0pO1xuYGBgXG5cblNlZSBbZXhhbXBsZXMvZXh0ZW5zaW9ucy9zc2gudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvc3NoLnRzKSBmb3IgYSBjb21wbGV0ZSBTU0ggZXhhbXBsZSB3aXRoIGAtLXNzaGAgZmxhZy5cblxuIyMjIE91dHB1dCBUcnVuY2F0aW9uXG5cbioqVG9vbHMgTVVTVCB0cnVuY2F0ZSB0aGVpciBvdXRwdXQqKiB0byBhdm9pZCBvdmVyd2hlbG1pbmcgdGhlIExMTSBjb250ZXh0LiBMYXJnZSBvdXRwdXRzIGNhbiBjYXVzZTpcbi0gQ29udGV4dCBvdmVyZmxvdyBlcnJvcnMgKHByb21wdCB0b28gbG9uZylcbi0gQ29tcGFjdGlvbiBmYWlsdXJlc1xuLSBEZWdyYWRlZCBtb2RlbCBwZXJmb3JtYW5jZVxuXG5UaGUgYnVpbHQtaW4gbGltaXQgaXMgKio1MEtCKiogKH4xMGsgdG9rZW5zKSBhbmQgKioyMDAwIGxpbmVzKiosIHdoaWNoZXZlciBpcyBoaXQgZmlyc3QuIFVzZSB0aGUgZXhwb3J0ZWQgdHJ1bmNhdGlvbiB1dGlsaXRpZXM6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7XG4gIHRydW5jYXRlSGVhZCwgICAgICAvLyBLZWVwIGZpcnN0IE4gbGluZXMvYnl0ZXMgKGdvb2QgZm9yIGZpbGUgcmVhZHMsIHNlYXJjaCByZXN1bHRzKVxuICB0cnVuY2F0ZVRhaWwsICAgICAgLy8gS2VlcCBsYXN0IE4gbGluZXMvYnl0ZXMgKGdvb2QgZm9yIGxvZ3MsIGNvbW1hbmQgb3V0cHV0KVxuICB0cnVuY2F0ZUxpbmUsICAgICAgLy8gVHJ1bmNhdGUgYSBzaW5nbGUgbGluZSB0byBtYXhCeXRlcyB3aXRoIGVsbGlwc2lzXG4gIGZvcm1hdFNpemUsICAgICAgICAvLyBIdW1hbi1yZWFkYWJsZSBzaXplIChlLmcuLCBcIjUwS0JcIiwgXCIxLjVNQlwiKVxuICBERUZBVUxUX01BWF9CWVRFUywgLy8gNTBLQlxuICBERUZBVUxUX01BWF9MSU5FUywgLy8gMjAwMFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuXG5hc3luYyBleGVjdXRlKHRvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBvblVwZGF0ZSwgY3R4KSB7XG4gIGNvbnN0IG91dHB1dCA9IGF3YWl0IHJ1bkNvbW1hbmQoKTtcblxuICAvLyBBcHBseSB0cnVuY2F0aW9uXG4gIGNvbnN0IHRydW5jYXRpb24gPSB0cnVuY2F0ZUhlYWQob3V0cHV0LCB7XG4gICAgbWF4TGluZXM6IERFRkFVTFRfTUFYX0xJTkVTLFxuICAgIG1heEJ5dGVzOiBERUZBVUxUX01BWF9CWVRFUyxcbiAgfSk7XG5cbiAgbGV0IHJlc3VsdCA9IHRydW5jYXRpb24uY29udGVudDtcblxuICBpZiAodHJ1bmNhdGlvbi50cnVuY2F0ZWQpIHtcbiAgICAvLyBXcml0ZSBmdWxsIG91dHB1dCB0byB0ZW1wIGZpbGVcbiAgICBjb25zdCB0ZW1wRmlsZSA9IHdyaXRlVGVtcEZpbGUob3V0cHV0KTtcblxuICAgIC8vIEluZm9ybSB0aGUgTExNIHdoZXJlIHRvIGZpbmQgY29tcGxldGUgb3V0cHV0XG4gICAgcmVzdWx0ICs9IGBcXG5cXG5bT3V0cHV0IHRydW5jYXRlZDogJHt0cnVuY2F0aW9uLm91dHB1dExpbmVzfSBvZiAke3RydW5jYXRpb24udG90YWxMaW5lc30gbGluZXNgO1xuICAgIHJlc3VsdCArPSBgICgke2Zvcm1hdFNpemUodHJ1bmNhdGlvbi5vdXRwdXRCeXRlcyl9IG9mICR7Zm9ybWF0U2l6ZSh0cnVuY2F0aW9uLnRvdGFsQnl0ZXMpfSkuYDtcbiAgICByZXN1bHQgKz0gYCBGdWxsIG91dHB1dCBzYXZlZCB0bzogJHt0ZW1wRmlsZX1dYDtcbiAgfVxuXG4gIHJldHVybiB7IGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiByZXN1bHQgfV0gfTtcbn1cbmBgYFxuXG4qKktleSBwb2ludHM6Kipcbi0gVXNlIGB0cnVuY2F0ZUhlYWRgIGZvciBjb250ZW50IHdoZXJlIHRoZSBiZWdpbm5pbmcgbWF0dGVycyAoc2VhcmNoIHJlc3VsdHMsIGZpbGUgcmVhZHMpXG4tIFVzZSBgdHJ1bmNhdGVUYWlsYCBmb3IgY29udGVudCB3aGVyZSB0aGUgZW5kIG1hdHRlcnMgKGxvZ3MsIGNvbW1hbmQgb3V0cHV0KVxuLSBBbHdheXMgaW5mb3JtIHRoZSBMTE0gd2hlbiBvdXRwdXQgaXMgdHJ1bmNhdGVkIGFuZCB3aGVyZSB0byBmaW5kIHRoZSBmdWxsIHZlcnNpb25cbi0gRG9jdW1lbnQgdGhlIHRydW5jYXRpb24gbGltaXRzIGluIHlvdXIgdG9vbCdzIGRlc2NyaXB0aW9uXG5cblNlZSBbZXhhbXBsZXMvZXh0ZW5zaW9ucy90cnVuY2F0ZWQtdG9vbC50c10oLi4vZXhhbXBsZXMvZXh0ZW5zaW9ucy90cnVuY2F0ZWQtdG9vbC50cykgZm9yIGEgY29tcGxldGUgZXhhbXBsZSB3cmFwcGluZyBgcmdgIChyaXBncmVwKSB3aXRoIHByb3BlciB0cnVuY2F0aW9uLlxuXG4jIyMgTXVsdGlwbGUgVG9vbHNcblxuT25lIGV4dGVuc2lvbiBjYW4gcmVnaXN0ZXIgbXVsdGlwbGUgdG9vbHMgd2l0aCBzaGFyZWQgc3RhdGU6XG5cbmBgYHR5cGVzY3JpcHRcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7XG4gIGxldCBjb25uZWN0aW9uID0gbnVsbDtcblxuICBwaS5yZWdpc3RlclRvb2woeyBuYW1lOiBcImRiX2Nvbm5lY3RcIiwgLi4uIH0pO1xuICBwaS5yZWdpc3RlclRvb2woeyBuYW1lOiBcImRiX3F1ZXJ5XCIsIC4uLiB9KTtcbiAgcGkucmVnaXN0ZXJUb29sKHsgbmFtZTogXCJkYl9jbG9zZVwiLCAuLi4gfSk7XG5cbiAgcGkub24oXCJzZXNzaW9uX3NodXRkb3duXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25uZWN0aW9uPy5jbG9zZSgpO1xuICB9KTtcbn1cbmBgYFxuXG4jIyMgQ3VzdG9tIFJlbmRlcmluZ1xuXG5Ub29scyBjYW4gcHJvdmlkZSBgcmVuZGVyQ2FsbGAgYW5kIGByZW5kZXJSZXN1bHRgIGZvciBjdXN0b20gVFVJIGRpc3BsYXkuIFNlZSBbdHVpLm1kXSh0dWkubWQpIGZvciB0aGUgZnVsbCBjb21wb25lbnQgQVBJIGFuZCBbdG9vbC1leGVjdXRpb24udHNdKGh0dHBzOi8vZ2l0aHViLmNvbS9lYXJlbmRpbC13b3Jrcy9waS1tb25vL2Jsb2IvbWFpbi9wYWNrYWdlcy9jb2RpbmctYWdlbnQvc3JjL21vZGVzL2ludGVyYWN0aXZlL2NvbXBvbmVudHMvdG9vbC1leGVjdXRpb24udHMpIGZvciBob3cgdG9vbCByb3dzIGFyZSBjb21wb3NlZC5cblxuQnkgZGVmYXVsdCwgdG9vbCBvdXRwdXQgaXMgd3JhcHBlZCBpbiBhIGBCb3hgIHRoYXQgaGFuZGxlcyBwYWRkaW5nIGFuZCBiYWNrZ3JvdW5kLiBBIGRlZmluZWQgYHJlbmRlckNhbGxgIG9yIGByZW5kZXJSZXN1bHRgIG11c3QgcmV0dXJuIGEgYENvbXBvbmVudGAuIElmIGEgc2xvdCByZW5kZXJlciBpcyBub3QgZGVmaW5lZCwgYHRvb2wtZXhlY3V0aW9uLnRzYCB1c2VzIGZhbGxiYWNrIHJlbmRlcmluZyBmb3IgdGhhdCBzbG90LlxuXG5TZXQgYHJlbmRlclNoZWxsOiBcInNlbGZcImAgd2hlbiB0aGUgdG9vbCBzaG91bGQgcmVuZGVyIGl0cyBvd24gc2hlbGwgaW5zdGVhZCBvZiB1c2luZyB0aGUgZGVmYXVsdCBgQm94YC4gVGhpcyBpcyB1c2VmdWwgZm9yIHRvb2xzIHRoYXQgbmVlZCBjb21wbGV0ZSBjb250cm9sIG92ZXIgZnJhbWluZyBvciBiYWNrZ3JvdW5kIGJlaGF2aW9yLCBmb3IgZXhhbXBsZSBsYXJnZSBwcmV2aWV3cyB0aGF0IG11c3Qgc3RheSB2aXN1YWxseSBzdGFibGUgYWZ0ZXIgdGhlIHRvb2wgc2V0dGxlcy5cblxuYGBgdHlwZXNjcmlwdFxucGkucmVnaXN0ZXJUb29sKHtcbiAgbmFtZTogXCJteV90b29sXCIsXG4gIGxhYmVsOiBcIk15IFRvb2xcIixcbiAgZGVzY3JpcHRpb246IFwiQ3VzdG9tIHNoZWxsIGV4YW1wbGVcIixcbiAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICByZW5kZXJTaGVsbDogXCJzZWxmXCIsXG4gIGFzeW5jIGV4ZWN1dGUoKSB7XG4gICAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwib2tcIiB9XSwgZGV0YWlsczogdW5kZWZpbmVkIH07XG4gIH0sXG4gIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJhY2NlbnRcIiwgXCJteSBjdXN0b20gc2hlbGxcIiksIDAsIDApO1xuICB9LFxufSk7XG5gYGBcblxuYHJlbmRlckNhbGxgIGFuZCBgcmVuZGVyUmVzdWx0YCBlYWNoIHJlY2VpdmUgYSBgY29udGV4dGAgb2JqZWN0IHdpdGg6XG4tIGBhcmdzYCAtIHRoZSBjdXJyZW50IHRvb2wgY2FsbCBhcmd1bWVudHNcbi0gYHN0YXRlYCAtIHNoYXJlZCByb3ctbG9jYWwgc3RhdGUgYWNyb3NzIGByZW5kZXJDYWxsYCBhbmQgYHJlbmRlclJlc3VsdGBcbi0gYGxhc3RDb21wb25lbnRgIC0gdGhlIHByZXZpb3VzbHkgcmV0dXJuZWQgY29tcG9uZW50IGZvciB0aGF0IHNsb3QsIGlmIGFueVxuLSBgaW52YWxpZGF0ZSgpYCAtIHJlcXVlc3QgYSByZXJlbmRlciBvZiB0aGlzIHRvb2wgcm93XG4tIGB0b29sQ2FsbElkYCwgYGN3ZGAsIGBleGVjdXRpb25TdGFydGVkYCwgYGFyZ3NDb21wbGV0ZWAsIGBpc1BhcnRpYWxgLCBgZXhwYW5kZWRgLCBgc2hvd0ltYWdlc2AsIGBpc0Vycm9yYFxuXG5Vc2UgYGNvbnRleHQuc3RhdGVgIGZvciBjcm9zcy1zbG90IHNoYXJlZCBzdGF0ZS4gS2VlcCBzbG90LWxvY2FsIGNhY2hlcyBvbiB0aGUgcmV0dXJuZWQgY29tcG9uZW50IGluc3RhbmNlIHdoZW4geW91IHdhbnQgdG8gcmV1c2UgYW5kIG11dGF0ZSB0aGUgc2FtZSBjb21wb25lbnQgYWNyb3NzIHJlbmRlcnMuXG5cbiMjIyMgcmVuZGVyQ2FsbFxuXG5SZW5kZXJzIHRoZSB0b29sIGNhbGwgb3IgaGVhZGVyOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxucmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgY29udGV4dCkge1xuICBjb25zdCB0ZXh0ID0gKGNvbnRleHQubGFzdENvbXBvbmVudCBhcyBUZXh0IHwgdW5kZWZpbmVkKSA/PyBuZXcgVGV4dChcIlwiLCAwLCAwKTtcbiAgbGV0IGNvbnRlbnQgPSB0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwibXlfdG9vbCBcIikpO1xuICBjb250ZW50ICs9IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy5hY3Rpb24pO1xuICBpZiAoYXJncy50ZXh0KSB7XG4gICAgY29udGVudCArPSBcIiBcIiArIHRoZW1lLmZnKFwiZGltXCIsIGBcIiR7YXJncy50ZXh0fVwiYCk7XG4gIH1cbiAgdGV4dC5zZXRUZXh0KGNvbnRlbnQpO1xuICByZXR1cm4gdGV4dDtcbn1cbmBgYFxuXG4jIyMjIHJlbmRlclJlc3VsdFxuXG5SZW5kZXJzIHRoZSB0b29sIHJlc3VsdCBvciBvdXRwdXQ6XG5cbmBgYHR5cGVzY3JpcHRcbnJlbmRlclJlc3VsdChyZXN1bHQsIHsgZXhwYW5kZWQsIGlzUGFydGlhbCB9LCB0aGVtZSwgY29udGV4dCkge1xuICBpZiAoaXNQYXJ0aWFsKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwid2FybmluZ1wiLCBcIlByb2Nlc3NpbmcuLi5cIiksIDAsIDApO1xuICB9XG5cbiAgaWYgKHJlc3VsdC5kZXRhaWxzPy5lcnJvcikge1xuICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcImVycm9yXCIsIGBFcnJvcjogJHtyZXN1bHQuZGV0YWlscy5lcnJvcn1gKSwgMCwgMCk7XG4gIH1cblxuICBsZXQgdGV4dCA9IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKckyBEb25lXCIpO1xuICBpZiAoZXhwYW5kZWQgJiYgcmVzdWx0LmRldGFpbHM/Lml0ZW1zKSB7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIHJlc3VsdC5kZXRhaWxzLml0ZW1zKSB7XG4gICAgICB0ZXh0ICs9IFwiXFxuICBcIiArIHRoZW1lLmZnKFwiZGltXCIsIGl0ZW0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG59XG5gYGBcblxuSWYgYSBzbG90IGludGVudGlvbmFsbHkgaGFzIG5vIHZpc2libGUgY29udGVudCwgcmV0dXJuIGFuIGVtcHR5IGBDb21wb25lbnRgIHN1Y2ggYXMgYW4gZW1wdHkgYENvbnRhaW5lcmAuXG5cbiMjIyMgS2V5YmluZGluZyBIaW50c1xuXG5Vc2UgYGtleUhpbnQoKWAgdG8gZGlzcGxheSBrZXliaW5kaW5nIGhpbnRzIHRoYXQgcmVzcGVjdCB0aGUgYWN0aXZlIGtleWJpbmRpbmcgY29uZmlndXJhdGlvbjpcblxuYGBgdHlwZXNjcmlwdFxuaW1wb3J0IHsga2V5SGludCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbnJlbmRlclJlc3VsdChyZXN1bHQsIHsgZXhwYW5kZWQgfSwgdGhlbWUsIGNvbnRleHQpIHtcbiAgbGV0IHRleHQgPSB0aGVtZS5mZyhcInN1Y2Nlc3NcIiwgXCLinJMgRG9uZVwiKTtcbiAgaWYgKCFleHBhbmRlZCkge1xuICAgIHRleHQgKz0gYCAoJHtrZXlIaW50KFwiYXBwLnRvb2xzLmV4cGFuZFwiLCBcInRvIGV4cGFuZFwiKX0pYDtcbiAgfVxuICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG59XG5gYGBcblxuQXZhaWxhYmxlIGZ1bmN0aW9uczpcbi0gYGtleUhpbnQoa2V5YmluZGluZywgZGVzY3JpcHRpb24pYCAtIEZvcm1hdHMgYSBjb25maWd1cmVkIGtleWJpbmRpbmcgaWQgc3VjaCBhcyBgXCJhcHAudG9vbHMuZXhwYW5kXCJgIG9yIGBcInR1aS5zZWxlY3QuY29uZmlybVwiYFxuLSBga2V5VGV4dChrZXliaW5kaW5nKWAgLSBSZXR1cm5zIHRoZSByYXcgY29uZmlndXJlZCBrZXkgdGV4dCBmb3IgYSBrZXliaW5kaW5nIGlkXG4tIGByYXdLZXlIaW50KGtleSwgZGVzY3JpcHRpb24pYCAtIEZvcm1hdCBhIHJhdyBrZXkgc3RyaW5nXG5cblVzZSBuYW1lc3BhY2VkIGtleWJpbmRpbmcgaWRzOlxuLSBDb2RpbmctYWdlbnQgaWRzIHVzZSB0aGUgYGFwcC4qYCBuYW1lc3BhY2UsIGZvciBleGFtcGxlIGBhcHAudG9vbHMuZXhwYW5kYCwgYGFwcC5lZGl0b3IuZXh0ZXJuYWxgLCBgYXBwLnNlc3Npb24ucmVuYW1lYFxuLSBTaGFyZWQgVFVJIGlkcyB1c2UgdGhlIGB0dWkuKmAgbmFtZXNwYWNlLCBmb3IgZXhhbXBsZSBgdHVpLnNlbGVjdC5jb25maXJtYCwgYHR1aS5zZWxlY3QuY2FuY2VsYCwgYHR1aS5pbnB1dC50YWJgXG5cbkZvciB0aGUgZXhoYXVzdGl2ZSBsaXN0IG9mIGtleWJpbmRpbmcgaWRzIGFuZCBkZWZhdWx0cywgc2VlIFtrZXliaW5kaW5ncy5tZF0oa2V5YmluZGluZ3MubWQpLiBga2V5YmluZGluZ3MuanNvbmAgdXNlcyB0aG9zZSBzYW1lIG5hbWVzcGFjZWQgaWRzLlxuXG5DdXN0b20gZWRpdG9ycyBhbmQgYGN0eC51aS5jdXN0b20oKWAgY29tcG9uZW50cyByZWNlaXZlIGBrZXliaW5kaW5nczogS2V5YmluZGluZ3NNYW5hZ2VyYCBhcyBhbiBpbmplY3RlZCBhcmd1bWVudC4gVGhleSBzaG91bGQgdXNlIHRoYXQgaW5qZWN0ZWQgbWFuYWdlciBkaXJlY3RseSBpbnN0ZWFkIG9mIGNhbGxpbmcgYGdldEtleWJpbmRpbmdzKClgIG9yIGBzZXRLZXliaW5kaW5ncygpYC5cblxuIyMjIyBCZXN0IFByYWN0aWNlc1xuXG4tIFVzZSBgVGV4dGAgd2l0aCBwYWRkaW5nIGAoMCwgMClgLiBUaGUgZGVmYXVsdCBCb3ggaGFuZGxlcyBwYWRkaW5nLlxuLSBVc2UgYFxcbmAgZm9yIG11bHRpLWxpbmUgY29udGVudC5cbi0gSGFuZGxlIGBpc1BhcnRpYWxgIGZvciBzdHJlYW1pbmcgcHJvZ3Jlc3MuXG4tIFN1cHBvcnQgYGV4cGFuZGVkYCBmb3IgZGV0YWlsIG9uIGRlbWFuZC5cbi0gS2VlcCBkZWZhdWx0IHZpZXcgY29tcGFjdC5cbi0gUmVhZCBgY29udGV4dC5hcmdzYCBpbiBgcmVuZGVyUmVzdWx0YCBpbnN0ZWFkIG9mIGNvcHlpbmcgYXJncyBpbnRvIGBjb250ZXh0LnN0YXRlYC5cbi0gVXNlIGBjb250ZXh0LnN0YXRlYCBvbmx5IGZvciBkYXRhIHRoYXQgbXVzdCBiZSBzaGFyZWQgYWNyb3NzIGNhbGwgYW5kIHJlc3VsdCBzbG90cy5cbi0gUmV1c2UgYGNvbnRleHQubGFzdENvbXBvbmVudGAgd2hlbiB0aGUgc2FtZSBjb21wb25lbnQgaW5zdGFuY2UgY2FuIGJlIHVwZGF0ZWQgaW4gcGxhY2UuXG4tIFVzZSBgcmVuZGVyU2hlbGw6IFwic2VsZlwiYCBvbmx5IHdoZW4gdGhlIGRlZmF1bHQgYm94ZWQgc2hlbGwgZ2V0cyBpbiB0aGUgd2F5LiBJbiBzZWxmLXNoZWxsIG1vZGUgdGhlIHRvb2wgaXMgcmVzcG9uc2libGUgZm9yIGl0cyBvd24gZnJhbWluZywgcGFkZGluZywgYW5kIGJhY2tncm91bmQuXG5cbiMjIyMgRmFsbGJhY2tcblxuSWYgYSBzbG90IHJlbmRlcmVyIGlzIG5vdCBkZWZpbmVkIG9yIHRocm93czpcbi0gYHJlbmRlckNhbGxgOiBTaG93cyB0aGUgdG9vbCBuYW1lXG4tIGByZW5kZXJSZXN1bHRgOiBTaG93cyByYXcgdGV4dCBmcm9tIGBjb250ZW50YFxuXG4jIyBDdXN0b20gVUlcblxuRXh0ZW5zaW9ucyBjYW4gaW50ZXJhY3Qgd2l0aCB1c2VycyB2aWEgYGN0eC51aWAgbWV0aG9kcyBhbmQgY3VzdG9taXplIGhvdyBtZXNzYWdlcy90b29scyByZW5kZXIuXG5cbioqRm9yIGN1c3RvbSBjb21wb25lbnRzLCBzZWUgW3R1aS5tZF0odHVpLm1kKSoqIHdoaWNoIGhhcyBjb3B5LXBhc3RlIHBhdHRlcm5zIGZvcjpcbi0gU2VsZWN0aW9uIGRpYWxvZ3MgKFNlbGVjdExpc3QpXG4tIEFzeW5jIG9wZXJhdGlvbnMgd2l0aCBjYW5jZWwgKEJvcmRlcmVkTG9hZGVyKVxuLSBTZXR0aW5ncyB0b2dnbGVzIChTZXR0aW5nc0xpc3QpXG4tIFN0YXR1cyBpbmRpY2F0b3JzIChzZXRTdGF0dXMpXG4tIFdvcmtpbmcgbWVzc2FnZSwgdmlzaWJpbGl0eSwgYW5kIGluZGljYXRvciBkdXJpbmcgc3RyZWFtaW5nIChgc2V0V29ya2luZ01lc3NhZ2VgLCBgc2V0V29ya2luZ1Zpc2libGVgLCBgc2V0V29ya2luZ0luZGljYXRvcmApXG4tIFdpZGdldHMgYWJvdmUvYmVsb3cgZWRpdG9yIChzZXRXaWRnZXQpXG4tIEF1dG9jb21wbGV0ZSBwcm92aWRlcnMgbGF5ZXJlZCBvbiB0b3Agb2YgYnVpbHQtaW4gc2xhc2gvcGF0aCBjb21wbGV0aW9uIChhZGRBdXRvY29tcGxldGVQcm92aWRlcilcbi0gQ3VzdG9tIGZvb3RlcnMgKHNldEZvb3RlcilcblxuIyMjIERpYWxvZ3NcblxuYGBgdHlwZXNjcmlwdFxuLy8gU2VsZWN0IGZyb20gb3B0aW9uc1xuY29uc3QgY2hvaWNlID0gYXdhaXQgY3R4LnVpLnNlbGVjdChcIlBpY2sgb25lOlwiLCBbXCJBXCIsIFwiQlwiLCBcIkNcIl0pO1xuXG4vLyBDb25maXJtIGRpYWxvZ1xuY29uc3Qgb2sgPSBhd2FpdCBjdHgudWkuY29uZmlybShcIkRlbGV0ZT9cIiwgXCJUaGlzIGNhbm5vdCBiZSB1bmRvbmVcIik7XG5cbi8vIFRleHQgaW5wdXRcbmNvbnN0IG5hbWUgPSBhd2FpdCBjdHgudWkuaW5wdXQoXCJOYW1lOlwiLCBcInBsYWNlaG9sZGVyXCIpO1xuXG4vLyBNdWx0aS1saW5lIGVkaXRvclxuY29uc3QgdGV4dCA9IGF3YWl0IGN0eC51aS5lZGl0b3IoXCJFZGl0OlwiLCBcInByZWZpbGxlZCB0ZXh0XCIpO1xuXG4vLyBOb3RpZmljYXRpb24gKG5vbi1ibG9ja2luZylcbmN0eC51aS5ub3RpZnkoXCJEb25lIVwiLCBcImluZm9cIik7ICAvLyBcImluZm9cIiB8IFwid2FybmluZ1wiIHwgXCJlcnJvclwiXG5gYGBcblxuIyMjIyBUaW1lZCBEaWFsb2dzIHdpdGggQ291bnRkb3duXG5cbkRpYWxvZ3Mgc3VwcG9ydCBhIGB0aW1lb3V0YCBvcHRpb24gdGhhdCBhdXRvLWRpc21pc3NlcyB3aXRoIGEgbGl2ZSBjb3VudGRvd24gZGlzcGxheTpcblxuYGBgdHlwZXNjcmlwdFxuLy8gRGlhbG9nIHNob3dzIFwiVGl0bGUgKDVzKVwiIOKGkiBcIlRpdGxlICg0cylcIiDihpIgLi4uIOKGkiBhdXRvLWRpc21pc3NlcyBhdCAwXG5jb25zdCBjb25maXJtZWQgPSBhd2FpdCBjdHgudWkuY29uZmlybShcbiAgXCJUaW1lZCBDb25maXJtYXRpb25cIixcbiAgXCJUaGlzIGRpYWxvZyB3aWxsIGF1dG8tY2FuY2VsIGluIDUgc2Vjb25kcy4gQ29uZmlybT9cIixcbiAgeyB0aW1lb3V0OiA1MDAwIH1cbik7XG5cbmlmIChjb25maXJtZWQpIHtcbiAgLy8gVXNlciBjb25maXJtZWRcbn0gZWxzZSB7XG4gIC8vIFVzZXIgY2FuY2VsbGVkIG9yIHRpbWVkIG91dFxufVxuYGBgXG5cbioqUmV0dXJuIHZhbHVlcyBvbiB0aW1lb3V0OioqXG4tIGBzZWxlY3QoKWAgcmV0dXJucyBgdW5kZWZpbmVkYFxuLSBgY29uZmlybSgpYCByZXR1cm5zIGBmYWxzZWBcbi0gYGlucHV0KClgIHJldHVybnMgYHVuZGVmaW5lZGBcblxuIyMjIyBNYW51YWwgRGlzbWlzc2FsIHdpdGggQWJvcnRTaWduYWxcblxuRm9yIG1vcmUgY29udHJvbCAoZS5nLiwgdG8gZGlzdGluZ3Vpc2ggdGltZW91dCBmcm9tIHVzZXIgY2FuY2VsKSwgdXNlIGBBYm9ydFNpZ25hbGA6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5jb25zdCB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgNTAwMCk7XG5cbmNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IGN0eC51aS5jb25maXJtKFxuICBcIlRpbWVkIENvbmZpcm1hdGlvblwiLFxuICBcIlRoaXMgZGlhbG9nIHdpbGwgYXV0by1jYW5jZWwgaW4gNSBzZWNvbmRzLiBDb25maXJtP1wiLFxuICB7IHNpZ25hbDogY29udHJvbGxlci5zaWduYWwgfVxuKTtcblxuY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG5cbmlmIChjb25maXJtZWQpIHtcbiAgLy8gVXNlciBjb25maXJtZWRcbn0gZWxzZSBpZiAoY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAvLyBEaWFsb2cgdGltZWQgb3V0XG59IGVsc2Uge1xuICAvLyBVc2VyIGNhbmNlbGxlZCAocHJlc3NlZCBFc2NhcGUgb3Igc2VsZWN0ZWQgXCJOb1wiKVxufVxuYGBgXG5cblNlZSBbZXhhbXBsZXMvZXh0ZW5zaW9ucy90aW1lZC1jb25maXJtLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL3RpbWVkLWNvbmZpcm0udHMpIGZvciBjb21wbGV0ZSBleGFtcGxlcy5cblxuIyMjIFdpZGdldHMsIFN0YXR1cywgYW5kIEZvb3RlclxuXG5gYGB0eXBlc2NyaXB0XG4vLyBTdGF0dXMgaW4gZm9vdGVyIChwZXJzaXN0ZW50IHVudGlsIGNsZWFyZWQpXG5jdHgudWkuc2V0U3RhdHVzKFwibXktZXh0XCIsIFwiUHJvY2Vzc2luZy4uLlwiKTtcbmN0eC51aS5zZXRTdGF0dXMoXCJteS1leHRcIiwgdW5kZWZpbmVkKTsgIC8vIENsZWFyXG5cbi8vIFdvcmtpbmcgbG9hZGVyIChzaG93biBkdXJpbmcgc3RyZWFtaW5nKVxuY3R4LnVpLnNldFdvcmtpbmdNZXNzYWdlKFwiVGhpbmtpbmcgZGVlcGx5Li4uXCIpO1xuY3R4LnVpLnNldFdvcmtpbmdNZXNzYWdlKCk7ICAvLyBSZXN0b3JlIGRlZmF1bHRcbmN0eC51aS5zZXRXb3JraW5nVmlzaWJsZShmYWxzZSk7ICAvLyBIaWRlIHRoZSBidWlsdC1pbiB3b3JraW5nIGxvYWRlciByb3cgZW50aXJlbHlcbmN0eC51aS5zZXRXb3JraW5nVmlzaWJsZSh0cnVlKTsgICAvLyBTaG93IHRoZSBidWlsdC1pbiB3b3JraW5nIGxvYWRlciByb3dcblxuLy8gV29ya2luZyBpbmRpY2F0b3IgKHNob3duIGR1cmluZyBzdHJlYW1pbmcpXG5jdHgudWkuc2V0V29ya2luZ0luZGljYXRvcih7IGZyYW1lczogW2N0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBcIuKXj1wiKV0gfSk7ICAvLyBTdGF0aWMgZG90XG5jdHgudWkuc2V0V29ya2luZ0luZGljYXRvcih7XG4gIGZyYW1lczogW1xuICAgIGN0eC51aS50aGVtZS5mZyhcImRpbVwiLCBcIsK3XCIpLFxuICAgIGN0eC51aS50aGVtZS5mZyhcIm11dGVkXCIsIFwi4oCiXCIpLFxuICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBcIuKXj1wiKSxcbiAgICBjdHgudWkudGhlbWUuZmcoXCJtdXRlZFwiLCBcIuKAolwiKSxcbiAgXSxcbiAgaW50ZXJ2YWxNczogMTIwLFxufSk7XG5jdHgudWkuc2V0V29ya2luZ0luZGljYXRvcih7IGZyYW1lczogW10gfSk7ICAvLyBIaWRlIGluZGljYXRvclxuY3R4LnVpLnNldFdvcmtpbmdJbmRpY2F0b3IoKTsgIC8vIFJlc3RvcmUgZGVmYXVsdCBzcGlubmVyXG5cbi8vIFdpZGdldCBhYm92ZSBlZGl0b3IgKGRlZmF1bHQpXG5jdHgudWkuc2V0V2lkZ2V0KFwibXktd2lkZ2V0XCIsIFtcIkxpbmUgMVwiLCBcIkxpbmUgMlwiXSk7XG4vLyBXaWRnZXQgYmVsb3cgZWRpdG9yXG5jdHgudWkuc2V0V2lkZ2V0KFwibXktd2lkZ2V0XCIsIFtcIkxpbmUgMVwiLCBcIkxpbmUgMlwiXSwgeyBwbGFjZW1lbnQ6IFwiYmVsb3dFZGl0b3JcIiB9KTtcbmN0eC51aS5zZXRXaWRnZXQoXCJteS13aWRnZXRcIiwgKHR1aSwgdGhlbWUpID0+IG5ldyBUZXh0KHRoZW1lLmZnKFwiYWNjZW50XCIsIFwiQ3VzdG9tXCIpLCAwLCAwKSk7XG5jdHgudWkuc2V0V2lkZ2V0KFwibXktd2lkZ2V0XCIsIHVuZGVmaW5lZCk7ICAvLyBDbGVhclxuXG4vLyBDdXN0b20gZm9vdGVyIChyZXBsYWNlcyBidWlsdC1pbiBmb290ZXIgZW50aXJlbHkpXG5jdHgudWkuc2V0Rm9vdGVyKCh0dWksIHRoZW1lKSA9PiAoe1xuICByZW5kZXIod2lkdGgpIHsgcmV0dXJuIFt0aGVtZS5mZyhcImRpbVwiLCBcIkN1c3RvbSBmb290ZXJcIildOyB9LFxuICBpbnZhbGlkYXRlKCkge30sXG59KSk7XG5jdHgudWkuc2V0Rm9vdGVyKHVuZGVmaW5lZCk7ICAvLyBSZXN0b3JlIGJ1aWx0LWluIGZvb3RlclxuXG4vLyBUZXJtaW5hbCB0aXRsZVxuY3R4LnVpLnNldFRpdGxlKFwicGkgLSBteS1wcm9qZWN0XCIpO1xuXG4vLyBFZGl0b3IgdGV4dFxuY3R4LnVpLnNldEVkaXRvclRleHQoXCJQcmVmaWxsIHRleHRcIik7XG5jb25zdCBjdXJyZW50ID0gY3R4LnVpLmdldEVkaXRvclRleHQoKTtcblxuLy8gUGFzdGUgaW50byBlZGl0b3IgKHRyaWdnZXJzIHBhc3RlIGhhbmRsaW5nLCBpbmNsdWRpbmcgY29sbGFwc2UgZm9yIGxhcmdlIGNvbnRlbnQpXG5jdHgudWkucGFzdGVUb0VkaXRvcihcInBhc3RlZCBjb250ZW50XCIpO1xuXG4vLyBTdGFjayBjdXN0b20gYXV0b2NvbXBsZXRlIGJlaGF2aW9yIG9uIHRvcCBvZiB0aGUgYnVpbHQtaW4gcHJvdmlkZXJcbmN0eC51aS5hZGRBdXRvY29tcGxldGVQcm92aWRlcigoY3VycmVudCkgPT4gKHtcbiAgdHJpZ2dlckNoYXJhY3RlcnM6IFtcIiNcIl0sXG4gIGFzeW5jIGdldFN1Z2dlc3Rpb25zKGxpbmVzLCBsaW5lLCBjb2wsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBiZWZvcmVDdXJzb3IgPSAobGluZXNbbGluZV0gPz8gXCJcIikuc2xpY2UoMCwgY29sKTtcbiAgICBjb25zdCBtYXRjaCA9IGJlZm9yZUN1cnNvci5tYXRjaCgvKD86XnxbIFxcdF0pIyhbXlxccyNdKikkLyk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgcmV0dXJuIGN1cnJlbnQuZ2V0U3VnZ2VzdGlvbnMobGluZXMsIGxpbmUsIGNvbCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByZWZpeDogYCMke21hdGNoWzFdID8/IFwiXCJ9YCxcbiAgICAgIGl0ZW1zOiBbeyB2YWx1ZTogXCIjMjk4M1wiLCBsYWJlbDogXCIjMjk4M1wiLCBkZXNjcmlwdGlvbjogXCJFeHRlbnNpb24gQVBJIGZvciBhdXRvY29tcGxldGVcIiB9XSxcbiAgICB9O1xuICB9LFxuICBhcHBseUNvbXBsZXRpb24obGluZXMsIGxpbmUsIGNvbCwgaXRlbSwgcHJlZml4KSB7XG4gICAgcmV0dXJuIGN1cnJlbnQuYXBwbHlDb21wbGV0aW9uKGxpbmVzLCBsaW5lLCBjb2wsIGl0ZW0sIHByZWZpeCk7XG4gIH0sXG4gIHNob3VsZFRyaWdnZXJGaWxlQ29tcGxldGlvbihsaW5lcywgbGluZSwgY29sKSB7XG4gICAgcmV0dXJuIGN1cnJlbnQuc2hvdWxkVHJpZ2dlckZpbGVDb21wbGV0aW9uPy4obGluZXMsIGxpbmUsIGNvbCkgPz8gdHJ1ZTtcbiAgfSxcbn0pKTtcblxuLy8gVG9vbCBvdXRwdXQgZXhwYW5zaW9uXG5jb25zdCB3YXNFeHBhbmRlZCA9IGN0eC51aS5nZXRUb29sc0V4cGFuZGVkKCk7XG5jdHgudWkuc2V0VG9vbHNFeHBhbmRlZCh0cnVlKTtcbmN0eC51aS5zZXRUb29sc0V4cGFuZGVkKHdhc0V4cGFuZGVkKTtcblxuLy8gQ3VzdG9tIGVkaXRvciAodmltIG1vZGUsIGVtYWNzIG1vZGUsIGV0Yy4pXG5jdHgudWkuc2V0RWRpdG9yQ29tcG9uZW50KCh0dWksIHRoZW1lLCBrZXliaW5kaW5ncykgPT4gbmV3IFZpbUVkaXRvcih0dWksIHRoZW1lLCBrZXliaW5kaW5ncykpO1xuY29uc3QgY3VycmVudEVkaXRvciA9IGN0eC51aS5nZXRFZGl0b3JDb21wb25lbnQoKTtcbmN0eC51aS5zZXRFZGl0b3JDb21wb25lbnQoKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzKSA9PlxuICBuZXcgV3JhcHBlZEVkaXRvcih0dWksIHRoZW1lLCBrZXliaW5kaW5ncywgY3VycmVudEVkaXRvcj8uKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzKSlcbik7XG5jdHgudWkuc2V0RWRpdG9yQ29tcG9uZW50KHVuZGVmaW5lZCk7ICAvLyBSZXN0b3JlIGRlZmF1bHQgZWRpdG9yXG5cbi8vIFRoZW1lIG1hbmFnZW1lbnQgKHNlZSB0aGVtZXMubWQgZm9yIGNyZWF0aW5nIHRoZW1lcylcbmNvbnN0IHRoZW1lcyA9IGN0eC51aS5nZXRBbGxUaGVtZXMoKTsgIC8vIFt7IG5hbWU6IFwiZGFya1wiLCBwYXRoOiBcIi8uLi5cIiB8IHVuZGVmaW5lZCB9LCAuLi5dXG5jb25zdCBsaWdodFRoZW1lID0gY3R4LnVpLmdldFRoZW1lKFwibGlnaHRcIik7ICAvLyBMb2FkIHdpdGhvdXQgc3dpdGNoaW5nXG5jb25zdCByZXN1bHQgPSBjdHgudWkuc2V0VGhlbWUoXCJsaWdodFwiKTsgIC8vIFN3aXRjaCBieSBuYW1lXG5pZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gIGN0eC51aS5ub3RpZnkoYEZhaWxlZDogJHtyZXN1bHQuZXJyb3J9YCwgXCJlcnJvclwiKTtcbn1cbmN0eC51aS5zZXRUaGVtZShsaWdodFRoZW1lISk7ICAvLyBPciBzd2l0Y2ggYnkgVGhlbWUgb2JqZWN0XG5jdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgXCJzdHlsZWQgdGV4dFwiKTsgIC8vIEFjY2VzcyBjdXJyZW50IHRoZW1lXG5gYGBcblxuQ3VzdG9tIHdvcmtpbmctaW5kaWNhdG9yIGZyYW1lcyBhcmUgcmVuZGVyZWQgdmVyYmF0aW0uIElmIHlvdSB3YW50IGNvbG9ycywgYWRkIHRoZW0gdG8gdGhlIGZyYW1lIHN0cmluZ3MgeW91cnNlbGYsIGZvciBleGFtcGxlIHdpdGggYGN0eC51aS50aGVtZS5mZyguLi4pYC5cblxuIyMjIEF1dG9jb21wbGV0ZSBQcm92aWRlcnNcblxuVXNlIGBjdHgudWkuYWRkQXV0b2NvbXBsZXRlUHJvdmlkZXIoKWAgdG8gc3RhY2sgY3VzdG9tIGF1dG9jb21wbGV0ZSBsb2dpYyBvbiB0b3Agb2YgdGhlIGJ1aWx0LWluIHNsYXNoLWNvbW1hbmQgYW5kIHBhdGggcHJvdmlkZXIuIFNldCBgdHJpZ2dlckNoYXJhY3RlcnNgIGZvciBjdXN0b20gbmF0dXJhbCB0cmlnZ2VycyBzdWNoIGFzIGAkYC5cblxuVHlwaWNhbCBwYXR0ZXJuOlxuXG4tIGluc3BlY3QgdGhlIHRleHQgYmVmb3JlIHRoZSBjdXJzb3Jcbi0gcmV0dXJuIHlvdXIgb3duIHN1Z2dlc3Rpb25zIHdoZW4geW91ciBleHRlbnNpb24tc3BlY2lmaWMgc3ludGF4IG1hdGNoZXNcbi0gb3RoZXJ3aXNlIGRlbGVnYXRlIHRvIGBjdXJyZW50LmdldFN1Z2dlc3Rpb25zKC4uLilgXG4tIGRlbGVnYXRlIGBhcHBseUNvbXBsZXRpb24oLi4uKWAgdW5sZXNzIHlvdSBuZWVkIGN1c3RvbSBpbnNlcnRpb24gYmVoYXZpb3JcblxuYGBgdHlwZXNjcmlwdFxucGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIChfZXZlbnQsIGN0eCkgPT4ge1xuICBjdHgudWkuYWRkQXV0b2NvbXBsZXRlUHJvdmlkZXIoKGN1cnJlbnQpID0+ICh7XG4gICAgdHJpZ2dlckNoYXJhY3RlcnM6IFtcIiNcIl0sXG4gICAgYXN5bmMgZ2V0U3VnZ2VzdGlvbnMobGluZXMsIGN1cnNvckxpbmUsIGN1cnNvckNvbCwgb3B0aW9ucykge1xuICAgICAgY29uc3QgbGluZSA9IGxpbmVzW2N1cnNvckxpbmVdID8/IFwiXCI7XG4gICAgICBjb25zdCBiZWZvcmVDdXJzb3IgPSBsaW5lLnNsaWNlKDAsIGN1cnNvckNvbCk7XG4gICAgICBjb25zdCBtYXRjaCA9IGJlZm9yZUN1cnNvci5tYXRjaCgvKD86XnxbIFxcdF0pIyhbXlxccyNdKikkLyk7XG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50LmdldFN1Z2dlc3Rpb25zKGxpbmVzLCBjdXJzb3JMaW5lLCBjdXJzb3JDb2wsIG9wdGlvbnMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcmVmaXg6IGAjJHttYXRjaFsxXSA/PyBcIlwifWAsXG4gICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgeyB2YWx1ZTogXCIjMjk4M1wiLCBsYWJlbDogXCIjMjk4M1wiLCBkZXNjcmlwdGlvbjogXCJFeHRlbnNpb24gQVBJIGZvciByZWdpc3RlcmluZyBjdXN0b20gQCBhdXRvY29tcGxldGUgcHJvdmlkZXJzXCIgfSxcbiAgICAgICAgICB7IHZhbHVlOiBcIiMyNzUzXCIsIGxhYmVsOiBcIiMyNzUzXCIsIGRlc2NyaXB0aW9uOiBcIlJlbG9hZCBzdGFsZSByZXNvdXJjZSBzZXR0aW5nc1wiIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0sXG5cbiAgICBhcHBseUNvbXBsZXRpb24obGluZXMsIGN1cnNvckxpbmUsIGN1cnNvckNvbCwgaXRlbSwgcHJlZml4KSB7XG4gICAgICByZXR1cm4gY3VycmVudC5hcHBseUNvbXBsZXRpb24obGluZXMsIGN1cnNvckxpbmUsIGN1cnNvckNvbCwgaXRlbSwgcHJlZml4KTtcbiAgICB9LFxuXG4gICAgc2hvdWxkVHJpZ2dlckZpbGVDb21wbGV0aW9uKGxpbmVzLCBjdXJzb3JMaW5lLCBjdXJzb3JDb2wpIHtcbiAgICAgIHJldHVybiBjdXJyZW50LnNob3VsZFRyaWdnZXJGaWxlQ29tcGxldGlvbj8uKGxpbmVzLCBjdXJzb3JMaW5lLCBjdXJzb3JDb2wpID8/IHRydWU7XG4gICAgfSxcbiAgfSkpO1xufSk7XG5gYGBcblxuU2VlIFtnaXRodWItaXNzdWUtYXV0b2NvbXBsZXRlLnRzXSguLi9leGFtcGxlcy9leHRlbnNpb25zL2dpdGh1Yi1pc3N1ZS1hdXRvY29tcGxldGUudHMpIGZvciBhIGNvbXBsZXRlIGV4YW1wbGUgdGhhdCBwcmVsb2FkcyB0aGUgbGF0ZXN0IG9wZW4gR2l0SHViIGlzc3VlcyB3aXRoIGBnaCBpc3N1ZSBsaXN0YCBhbmQgZmlsdGVycyB0aGVtIGxvY2FsbHkgZm9yIGZhc3QgYCMuLi5gIGNvbXBsZXRpb24uIEl0IHJlcXVpcmVzIEdpdEh1YiBDTEkgKGBnaGApIGFuZCBhIEdpdEh1YiByZXBvc2l0b3J5IGNoZWNrb3V0LlxuXG4jIyMgQ3VzdG9tIENvbXBvbmVudHNcblxuRm9yIGNvbXBsZXggVUksIHVzZSBgY3R4LnVpLmN1c3RvbSgpYC4gVGhpcyB0ZW1wb3JhcmlseSByZXBsYWNlcyB0aGUgZWRpdG9yIHdpdGggeW91ciBjb21wb25lbnQgdW50aWwgYGRvbmUoKWAgaXMgY2FsbGVkOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBUZXh0LCBDb21wb25lbnQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuXG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHgudWkuY3VzdG9tPGJvb2xlYW4+KCh0dWksIHRoZW1lLCBrZXliaW5kaW5ncywgZG9uZSkgPT4ge1xuICBjb25zdCB0ZXh0ID0gbmV3IFRleHQoXCJQcmVzcyBFbnRlciB0byBjb25maXJtLCBFc2NhcGUgdG8gY2FuY2VsXCIsIDEsIDEpO1xuXG4gIHRleHQub25LZXkgPSAoa2V5KSA9PiB7XG4gICAgaWYgKGtleSA9PT0gXCJyZXR1cm5cIikgZG9uZSh0cnVlKTtcbiAgICBpZiAoa2V5ID09PSBcImVzY2FwZVwiKSBkb25lKGZhbHNlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICByZXR1cm4gdGV4dDtcbn0pO1xuXG5pZiAocmVzdWx0KSB7XG4gIC8vIFVzZXIgcHJlc3NlZCBFbnRlclxufVxuYGBgXG5cblRoZSBjYWxsYmFjayByZWNlaXZlczpcbi0gYHR1aWAgLSBUVUkgaW5zdGFuY2UgKGZvciBzY3JlZW4gZGltZW5zaW9ucywgZm9jdXMgbWFuYWdlbWVudClcbi0gYHRoZW1lYCAtIEN1cnJlbnQgdGhlbWUgZm9yIHN0eWxpbmdcbi0gYGtleWJpbmRpbmdzYCAtIEFwcCBrZXliaW5kaW5nIG1hbmFnZXIgKGZvciBjaGVja2luZyBzaG9ydGN1dHMpXG4tIGBkb25lKHZhbHVlKWAgLSBDYWxsIHRvIGNsb3NlIGNvbXBvbmVudCBhbmQgcmV0dXJuIHZhbHVlXG5cblNlZSBbdHVpLm1kXSh0dWkubWQpIGZvciB0aGUgZnVsbCBjb21wb25lbnQgQVBJLlxuXG4jIyMjIE92ZXJsYXkgTW9kZSAoRXhwZXJpbWVudGFsKVxuXG5QYXNzIGB7IG92ZXJsYXk6IHRydWUgfWAgdG8gcmVuZGVyIHRoZSBjb21wb25lbnQgYXMgYSBmbG9hdGluZyBtb2RhbCBvbiB0b3Agb2YgZXhpc3RpbmcgY29udGVudCwgd2l0aG91dCBjbGVhcmluZyB0aGUgc2NyZWVuOlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHgudWkuY3VzdG9tPHN0cmluZyB8IG51bGw+KFxuICAodHVpLCB0aGVtZSwga2V5YmluZGluZ3MsIGRvbmUpID0+IG5ldyBNeU92ZXJsYXlDb21wb25lbnQoeyBvbkNsb3NlOiBkb25lIH0pLFxuICB7IG92ZXJsYXk6IHRydWUgfVxuKTtcbmBgYFxuXG5Gb3IgYWR2YW5jZWQgcG9zaXRpb25pbmcgKGFuY2hvcnMsIG1hcmdpbnMsIHBlcmNlbnRhZ2VzLCByZXNwb25zaXZlIHZpc2liaWxpdHkpLCBwYXNzIGBvdmVybGF5T3B0aW9uc2AuIFVzZSBgb25IYW5kbGVgIHRvIGNvbnRyb2wgZm9jdXMgb3IgdmlzaWJpbGl0eSBwcm9ncmFtbWF0aWNhbGx5OlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCByZXN1bHQgPSBhd2FpdCBjdHgudWkuY3VzdG9tPHN0cmluZyB8IG51bGw+KFxuICAodHVpLCB0aGVtZSwga2V5YmluZGluZ3MsIGRvbmUpID0+IG5ldyBNeU92ZXJsYXlDb21wb25lbnQoeyBvbkNsb3NlOiBkb25lIH0pLFxuICB7XG4gICAgb3ZlcmxheTogdHJ1ZSxcbiAgICBvdmVybGF5T3B0aW9uczogeyBhbmNob3I6IFwidG9wLXJpZ2h0XCIsIHdpZHRoOiBcIjUwJVwiLCBtYXJnaW46IDIgfSxcbiAgICBvbkhhbmRsZTogKGhhbmRsZSkgPT4ge1xuICAgICAgaGFuZGxlLmZvY3VzKCk7IC8vIGZvY3VzIHRoaXMgb3ZlcmxheSBhbmQgYnJpbmcgaXQgdG8gdGhlIHZpc3VhbCBmcm9udFxuICAgICAgLy8gaGFuZGxlLnVuZm9jdXMoeyB0YXJnZXQ6IGVkaXRvckNvbXBvbmVudCB9KTsgLy8gcmVsZWFzZSBpbnB1dCB0byBhIHNwZWNpZmljIGNvbXBvbmVudFxuICAgICAgLy8gaGFuZGxlLnNldEhpZGRlbih0cnVlL2ZhbHNlKTsgLy8gdG9nZ2xlIHZpc2liaWxpdHlcbiAgICAgIC8vIGhhbmRsZS5oaWRlKCk7IC8vIHBlcm1hbmVudGx5IHJlbW92ZVxuICAgIH1cbiAgfVxuKTtcbmBgYFxuXG5BIGZvY3VzZWQgdmlzaWJsZSBvdmVybGF5IGNhbiByZWNsYWltIGlucHV0IGFmdGVyIHRlbXBvcmFyeSBub24tb3ZlcmxheSBjdXN0b20gVUkgY2xvc2VzLiBJZiB5b3UgaW50ZW50aW9uYWxseSB3YW50IGFub3RoZXIgY29tcG9uZW50IHRvIGtlZXAgaW5wdXQgd2hpbGUgdGhlIG92ZXJsYXkgc3RheXMgdmlzaWJsZSwgY2FsbCBgaGFuZGxlLnVuZm9jdXMoeyB0YXJnZXQgfSlgLiBQYXNzaW5nIGB7IHRhcmdldDogbnVsbCB9YCByZWxlYXNlcyB0aGUgb3ZlcmxheSB3aXRob3V0IGZvY3VzaW5nIGFub3RoZXIgY29tcG9uZW50LlxuXG5TZWUgW3R1aS5tZF0odHVpLm1kKSBmb3IgdGhlIGZ1bGwgYE92ZXJsYXlPcHRpb25zYCBhbmQgYE92ZXJsYXlIYW5kbGVgIEFQSSBhbmQgW292ZXJsYXktcWEtdGVzdHMudHNdKC4uL2V4YW1wbGVzL2V4dGVuc2lvbnMvb3ZlcmxheS1xYS10ZXN0cy50cykgZm9yIGV4YW1wbGVzLlxuXG4jIyMgQ3VzdG9tIEVkaXRvclxuXG5SZXBsYWNlIHRoZSBtYWluIGlucHV0IGVkaXRvciB3aXRoIGEgY3VzdG9tIGltcGxlbWVudGF0aW9uICh2aW0gbW9kZSwgZW1hY3MgbW9kZSwgZXRjLik6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IEN1c3RvbUVkaXRvciwgdHlwZSBFeHRlbnNpb25BUEkgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgbWF0Y2hlc0tleSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5cbmNsYXNzIFZpbUVkaXRvciBleHRlbmRzIEN1c3RvbUVkaXRvciB7XG4gIHByaXZhdGUgbW9kZTogXCJub3JtYWxcIiB8IFwiaW5zZXJ0XCIgPSBcImluc2VydFwiO1xuXG4gIGhhbmRsZUlucHV0KGRhdGE6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChtYXRjaGVzS2V5KGRhdGEsIFwiZXNjYXBlXCIpICYmIHRoaXMubW9kZSA9PT0gXCJpbnNlcnRcIikge1xuICAgICAgdGhpcy5tb2RlID0gXCJub3JtYWxcIjtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gXCJub3JtYWxcIiAmJiBkYXRhID09PSBcImlcIikge1xuICAgICAgdGhpcy5tb2RlID0gXCJpbnNlcnRcIjtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc3VwZXIuaGFuZGxlSW5wdXQoZGF0YSk7ICAvLyBBcHAga2V5YmluZGluZ3MgKyB0ZXh0IGVkaXRpbmdcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAocGk6IEV4dGVuc2lvbkFQSSkge1xuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgY3R4LnVpLnNldEVkaXRvckNvbXBvbmVudCgoX3R1aSwgdGhlbWUsIGtleWJpbmRpbmdzKSA9PlxuICAgICAgbmV3IFZpbUVkaXRvcih0aGVtZSwga2V5YmluZGluZ3MpXG4gICAgKTtcbiAgfSk7XG59XG5gYGBcblxuKipLZXkgcG9pbnRzOioqXG4tIEV4dGVuZCBgQ3VzdG9tRWRpdG9yYCAobm90IGJhc2UgYEVkaXRvcmApIHRvIGdldCBhcHAga2V5YmluZGluZ3MgKGVzY2FwZSB0byBhYm9ydCwgY3RybCtkLCBtb2RlbCBzd2l0Y2hpbmcpXG4tIENhbGwgYHN1cGVyLmhhbmRsZUlucHV0KGRhdGEpYCBmb3Iga2V5cyB5b3UgZG9uJ3QgaGFuZGxlXG4tIEZhY3RvcnkgcmVjZWl2ZXMgYHRoZW1lYCBhbmQgYGtleWJpbmRpbmdzYCBmcm9tIHRoZSBhcHBcbi0gVXNlIGBjdHgudWkuZ2V0RWRpdG9yQ29tcG9uZW50KClgIGJlZm9yZSBgc2V0RWRpdG9yQ29tcG9uZW50KClgIHRvIHdyYXAgdGhlIHByZXZpb3VzbHkgY29uZmlndXJlZCBjdXN0b20gZWRpdG9yXG4tIFBhc3MgYHVuZGVmaW5lZGAgdG8gcmVzdG9yZSBkZWZhdWx0OiBgY3R4LnVpLnNldEVkaXRvckNvbXBvbmVudCh1bmRlZmluZWQpYFxuXG5UbyBjb21wb3NlIHdpdGggYW5vdGhlciBleHRlbnNpb24gdGhhdCBhbHJlYWR5IHJlcGxhY2VkIHRoZSBlZGl0b3IsIGNhcHR1cmUgdGhlIHByZXZpb3VzIGZhY3RvcnkgYmVmb3JlIHNldHRpbmcgeW91cnM6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHByZXZpb3VzID0gY3R4LnVpLmdldEVkaXRvckNvbXBvbmVudCgpO1xuY3R4LnVpLnNldEVkaXRvckNvbXBvbmVudCgodHVpLCB0aGVtZSwga2V5YmluZGluZ3MpID0+XG4gIG5ldyBNeUVkaXRvcih0dWksIHRoZW1lLCBrZXliaW5kaW5ncywgeyBiYXNlOiBwcmV2aW91cz8uKHR1aSwgdGhlbWUsIGtleWJpbmRpbmdzKSB9KVxuKTtcbmBgYFxuXG5TZWUgW3R1aS5tZF0odHVpLm1kKSBQYXR0ZXJuIDcgZm9yIGEgY29tcGxldGUgZXhhbXBsZSB3aXRoIG1vZGUgaW5kaWNhdG9yLlxuXG4jIyMgTWVzc2FnZSBSZW5kZXJpbmdcblxuUmVnaXN0ZXIgYSBjdXN0b20gcmVuZGVyZXIgZm9yIG1lc3NhZ2VzIHdpdGggeW91ciBgY3VzdG9tVHlwZWA6XG5cbmBgYHR5cGVzY3JpcHRcbmltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuXG5waS5yZWdpc3Rlck1lc3NhZ2VSZW5kZXJlcihcIm15LWV4dGVuc2lvblwiLCAobWVzc2FnZSwgb3B0aW9ucywgdGhlbWUpID0+IHtcbiAgY29uc3QgeyBleHBhbmRlZCB9ID0gb3B0aW9ucztcbiAgbGV0IHRleHQgPSB0aGVtZS5mZyhcImFjY2VudFwiLCBgWyR7bWVzc2FnZS5jdXN0b21UeXBlfV0gYCk7XG4gIHRleHQgKz0gbWVzc2FnZS5jb250ZW50O1xuXG4gIGlmIChleHBhbmRlZCAmJiBtZXNzYWdlLmRldGFpbHMpIHtcbiAgICB0ZXh0ICs9IFwiXFxuXCIgKyB0aGVtZS5mZyhcImRpbVwiLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlLmRldGFpbHMsIG51bGwsIDIpKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbn0pO1xuYGBgXG5cbk1lc3NhZ2VzIGFyZSBzZW50IHZpYSBgcGkuc2VuZE1lc3NhZ2UoKWA6XG5cbmBgYHR5cGVzY3JpcHRcbnBpLnNlbmRNZXNzYWdlKHtcbiAgY3VzdG9tVHlwZTogXCJteS1leHRlbnNpb25cIiwgIC8vIE1hdGNoZXMgcmVnaXN0ZXJNZXNzYWdlUmVuZGVyZXJcbiAgY29udGVudDogXCJTdGF0dXMgdXBkYXRlXCIsXG4gIGRpc3BsYXk6IHRydWUsICAgICAgICAgICAgICAgLy8gU2hvdyBpbiBUVUlcbiAgZGV0YWlsczogeyAuLi4gfSwgICAgICAgICAgICAvLyBBdmFpbGFibGUgaW4gcmVuZGVyZXJcbn0pO1xuYGBgXG5cbiMjIyBUaGVtZSBDb2xvcnNcblxuQWxsIHJlbmRlciBmdW5jdGlvbnMgcmVjZWl2ZSBhIGB0aGVtZWAgb2JqZWN0LiBTZWUgW3RoZW1lcy5tZF0odGhlbWVzLm1kKSBmb3IgY3JlYXRpbmcgY3VzdG9tIHRoZW1lcyBhbmQgdGhlIGZ1bGwgY29sb3IgcGFsZXR0ZS5cblxuYGBgdHlwZXNjcmlwdFxuLy8gRm9yZWdyb3VuZCBjb2xvcnNcbnRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRleHQpICAgLy8gVG9vbCBuYW1lc1xudGhlbWUuZmcoXCJhY2NlbnRcIiwgdGV4dCkgICAgICAvLyBIaWdobGlnaHRzXG50aGVtZS5mZyhcInN1Y2Nlc3NcIiwgdGV4dCkgICAgIC8vIFN1Y2Nlc3MgKGdyZWVuKVxudGhlbWUuZmcoXCJlcnJvclwiLCB0ZXh0KSAgICAgICAvLyBFcnJvcnMgKHJlZClcbnRoZW1lLmZnKFwid2FybmluZ1wiLCB0ZXh0KSAgICAgLy8gV2FybmluZ3MgKHllbGxvdylcbnRoZW1lLmZnKFwibXV0ZWRcIiwgdGV4dCkgICAgICAgLy8gU2Vjb25kYXJ5IHRleHRcbnRoZW1lLmZnKFwiZGltXCIsIHRleHQpICAgICAgICAgLy8gVGVydGlhcnkgdGV4dFxuXG4vLyBUZXh0IHN0eWxlc1xudGhlbWUuYm9sZCh0ZXh0KVxudGhlbWUuaXRhbGljKHRleHQpXG50aGVtZS5zdHJpa2V0aHJvdWdoKHRleHQpXG5gYGBcblxuRm9yIHN5bnRheCBoaWdobGlnaHRpbmcgaW4gY3VzdG9tIHRvb2wgcmVuZGVyZXJzOlxuXG5gYGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBoaWdobGlnaHRDb2RlLCBnZXRMYW5ndWFnZUZyb21QYXRoIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxuLy8gSGlnaGxpZ2h0IGNvZGUgd2l0aCBleHBsaWNpdCBsYW5ndWFnZVxuY29uc3QgaGlnaGxpZ2h0ZWQgPSBoaWdobGlnaHRDb2RlKFwiY29uc3QgeCA9IDE7XCIsIFwidHlwZXNjcmlwdFwiLCB0aGVtZSk7XG5cbi8vIEF1dG8tZGV0ZWN0IGxhbmd1YWdlIGZyb20gZmlsZSBwYXRoXG5jb25zdCBsYW5nID0gZ2V0TGFuZ3VhZ2VGcm9tUGF0aChcIi9wYXRoL3RvL2ZpbGUucnNcIik7ICAvLyBcInJ1c3RcIlxuY29uc3QgaGlnaGxpZ2h0ZWQgPSBoaWdobGlnaHRDb2RlKGNvZGUsIGxhbmcsIHRoZW1lKTtcbmBgYFxuXG4jIyBFcnJvciBIYW5kbGluZ1xuXG4tIEV4dGVuc2lvbiBlcnJvcnMgYXJlIGxvZ2dlZCwgYWdlbnQgY29udGludWVzXG4tIGB0b29sX2NhbGxgIGVycm9ycyBibG9jayB0aGUgdG9vbCAoZmFpbC1zYWZlKVxuLSBUb29sIGBleGVjdXRlYCBlcnJvcnMgbXVzdCBiZSBzaWduYWxlZCBieSB0aHJvd2luZzsgdGhlIHRocm93biBlcnJvciBpcyBjYXVnaHQsIHJlcG9ydGVkIHRvIHRoZSBMTE0gd2l0aCBgaXNFcnJvcjogdHJ1ZWAsIGFuZCBleGVjdXRpb24gY29udGludWVzXG5cbiMjIE1vZGUgQmVoYXZpb3JcblxufCBNb2RlIHwgYGN0eC5tb2RlYCB8IGBjdHguaGFzVUlgIHwgTm90ZXMgfFxufC0tLS0tLXwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXwtLS0tLS0tfFxufCBJbnRlcmFjdGl2ZSB8IGBcInR1aVwiYCB8IGB0cnVlYCB8IEZ1bGwgVFVJIHdpdGggdGVybWluYWwgcmVuZGVyaW5nIHxcbnwgUlBDIChgLS1tb2RlIHJwY2ApIHwgYFwicnBjXCJgIHwgYHRydWVgIHwgRGlhbG9ncyBhbmQgbm90aWZpY2F0aW9ucyB2aWEgSlNPTiBwcm90b2NvbDsgYGN1c3RvbSgpYCByZXR1cm5zIGB1bmRlZmluZWRgLiBTZWUgW3JwYy5tZF0ocnBjLm1kKSB8XG58IEpTT04gKGAtLW1vZGUganNvbmApIHwgYFwianNvblwiYCB8IGBmYWxzZWAgfCBFdmVudCBzdHJlYW0gdG8gc3Rkb3V0OyBVSSBtZXRob2RzIGFyZSBuby1vcHMgfFxufCBQcmludCAoYC1wYCkgfCBgXCJwcmludFwiYCB8IGBmYWxzZWAgfCBFeHRlbnNpb25zIHJ1biBidXQgY2FuJ3QgcHJvbXB0IHxcblxuVXNlIGBjdHgubW9kZSA9PT0gXCJ0dWlcImAgYmVmb3JlIFRVSS1zcGVjaWZpYyBmZWF0dXJlcyAoYGN1c3RvbSgpYCwgY29tcG9uZW50IGZhY3RvcmllcywgdGVybWluYWwgaW5wdXQpLiBVc2UgYGN0eC5oYXNVSWAgYmVmb3JlIGRpYWxvZyBhbmQgbm90aWZpY2F0aW9uIG1ldGhvZHMgdGhhdCB3b3JrIGluIGJvdGggVFVJIGFuZCBSUEMgbW9kZXMuXG5cbiMjIEV4YW1wbGVzIFJlZmVyZW5jZVxuXG5BbGwgZXhhbXBsZXMgaW4gW2V4YW1wbGVzL2V4dGVuc2lvbnMvXSguLi9leGFtcGxlcy9leHRlbnNpb25zLykuXG5cbnwgRXhhbXBsZSB8IERlc2NyaXB0aW9uIHwgS2V5IEFQSXMgfFxufC0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS18XG58ICoqVG9vbHMqKiB8fHxcbnwgYGhlbGxvLnRzYCB8IE1pbmltYWwgdG9vbCByZWdpc3RyYXRpb24gfCBgcmVnaXN0ZXJUb29sYCB8XG58IGBxdWVzdGlvbi50c2AgfCBUb29sIHdpdGggdXNlciBpbnRlcmFjdGlvbiB8IGByZWdpc3RlclRvb2xgLCBgdWkuc2VsZWN0YCB8XG58IGBxdWVzdGlvbm5haXJlLnRzYCB8IE11bHRpLXN0ZXAgd2l6YXJkIHRvb2wgfCBgcmVnaXN0ZXJUb29sYCwgYHVpLmN1c3RvbWAgfFxufCBgdG9kby50c2AgfCBTdGF0ZWZ1bCB0b29sIHdpdGggcGVyc2lzdGVuY2UgfCBgcmVnaXN0ZXJUb29sYCwgYGFwcGVuZEVudHJ5YCwgYHJlbmRlclJlc3VsdGAsIHNlc3Npb24gZXZlbnRzIHxcbnwgYGR5bmFtaWMtdG9vbHMudHNgIHwgUmVnaXN0ZXIgdG9vbHMgYWZ0ZXIgc3RhcnR1cCBhbmQgZHVyaW5nIGNvbW1hbmRzIHwgYHJlZ2lzdGVyVG9vbGAsIGBzZXNzaW9uX3N0YXJ0YCwgYHJlZ2lzdGVyQ29tbWFuZGAgfFxufCBgc3RydWN0dXJlZC1vdXRwdXQudHNgIHwgRmluYWwgc3RydWN0dXJlZC1vdXRwdXQgdG9vbCB3aXRoIGB0ZXJtaW5hdGU6IHRydWVgIHwgYHJlZ2lzdGVyVG9vbGAsIHRlcm1pbmF0aW5nIHRvb2wgcmVzdWx0cyB8XG58IGB0cnVuY2F0ZWQtdG9vbC50c2AgfCBPdXRwdXQgdHJ1bmNhdGlvbiBleGFtcGxlIHwgYHJlZ2lzdGVyVG9vbGAsIGB0cnVuY2F0ZUhlYWRgIHxcbnwgYHRvb2wtb3ZlcnJpZGUudHNgIHwgT3ZlcnJpZGUgYnVpbHQtaW4gcmVhZCB0b29sIHwgYHJlZ2lzdGVyVG9vbGAgKHNhbWUgbmFtZSBhcyBidWlsdC1pbikgfFxufCAqKkNvbW1hbmRzKiogfHx8XG58IGBwaXJhdGUudHNgIHwgTW9kaWZ5IHN5c3RlbSBwcm9tcHQgcGVyLXR1cm4gfCBgcmVnaXN0ZXJDb21tYW5kYCwgYGJlZm9yZV9hZ2VudF9zdGFydGAgfFxufCBgc3VtbWFyaXplLnRzYCB8IENvbnZlcnNhdGlvbiBzdW1tYXJ5IGNvbW1hbmQgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHVpLmN1c3RvbWAgfFxufCBgaGFuZG9mZi50c2AgfCBDcm9zcy1wcm92aWRlciBtb2RlbCBoYW5kb2ZmIHwgYHJlZ2lzdGVyQ29tbWFuZGAsIGB1aS5lZGl0b3JgLCBgdWkuY3VzdG9tYCB8XG58IGBxbmEudHNgIHwgUSZBIHdpdGggY3VzdG9tIFVJIHwgYHJlZ2lzdGVyQ29tbWFuZGAsIGB1aS5jdXN0b21gLCBgc2V0RWRpdG9yVGV4dGAgfFxufCBgc2VuZC11c2VyLW1lc3NhZ2UudHNgIHwgSW5qZWN0IHVzZXIgbWVzc2FnZXMgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHNlbmRVc2VyTWVzc2FnZWAgfFxufCBgcmVsb2FkLXJ1bnRpbWUudHNgIHwgUmVsb2FkIGNvbW1hbmQgYW5kIExMTSB0b29sIGhhbmRvZmYgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYGN0eC5yZWxvYWQoKWAsIGBzZW5kVXNlck1lc3NhZ2VgIHxcbnwgYHNodXRkb3duLWNvbW1hbmQudHNgIHwgR3JhY2VmdWwgc2h1dGRvd24gY29tbWFuZCB8IGByZWdpc3RlckNvbW1hbmRgLCBgc2h1dGRvd24oKWAgfFxufCAqKkV2ZW50cyAmIEdhdGVzKiogfHx8XG58IGBwZXJtaXNzaW9uLWdhdGUudHNgIHwgQmxvY2sgZGFuZ2Vyb3VzIGNvbW1hbmRzIHwgYG9uKFwidG9vbF9jYWxsXCIpYCwgYHVpLmNvbmZpcm1gIHxcbnwgYHByb2plY3QtdHJ1c3QudHNgIHwgRGVjaWRlIG9yIGRlZmVyIHByb2plY3QgdHJ1c3QgZnJvbSBhIHVzZXIvZ2xvYmFsIG9yIENMSSBleHRlbnNpb24gfCBgb24oXCJwcm9qZWN0X3RydXN0XCIpYCwgdHJ1c3QgVUksIHJlcXVpcmVkIHRydXN0IHJlc3VsdCB8XG58IGBwcm90ZWN0ZWQtcGF0aHMudHNgIHwgQmxvY2sgd3JpdGVzIHRvIHNwZWNpZmljIHBhdGhzIHwgYG9uKFwidG9vbF9jYWxsXCIpYCB8XG58IGBjb25maXJtLWRlc3RydWN0aXZlLnRzYCB8IENvbmZpcm0gc2Vzc2lvbiBjaGFuZ2VzIHwgYG9uKFwic2Vzc2lvbl9iZWZvcmVfc3dpdGNoXCIpYCwgYG9uKFwic2Vzc2lvbl9iZWZvcmVfZm9ya1wiKWAgfFxufCBgZGlydHktcmVwby1ndWFyZC50c2AgfCBXYXJuIG9uIGRpcnR5IGdpdCByZXBvIHwgYG9uKFwic2Vzc2lvbl9iZWZvcmVfKlwiKWAsIGBleGVjYCB8XG58IGBpbnB1dC10cmFuc2Zvcm0udHNgIHwgVHJhbnNmb3JtIHVzZXIgaW5wdXQgfCBgb24oXCJpbnB1dFwiKWAgfFxufCBgaW5wdXQtdHJhbnNmb3JtLXN0cmVhbWluZy50c2AgfCBTdHJlYW1pbmctYXdhcmUgaW5wdXQgdHJhbnNmb3JtIHwgYG9uKFwiaW5wdXRcIilgLCBgc3RyZWFtaW5nQmVoYXZpb3JgIHxcbnwgYG1vZGVsLXN0YXR1cy50c2AgfCBSZWFjdCB0byBtb2RlbCBjaGFuZ2VzIHwgYG9uKFwibW9kZWxfc2VsZWN0XCIpYCwgYHNldFN0YXR1c2AgfFxufCBgcHJvdmlkZXItcGF5bG9hZC50c2AgfCBJbnNwZWN0IHBheWxvYWRzIGFuZCBwcm92aWRlciByZXNwb25zZSBoZWFkZXJzIHwgYG9uKFwiYmVmb3JlX3Byb3ZpZGVyX3JlcXVlc3RcIilgLCBgb24oXCJhZnRlcl9wcm92aWRlcl9yZXNwb25zZVwiKWAgfFxufCBgc3lzdGVtLXByb21wdC1oZWFkZXIudHNgIHwgRGlzcGxheSBzeXN0ZW0gcHJvbXB0IGluZm8gfCBgb24oXCJhZ2VudF9zdGFydFwiKWAsIGBnZXRTeXN0ZW1Qcm9tcHRgIHxcbnwgYGNsYXVkZS1ydWxlcy50c2AgfCBMb2FkIHJ1bGVzIGZyb20gZmlsZXMgfCBgb24oXCJzZXNzaW9uX3N0YXJ0XCIpYCwgYG9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIpYCB8XG58IGBwcm9tcHQtY3VzdG9taXplci50c2AgfCBBZGQgY29udGV4dC1hd2FyZSB0b29sIGd1aWRhbmNlIHVzaW5nIGBzeXN0ZW1Qcm9tcHRPcHRpb25zYCB8IGBvbihcImJlZm9yZV9hZ2VudF9zdGFydFwiKWAsIGBCdWlsZFN5c3RlbVByb21wdE9wdGlvbnNgIHxcbnwgYGZpbGUtdHJpZ2dlci50c2AgfCBGaWxlIHdhdGNoZXIgdHJpZ2dlcnMgbWVzc2FnZXMgfCBgc2VuZE1lc3NhZ2VgIHxcbnwgKipDb21wYWN0aW9uICYgU2Vzc2lvbnMqKiB8fHxcbnwgYGN1c3RvbS1jb21wYWN0aW9uLnRzYCB8IEN1c3RvbSBjb21wYWN0aW9uIHN1bW1hcnkgfCBgb24oXCJzZXNzaW9uX2JlZm9yZV9jb21wYWN0XCIpYCB8XG58IGB0cmlnZ2VyLWNvbXBhY3QudHNgIHwgVHJpZ2dlciBjb21wYWN0aW9uIG1hbnVhbGx5IHwgYGNvbXBhY3QoKWAgfFxufCBgZ2l0LWNoZWNrcG9pbnQudHNgIHwgR2l0IHN0YXNoIG9uIHR1cm5zIHwgYG9uKFwidHVybl9zdGFydFwiKWAsIGBvbihcInNlc3Npb25fYmVmb3JlX2ZvcmtcIilgLCBgZXhlY2AgfFxufCBgZ2l0LW1lcmdlLWFuZC1yZXNvbHZlLnRzYCB8IEZldGNoLCBtZXJnZSwgYW5kIHJlc29sdmUgY29uZmxpY3RzIHwgYG9uKFwiYWdlbnRfZW5kXCIpYCwgYGV4ZWNgLCBgc2VuZFVzZXJNZXNzYWdlYCB8XG58IGBhdXRvLWNvbW1pdC1vbi1leGl0LnRzYCB8IENvbW1pdCBvbiBzaHV0ZG93biB8IGBvbihcInNlc3Npb25fc2h1dGRvd25cIilgLCBgZXhlY2AgfFxufCAqKlVJIENvbXBvbmVudHMqKiB8fHxcbnwgYHN0YXR1cy1saW5lLnRzYCB8IEZvb3RlciBzdGF0dXMgaW5kaWNhdG9yIHwgYHNldFN0YXR1c2AsIHNlc3Npb24gZXZlbnRzIHxcbnwgYHdvcmtpbmctaW5kaWNhdG9yLnRzYCB8IEN1c3RvbWl6ZSB0aGUgc3RyZWFtaW5nIHdvcmtpbmcgaW5kaWNhdG9yIHwgYHNldFdvcmtpbmdJbmRpY2F0b3JgLCBgcmVnaXN0ZXJDb21tYW5kYCB8XG58IGBnaXRodWItaXNzdWUtYXV0b2NvbXBsZXRlLnRzYCB8IEFkZCBgIzEyMzRgIGlzc3VlIGNvbXBsZXRpb25zIG9uIHRvcCBvZiBidWlsdC1pbiBhdXRvY29tcGxldGUgYnkgcHJlbG9hZGluZyByZWNlbnQgb3BlbiBpc3N1ZXMgZnJvbSBgZ2ggaXNzdWUgbGlzdGAgfCBgYWRkQXV0b2NvbXBsZXRlUHJvdmlkZXJgLCBgb24oXCJzZXNzaW9uX3N0YXJ0XCIpYCwgYGV4ZWNgIHxcbnwgYGN1c3RvbS1mb290ZXIudHNgIHwgUmVwbGFjZSBmb290ZXIgZW50aXJlbHkgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHNldEZvb3RlcmAgfFxufCBgY3VzdG9tLWhlYWRlci50c2AgfCBSZXBsYWNlIHN0YXJ0dXAgaGVhZGVyIHwgYG9uKFwic2Vzc2lvbl9zdGFydFwiKWAsIGBzZXRIZWFkZXJgIHxcbnwgYG1vZGFsLWVkaXRvci50c2AgfCBWaW0tc3R5bGUgbW9kYWwgZWRpdG9yIHwgYHNldEVkaXRvckNvbXBvbmVudGAsIGBDdXN0b21FZGl0b3JgIHxcbnwgYHJhaW5ib3ctZWRpdG9yLnRzYCB8IEN1c3RvbSBlZGl0b3Igc3R5bGluZyB8IGBzZXRFZGl0b3JDb21wb25lbnRgIHxcbnwgYHdpZGdldC1wbGFjZW1lbnQudHNgIHwgV2lkZ2V0IGFib3ZlL2JlbG93IGVkaXRvciB8IGBzZXRXaWRnZXRgIHxcbnwgYG92ZXJsYXktdGVzdC50c2AgfCBPdmVybGF5IGNvbXBvbmVudHMgfCBgdWkuY3VzdG9tYCB3aXRoIG92ZXJsYXkgb3B0aW9ucyB8XG58IGBvdmVybGF5LXFhLXRlc3RzLnRzYCB8IENvbXByZWhlbnNpdmUgb3ZlcmxheSB0ZXN0cyB8IGB1aS5jdXN0b21gLCBhbGwgb3ZlcmxheSBvcHRpb25zIHxcbnwgYG5vdGlmeS50c2AgfCBTaW1wbGUgbm90aWZpY2F0aW9ucyB8IGB1aS5ub3RpZnlgIHxcbnwgYHRpbWVkLWNvbmZpcm0udHNgIHwgRGlhbG9ncyB3aXRoIHRpbWVvdXQgfCBgdWkuY29uZmlybWAgd2l0aCB0aW1lb3V0L3NpZ25hbCB8XG58IGBtYWMtc3lzdGVtLXRoZW1lLnRzYCB8IEF1dG8tc3dpdGNoIHRoZW1lIHwgYHNldFRoZW1lYCwgYGV4ZWNgIHxcbnwgKipDb21wbGV4IEV4dGVuc2lvbnMqKiB8fHxcbnwgYHBsYW4tbW9kZS9gIHwgRnVsbCBwbGFuIG1vZGUgaW1wbGVtZW50YXRpb24gfCBBbGwgZXZlbnQgdHlwZXMsIGByZWdpc3RlckNvbW1hbmRgLCBgcmVnaXN0ZXJTaG9ydGN1dGAsIGByZWdpc3RlckZsYWdgLCBgc2V0U3RhdHVzYCwgYHNldFdpZGdldGAsIGBzZW5kTWVzc2FnZWAsIGBzZXRBY3RpdmVUb29sc2AgfFxufCBgcHJlc2V0LnRzYCB8IFNhdmVhYmxlIHByZXNldHMgKG1vZGVsLCB0b29scywgdGhpbmtpbmcpIHwgYHJlZ2lzdGVyQ29tbWFuZGAsIGByZWdpc3RlclNob3J0Y3V0YCwgYHJlZ2lzdGVyRmxhZ2AsIGBzZXRNb2RlbGAsIGBzZXRBY3RpdmVUb29sc2AsIGBzZXRUaGlua2luZ0xldmVsYCwgYGFwcGVuZEVudHJ5YCB8XG58IGB0b29scy50c2AgfCBUb2dnbGUgdG9vbHMgb24vb2ZmIFVJIHwgYHJlZ2lzdGVyQ29tbWFuZGAsIGBzZXRBY3RpdmVUb29sc2AsIGBTZXR0aW5nc0xpc3RgLCBzZXNzaW9uIGV2ZW50cyB8XG58ICoqUmVtb3RlICYgU2FuZGJveCoqIHx8fFxufCBgc3NoLnRzYCB8IFNTSCByZW1vdGUgZXhlY3V0aW9uIHwgYHJlZ2lzdGVyRmxhZ2AsIGBvbihcInVzZXJfYmFzaFwiKWAsIGBvbihcImJlZm9yZV9hZ2VudF9zdGFydFwiKWAsIHRvb2wgb3BlcmF0aW9ucyB8XG58IGBpbnRlcmFjdGl2ZS1zaGVsbC50c2AgfCBQZXJzaXN0ZW50IHNoZWxsIHNlc3Npb24gfCBgb24oXCJ1c2VyX2Jhc2hcIilgIHxcbnwgYHNhbmRib3gvYCB8IFNhbmRib3hlZCB0b29sIGV4ZWN1dGlvbiB8IFRvb2wgb3BlcmF0aW9ucyB8XG58IGBnb25kb2xpbi9gIHwgUm91dGUgYnVpbHQtaW4gdG9vbHMgYW5kIGAhYCBjb21tYW5kcyBpbnRvIGEgR29uZG9saW4gbWljcm8tVk0gfCBUb29sIG9wZXJhdGlvbnMsIGJ1aWx0LWluIHRvb2wgb3ZlcnJpZGVzLCBgb24oXCJ1c2VyX2Jhc2hcIilgIHxcbnwgYHN1YmFnZW50L2AgfCBTcGF3biBzdWItYWdlbnRzIHwgYHJlZ2lzdGVyVG9vbGAsIGBleGVjYCB8XG58ICoqR2FtZXMqKiB8fHxcbnwgYHNuYWtlLnRzYCB8IFNuYWtlIGdhbWUgfCBgcmVnaXN0ZXJDb21tYW5kYCwgYHVpLmN1c3RvbWAsIGtleWJvYXJkIGhhbmRsaW5nIHwiLCJ0cnVuY2F0ZWQiOnRydWUsInRydW5jYXRlZEJ5IjoiYnl0ZXMiLCJ0b3RhbExpbmVzIjoxMjkwLCJ0b3RhbEJ5dGVzIjo1MjE3Mywib3V0cHV0TGluZXMiOjEyNzUsIm91dHB1dEJ5dGVzIjo1MTE4OSwibGFzdExpbmVQYXJ0aWFsIjpmYWxzZSwiZmlyc3RMaW5lRXhjZWVkc0xpbWl0IjpmYWxzZSwibWF4TGluZXMiOjIwMDAsIm1heEJ5dGVzIjo1MTIwMH19LCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MjQyOTA1fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZjE5MjM1OTYiLCJwYXJlbnRJZCI6IjgwNzljMzYyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MDo0Mi45MDZaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJOS3dRM0d6VGd6dllqc3ZaQWhVODVLY29neE1LdGZOYSIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IntcbiAgXCJuYW1lXCI6IFwicGktdGRkLWN5Y2xlXCIsXG4gIFwidmVyc2lvblwiOiBcIjEuMC4wXCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJcIixcbiAgXCJtYWluXCI6IFwiaW5kZXguanNcIixcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gIH0sXG4gIFwia2V5d29yZHNcIjogW10sXG4gIFwiYXV0aG9yXCI6IFwiXCIsXG4gIFwibGljZW5zZVwiOiBcIklTQ1wiLFxuICBcInBhY2thZ2VNYW5hZ2VyXCI6IFwicG5wbUAxMC4zMy4yXCJcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODI0MjkwNn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjM4MWE0NWYxIiwicGFyZW50SWQiOiJmMTkyMzU5NiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTA6NDIuOTA2WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoidFhKeDdPcHBMZzNPcXlPYlpaRDV3aDFBcnBmbk1mY20iLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJbdG9vbHNdXG5ub2RlID0gXCIyNFwiXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzgyNDI5MDZ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI4NjJjY2E4NCIsInBhcmVudElkIjoiMzgxYTQ1ZjEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjUwOjQyLjkwNloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IkE1TW8zeWh3ZzhwWDl5WEk2MlFSMEV6cHZ1ajBFR1NBIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiYXV0by1jb21taXQtb24tZXhpdC50c1xuYmFzaC1zcGF3bi1ob29rLnRzXG5ib29rbWFyay50c1xuYm9yZGVyLXN0YXR1cy1lZGl0b3IudHNcbmJ1aWx0LWluLXRvb2wtcmVuZGVyZXIudHNcbmNsYXVkZS1ydWxlcy50c1xuY29tbWFuZHMudHNcbmNvbmZpcm0tZGVzdHJ1Y3RpdmUudHNcbmN1c3RvbS1jb21wYWN0aW9uLnRzXG5jdXN0b20tZm9vdGVyLnRzXG5jdXN0b20taGVhZGVyLnRzXG5jdXN0b20tcHJvdmlkZXItYW50aHJvcGljXG5jdXN0b20tcHJvdmlkZXItZ2l0bGFiLWR1b1xuZGlydHktcmVwby1ndWFyZC50c1xuZG9vbS1vdmVybGF5XG5keW5hbWljLXJlc291cmNlc1xuZHluYW1pYy10b29scy50c1xuZXZlbnQtYnVzLnRzXG5maWxlLXRyaWdnZXIudHNcbmdpdC1jaGVja3BvaW50LnRzXG5naXQtbWVyZ2UtYW5kLXJlc29sdmUudHNcbmdpdGh1Yi1pc3N1ZS1hdXRvY29tcGxldGUudHNcbmdvbmRvbGluXG5oYW5kb2ZmLnRzXG5oZWxsby50c1xuaGlkZGVuLXRoaW5raW5nLWxhYmVsLnRzXG5pbmxpbmUtYmFzaC50c1xuaW5wdXQtdHJhbnNmb3JtLXN0cmVhbWluZy50c1xuaW5wdXQtdHJhbnNmb3JtLnRzXG5pbnRlcmFjdGl2ZS1zaGVsbC50c1xubWFjLXN5c3RlbS10aGVtZS50c1xubWVzc2FnZS1yZW5kZXJlci50c1xubWluaW1hbC1tb2RlLnRzXG5tb2RhbC1lZGl0b3IudHNcbm1vZGVsLXN0YXR1cy50c1xubm90aWZ5LnRzXG5vdmVybGF5LXFhLXRlc3RzLnRzXG5vdmVybGF5LXRlc3QudHNcbnBlcm1pc3Npb24tZ2F0ZS50c1xucGlyYXRlLnRzXG5wbGFuLW1vZGVcbnByZXNldC50c1xucHJvamVjdC10cnVzdC50c1xucHJvbXB0LWN1c3RvbWl6ZXIudHNcbnByb3RlY3RlZC1wYXRocy50c1xucHJvdmlkZXItcGF5bG9hZC50c1xucW5hLnRzXG5xdWVzdGlvbi50c1xucXVlc3Rpb25uYWlyZS50c1xucmFpbmJvdy1lZGl0b3IudHNcblJFQURNRS5tZFxucmVsb2FkLXJ1bnRpbWUudHNcbnJwYy1kZW1vLnRzXG5zYW5kYm94XG5zZW5kLXVzZXItbWVzc2FnZS50c1xuc2Vzc2lvbi1uYW1lLnRzXG5zaHV0ZG93bi1jb21tYW5kLnRzXG5zbmFrZS50c1xuc3BhY2UtaW52YWRlcnMudHNcbnNzaC50c1xuc3RhdHVzLWxpbmUudHNcbnN0cnVjdHVyZWQtb3V0cHV0LnRzXG5zdWJhZ2VudFxuc3VtbWFyaXplLnRzXG5zeXN0ZW0tcHJvbXB0LWhlYWRlci50c1xudGljLXRhYy10b2UudHNcbnRpbWVkLWNvbmZpcm0udHNcbnRpdGxlYmFyLXNwaW5uZXIudHNcbnRvZG8udHNcbnRvb2wtb3ZlcnJpZGUudHNcbnRvb2xzLnRzXG50cmlnZ2VyLWNvbXBhY3QudHNcbnRydW5jYXRlZC10b29sLnRzXG53aWRnZXQtcGxhY2VtZW50LnRzXG53aXRoLWRlcHNcbndvcmtpbmctaW5kaWNhdG9yLnRzXG53b3JraW5nLW1lc3NhZ2UtdGVzdC50c1xuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MjQyOTA2fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMzY0ZWY4NTMiLCJwYXJlbnRJZCI6Ijg2MmNjYTg0IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MToxMi4yMThaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJOb3cgbGV0IG1lIGxvb2sgYXQgYSBmZXcgcmVsZXZhbnQgZXhhbXBsZXMgdG8gdW5kZXJzdGFuZCB0aGUgcGF0dGVybnMgYmV0dGVyLCBlc3BlY2lhbGx5IHRoZSBwbGFuLW1vZGUgZXh0ZW5zaW9uIHdoaWNoIHNlZW1zIG1vc3Qgc2ltaWxhciB0byB3aGF0IHdlIHdhbnQgdG8gYnVpbGQ6XG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJMZXQgbWUgbG9vayBhdCB0aGUgcGxhbi1tb2RlIGV4YW1wbGUgKG1vc3Qgc2ltaWxhciB0byB3aGF0IHdlIG5lZWQpIGFuZCB0aGUgcXVlc3Rpb24gZXhhbXBsZTpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImtLaUxNQ2c3Q3dqM0F5UTNSVTRCMTVVajhINEMxV1B2IiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImxzIC9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2V4YW1wbGVzL2V4dGVuc2lvbnMvcGxhbi1tb2RlLyJ9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiUDJQNTJDSWx3cW1pNEZuU1BDaFZhUjJ5bnBSZWh0NEgiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS8ubG9jYWwvc2hhcmUvbWlzZS9pbnN0YWxscy9ub2RlLzI0LjAuMS9saWIvbm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnQvZXhhbXBsZXMvZXh0ZW5zaW9ucy9xdWVzdGlvbi50cyJ9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoic2ZmdUk3N2EwU01ycUFvb2FZNVdCRG8zcUF2eExXY2siLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoibHMgL1VzZXJzL3dpbGxlbS8ubG9jYWwvc2hhcmUvbWlzZS9pbnN0YWxscy9ub2RlLzI0LjAuMS9saWIvbm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnQvZXhhbXBsZXMvZXh0ZW5zaW9ucy93aXRoLWRlcHMvIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoxMzc2Mywib3V0cHV0IjoyNDksImNhY2hlUmVhZCI6MjI3MDAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjozNjcxMiwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4MjQyOTA2LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtdkJpOXgzMHFwSW1DR1pFc0RVTlpibTVKZUxVUmVxckUifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMjBlYTBhZGMiLCJwYXJlbnRJZCI6IjM2NGVmODUzIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MToxMi4yMzJaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJrS2lMTUNnN0N3ajNBeVEzUlU0QjE1VWo4SDRDMVdQdiIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6ImluZGV4LnRzXG5SRUFETUUubWRcbnV0aWxzLnRzXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzgyNzIyMzJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJkZDRhOGQyMCIsInBhcmVudElkIjoiMjBlYTBhZGMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjUxOjEyLjIzMloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IlAyUDUyQ0lsd3FtaTRGblNQQ2hWYVIyeW5wUmVodDRIIiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiLyoqXG4gKiBRdWVzdGlvbiBUb29sIC0gU2luZ2xlIHF1ZXN0aW9uIHdpdGggb3B0aW9uc1xuICogRnVsbCBjdXN0b20gVUk6IG9wdGlvbnMgbGlzdCArIGlubGluZSBlZGl0b3IgZm9yIFwiVHlwZSBzb21ldGhpbmcuLi5cIlxuICogRXNjYXBlIGluIGVkaXRvciByZXR1cm5zIHRvIG9wdGlvbnMsIEVzY2FwZSBpbiBvcHRpb25zIGNhbmNlbHNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQge1xuXHRFZGl0b3IsXG5cdHR5cGUgRWRpdG9yVGhlbWUsXG5cdEtleSxcblx0bWF0Y2hlc0tleSxcblx0VGV4dCxcblx0dmlzaWJsZVdpZHRoLFxuXHR3cmFwVGV4dFdpdGhBbnNpLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5cbmludGVyZmFjZSBPcHRpb25XaXRoRGVzYyB7XG5cdGxhYmVsOiBzdHJpbmc7XG5cdGRlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG50eXBlIERpc3BsYXlPcHRpb24gPSBPcHRpb25XaXRoRGVzYyAmIHsgaXNPdGhlcj86IGJvb2xlYW4gfTtcblxuaW50ZXJmYWNlIFF1ZXN0aW9uRGV0YWlscyB7XG5cdHF1ZXN0aW9uOiBzdHJpbmc7XG5cdG9wdGlvbnM6IHN0cmluZ1tdO1xuXHRhbnN3ZXI6IHN0cmluZyB8IG51bGw7XG5cdHdhc0N1c3RvbT86IGJvb2xlYW47XG59XG5cbi8vIE9wdGlvbnMgd2l0aCBsYWJlbHMgYW5kIG9wdGlvbmFsIGRlc2NyaXB0aW9uc1xuY29uc3QgT3B0aW9uU2NoZW1hID0gVHlwZS5PYmplY3Qoe1xuXHRsYWJlbDogVHlwZS5TdHJpbmcoeyBkZXNjcmlwdGlvbjogXCJEaXNwbGF5IGxhYmVsIGZvciB0aGUgb3B0aW9uXCIgfSksXG5cdGRlc2NyaXB0aW9uOiBUeXBlLk9wdGlvbmFsKFR5cGUuU3RyaW5nKHsgZGVzY3JpcHRpb246IFwiT3B0aW9uYWwgZGVzY3JpcHRpb24gc2hvd24gYmVsb3cgbGFiZWxcIiB9KSksXG59KTtcblxuY29uc3QgUXVlc3Rpb25QYXJhbXMgPSBUeXBlLk9iamVjdCh7XG5cdHF1ZXN0aW9uOiBUeXBlLlN0cmluZyh7IGRlc2NyaXB0aW9uOiBcIlRoZSBxdWVzdGlvbiB0byBhc2sgdGhlIHVzZXJcIiB9KSxcblx0b3B0aW9uczogVHlwZS5BcnJheShPcHRpb25TY2hlbWEsIHsgZGVzY3JpcHRpb246IFwiT3B0aW9ucyBmb3IgdGhlIHVzZXIgdG8gY2hvb3NlIGZyb21cIiB9KSxcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBxdWVzdGlvbihwaTogRXh0ZW5zaW9uQVBJKSB7XG5cdHBpLnJlZ2lzdGVyVG9vbCh7XG5cdFx0bmFtZTogXCJxdWVzdGlvblwiLFxuXHRcdGxhYmVsOiBcIlF1ZXN0aW9uXCIsXG5cdFx0ZGVzY3JpcHRpb246IFwiQXNrIHRoZSB1c2VyIGEgcXVlc3Rpb24gYW5kIGxldCB0aGVtIHBpY2sgZnJvbSBvcHRpb25zLiBVc2Ugd2hlbiB5b3UgbmVlZCB1c2VyIGlucHV0IHRvIHByb2NlZWQuXCIsXG5cdFx0cGFyYW1ldGVyczogUXVlc3Rpb25QYXJhbXMsXG5cblx0XHRhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG5cdFx0XHRpZiAoY3R4Lm1vZGUgIT09IFwidHVpXCIpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJFcnJvcjogVUkgbm90IGF2YWlsYWJsZSAocnVubmluZyBpbiBub24taW50ZXJhY3RpdmUgbW9kZSlcIiB9XSxcblx0XHRcdFx0XHRkZXRhaWxzOiB7XG5cdFx0XHRcdFx0XHRxdWVzdGlvbjogcGFyYW1zLnF1ZXN0aW9uLFxuXHRcdFx0XHRcdFx0b3B0aW9uczogcGFyYW1zLm9wdGlvbnMubWFwKChvKSA9PiBvLmxhYmVsKSxcblx0XHRcdFx0XHRcdGFuc3dlcjogbnVsbCxcblx0XHRcdFx0XHR9IGFzIFF1ZXN0aW9uRGV0YWlscyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHBhcmFtcy5vcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIkVycm9yOiBObyBvcHRpb25zIHByb3ZpZGVkXCIgfV0sXG5cdFx0XHRcdFx0ZGV0YWlsczogeyBxdWVzdGlvbjogcGFyYW1zLnF1ZXN0aW9uLCBvcHRpb25zOiBbXSwgYW5zd2VyOiBudWxsIH0gYXMgUXVlc3Rpb25EZXRhaWxzLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBhbGxPcHRpb25zOiBEaXNwbGF5T3B0aW9uW10gPSBbLi4ucGFyYW1zLm9wdGlvbnMsIHsgbGFiZWw6IFwiVHlwZSBzb21ldGhpbmcuXCIsIGlzT3RoZXI6IHRydWUgfV07XG5cblx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IGN0eC51aS5jdXN0b208eyBhbnN3ZXI6IHN0cmluZzsgd2FzQ3VzdG9tOiBib29sZWFuOyBpbmRleD86IG51bWJlciB9IHwgbnVsbD4oXG5cdFx0XHRcdCh0dWksIHRoZW1lLCBfa2IsIGRvbmUpID0+IHtcblx0XHRcdFx0XHRsZXQgb3B0aW9uSW5kZXggPSAwO1xuXHRcdFx0XHRcdGxldCBlZGl0TW9kZSA9IGZhbHNlO1xuXHRcdFx0XHRcdGxldCBjYWNoZWRMaW5lczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cblx0XHRcdFx0XHRjb25zdCBlZGl0b3JUaGVtZTogRWRpdG9yVGhlbWUgPSB7XG5cdFx0XHRcdFx0XHRib3JkZXJDb2xvcjogKHMpID0+IHRoZW1lLmZnKFwiYWNjZW50XCIsIHMpLFxuXHRcdFx0XHRcdFx0c2VsZWN0TGlzdDoge1xuXHRcdFx0XHRcdFx0XHRzZWxlY3RlZFByZWZpeDogKHQpID0+IHRoZW1lLmZnKFwiYWNjZW50XCIsIHQpLFxuXHRcdFx0XHRcdFx0XHRzZWxlY3RlZFRleHQ6ICh0KSA9PiB0aGVtZS5mZyhcImFjY2VudFwiLCB0KSxcblx0XHRcdFx0XHRcdFx0ZGVzY3JpcHRpb246ICh0KSA9PiB0aGVtZS5mZyhcIm11dGVkXCIsIHQpLFxuXHRcdFx0XHRcdFx0XHRzY3JvbGxJbmZvOiAodCkgPT4gdGhlbWUuZmcoXCJkaW1cIiwgdCksXG5cdFx0XHRcdFx0XHRcdG5vTWF0Y2g6ICh0KSA9PiB0aGVtZS5mZyhcIndhcm5pbmdcIiwgdCksXG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0Y29uc3QgZWRpdG9yID0gbmV3IEVkaXRvcih0dWksIGVkaXRvclRoZW1lKTtcblxuXHRcdFx0XHRcdGVkaXRvci5vblN1Ym1pdCA9ICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3QgdHJpbW1lZCA9IHZhbHVlLnRyaW0oKTtcblx0XHRcdFx0XHRcdGlmICh0cmltbWVkKSB7XG5cdFx0XHRcdFx0XHRcdGRvbmUoeyBhbnN3ZXI6IHRyaW1tZWQsIHdhc0N1c3RvbTogdHJ1ZSB9KTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGVkaXRNb2RlID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdGVkaXRvci5zZXRUZXh0KFwiXCIpO1xuXHRcdFx0XHRcdFx0XHRyZWZyZXNoKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGZ1bmN0aW9uIHJlZnJlc2goKSB7XG5cdFx0XHRcdFx0XHRjYWNoZWRMaW5lcyA9IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdHR1aS5yZXF1ZXN0UmVuZGVyKCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZnVuY3Rpb24gaGFuZGxlSW5wdXQoZGF0YTogc3RyaW5nKSB7XG5cdFx0XHRcdFx0XHRpZiAoZWRpdE1vZGUpIHtcblx0XHRcdFx0XHRcdFx0aWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVzY2FwZSkpIHtcblx0XHRcdFx0XHRcdFx0XHRlZGl0TW9kZSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdGVkaXRvci5zZXRUZXh0KFwiXCIpO1xuXHRcdFx0XHRcdFx0XHRcdHJlZnJlc2goKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWRpdG9yLmhhbmRsZUlucHV0KGRhdGEpO1xuXHRcdFx0XHRcdFx0XHRyZWZyZXNoKCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LnVwKSkge1xuXHRcdFx0XHRcdFx0XHRvcHRpb25JbmRleCA9IE1hdGgubWF4KDAsIG9wdGlvbkluZGV4IC0gMSk7XG5cdFx0XHRcdFx0XHRcdHJlZnJlc2goKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmRvd24pKSB7XG5cdFx0XHRcdFx0XHRcdG9wdGlvbkluZGV4ID0gTWF0aC5taW4oYWxsT3B0aW9ucy5sZW5ndGggLSAxLCBvcHRpb25JbmRleCArIDEpO1xuXHRcdFx0XHRcdFx0XHRyZWZyZXNoKCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVudGVyKSkge1xuXHRcdFx0XHRcdFx0XHRjb25zdCBzZWxlY3RlZCA9IGFsbE9wdGlvbnNbb3B0aW9uSW5kZXhdO1xuXHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0ZWQuaXNPdGhlcikge1xuXHRcdFx0XHRcdFx0XHRcdGVkaXRNb2RlID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRyZWZyZXNoKCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0ZG9uZSh7IGFuc3dlcjogc2VsZWN0ZWQubGFiZWwsIHdhc0N1c3RvbTogZmFsc2UsIGluZGV4OiBvcHRpb25JbmRleCArIDEgfSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAobWF0Y2hlc0tleShkYXRhLCBLZXkuZXNjYXBlKSkge1xuXHRcdFx0XHRcdFx0XHRkb25lKG51bGwpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGZ1bmN0aW9uIHJlbmRlcih3aWR0aDogbnVtYmVyKTogc3RyaW5nW10ge1xuXHRcdFx0XHRcdFx0aWYgKGNhY2hlZExpbmVzKSByZXR1cm4gY2FjaGVkTGluZXM7XG5cblx0XHRcdFx0XHRcdGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXHRcdFx0XHRcdFx0Y29uc3QgcmVuZGVyV2lkdGggPSBNYXRoLm1heCgxLCB3aWR0aCk7XG5cblx0XHRcdFx0XHRcdGZ1bmN0aW9uIGFkZFdyYXBwZWQodGV4dDogc3RyaW5nKSB7XG5cdFx0XHRcdFx0XHRcdGxpbmVzLnB1c2goLi4ud3JhcFRleHRXaXRoQW5zaSh0ZXh0LCByZW5kZXJXaWR0aCkpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRmdW5jdGlvbiBhZGRXcmFwcGVkV2l0aFByZWZpeChwcmVmaXg6IHN0cmluZywgdGV4dDogc3RyaW5nKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHByZWZpeFdpZHRoID0gdmlzaWJsZVdpZHRoKHByZWZpeCk7XG5cdFx0XHRcdFx0XHRcdGlmIChwcmVmaXhXaWR0aCA+PSByZW5kZXJXaWR0aCkge1xuXHRcdFx0XHRcdFx0XHRcdGFkZFdyYXBwZWQocHJlZml4ICsgdGV4dCk7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHdyYXBwZWQgPSB3cmFwVGV4dFdpdGhBbnNpKHRleHQsIHJlbmRlcldpZHRoIC0gcHJlZml4V2lkdGgpO1xuXHRcdFx0XHRcdFx0XHRjb25zdCBjb250aW51YXRpb25QcmVmaXggPSBcIiBcIi5yZXBlYXQocHJlZml4V2lkdGgpO1xuXHRcdFx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHdyYXBwZWQubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0XHRsaW5lcy5wdXNoKGAke2kgPT09IDAgPyBwcmVmaXggOiBjb250aW51YXRpb25QcmVmaXh9JHt3cmFwcGVkW2ldfWApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGxpbmVzLnB1c2godGhlbWUuZmcoXCJhY2NlbnRcIiwgXCLilIBcIi5yZXBlYXQocmVuZGVyV2lkdGgpKSk7XG5cdFx0XHRcdFx0XHRhZGRXcmFwcGVkV2l0aFByZWZpeChcIiBcIiwgdGhlbWUuZmcoXCJ0ZXh0XCIsIHBhcmFtcy5xdWVzdGlvbikpO1xuXHRcdFx0XHRcdFx0bGluZXMucHVzaChcIlwiKTtcblxuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhbGxPcHRpb25zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IG9wdCA9IGFsbE9wdGlvbnNbaV07XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHNlbGVjdGVkID0gaSA9PT0gb3B0aW9uSW5kZXg7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGlzT3RoZXIgPSBvcHQuaXNPdGhlciA9PT0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0Y29uc3QgcHJlZml4ID0gc2VsZWN0ZWQgPyB0aGVtZS5mZyhcImFjY2VudFwiLCBcIj4gXCIpIDogXCIgIFwiO1xuXHRcdFx0XHRcdFx0XHRjb25zdCBsYWJlbCA9IGAke2kgKyAxfS4gJHtvcHQubGFiZWx9JHtpc090aGVyICYmIGVkaXRNb2RlID8gXCIg4pyOXCIgOiBcIlwifWA7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGNvbG9yID0gc2VsZWN0ZWQgfHwgKGlzT3RoZXIgJiYgZWRpdE1vZGUpID8gXCJhY2NlbnRcIiA6IFwidGV4dFwiO1xuXG5cdFx0XHRcdFx0XHRcdGFkZFdyYXBwZWRXaXRoUHJlZml4KHByZWZpeCwgdGhlbWUuZmcoY29sb3IsIGxhYmVsKSk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU2hvdyBkZXNjcmlwdGlvbiBpZiBwcmVzZW50XG5cdFx0XHRcdFx0XHRcdGlmIChvcHQuZGVzY3JpcHRpb24pIHtcblx0XHRcdFx0XHRcdFx0XHRhZGRXcmFwcGVkV2l0aFByZWZpeChcIiAgICAgXCIsIHRoZW1lLmZnKFwibXV0ZWRcIiwgb3B0LmRlc2NyaXB0aW9uKSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKGVkaXRNb2RlKSB7XG5cdFx0XHRcdFx0XHRcdGxpbmVzLnB1c2goXCJcIik7XG5cdFx0XHRcdFx0XHRcdGFkZFdyYXBwZWRXaXRoUHJlZml4KFwiIFwiLCB0aGVtZS5mZyhcIm11dGVkXCIsIFwiWW91ciBhbnN3ZXI6XCIpKTtcblx0XHRcdFx0XHRcdFx0Zm9yIChjb25zdCBsaW5lIG9mIGVkaXRvci5yZW5kZXIoTWF0aC5tYXgoMSwgcmVuZGVyV2lkdGggLSAyKSkpIHtcblx0XHRcdFx0XHRcdFx0XHRsaW5lcy5wdXNoKGAgJHtsaW5lfWApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGxpbmVzLnB1c2goXCJcIik7XG5cdFx0XHRcdFx0XHRpZiAoZWRpdE1vZGUpIHtcblx0XHRcdFx0XHRcdFx0YWRkV3JhcHBlZFdpdGhQcmVmaXgoXCIgXCIsIHRoZW1lLmZnKFwiZGltXCIsIFwiRW50ZXIgdG8gc3VibWl0IOKAoiBFc2MgdG8gZ28gYmFja1wiKSk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRhZGRXcmFwcGVkV2l0aFByZWZpeChcIiBcIiwgdGhlbWUuZmcoXCJkaW1cIiwgXCLihpHihpMgbmF2aWdhdGUg4oCiIEVudGVyIHRvIHNlbGVjdCDigKIgRXNjIHRvIGNhbmNlbFwiKSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRsaW5lcy5wdXNoKHRoZW1lLmZnKFwiYWNjZW50XCIsIFwi4pSAXCIucmVwZWF0KHJlbmRlcldpZHRoKSkpO1xuXG5cdFx0XHRcdFx0XHRjYWNoZWRMaW5lcyA9IGxpbmVzO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGxpbmVzO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRyZW5kZXIsXG5cdFx0XHRcdFx0XHRpbnZhbGlkYXRlOiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGNhY2hlZExpbmVzID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGhhbmRsZUlucHV0LFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH0sXG5cdFx0XHQpO1xuXG5cdFx0XHQvLyBCdWlsZCBzaW1wbGUgb3B0aW9ucyBsaXN0IGZvciBkZXRhaWxzXG5cdFx0XHRjb25zdCBzaW1wbGVPcHRpb25zID0gcGFyYW1zLm9wdGlvbnMubWFwKChvKSA9PiBvLmxhYmVsKTtcblxuXHRcdFx0aWYgKCFyZXN1bHQpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJVc2VyIGNhbmNlbGxlZCB0aGUgc2VsZWN0aW9uXCIgfV0sXG5cdFx0XHRcdFx0ZGV0YWlsczogeyBxdWVzdGlvbjogcGFyYW1zLnF1ZXN0aW9uLCBvcHRpb25zOiBzaW1wbGVPcHRpb25zLCBhbnN3ZXI6IG51bGwgfSBhcyBRdWVzdGlvbkRldGFpbHMsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChyZXN1bHQud2FzQ3VzdG9tKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0Y29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IGBVc2VyIHdyb3RlOiAke3Jlc3VsdC5hbnN3ZXJ9YCB9XSxcblx0XHRcdFx0XHRkZXRhaWxzOiB7XG5cdFx0XHRcdFx0XHRxdWVzdGlvbjogcGFyYW1zLnF1ZXN0aW9uLFxuXHRcdFx0XHRcdFx0b3B0aW9uczogc2ltcGxlT3B0aW9ucyxcblx0XHRcdFx0XHRcdGFuc3dlcjogcmVzdWx0LmFuc3dlcixcblx0XHRcdFx0XHRcdHdhc0N1c3RvbTogdHJ1ZSxcblx0XHRcdFx0XHR9IGFzIFF1ZXN0aW9uRGV0YWlscyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBgVXNlciBzZWxlY3RlZDogJHtyZXN1bHQuaW5kZXh9LiAke3Jlc3VsdC5hbnN3ZXJ9YCB9XSxcblx0XHRcdFx0ZGV0YWlsczoge1xuXHRcdFx0XHRcdHF1ZXN0aW9uOiBwYXJhbXMucXVlc3Rpb24sXG5cdFx0XHRcdFx0b3B0aW9uczogc2ltcGxlT3B0aW9ucyxcblx0XHRcdFx0XHRhbnN3ZXI6IHJlc3VsdC5hbnN3ZXIsXG5cdFx0XHRcdFx0d2FzQ3VzdG9tOiBmYWxzZSxcblx0XHRcdFx0fSBhcyBRdWVzdGlvbkRldGFpbHMsXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRyZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuXHRcdFx0bGV0IHRleHQgPSB0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwicXVlc3Rpb24gXCIpKSArIHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy5xdWVzdGlvbik7XG5cdFx0XHRjb25zdCBvcHRzID0gQXJyYXkuaXNBcnJheShhcmdzLm9wdGlvbnMpID8gYXJncy5vcHRpb25zIDogW107XG5cdFx0XHRpZiAob3B0cy5sZW5ndGgpIHtcblx0XHRcdFx0Y29uc3QgbGFiZWxzID0gb3B0cy5tYXAoKG86IE9wdGlvbldpdGhEZXNjKSA9PiBvLmxhYmVsKTtcblx0XHRcdFx0Y29uc3QgbnVtYmVyZWQgPSBbLi4ubGFiZWxzLCBcIlR5cGUgc29tZXRoaW5nLlwiXS5tYXAoKG8sIGkpID0+IGAke2kgKyAxfS4gJHtvfWApO1xuXHRcdFx0XHR0ZXh0ICs9IGBcXG4ke3RoZW1lLmZnKFwiZGltXCIsIGAgIE9wdGlvbnM6ICR7bnVtYmVyZWQuam9pbihcIiwgXCIpfWApfWA7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG5cdFx0fSxcblxuXHRcdHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcblx0XHRcdGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyBRdWVzdGlvbkRldGFpbHMgfCB1bmRlZmluZWQ7XG5cdFx0XHRpZiAoIWRldGFpbHMpIHtcblx0XHRcdFx0Y29uc3QgdGV4dCA9IHJlc3VsdC5jb250ZW50WzBdO1xuXHRcdFx0XHRyZXR1cm4gbmV3IFRleHQodGV4dD8udHlwZSA9PT0gXCJ0ZXh0XCIgPyB0ZXh0LnRleHQgOiBcIlwiLCAwLCAwKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGRldGFpbHMuYW5zd2VyID09PSBudWxsKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcIndhcm5pbmdcIiwgXCJDYW5jZWxsZWRcIiksIDAsIDApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoZGV0YWlscy53YXNDdXN0b20pIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBUZXh0KFxuXHRcdFx0XHRcdHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKckyBcIikgKyB0aGVtZS5mZyhcIm11dGVkXCIsIFwiKHdyb3RlKSBcIikgKyB0aGVtZS5mZyhcImFjY2VudFwiLCBkZXRhaWxzLmFuc3dlciksXG5cdFx0XHRcdFx0MCxcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgaWR4ID0gZGV0YWlscy5vcHRpb25zLmluZGV4T2YoZGV0YWlscy5hbnN3ZXIpICsgMTtcblx0XHRcdGNvbnN0IGRpc3BsYXkgPSBpZHggPiAwID8gYCR7aWR4fS4gJHtkZXRhaWxzLmFuc3dlcn1gIDogZGV0YWlscy5hbnN3ZXI7XG5cdFx0XHRyZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJzdWNjZXNzXCIsIFwi4pyTIFwiKSArIHRoZW1lLmZnKFwiYWNjZW50XCIsIGRpc3BsYXkpLCAwLCAwKTtcblx0XHR9LFxuXHR9KTtcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODI3MjIzMn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijk0OTJjNzJkIiwicGFyZW50SWQiOiJkZDRhOGQyMCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTE6MTIuMjMyWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoic2ZmdUk3N2EwU01ycUFvb2FZNVdCRG8zcUF2eExXY2siLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJpbmRleC50c1xucGFja2FnZS1sb2NrLmpzb25cbnBhY2thZ2UuanNvblxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MjcyMjMyfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNDgzMTE4YzgiLCJwYXJlbnRJZCI6Ijk0OTJjNzJkIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MToyMC43MzFaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJMZXQgbWUgbG9vayBhdCB0aGUgcGxhbi1tb2RlIGV4dGVuc2lvbiBhbmQgdGhlIHdpdGgtZGVwcyBleHRlbnNpb24gdG8gdW5kZXJzdGFuZCB0aGUgcGFja2FnZSBzdHJ1Y3R1cmU6XG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IkVYeUhOUGk2UDNoa0VLS2RnNFVLd1lpMUlhR1FhMnJtIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2V4YW1wbGVzL2V4dGVuc2lvbnMvcGxhbi1tb2RlL2luZGV4LnRzIn19LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiI3dVpVM2VFUUhHMHVLVUY4emhvQWl4R2RBQ1FnaHlFUyIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtLy5sb2NhbC9zaGFyZS9taXNlL2luc3RhbGxzL25vZGUvMjQuMC4xL2xpYi9ub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudC9leGFtcGxlcy9leHRlbnNpb25zL3dpdGgtZGVwcy9wYWNrYWdlLmpzb24ifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjI0ODUsIm91dHB1dCI6MTUwLCJjYWNoZVJlYWQiOjM2NzExLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MzkzNDYsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODI3MjIzMywicmVzcG9uc2VJZCI6ImNoYXRjbXBsLTNzNEtDYXJ1bHVNQ3U2SVdFTlRIM2VISkpGUkd6bFR5In19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImJkYmQ3YjBlIiwicGFyZW50SWQiOiI0ODMxMThjOCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTE6MjAuNzM1WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiRVh5SE5QaTZQM2hrRUtLZGc0VUt3WWkxSWFHUWEycm0iLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIvKipcbiAqIFBsYW4gTW9kZSBFeHRlbnNpb25cbiAqXG4gKiBSZWFkLW9ubHkgZXhwbG9yYXRpb24gbW9kZSBmb3Igc2FmZSBjb2RlIGFuYWx5c2lzLlxuICogV2hlbiBlbmFibGVkLCBvbmx5IHJlYWQtb25seSB0b29scyBhcmUgYXZhaWxhYmxlLlxuICpcbiAqIEZlYXR1cmVzOlxuICogLSAvcGxhbiBjb21tYW5kIG9yIEN0cmwrQWx0K1AgdG8gdG9nZ2xlXG4gKiAtIEJhc2ggcmVzdHJpY3RlZCB0byBhbGxvd2xpc3RlZCByZWFkLW9ubHkgY29tbWFuZHNcbiAqIC0gRXh0cmFjdHMgbnVtYmVyZWQgcGxhbiBzdGVwcyBmcm9tIFwiUGxhbjpcIiBzZWN0aW9uc1xuICogLSBbRE9ORTpuXSBtYXJrZXJzIHRvIGNvbXBsZXRlIHN0ZXBzIGR1cmluZyBleGVjdXRpb25cbiAqIC0gUHJvZ3Jlc3MgdHJhY2tpbmcgd2lkZ2V0IGR1cmluZyBleGVjdXRpb25cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEFnZW50TWVzc2FnZSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktYWdlbnQtY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBBc3Npc3RhbnRNZXNzYWdlLCBUZXh0Q29udGVudCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktYWlcIjtcbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB7IEtleSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5pbXBvcnQgeyBleHRyYWN0VG9kb0l0ZW1zLCBpc1NhZmVDb21tYW5kLCBtYXJrQ29tcGxldGVkU3RlcHMsIHR5cGUgVG9kb0l0ZW0gfSBmcm9tIFwiLi91dGlscy50c1wiO1xuXG4vLyBUb29sc1xuY29uc3QgUExBTl9NT0RFX1RPT0xTID0gW1wicmVhZFwiLCBcImJhc2hcIiwgXCJncmVwXCIsIFwiZmluZFwiLCBcImxzXCIsIFwicXVlc3Rpb25uYWlyZVwiXTtcbmNvbnN0IE5PUk1BTF9NT0RFX1RPT0xTID0gW1wicmVhZFwiLCBcImJhc2hcIiwgXCJlZGl0XCIsIFwid3JpdGVcIl07XG5cbi8vIFR5cGUgZ3VhcmQgZm9yIGFzc2lzdGFudCBtZXNzYWdlc1xuZnVuY3Rpb24gaXNBc3Npc3RhbnRNZXNzYWdlKG06IEFnZW50TWVzc2FnZSk6IG0gaXMgQXNzaXN0YW50TWVzc2FnZSB7XG5cdHJldHVybiBtLnJvbGUgPT09IFwiYXNzaXN0YW50XCIgJiYgQXJyYXkuaXNBcnJheShtLmNvbnRlbnQpO1xufVxuXG4vLyBFeHRyYWN0IHRleHQgY29udGVudCBmcm9tIGFuIGFzc2lzdGFudCBtZXNzYWdlXG5mdW5jdGlvbiBnZXRUZXh0Q29udGVudChtZXNzYWdlOiBBc3Npc3RhbnRNZXNzYWdlKTogc3RyaW5nIHtcblx0cmV0dXJuIG1lc3NhZ2UuY29udGVudFxuXHRcdC5maWx0ZXIoKGJsb2NrKTogYmxvY2sgaXMgVGV4dENvbnRlbnQgPT4gYmxvY2sudHlwZSA9PT0gXCJ0ZXh0XCIpXG5cdFx0Lm1hcCgoYmxvY2spID0+IGJsb2NrLnRleHQpXG5cdFx0LmpvaW4oXCJcXG5cIik7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHBsYW5Nb2RlRXh0ZW5zaW9uKHBpOiBFeHRlbnNpb25BUEkpOiB2b2lkIHtcblx0bGV0IHBsYW5Nb2RlRW5hYmxlZCA9IGZhbHNlO1xuXHRsZXQgZXhlY3V0aW9uTW9kZSA9IGZhbHNlO1xuXHRsZXQgdG9kb0l0ZW1zOiBUb2RvSXRlbVtdID0gW107XG5cblx0cGkucmVnaXN0ZXJGbGFnKFwicGxhblwiLCB7XG5cdFx0ZGVzY3JpcHRpb246IFwiU3RhcnQgaW4gcGxhbiBtb2RlIChyZWFkLW9ubHkgZXhwbG9yYXRpb24pXCIsXG5cdFx0dHlwZTogXCJib29sZWFuXCIsXG5cdFx0ZGVmYXVsdDogZmFsc2UsXG5cdH0pO1xuXG5cdGZ1bmN0aW9uIHVwZGF0ZVN0YXR1cyhjdHg6IEV4dGVuc2lvbkNvbnRleHQpOiB2b2lkIHtcblx0XHQvLyBGb290ZXIgc3RhdHVzXG5cdFx0aWYgKGV4ZWN1dGlvbk1vZGUgJiYgdG9kb0l0ZW1zLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IGNvbXBsZXRlZCA9IHRvZG9JdGVtcy5maWx0ZXIoKHQpID0+IHQuY29tcGxldGVkKS5sZW5ndGg7XG5cdFx0XHRjdHgudWkuc2V0U3RhdHVzKFwicGxhbi1tb2RlXCIsIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBg8J+TiyAke2NvbXBsZXRlZH0vJHt0b2RvSXRlbXMubGVuZ3RofWApKTtcblx0XHR9IGVsc2UgaWYgKHBsYW5Nb2RlRW5hYmxlZCkge1xuXHRcdFx0Y3R4LnVpLnNldFN0YXR1cyhcInBsYW4tbW9kZVwiLCBjdHgudWkudGhlbWUuZmcoXCJ3YXJuaW5nXCIsIFwi4o+4IHBsYW5cIikpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdHgudWkuc2V0U3RhdHVzKFwicGxhbi1tb2RlXCIsIHVuZGVmaW5lZCk7XG5cdFx0fVxuXG5cdFx0Ly8gV2lkZ2V0IHNob3dpbmcgdG9kbyBsaXN0XG5cdFx0aWYgKGV4ZWN1dGlvbk1vZGUgJiYgdG9kb0l0ZW1zLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IGxpbmVzID0gdG9kb0l0ZW1zLm1hcCgoaXRlbSkgPT4ge1xuXHRcdFx0XHRpZiAoaXRlbS5jb21wbGV0ZWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRcdFx0Y3R4LnVpLnRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKYkSBcIikgKyBjdHgudWkudGhlbWUuZmcoXCJtdXRlZFwiLCBjdHgudWkudGhlbWUuc3RyaWtldGhyb3VnaChpdGVtLnRleHQpKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGAke2N0eC51aS50aGVtZS5mZyhcIm11dGVkXCIsIFwi4piQIFwiKX0ke2l0ZW0udGV4dH1gO1xuXHRcdFx0fSk7XG5cdFx0XHRjdHgudWkuc2V0V2lkZ2V0KFwicGxhbi10b2Rvc1wiLCBsaW5lcyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN0eC51aS5zZXRXaWRnZXQoXCJwbGFuLXRvZG9zXCIsIHVuZGVmaW5lZCk7XG5cdFx0fVxuXHR9XG5cblx0ZnVuY3Rpb24gdG9nZ2xlUGxhbk1vZGUoY3R4OiBFeHRlbnNpb25Db250ZXh0KTogdm9pZCB7XG5cdFx0cGxhbk1vZGVFbmFibGVkID0gIXBsYW5Nb2RlRW5hYmxlZDtcblx0XHRleGVjdXRpb25Nb2RlID0gZmFsc2U7XG5cdFx0dG9kb0l0ZW1zID0gW107XG5cblx0XHRpZiAocGxhbk1vZGVFbmFibGVkKSB7XG5cdFx0XHRwaS5zZXRBY3RpdmVUb29scyhQTEFOX01PREVfVE9PTFMpO1xuXHRcdFx0Y3R4LnVpLm5vdGlmeShgUGxhbiBtb2RlIGVuYWJsZWQuIFRvb2xzOiAke1BMQU5fTU9ERV9UT09MUy5qb2luKFwiLCBcIil9YCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBpLnNldEFjdGl2ZVRvb2xzKE5PUk1BTF9NT0RFX1RPT0xTKTtcblx0XHRcdGN0eC51aS5ub3RpZnkoXCJQbGFuIG1vZGUgZGlzYWJsZWQuIEZ1bGwgYWNjZXNzIHJlc3RvcmVkLlwiKTtcblx0XHR9XG5cdFx0dXBkYXRlU3RhdHVzKGN0eCk7XG5cdH1cblxuXHRmdW5jdGlvbiBwZXJzaXN0U3RhdGUoKTogdm9pZCB7XG5cdFx0cGkuYXBwZW5kRW50cnkoXCJwbGFuLW1vZGVcIiwge1xuXHRcdFx0ZW5hYmxlZDogcGxhbk1vZGVFbmFibGVkLFxuXHRcdFx0dG9kb3M6IHRvZG9JdGVtcyxcblx0XHRcdGV4ZWN1dGluZzogZXhlY3V0aW9uTW9kZSxcblx0XHR9KTtcblx0fVxuXG5cdHBpLnJlZ2lzdGVyQ29tbWFuZChcInBsYW5cIiwge1xuXHRcdGRlc2NyaXB0aW9uOiBcIlRvZ2dsZSBwbGFuIG1vZGUgKHJlYWQtb25seSBleHBsb3JhdGlvbilcIixcblx0XHRoYW5kbGVyOiBhc3luYyAoX2FyZ3MsIGN0eCkgPT4gdG9nZ2xlUGxhbk1vZGUoY3R4KSxcblx0fSk7XG5cblx0cGkucmVnaXN0ZXJDb21tYW5kKFwidG9kb3NcIiwge1xuXHRcdGRlc2NyaXB0aW9uOiBcIlNob3cgY3VycmVudCBwbGFuIHRvZG8gbGlzdFwiLFxuXHRcdGhhbmRsZXI6IGFzeW5jIChfYXJncywgY3R4KSA9PiB7XG5cdFx0XHRpZiAodG9kb0l0ZW1zLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRjdHgudWkubm90aWZ5KFwiTm8gdG9kb3MuIENyZWF0ZSBhIHBsYW4gZmlyc3Qgd2l0aCAvcGxhblwiLCBcImluZm9cIik7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGxpc3QgPSB0b2RvSXRlbXMubWFwKChpdGVtLCBpKSA9PiBgJHtpICsgMX0uICR7aXRlbS5jb21wbGV0ZWQgPyBcIuKck1wiIDogXCLil4tcIn0gJHtpdGVtLnRleHR9YCkuam9pbihcIlxcblwiKTtcblx0XHRcdGN0eC51aS5ub3RpZnkoYFBsYW4gUHJvZ3Jlc3M6XFxuJHtsaXN0fWAsIFwiaW5mb1wiKTtcblx0XHR9LFxuXHR9KTtcblxuXHRwaS5yZWdpc3RlclNob3J0Y3V0KEtleS5jdHJsQWx0KFwicFwiKSwge1xuXHRcdGRlc2NyaXB0aW9uOiBcIlRvZ2dsZSBwbGFuIG1vZGVcIixcblx0XHRoYW5kbGVyOiBhc3luYyAoY3R4KSA9PiB0b2dnbGVQbGFuTW9kZShjdHgpLFxuXHR9KTtcblxuXHQvLyBCbG9jayBkZXN0cnVjdGl2ZSBiYXNoIGNvbW1hbmRzIGluIHBsYW4gbW9kZVxuXHRwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQpID0+IHtcblx0XHRpZiAoIXBsYW5Nb2RlRW5hYmxlZCB8fCBldmVudC50b29sTmFtZSAhPT0gXCJiYXNoXCIpIHJldHVybjtcblxuXHRcdGNvbnN0IGNvbW1hbmQgPSBldmVudC5pbnB1dC5jb21tYW5kIGFzIHN0cmluZztcblx0XHRpZiAoIWlzU2FmZUNvbW1hbmQoY29tbWFuZCkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGJsb2NrOiB0cnVlLFxuXHRcdFx0XHRyZWFzb246IGBQbGFuIG1vZGU6IGNvbW1hbmQgYmxvY2tlZCAobm90IGFsbG93bGlzdGVkKS4gVXNlIC9wbGFuIHRvIGRpc2FibGUgcGxhbiBtb2RlIGZpcnN0LlxcbkNvbW1hbmQ6ICR7Y29tbWFuZH1gLFxuXHRcdFx0fTtcblx0XHR9XG5cdH0pO1xuXG5cdC8vIEZpbHRlciBvdXQgc3RhbGUgcGxhbiBtb2RlIGNvbnRleHQgd2hlbiBub3QgaW4gcGxhbiBtb2RlXG5cdHBpLm9uKFwiY29udGV4dFwiLCBhc3luYyAoZXZlbnQpID0+IHtcblx0XHRpZiAocGxhbk1vZGVFbmFibGVkKSByZXR1cm47XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0bWVzc2FnZXM6IGV2ZW50Lm1lc3NhZ2VzLmZpbHRlcigobSkgPT4ge1xuXHRcdFx0XHRjb25zdCBtc2cgPSBtIGFzIEFnZW50TWVzc2FnZSAmIHsgY3VzdG9tVHlwZT86IHN0cmluZyB9O1xuXHRcdFx0XHRpZiAobXNnLmN1c3RvbVR5cGUgPT09IFwicGxhbi1tb2RlLWNvbnRleHRcIikgcmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRpZiAobXNnLnJvbGUgIT09IFwidXNlclwiKSByZXR1cm4gdHJ1ZTtcblxuXHRcdFx0XHRjb25zdCBjb250ZW50ID0gbXNnLmNvbnRlbnQ7XG5cdFx0XHRcdGlmICh0eXBlb2YgY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0XHRcdHJldHVybiAhY29udGVudC5pbmNsdWRlcyhcIltQTEFOIE1PREUgQUNUSVZFXVwiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoQXJyYXkuaXNBcnJheShjb250ZW50KSkge1xuXHRcdFx0XHRcdHJldHVybiAhY29udGVudC5zb21lKFxuXHRcdFx0XHRcdFx0KGMpID0+IGMudHlwZSA9PT0gXCJ0ZXh0XCIgJiYgKGMgYXMgVGV4dENvbnRlbnQpLnRleHQ/LmluY2x1ZGVzKFwiW1BMQU4gTU9ERSBBQ1RJVkVdXCIpLFxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9KSxcblx0XHR9O1xuXHR9KTtcblxuXHQvLyBJbmplY3QgcGxhbi9leGVjdXRpb24gY29udGV4dCBiZWZvcmUgYWdlbnQgc3RhcnRzXG5cdHBpLm9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIsIGFzeW5jICgpID0+IHtcblx0XHRpZiAocGxhbk1vZGVFbmFibGVkKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRtZXNzYWdlOiB7XG5cdFx0XHRcdFx0Y3VzdG9tVHlwZTogXCJwbGFuLW1vZGUtY29udGV4dFwiLFxuXHRcdFx0XHRcdGNvbnRlbnQ6IGBbUExBTiBNT0RFIEFDVElWRV1cbllvdSBhcmUgaW4gcGxhbiBtb2RlIC0gYSByZWFkLW9ubHkgZXhwbG9yYXRpb24gbW9kZSBmb3Igc2FmZSBjb2RlIGFuYWx5c2lzLlxuXG5SZXN0cmljdGlvbnM6XG4tIFlvdSBjYW4gb25seSB1c2U6IHJlYWQsIGJhc2gsIGdyZXAsIGZpbmQsIGxzLCBxdWVzdGlvbm5haXJlXG4tIFlvdSBDQU5OT1QgdXNlOiBlZGl0LCB3cml0ZSAoZmlsZSBtb2RpZmljYXRpb25zIGFyZSBkaXNhYmxlZClcbi0gQmFzaCBpcyByZXN0cmljdGVkIHRvIGFuIGFsbG93bGlzdCBvZiByZWFkLW9ubHkgY29tbWFuZHNcblxuQXNrIGNsYXJpZnlpbmcgcXVlc3Rpb25zIHVzaW5nIHRoZSBxdWVzdGlvbm5haXJlIHRvb2wuXG5Vc2UgYnJhdmUtc2VhcmNoIHNraWxsIHZpYSBiYXNoIGZvciB3ZWIgcmVzZWFyY2guXG5cbkNyZWF0ZSBhIGRldGFpbGVkIG51bWJlcmVkIHBsYW4gdW5kZXIgYSBcIlBsYW46XCIgaGVhZGVyOlxuXG5QbGFuOlxuMS4gRmlyc3Qgc3RlcCBkZXNjcmlwdGlvblxuMi4gU2Vjb25kIHN0ZXAgZGVzY3JpcHRpb25cbi4uLlxuXG5EbyBOT1QgYXR0ZW1wdCB0byBtYWtlIGNoYW5nZXMgLSBqdXN0IGRlc2NyaWJlIHdoYXQgeW91IHdvdWxkIGRvLmAsXG5cdFx0XHRcdFx0ZGlzcGxheTogZmFsc2UsXG5cdFx0XHRcdH0sXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmIChleGVjdXRpb25Nb2RlICYmIHRvZG9JdGVtcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRjb25zdCByZW1haW5pbmcgPSB0b2RvSXRlbXMuZmlsdGVyKCh0KSA9PiAhdC5jb21wbGV0ZWQpO1xuXHRcdFx0Y29uc3QgdG9kb0xpc3QgPSByZW1haW5pbmcubWFwKCh0KSA9PiBgJHt0LnN0ZXB9LiAke3QudGV4dH1gKS5qb2luKFwiXFxuXCIpO1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0bWVzc2FnZToge1xuXHRcdFx0XHRcdGN1c3RvbVR5cGU6IFwicGxhbi1leGVjdXRpb24tY29udGV4dFwiLFxuXHRcdFx0XHRcdGNvbnRlbnQ6IGBbRVhFQ1VUSU5HIFBMQU4gLSBGdWxsIHRvb2wgYWNjZXNzIGVuYWJsZWRdXG5cblJlbWFpbmluZyBzdGVwczpcbiR7dG9kb0xpc3R9XG5cbkV4ZWN1dGUgZWFjaCBzdGVwIGluIG9yZGVyLlxuQWZ0ZXIgY29tcGxldGluZyBhIHN0ZXAsIGluY2x1ZGUgYSBbRE9ORTpuXSB0YWcgaW4geW91ciByZXNwb25zZS5gLFxuXHRcdFx0XHRcdGRpc3BsYXk6IGZhbHNlLFxuXHRcdFx0XHR9LFxuXHRcdFx0fTtcblx0XHR9XG5cdH0pO1xuXG5cdC8vIFRyYWNrIHByb2dyZXNzIGFmdGVyIGVhY2ggdHVyblxuXHRwaS5vbihcInR1cm5fZW5kXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG5cdFx0aWYgKCFleGVjdXRpb25Nb2RlIHx8IHRvZG9JdGVtcy5sZW5ndGggPT09IDApIHJldHVybjtcblx0XHRpZiAoIWlzQXNzaXN0YW50TWVzc2FnZShldmVudC5tZXNzYWdlKSkgcmV0dXJuO1xuXG5cdFx0Y29uc3QgdGV4dCA9IGdldFRleHRDb250ZW50KGV2ZW50Lm1lc3NhZ2UpO1xuXHRcdGlmIChtYXJrQ29tcGxldGVkU3RlcHModGV4dCwgdG9kb0l0ZW1zKSA+IDApIHtcblx0XHRcdHVwZGF0ZVN0YXR1cyhjdHgpO1xuXHRcdH1cblx0XHRwZXJzaXN0U3RhdGUoKTtcblx0fSk7XG5cblx0Ly8gSGFuZGxlIHBsYW4gY29tcGxldGlvbiBhbmQgcGxhbiBtb2RlIFVJXG5cdHBpLm9uKFwiYWdlbnRfZW5kXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG5cdFx0Ly8gQ2hlY2sgaWYgZXhlY3V0aW9uIGlzIGNvbXBsZXRlXG5cdFx0aWYgKGV4ZWN1dGlvbk1vZGUgJiYgdG9kb0l0ZW1zLmxlbmd0aCA+IDApIHtcblx0XHRcdGlmICh0b2RvSXRlbXMuZXZlcnkoKHQpID0+IHQuY29tcGxldGVkKSkge1xuXHRcdFx0XHRjb25zdCBjb21wbGV0ZWRMaXN0ID0gdG9kb0l0ZW1zLm1hcCgodCkgPT4gYH5+JHt0LnRleHR9fn5gKS5qb2luKFwiXFxuXCIpO1xuXHRcdFx0XHRwaS5zZW5kTWVzc2FnZShcblx0XHRcdFx0XHR7IGN1c3RvbVR5cGU6IFwicGxhbi1jb21wbGV0ZVwiLCBjb250ZW50OiBgKipQbGFuIENvbXBsZXRlISoqIOKck1xcblxcbiR7Y29tcGxldGVkTGlzdH1gLCBkaXNwbGF5OiB0cnVlIH0sXG5cdFx0XHRcdFx0eyB0cmlnZ2VyVHVybjogZmFsc2UgfSxcblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhlY3V0aW9uTW9kZSA9IGZhbHNlO1xuXHRcdFx0XHR0b2RvSXRlbXMgPSBbXTtcblx0XHRcdFx0cGkuc2V0QWN0aXZlVG9vbHMoTk9STUFMX01PREVfVE9PTFMpO1xuXHRcdFx0XHR1cGRhdGVTdGF0dXMoY3R4KTtcblx0XHRcdFx0cGVyc2lzdFN0YXRlKCk7IC8vIFNhdmUgY2xlYXJlZCBzdGF0ZSBzbyByZXN1bWUgZG9lc24ndCByZXN0b3JlIG9sZCBleGVjdXRpb24gbW9kZVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICghcGxhbk1vZGVFbmFibGVkIHx8ICFjdHguaGFzVUkpIHJldHVybjtcblxuXHRcdC8vIEV4dHJhY3QgdG9kb3MgZnJvbSBsYXN0IGFzc2lzdGFudCBtZXNzYWdlXG5cdFx0Y29uc3QgbGFzdEFzc2lzdGFudCA9IFsuLi5ldmVudC5tZXNzYWdlc10ucmV2ZXJzZSgpLmZpbmQoaXNBc3Npc3RhbnRNZXNzYWdlKTtcblx0XHRpZiAobGFzdEFzc2lzdGFudCkge1xuXHRcdFx0Y29uc3QgZXh0cmFjdGVkID0gZXh0cmFjdFRvZG9JdGVtcyhnZXRUZXh0Q29udGVudChsYXN0QXNzaXN0YW50KSk7XG5cdFx0XHRpZiAoZXh0cmFjdGVkLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0dG9kb0l0ZW1zID0gZXh0cmFjdGVkO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNob3cgcGxhbiBzdGVwcyBhbmQgcHJvbXB0IGZvciBuZXh0IGFjdGlvblxuXHRcdGlmICh0b2RvSXRlbXMubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc3QgdG9kb0xpc3RUZXh0ID0gdG9kb0l0ZW1zLm1hcCgodCwgaSkgPT4gYCR7aSArIDF9LiDimJAgJHt0LnRleHR9YCkuam9pbihcIlxcblwiKTtcblx0XHRcdHBpLnNlbmRNZXNzYWdlKFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0Y3VzdG9tVHlwZTogXCJwbGFuLXRvZG8tbGlzdFwiLFxuXHRcdFx0XHRcdGNvbnRlbnQ6IGAqKlBsYW4gU3RlcHMgKCR7dG9kb0l0ZW1zLmxlbmd0aH0pOioqXFxuXFxuJHt0b2RvTGlzdFRleHR9YCxcblx0XHRcdFx0XHRkaXNwbGF5OiB0cnVlLFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7IHRyaWdnZXJUdXJuOiBmYWxzZSB9LFxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRjb25zdCBjaG9pY2UgPSBhd2FpdCBjdHgudWkuc2VsZWN0KFwiUGxhbiBtb2RlIC0gd2hhdCBuZXh0P1wiLCBbXG5cdFx0XHR0b2RvSXRlbXMubGVuZ3RoID4gMCA/IFwiRXhlY3V0ZSB0aGUgcGxhbiAodHJhY2sgcHJvZ3Jlc3MpXCIgOiBcIkV4ZWN1dGUgdGhlIHBsYW5cIixcblx0XHRcdFwiU3RheSBpbiBwbGFuIG1vZGVcIixcblx0XHRcdFwiUmVmaW5lIHRoZSBwbGFuXCIsXG5cdFx0XSk7XG5cblx0XHRpZiAoY2hvaWNlPy5zdGFydHNXaXRoKFwiRXhlY3V0ZVwiKSkge1xuXHRcdFx0cGxhbk1vZGVFbmFibGVkID0gZmFsc2U7XG5cdFx0XHRleGVjdXRpb25Nb2RlID0gdG9kb0l0ZW1zLmxlbmd0aCA+IDA7XG5cdFx0XHRwaS5zZXRBY3RpdmVUb29scyhOT1JNQUxfTU9ERV9UT09MUyk7XG5cdFx0XHR1cGRhdGVTdGF0dXMoY3R4KTtcblxuXHRcdFx0Y29uc3QgZXhlY01lc3NhZ2UgPVxuXHRcdFx0XHR0b2RvSXRlbXMubGVuZ3RoID4gMFxuXHRcdFx0XHRcdD8gYEV4ZWN1dGUgdGhlIHBsYW4uIFN0YXJ0IHdpdGg6ICR7dG9kb0l0ZW1zWzBdLnRleHR9YFxuXHRcdFx0XHRcdDogXCJFeGVjdXRlIHRoZSBwbGFuIHlvdSBqdXN0IGNyZWF0ZWQuXCI7XG5cdFx0XHRwaS5zZW5kTWVzc2FnZShcblx0XHRcdFx0eyBjdXN0b21UeXBlOiBcInBsYW4tbW9kZS1leGVjdXRlXCIsIGNvbnRlbnQ6IGV4ZWNNZXNzYWdlLCBkaXNwbGF5OiB0cnVlIH0sXG5cdFx0XHRcdHsgdHJpZ2dlclR1cm46IHRydWUgfSxcblx0XHRcdCk7XG5cdFx0fSBlbHNlIGlmIChjaG9pY2UgPT09IFwiUmVmaW5lIHRoZSBwbGFuXCIpIHtcblx0XHRcdGNvbnN0IHJlZmluZW1lbnQgPSBhd2FpdCBjdHgudWkuZWRpdG9yKFwiUmVmaW5lIHRoZSBwbGFuOlwiLCBcIlwiKTtcblx0XHRcdGlmIChyZWZpbmVtZW50Py50cmltKCkpIHtcblx0XHRcdFx0cGkuc2VuZFVzZXJNZXNzYWdlKHJlZmluZW1lbnQudHJpbSgpKTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xuXG5cdC8vIFJlc3RvcmUgc3RhdGUgb24gc2Vzc2lvbiBzdGFydC9yZXN1bWVcblx0cGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuXHRcdGlmIChwaS5nZXRGbGFnKFwicGxhblwiKSA9PT0gdHJ1ZSkge1xuXHRcdFx0cGxhbk1vZGVFbmFibGVkID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBlbnRyaWVzID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldEVudHJpZXMoKTtcblxuXHRcdC8vIFJlc3RvcmUgcGVyc2lzdGVkIHN0YXRlXG5cdFx0Y29uc3QgcGxhbk1vZGVFbnRyeSA9IGVudHJpZXNcblx0XHRcdC5maWx0ZXIoKGU6IHsgdHlwZTogc3RyaW5nOyBjdXN0b21UeXBlPzogc3RyaW5nIH0pID0+IGUudHlwZSA9PT0gXCJjdXN0b21cIiAmJiBlLmN1c3RvbVR5cGUgPT09IFwicGxhbi1tb2RlXCIpXG5cdFx0XHQucG9wKCkgYXMgeyBkYXRhPzogeyBlbmFibGVkOiBib29sZWFuOyB0b2Rvcz86IFRvZG9JdGVtW107IGV4ZWN1dGluZz86IGJvb2xlYW4gfSB9IHwgdW5kZWZpbmVkO1xuXG5cdFx0aWYgKHBsYW5Nb2RlRW50cnk/LmRhdGEpIHtcblx0XHRcdHBsYW5Nb2RlRW5hYmxlZCA9IHBsYW5Nb2RlRW50cnkuZGF0YS5lbmFibGVkID8/IHBsYW5Nb2RlRW5hYmxlZDtcblx0XHRcdHRvZG9JdGVtcyA9IHBsYW5Nb2RlRW50cnkuZGF0YS50b2RvcyA/PyB0b2RvSXRlbXM7XG5cdFx0XHRleGVjdXRpb25Nb2RlID0gcGxhbk1vZGVFbnRyeS5kYXRhLmV4ZWN1dGluZyA/PyBleGVjdXRpb25Nb2RlO1xuXHRcdH1cblxuXHRcdC8vIE9uIHJlc3VtZTogcmUtc2NhbiBtZXNzYWdlcyB0byByZWJ1aWxkIGNvbXBsZXRpb24gc3RhdGVcblx0XHQvLyBPbmx5IHNjYW4gbWVzc2FnZXMgQUZURVIgdGhlIGxhc3QgXCJwbGFuLW1vZGUtZXhlY3V0ZVwiIHRvIGF2b2lkIHBpY2tpbmcgdXAgW0RPTkU6bl0gZnJvbSBwcmV2aW91cyBwbGFuc1xuXHRcdGNvbnN0IGlzUmVzdW1lID0gcGxhbk1vZGVFbnRyeSAhPT0gdW5kZWZpbmVkO1xuXHRcdGlmIChpc1Jlc3VtZSAmJiBleGVjdXRpb25Nb2RlICYmIHRvZG9JdGVtcy5sZW5ndGggPiAwKSB7XG5cdFx0XHQvLyBGaW5kIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBwbGFuLW1vZGUtZXhlY3V0ZSBlbnRyeSAobWFya3Mgd2hlbiBjdXJyZW50IGV4ZWN1dGlvbiBzdGFydGVkKVxuXHRcdFx0bGV0IGV4ZWN1dGVJbmRleCA9IC0xO1xuXHRcdFx0Zm9yIChsZXQgaSA9IGVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0XHRcdFx0Y29uc3QgZW50cnkgPSBlbnRyaWVzW2ldIGFzIHsgdHlwZTogc3RyaW5nOyBjdXN0b21UeXBlPzogc3RyaW5nIH07XG5cdFx0XHRcdGlmIChlbnRyeS5jdXN0b21UeXBlID09PSBcInBsYW4tbW9kZS1leGVjdXRlXCIpIHtcblx0XHRcdFx0XHRleGVjdXRlSW5kZXggPSBpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9ubHkgc2NhbiBtZXNzYWdlcyBhZnRlciB0aGUgZXhlY3V0ZSBtYXJrZXJcblx0XHRcdGNvbnN0IG1lc3NhZ2VzOiBBc3Npc3RhbnRNZXNzYWdlW10gPSBbXTtcblx0XHRcdGZvciAobGV0IGkgPSBleGVjdXRlSW5kZXggKyAxOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRjb25zdCBlbnRyeSA9IGVudHJpZXNbaV07XG5cdFx0XHRcdGlmIChlbnRyeS50eXBlID09PSBcIm1lc3NhZ2VcIiAmJiBcIm1lc3NhZ2VcIiBpbiBlbnRyeSAmJiBpc0Fzc2lzdGFudE1lc3NhZ2UoZW50cnkubWVzc2FnZSBhcyBBZ2VudE1lc3NhZ2UpKSB7XG5cdFx0XHRcdFx0bWVzc2FnZXMucHVzaChlbnRyeS5tZXNzYWdlIGFzIEFzc2lzdGFudE1lc3NhZ2UpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBhbGxUZXh0ID0gbWVzc2FnZXMubWFwKGdldFRleHRDb250ZW50KS5qb2luKFwiXFxuXCIpO1xuXHRcdFx0bWFya0NvbXBsZXRlZFN0ZXBzKGFsbFRleHQsIHRvZG9JdGVtcyk7XG5cdFx0fVxuXG5cdFx0aWYgKHBsYW5Nb2RlRW5hYmxlZCkge1xuXHRcdFx0cGkuc2V0QWN0aXZlVG9vbHMoUExBTl9NT0RFX1RPT0xTKTtcblx0XHR9XG5cdFx0dXBkYXRlU3RhdHVzKGN0eCk7XG5cdH0pO1xufVxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MjgwNzM1fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOTA2OGUyYmMiLCJwYXJlbnRJZCI6ImJkYmQ3YjBlIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MToyMC43MzZaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiI3dVpVM2VFUUhHMHVLVUY4emhvQWl4R2RBQ1FnaHlFUyIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IntcbiAgXCJuYW1lXCI6IFwicGktZXh0ZW5zaW9uLXdpdGgtZGVwc1wiLFxuICBcInByaXZhdGVcIjogdHJ1ZSxcbiAgXCJ2ZXJzaW9uXCI6IFwiMC43OS44XCIsXG4gIFwidHlwZVwiOiBcIm1vZHVsZVwiLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwiY2xlYW5cIjogXCJlY2hvICdub3RoaW5nIHRvIGNsZWFuJ1wiLFxuICAgIFwiYnVpbGRcIjogXCJlY2hvICdub3RoaW5nIHRvIGJ1aWxkJ1wiLFxuICAgIFwiY2hlY2tcIjogXCJlY2hvICdub3RoaW5nIHRvIGNoZWNrJ1wiXG4gIH0sXG4gIFwicGlcIjoge1xuICAgIFwiZXh0ZW5zaW9uc1wiOiBbXG4gICAgICBcIi4vaW5kZXgudHNcIlxuICAgIF1cbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwibXNcIjogXCIyLjEuM1wiXG4gIH0sXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcIkB0eXBlcy9tc1wiOiBcIjIuMS4wXCJcbiAgfVxufVxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MjgwNzM2fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMGMwMGRmNDEiLCJwYXJlbnRJZCI6IjkwNjhlMmJjIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MTozNi41NDJaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJOb3cgSSBoYXZlIGEgZ29vZCB1bmRlcnN0YW5kaW5nIG9mIHRoZSBQaSBleHRlbnNpb24gc3lzdGVtLiBMZXQgbWUgZGVzaWduIHRoZSBUREQgY3ljbGUgZXh0ZW5zaW9uLiBUaGUga2V5IHJlcXVpcmVtZW50cyBhcmU6XG5cbjEuIFN0ZWVyIGFnZW50IHRocm91Z2ggcmVkLWdyZWVuLXJlZmFjdG9yIGN5Y2xlXG4yLiBNYWtlIGl0IGltcG9zc2libGUgdG8gc2tpcCByZWZhY3RvcmluZ1xuMy4gS2VlcCBkZXZlbG9wZXIgaW4gdGhlIGxvb3BcbjQuIFRlc3RzIHJ1biB3aGVuIGFnZW50IGNhbGxzICdnby10by1ncmVlbicgdG9vbFxuNS4gV2hlbiB0ZXN0cyBmYWlsLCBzdGF0ZSBzdGF5cyBpbiByZWRcbjYuIFdoZW4gdGVzdHMgcGFzcywgYWdlbnQgZ2V0cyBzdGVlcmluZyBtZXNzYWdlIHRoYXQgbmV4dCBwaGFzZSBpcyByZWZhY3RvclxuNy4gRGV2ZWxvcGVyIHByZXNlbnRlZCB3aXRoIGNob2ljZXM6IHJlZmFjdG9yIHRlc3RzLCByZWZhY3RvciBpbXBsZW1lbnRhdGlvbiwgY29udGludWUgdG8gbmV4dCB0ZXN0LCBvciBjdXN0b20gaW5zdHJ1Y3Rpb25cblxuTGV0IG1lIHBsYW4gdGhlIHN0cnVjdHVyZTpcblxuLSBBIFBpIHBhY2thZ2Ugd2l0aDpcbiAgLSBFeHRlbnNpb24gdGhhdCBtYW5hZ2VzIFRERCBzdGF0ZSBtYWNoaW5lXG4gIC0gVG9vbHM6IGBnby10by1ncmVlbmAsIGBydW4tdGVzdHNgLCBgZ28tdG8tcmVmYWN0b3JgXG4gIC0gU3RhdGUgbWFjaGluZTogUkVEIOKGkiBHUkVFTiDihpIgUkVGQUNUT1Ig4oaSIChiYWNrIHRvIFJFRCBmb3IgbmV4dCB0ZXN0KVxuICAtIEludGVyYWN0aXZlIHByb21wdHMgZm9yIGRldmVsb3BlciBkZWNpc2lvbnMgZHVyaW5nIFJFRkFDVE9SIHBoYXNlXG5cbkxldCBtZSBjcmVhdGUgdGhlIHByb2plY3Qgc3RydWN0dXJlOlxuXG5gYGBcbnBpLXRkZC1jeWNsZS9cbuKUnOKUgOKUgCBwYWNrYWdlLmpzb25cbuKUnOKUgOKUgCB0c2NvbmZpZy5qc29uXG7ilJzilIDilIAgdml0ZXN0LmNvbmZpZy50c1xu4pSc4pSA4pSAIHNyYy9cbuKUgiAgIOKUnOKUgOKUgCBpbmRleC50cyAgICAgICAgICAjIEV4dGVuc2lvbiBlbnRyeSBwb2ludFxu4pSCICAg4pSc4pSA4pSAIHN0YXRlLnRzICAgICAgICAgICMgU3RhdGUgbWFjaGluZSBsb2dpY1xu4pSCICAg4pSc4pSA4pSAIHRvb2xzLnRzICAgICAgICAgICMgVG9vbCBkZWZpbml0aW9uc1xu4pSCICAg4pSc4pSA4pSAIHVpLnRzICAgICAgICAgICAgICMgQ3VzdG9tIFVJIGNvbXBvbmVudHNcbuKUgiAgIOKUlOKUgOKUgCB0ZXN0L1xu4pSCICAgICAgIOKUnOKUgOKUgCBzdGF0ZS50ZXN0LnRzICMgVGVzdHMgZm9yIHN0YXRlIG1hY2hpbmVcbuKUgiAgICAgICDilJTilIDilIAgLi4uXG7ilJTilIDilIAgUkVBRE1FLm1kXG5gYGBcblxuTGV0IG1lIHN0YXJ0IGJ1aWxkaW5nIHRoaXMuXG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJOb3cgSSBoYXZlIGEgc29saWQgdW5kZXJzdGFuZGluZyBvZiB0aGUgUGkgZXh0ZW5zaW9uIHN5c3RlbS4gTGV0IG1lIGRlc2lnbiBhbmQgc2NhZmZvbGQgdGhpcyBUREQgY3ljbGUgZXh0ZW5zaW9uLlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiUnZQWDhmM3BOY0JRcDRNZ0pPSG1kRWpTRkIwOUlaZEUiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgY2F0IHBhY2thZ2UuanNvbiJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MzI5NCwib3V0cHV0IjozOTgsImNhY2hlUmVhZCI6MzkzNDUsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo0MzAzNywiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4MjgwNzM2LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtcnFjU1RZVWx4ZldMTUdKM3BLMkRDTTdtdk9kb1I5QkQifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZTU0ZjZkM2UiLCJwYXJlbnRJZCI6IjBjMDBkZjQxIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MTozNi41NTdaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJSdlBYOGYzcE5jQlFwNE1nSk9IbWRFalNGQjA5SVpkRSIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IntcbiAgXCJuYW1lXCI6IFwicGktdGRkLWN5Y2xlXCIsXG4gIFwidmVyc2lvblwiOiBcIjEuMC4wXCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJcIixcbiAgXCJtYWluXCI6IFwiaW5kZXguanNcIixcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInRlc3RcIjogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiXG4gIH0sXG4gIFwia2V5d29yZHNcIjogW10sXG4gIFwiYXV0aG9yXCI6IFwiXCIsXG4gIFwibGljZW5zZVwiOiBcIklTQ1wiLFxuICBcInBhY2thZ2VNYW5hZ2VyXCI6IFwicG5wbUAxMC4zMy4yXCJcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODI5NjU1N319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImQwZjA3OTAwIiwicGFyZW50SWQiOiJlNTRmNmQzZSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTI6MTMuMzQ3WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTGV0IG1lIG5vdyBjcmVhdGUgdGhlIGZ1bGwgcHJvamVjdCBzdHJ1Y3R1cmUuIEknbGwgc2V0IHVwOlxuXG4xLiBgcGFja2FnZS5qc29uYCAtIHdpdGggcHJvcGVyIHBpIHBhY2thZ2UgbWFuaWZlc3QsIHZpdGVzdCBhcyBkZXZEZXBlbmRlbmN5XG4yLiBgdHNjb25maWcuanNvbmAgLSBUeXBlU2NyaXB0IGNvbmZpZ1xuMy4gYHZpdGVzdC5jb25maWcudHNgIC0gVml0ZXN0IGNvbmZpZ1xuNC4gYHNyYy9pbmRleC50c2AgLSBFeHRlbnNpb24gZW50cnkgcG9pbnRcbjUuIGBzcmMvc3RhdGUudHNgIC0gU3RhdGUgbWFjaGluZSBmb3IgVEREIGN5Y2xlXG42LiBgc3JjL3Rvb2xzLnRzYCAtIFRvb2wgZGVmaW5pdGlvbnNcbjcuIGBzcmMvdWkudHNgIC0gQ3VzdG9tIFVJIGZvciBkZXZlbG9wZXIgcHJvbXB0c1xuOC4gYHNyYy90ZXN0L3N0YXRlLnRlc3QudHNgIC0gVGVzdHMgZm9yIHN0YXRlIG1hY2hpbmVcblxuTGV0IG1lIHRoaW5rIGFib3V0IHRoZSBhcmNoaXRlY3R1cmU6XG5cbioqU3RhdGUgTWFjaGluZToqKlxuLSBgUkVEYDogTm8gdGVzdHMgcGFzc2luZyAob3Igbm8gdGVzdHMgd3JpdHRlbiB5ZXQpLiBBZ2VudCBzaG91bGQgd3JpdGUgdGVzdHMuXG4tIGBHUkVFTmA6IFRlc3RzIHBhc3MuIEFnZW50IHNob3VsZCByZWZhY3RvciAoYnV0IGRldmVsb3BlciBkZWNpZGVzIHdoYXQgdG8gcmVmYWN0b3IpLlxuLSBgUkVGQUNUT1JgOiBEZXZlbG9wZXIgY2hvb3NlcyB3aGF0IHRvIHJlZmFjdG9yLiBBZnRlciByZWZhY3RvcmluZywgdGVzdHMgc3RpbGwgcGFzcywgdGhlbiBiYWNrIHRvIFJFRCAobmV4dCB0ZXN0KSBvciBHUkVFTi5cblxuXG4tIFRoZSBjeWNsZSBmbG93cyBmcm9tIFJFRCB0aHJvdWdoIEdSRUVOIHRvIFJFRkFDVE9SLCB0aGVuIGxvb3BzIGJhY2sgdG8gUkVEIGZvciB0aGUgbmV4dCB0ZXN0LlxuXG4qKlRvb2xzOioqXG4tIGBnby10by1ncmVlbmA6IEFnZW50IGNhbGxzIHRoaXMgdG8gc2lnbmFsIFwiSSd2ZSB3cml0dGVuIGNvZGUsIHJ1biB0ZXN0c1wiLiBUaGUgdG9vbCBleGVjdXRlcyB0ZXN0cywgYW5kIGlmIHRoZXkgZmFpbCwgc3RheXMgaW4gUkVEIHdpdGggZmVlZGJhY2s7IGlmIHRoZXkgcGFzcywgdHJhbnNpdGlvbnMgdG8gR1JFRU4uXG4tIGBnby10by1yZWZhY3RvcmA6IEFnZW50IGNhbGxzIHRoaXMgdG8gc2lnbmFsIFwiSSB0aGluayB0aGUgY29kZSBpcyByZWFkeSB0byByZWZhY3RvclwiLiBUaGUgdG9vbCB2ZXJpZmllcyB0ZXN0cyBzdGlsbCBwYXNzLCB0aGVuIHRyYW5zaXRpb25zIHRvIFJFRkFDVE9SIHdoZXJlIHRoZSBkZXZlbG9wZXIgbWFrZXMgZGVjaXNpb25zLlxuLSBgcnVuLXRlc3RzYDogVXRpbGl0eSBmb3IgcnVubmluZyB0ZXN0cyBpbmRlcGVuZGVudGx5LlxuXG4qKkRldmVsb3BlciBQcm9tcHRzIChpbiBSRUZBQ1RPUiBwaGFzZSk6KipcbldoZW4gdHJhbnNpdGlvbmluZyB0byBSRUZBQ1RPUiwgSSBuZWVkIHRvIGdpdmUgdGhlIGRldmVsb3BlciBjb25jcmV0ZSBjaG9pY2VzIGFib3V0IHdoYXQgdG8gZm9jdXMgb27igJR3aGV0aGVyIHRoYXQncyByZWZhY3RvcmluZyB0aGUgdGVzdHMgdGhlbXNlbHZlcywgY2xlYW5pbmcgdXAgdGhlIGltcGxlbWVudGF0aW9uLCBtb3Zpbmcgb24gdG8gdGhlIG5leHQgdGVzdCBjYXNlLCBvciBwcm92aWRpbmcgY3VzdG9tIGluc3RydWN0aW9ucy5cblxuVGhlIHRyaWNreSBwYXJ0IGlzIGhhbmRsaW5nIHRoZSBhZ2VudCdzIGJlaGF2aW9yOiB3aGVuIHRlc3RzIGZhaWwgZHVyaW5nIGBnby10by1ncmVlbmAsIHRoZSBhZ2VudCBuZWVkcyB0byBzdGF5IGluIFJFRCBhbmQga2VlcCB0cnlpbmcsIGJ1dCBJIG5lZWQgdG8gbWFrZSBzdXJlIGl0IGRvZXNuJ3Qgc2tpcCB0aGUgcmVmYWN0b3JpbmcgcGhhc2UgZW50aXJlbHkuXG5cblRoZSBmbG93IHdvcmtzIGxpa2UgdGhpczogdGhlIGFnZW50IHdyaXRlcyBhIGZhaWxpbmcgdGVzdCBhbmQgaW1wbGVtZW50YXRpb24sIGNhbGxzIGBnby10by1ncmVlbmAsIGFuZCBpZiB0ZXN0cyBwYXNzLCB0aGUgdG9vbCBibG9ja3MgZnVydGhlciBhZ2VudCBhY3Rpb24gdW50aWwgdGhlIGRldmVsb3BlciBleHBsaWNpdGx5IGFwcHJvdmVzIG1vdmluZyB0byByZWZhY3RvcmluZy4gVGhpcyBjcmVhdGVzIGEgaGFyZCBnYXRlIGJldHdlZW4gcGhhc2VzLlxuXG5Ob3cgSSdtIHJlYWxpemluZyB0aGUgcmVmYWN0b3JpbmcgcGhhc2UgbmVlZHMgbW9yZSB0aG91Z2h04oCUd2hlbiB0aGUgYWdlbnQgY2FsbHMgYGdvLXRvLXJlZmFjdG9yYCwgdGhlIGRldmVsb3BlciBjaG9vc2VzIHdoYXQgdG8gcmVmYWN0b3IsIGJ1dCBhZnRlciB0aGF0IHdvcmsgaXMgZG9uZSwgaG93IGRvIHdlIHZlcmlmeSBpdCdzIGFjdHVhbGx5IGltcHJvdmVkIHdpdGhvdXQgYnJlYWtpbmcgdGVzdHM/XG5cbkkgdGhpbmsgdGhlIGNsZWFuZXN0IGFwcHJvYWNoIGlzIHRvIG1ha2UgdGhlIGRldmVsb3BlcidzIGNob2ljZXMgZXhwbGljaXQ6IHRoZXkgY2FuIHJlZmFjdG9yIHRlc3RzLCByZWZhY3RvciBpbXBsZW1lbnRhdGlvbiwgcHJvY2VlZCB0byB0aGUgbmV4dCB0ZXN0LCBvciBwcm92aWRlIGN1c3RvbSBpbnN0cnVjdGlvbnMuIEFmdGVyIGFueSByZWZhY3RvcmluZywgd2UgbG9vcCBiYWNrIHRvIGBnby10by1ncmVlbmAgdG8gY29uZmlybSB0ZXN0cyBzdGlsbCBwYXNzIGJlZm9yZSBjb250aW51aW5nLlxuXG5UaGUgYWdlbnQgc3RheXMgaW4gYSBsb29wIGR1cmluZyBSRUQgYW5kIEdSRUVOIHBoYXNlcywgb25seSBwYXVzaW5nIHdoZW4gdGhlIGRldmVsb3BlciBpbnRlcnZlbmVzIGR1cmluZyBSRUZBQ1RPUi4gU28gdGhlIHJlYWwgcXVlc3Rpb24gaXMgaG93IHRvIGhhbmRsZSB0aGUgdHJhbnNpdGlvbiBiZXR3ZWVuIHBoYXNlc+KAlGRvZXMgdGhlIHRvb2wgZXhlY3V0aW9uIGl0c2VsZiBjcmVhdGUgdGhlIGJyZWFrLCBvciBkb2VzIHRoZSBhZ2VudCBuZWVkIHRvIHN0b3AgYW5kIHdhaXQgZm9yIGRldmVsb3BlciBpbnB1dD9cblxuSSdtIHRoaW5raW5nIHRoZSB0b29sIHNob3VsZCByZXR1cm4gYSBtZXNzYWdlIHRoYXQgc2lnbmFscyB0byB0aGUgTExNIHRoYXQgdGhlIHBoYXNlIGhhcyBjaGFuZ2VkLCBwcm9tcHRpbmcgaXQgdG8gZWl0aGVyIGNvbnRpbnVlIHdvcmtpbmcgaW4gdGhlIGN1cnJlbnQgcGhhc2Ugb3Igd2FpdCBmb3IgdGhlIGRldmVsb3BlcidzIGRpcmVjdGlvbi4gVGhlIGRldmVsb3BlciB0aGVuIG1ha2VzIHRoZWlyIGNob2ljZSB0aHJvdWdoIGEgY3VzdG9tIFVJIHByb21wdCwgYW5kIGJhc2VkIG9uIHRoYXQgc2VsZWN0aW9uLCB0aGUgc3lzdGVtIGVpdGhlciBzZW5kcyBhIHN0ZWVyaW5nIG1lc3NhZ2UgdG8gdGhlIGFnZW50IG9yIGxldHMgaXQgY29udGludWUuXG5cbkZvciB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uLCBJIG5lZWQgdG8gZmlndXJlIG91dCBob3cgdG8gcnVuIHRlc3Rz4oCUdGhlIGFnZW50IHdpbGwgdXNlIHRoZSBiYXNoIHRvb2wgZm9yIHRoYXQsIGJ1dCBJIHNob3VsZCBhbHNvIGhhdmUgYSBkZWRpY2F0ZWQgdG9vbCB0aGF0IHRoZSBleHRlbnNpb24gY2FuIGhvb2sgaW50byB0byBpbnRlcmNlcHQgYW5kIG1hbmFnZSB0aGUgdGVzdCBleGVjdXRpb24gZmxvdy4gSSdtIHNldHRsaW5nIG9uIGEgc2ltcGxlciBhcHByb2FjaDogdGhlIGFnZW50IHVzZXMgdGhlIHN0YW5kYXJkIGBiYXNoYCB0b29sIHRvIHJ1biB0ZXN0cywgYnV0IEknbGwgYWRkIGEgYHRkZC1zdGF0dXNgIHRvb2wgdGhhdCBsZXRzIHRoZSBhZ2VudCBxdWVyeSB0aGUgY3VycmVudCBzdGF0ZSBhbmQgcmVjZWl2ZSBndWlkYW5jZSBvbiB3aGF0IHRvIGRvIG5leHQuIFRoaXMga2VlcHMgdGhlIGZsb3cgc3RyYWlnaHRmb3J3YXJk4oCUdGhlIGFnZW50IHdyaXRlcyBjb2RlLCBydW5zIHRlc3RzIHZpYSBiYXNoLCBjaGVja3MgdGhlIHN0YXR1cywgYW5kIGdldHMgZGlyZWN0ZWQgdG8gdGhlIGFwcHJvcHJpYXRlIHBoYXNlLiBUaGUga2V5IGluc2lnaHQgaXMgdGhhdCB0aGUgcmVmYWN0b3JpbmcgZ2F0ZSB3b3JrcyBuYXR1cmFsbHk6IHRlc3RzIG11c3QgcGFzcyBiZWZvcmUgdGhlIGFnZW50IGNhbiBtb3ZlIGZvcndhcmQsIGFuZCBhZnRlciBncmVlbiwgaXQgY2FuJ3Qgc2tpcCBzdHJhaWdodCB0byB3cml0aW5nIG5ldyB0ZXN0cyB3aXRob3V0IGdvaW5nIHRocm91Z2ggcmVmYWN0b3JpbmcgZmlyc3QuIEknbSByZWFsaXppbmcgdGhlIGNvcmUgaXNzdWU6IHRoZSBhZ2VudCBuZWVkcyB0byBiZSBmb3JjZWQgdGhyb3VnaCByZWZhY3RvcmluZyBiZWZvcmUgbW92aW5nIHRvIHRoZSBuZXh0IHRlc3QsIGJ1dCBJIGNhbid0IHByZXZlbnQgaXQgZnJvbSB1c2luZyBiYXNoIGRpcmVjdGx5LiBUaGUgc29sdXRpb24gaXMgdG8gdXNlIGEgYHRvb2xfY2FsbGAgaG9vayB0aGF0IGludGVyY2VwdHMgd2hlbiB0aGUgYWdlbnQgdHJpZXMgdG8gc2tpcCBhaGVhZOKAlHdoZW4gaXQgYXR0ZW1wdHMgdG8gd3JpdGUgYSBuZXcgdGVzdCB3aGlsZSBpbiBSRUZBQ1RPUklORyBzdGF0ZSwgdGhlIGhvb2sgc2hvdWxkIGJsb2NrIGl0IGFuZCBwcm9tcHQgZm9yIGRldmVsb3BlciBpbnRlcnZlbnRpb24gaW5zdGVhZC5cblxuTm93IEknbSB0aGlua2luZyB0aHJvdWdoIHRoZSBjb21wbGV0ZSBmbG93OiB0aGUgYWdlbnQgd3JpdGVzIGEgZmFpbGluZyB0ZXN0IGFuZCBpbXBsZW1lbnRhdGlvbiwgcnVucyB0ZXN0cyB0byBjb25maXJtIHRoZXkgZmFpbCwgdGhlbiB1c2VzIHRoZSB0ZGQgdG9vbCB0byB0cmFuc2l0aW9uIHRvIGdyZWVuLiBPbmNlIHRlc3RzIHBhc3MsIHRoZSBhZ2VudCBzaG91bGQgcmVmYWN0b3IsIGFuZCBvbmx5IGFmdGVyIHJlZmFjdG9yaW5nIGNhbiBpdCBwcm9jZWVkIHRvIHRoZSBuZXh0IHRlc3QuIFRoZSBkZXZlbG9wZXIgZ2V0cyB0byBjaG9vc2Ugd2hhdCB0byByZWZhY3RvciBhbmQgY2FuIHByb3ZpZGUgY3VzdG9tIGluc3RydWN0aW9ucyBkdXJpbmcgdGhhdCBwaGFzZS5cblxuSSdtIGdvaW5nIHRvIHNpbXBsaWZ5IHRoaXMgYnkgaGF2aW5nIHRoZSBhZ2VudCBwcmltYXJpbHkgdXNlIGJhc2ggZm9yIHJ1bm5pbmcgdGVzdHMsIHdpdGggYSB0ZGQtc3RhdHVzIHRvb2wgdG8gY2hlY2sgdGhlIGN1cnJlbnQgcGhhc2UsIGFuZCBhIHRkZC1kZWNpZGUgdG9vbCB0byBnZXQgZGV2ZWxvcGVyIGlucHV0IG9uIHdoYXQgdG8gcmVmYWN0b3IgbmV4dC5cblxuU2V0dGluZyB1cCB0aGUgcHJvamVjdCBzdHJ1Y3R1cmUuLi5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vdyBsZXQgbWUgY3JlYXRlIHRoZSBmdWxsIHByb2plY3QuIEknbGwgc3RhcnQgd2l0aCB0aGUgcGFja2FnZS5qc29uIGFuZCB0c2NvbmZpZzpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IjJiVGp5aG5NQ1kzZXlHVTc4eGRFN0w4VnRFVG85ckJaIiwibmFtZSI6IndyaXRlIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9wYWNrYWdlLmpzb24iLCJjb250ZW50Ijoie1xuICBcIm5hbWVcIjogXCJwaS10ZGQtY3ljbGVcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMC4xLjBcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIlBpIGV4dGVuc2lvbiB0aGF0IGVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgVEREIGN5Y2xlXCIsXG4gIFwidHlwZVwiOiBcIm1vZHVsZVwiLFxuICBcInByaXZhdGVcIjogdHJ1ZSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInRlc3RcIjogXCJ2aXRlc3QgcnVuXCIsXG4gICAgXCJ0ZXN0OndhdGNoXCI6IFwidml0ZXN0XCJcbiAgfSxcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJwaS1wYWNrYWdlXCIsXG4gICAgXCJ0ZGRcIixcbiAgICBcInJlZC1ncmVlbi1yZWZhY3RvclwiLFxuICAgIFwiZXh0ZW5zaW9uXCJcbiAgXSxcbiAgXCJwaVwiOiB7XG4gICAgXCJleHRlbnNpb25zXCI6IFtcbiAgICAgIFwiLi9zcmMvaW5kZXgudHNcIlxuICAgIF1cbiAgfSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQHR5cGVzL25vZGVcIjogXCJeMjQuMC4wXCIsXG4gICAgXCJ0eXBlc2NyaXB0XCI6IFwiXjUuOC4wXCIsXG4gICAgXCJ2aXRlc3RcIjogXCJeMy4wLjBcIlxuICB9LFxuICBcInBlZXJEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiOiBcIj49MS4wLjBcIlxuICB9XG59XG4ifX0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IjB0aVRPQjRlNVVVa2RTWE9nZ0NpeTd0ZFQ1N0hvNlVXIiwibmFtZSI6IndyaXRlIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS90c2NvbmZpZy5qc29uIiwiY29udGVudCI6IntcbiAgXCJjb21waWxlck9wdGlvbnNcIjoge1xuICAgIFwidGFyZ2V0XCI6IFwiRVMyMDIyXCIsXG4gICAgXCJtb2R1bGVcIjogXCJFU05leHRcIixcbiAgICBcIm1vZHVsZVJlc29sdXRpb25cIjogXCJidW5kbGVyXCIsXG4gICAgXCJzdHJpY3RcIjogdHJ1ZSxcbiAgICBcImVzTW9kdWxlSW50ZXJvcFwiOiB0cnVlLFxuICAgIFwic2tpcExpYkNoZWNrXCI6IHRydWUsXG4gICAgXCJmb3JjZUNvbnNpc3RlbnRDYXNpbmdJbkZpbGVOYW1lc1wiOiB0cnVlLFxuICAgIFwicmVzb2x2ZUpzb25Nb2R1bGVcIjogdHJ1ZSxcbiAgICBcImlzb2xhdGVkTW9kdWxlc1wiOiB0cnVlLFxuICAgIFwiZGVjbGFyYXRpb25cIjogdHJ1ZSxcbiAgICBcIm91dERpclwiOiBcImRpc3RcIixcbiAgICBcInJvb3REaXJcIjogXCJzcmNcIixcbiAgICBcIm5vRW1pdFwiOiB0cnVlXG4gIH0sXG4gIFwiaW5jbHVkZVwiOiBbXCJzcmMvKiovKi50c1wiXSxcbiAgXCJleGNsdWRlXCI6IFtcIm5vZGVfbW9kdWxlc1wiLCBcImRpc3RcIl1cbn1cbiJ9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiZGJUNE95NDBabHpiWW1nRGw3WUJpcmlZWmhINFFncFAiLCJuYW1lIjoid3JpdGUiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3ZpdGVzdC5jb25maWcudHMiLCJjb250ZW50IjoiaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSBcInZpdGVzdC9jb25maWdcIjtcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgdGVzdDoge1xuICAgIGdsb2JhbHM6IHRydWUsXG4gICAgZW52aXJvbm1lbnQ6IFwibm9kZVwiLFxuICAgIGluY2x1ZGU6IFtcInNyYy90ZXN0LyoqLyoudGVzdC50c1wiXSxcbiAgfSxcbn0pO1xuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoxMjMsIm91dHB1dCI6MTcyOSwiY2FjaGVSZWFkIjo0MzAzNiwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjQ0ODg4LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5MzgyOTY1NTgsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC1Ib2twakxOY0lQbjBJRkRiTHBoSElheFRETmRWVzlBeSJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJiY2M4NjVmYSIsInBhcmVudElkIjoiZDBmMDc5MDAiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjUyOjEzLjM1NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IjJiVGp5aG5NQ1kzZXlHVTc4eGRFN0w4VnRFVG85ckJaIiwidG9vbE5hbWUiOiJ3cml0ZSIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSB3cm90ZSA1ODYgYnl0ZXMgdG8gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvcGFja2FnZS5qc29uIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4MzMzMzU0fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMmM2YmFmYzgiLCJwYXJlbnRJZCI6ImJjYzg2NWZhIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MjoxMy4zNTRaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiIwdGlUT0I0ZTVVVWtkU1hPZ2dDaXk3dGRUNTdIbzZVVyIsInRvb2xOYW1lIjoid3JpdGUiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgd3JvdGUgNDUyIGJ5dGVzIHRvIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3RzY29uZmlnLmpzb24ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzgzMzMzNTR9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI0NzlhOGUwZiIsInBhcmVudElkIjoiMmM2YmFmYzgiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjUyOjEzLjM1NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImRiVDRPeTQwWmx6YlltZ0RsN1lCaXJpWVpoSDRRZ3BQIiwidG9vbE5hbWUiOiJ3cml0ZSIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSB3cm90ZSAxODAgYnl0ZXMgdG8gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvdml0ZXN0LmNvbmZpZy50cyJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODMzMzM1NH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImFjNDllOWFmIiwicGFyZW50SWQiOiI0NzlhOGUwZiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTM6MDcuNjM0WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IGxldCBtZSB3cml0ZSB0aGUgY29yZSBzdGF0ZSBtYWNoaW5lIG1vZHVsZSwgd2hpY2ggaXMgdGhlIGhlYXJ0IG9mIHRoZSBleHRlbnNpb24uIFRoaXMgd2lsbCBiZSB1bml0LXRlc3RhYmxlIHdpdGggdml0ZXN0LlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IGxldCBtZSB3cml0ZSB0aGUgY29yZSBzdGF0ZSBtYWNoaW5lIG1vZHVsZSAodGhlIHBhcnQgdGhhdCdzIHRlc3RhYmxlIHdpdGggdml0ZXN0KTpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IndvZ2c5cndkaGdJVTJCRDRhNlBrM3RZRUNSRHFpdkIwIiwibmFtZSI6IndyaXRlIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHMiLCJjb250ZW50IjoiLyoqXG4gKiBUREQgQ3ljbGUgU3RhdGUgTWFjaGluZVxuICpcbiAqIEVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgY3ljbGU6XG4gKiAgIFJFRCAgICDihpIgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzc1xuICogICBHUkVFTiAg4oaSIFRlc3RzIHBhc3MsIHJlYWR5IGZvciByZWZhY3RvcmluZ1xuICogICBSRUZBQ1RPUiDihpIgRGV2ZWxvcGVyIGNob29zZXMgd2hhdCB0byByZWZhY3RvclxuICogICBBZnRlciByZWZhY3RvcjogYmFjayB0byBSRUQgZm9yIG5leHQgdGVzdCAob3IgR1JFRU4gaWYgbm8gbmV3IHRlc3QpXG4gKi9cblxuLy8g4pSA4pSAIFBoYXNlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgdHlwZSBQaGFzZSA9IFwiUkVEXCIgfCBcIkdSRUVOXCIgfCBcIlJFRkFDVE9SXCI7XG5cbmV4cG9ydCBjb25zdCBQSEFTRVM6IFBoYXNlW10gPSBbXCJSRURcIiwgXCJHUkVFTlwiLCBcIlJFRkFDVE9SXCJdO1xuXG4vLyDilIDilIAgUmVmYWN0b3IgRm9jdXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCB0eXBlIFJlZmFjdG9yRm9jdXMgPSBcInRlc3RzXCIgfCBcImltcGxlbWVudGF0aW9uXCIgfCBcIm5leHQtdGVzdFwiIHwgXCJjdXN0b21cIjtcblxuZXhwb3J0IGNvbnN0IFJFRkFDVE9SX0ZPQ0k6IFJlZmFjdG9yRm9jdXNbXSA9IFtcbiAgXCJ0ZXN0c1wiLFxuICBcImltcGxlbWVudGF0aW9uXCIsXG4gIFwibmV4dC10ZXN0XCIsXG4gIFwiY3VzdG9tXCIsXG5dO1xuXG4vLyDilIDilIAgRGVjaXNpb24gUmVzdWx0IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgaW50ZXJmYWNlIFJlZmFjdG9yRGVjaXNpb24ge1xuICBmb2N1czogUmVmYWN0b3JGb2N1cztcbiAgY3VzdG9tSW5zdHJ1Y3Rpb24/OiBzdHJpbmc7XG59XG5cbi8vIOKUgOKUgCBDeWNsZSBTdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGludGVyZmFjZSBDeWNsZVN0YXRlIHtcbiAgLyoqIEN1cnJlbnQgcGhhc2UgKi9cbiAgcGhhc2U6IFBoYXNlO1xuICAvKiogVGVzdCBkZXNjcmlwdGlvbiAod2hhdCB3ZSdyZSB0cnlpbmcgdG8gbWFrZSBwYXNzKSAqL1xuICB0ZXN0RGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIC8qKiBXaGV0aGVyIHRlc3RzIGhhdmUgYmVlbiBydW4gaW4gdGhlIGN1cnJlbnQgY3ljbGUgKi9cbiAgdGVzdHNSYW46IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIHRlc3RzIHBhc3NlZCBpbiB0aGUgY3VycmVudCBjeWNsZSAqL1xuICB0ZXN0c1Bhc3NlZDogYm9vbGVhbjtcbiAgLyoqIE51bWJlciBvZiB0ZXN0cyB3cml0dGVuIHNvIGZhciBpbiB0aGlzIHNlc3Npb24gKi9cbiAgdGVzdHNXcml0dGVuOiBudW1iZXI7XG4gIC8qKiBMYXN0IHJlZmFjdG9yaW5nIGRlY2lzaW9uIChpZiBhbnkpICovXG4gIGxhc3REZWNpc2lvbj86IFJlZmFjdG9yRGVjaXNpb247XG4gIC8qKiBDdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb24gZnJvbSBkZXZlbG9wZXIgKi9cbiAgY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUluaXRpYWxTdGF0ZSgpOiBDeWNsZVN0YXRlIHtcbiAgcmV0dXJuIHtcbiAgICBwaGFzZTogXCJSRURcIixcbiAgICB0ZXN0c1JhbjogZmFsc2UsXG4gICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICAgIHRlc3RzV3JpdHRlbjogMCxcbiAgfTtcbn1cblxuLy8g4pSA4pSAIFRyYW5zaXRpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zaXRpb25SZXN1bHQge1xuICAvKiogTmV3IHN0YXRlICovXG4gIHN0YXRlOiBDeWNsZVN0YXRlO1xuICAvKiogTWVzc2FnZSB0byBzaG93IHRvIHRoZSBMTE0gKG9wdGlvbmFsKSAqL1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICAvKiogV2hldGhlciB0aGUgdHJhbnNpdGlvbiB3YXMgdmFsaWQgKi9cbiAgdmFsaWQ6IGJvb2xlYW47XG4gIC8qKiBFcnJvciBtZXNzYWdlIGlmIHRyYW5zaXRpb24gd2FzIGludmFsaWQgKi9cbiAgZXJyb3I/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVHJhbnNpdGlvbiBmcm9tIFJFRCB0byBHUkVFTi5cbiAqIFZhbGlkIG9ubHkgd2hlbiB0ZXN0cyBoYXZlIGJlZW4gcnVuIGFuZCBwYXNzZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWRUb0dyZWVuKHN0YXRlOiBDeWNsZVN0YXRlKTogVHJhbnNpdGlvblJlc3VsdCB7XG4gIGlmICghc3RhdGUudGVzdHNSYW4pIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdGUsXG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICBlcnJvcjogXCJDYW5ub3QgdHJhbnNpdGlvbiB0byBHUkVFTjogdGVzdHMgaGF2ZSBub3QgYmVlbiBydW4geWV0LiBSdW4gdGVzdHMgZmlyc3QuXCIsXG4gICAgfTtcbiAgfVxuICBpZiAoIXN0YXRlLnRlc3RzUGFzc2VkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXRlLFxuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6IFwiQ2Fubm90IHRyYW5zaXRpb24gdG8gR1JFRU46IHRlc3RzIGRpZCBub3QgcGFzcy4gU3RheSBpbiBSRUQgYW5kIG1ha2UgdGVzdHMgcGFzcy5cIixcbiAgICB9O1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RhdGU6IHsgLi4uc3RhdGUsIHBoYXNlOiBcIkdSRUVOXCIsIHRlc3RzUmFuOiBmYWxzZSwgdGVzdHNQYXNzZWQ6IGZhbHNlIH0sXG4gICAgbWVzc2FnZTpcbiAgICAgIFwi4pyFIFRlc3RzIHBhc3MhIFBoYXNlIGNoYW5nZWQ6IEdSRUVOIOKGkiBSRUZBQ1RPUi4gXCIgK1xuICAgICAgXCJZb3Ugc2hvdWxkIG5vdyByZWZhY3Rvci4gQ2FsbCBnby10by1yZWZhY3RvciB3aGVuIHJlYWR5LlwiLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIFRyYW5zaXRpb24gZnJvbSBHUkVFTiB0byBSRUZBQ1RPUi5cbiAqIEFsd2F5cyB2YWxpZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyZWVuVG9SZWZhY3RvcihzdGF0ZTogQ3ljbGVTdGF0ZSk6IFRyYW5zaXRpb25SZXN1bHQge1xuICByZXR1cm4ge1xuICAgIHN0YXRlOiB7IC4uLnN0YXRlLCBwaGFzZTogXCJSRUZBQ1RPUlwiIH0sXG4gICAgbWVzc2FnZTpcbiAgICAgIFwi8J+UhCBQaGFzZSBjaGFuZ2VkOiBHUkVFTiDihpIgUkVGQUNUT1IuIFwiICtcbiAgICAgIFwiRGV2ZWxvcGVyIHdpbGwgbm93IGRlY2lkZSB3aGF0IHRvIHJlZmFjdG9yLlwiLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIEFwcGx5IGEgcmVmYWN0b3JpbmcgZGVjaXNpb24gYW5kIHRyYW5zaXRpb24gYmFjayB0byBSRUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVJlZmFjdG9yRGVjaXNpb24oXG4gIHN0YXRlOiBDeWNsZVN0YXRlLFxuICBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbixcbik6IFRyYW5zaXRpb25SZXN1bHQge1xuICBjb25zdCBuZXdTdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBwaGFzZTogXCJSRURcIixcbiAgICBsYXN0RGVjaXNpb246IGRlY2lzaW9uLFxuICAgIGN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb246XG4gICAgICBkZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIiA/IGRlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9uIDogdW5kZWZpbmVkLFxuICAgIHRlc3RzUmFuOiBmYWxzZSxcbiAgICB0ZXN0c1Bhc3NlZDogZmFsc2UsXG4gIH07XG5cbiAgLy8gSWYgZGV2ZWxvcGVyIGNob3NlIFwibmV4dC10ZXN0XCIsIGluY3JlbWVudCB0ZXN0IGNvdW50XG4gIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJuZXh0LXRlc3RcIikge1xuICAgIG5ld1N0YXRlLnRlc3RzV3JpdHRlbiA9IChzdGF0ZS50ZXN0c1dyaXR0ZW4gPz8gMCkgKyAxO1xuICB9XG5cbiAgbGV0IG1lc3NhZ2UgPSBg8J+UgCBSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICBtZXNzYWdlICs9IGAgQ3VzdG9tIGluc3RydWN0aW9uOiBcIiR7ZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb259XCJgO1xuICB9XG4gIG1lc3NhZ2UgKz0gXCIgUGhhc2UgY2hhbmdlZDogUkVGQUNUT1Ig4oaSIFJFRC5cIjtcblxuICByZXR1cm4ge1xuICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICBtZXNzYWdlLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIFJlY29yZCB0aGF0IHRlc3RzIGhhdmUgYmVlbiBydW4gYW5kIHRoZWlyIHJlc3VsdC5cbiAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBnby10by1ncmVlbiB0b29sIGFmdGVyIHRlc3QgZXhlY3V0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkVGVzdFJlc3VsdChcbiAgc3RhdGU6IEN5Y2xlU3RhdGUsXG4gIHBhc3NlZDogYm9vbGVhbixcbik6IFRyYW5zaXRpb25SZXN1bHQge1xuICBpZiAoc3RhdGUucGhhc2UgIT09IFwiUkVEXCIgJiYgc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0ZSxcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiBgQ2Fubm90IHJlY29yZCB0ZXN0IHJlc3VsdHMgaW4gcGhhc2UgJHtzdGF0ZS5waGFzZX0uIE11c3QgYmUgaW4gUkVEIG9yIEdSRUVOLmAsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IG5ld1N0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgIHRlc3RzUGFzc2VkOiBwYXNzZWQsXG4gIH07XG5cbiAgaWYgKHBhc3NlZCAmJiBzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuICAgIC8vIFRlc3RzIHBhc3NlZCB3aGlsZSBpbiBSRUQg4oaSIGF1dG8tdHJhbnNpdGlvbiB0byBHUkVFTlxuICAgIHJldHVybiByZWRUb0dyZWVuKG5ld1N0YXRlKTtcbiAgfVxuXG4gIGlmICghcGFzc2VkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIFwi4p2MIFRlc3RzIGZhaWxlZC4gU3RheSBpbiBSRUQuIEZpeCB0aGUgaW1wbGVtZW50YXRpb24gdG8gbWFrZSB0ZXN0cyBwYXNzLlwiLFxuICAgICAgdmFsaWQ6IHRydWUsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFRlc3RzIHBhc3NlZCB3aGlsZSBhbHJlYWR5IGluIEdSRUVOIOKGkiBzdGF5IGluIEdSRUVOXG4gIHJldHVybiB7XG4gICAgc3RhdGU6IG5ld1N0YXRlLFxuICAgIG1lc3NhZ2U6IFwi4pyFIFRlc3RzIHN0aWxsIHBhc3MuIFN0YXkgaW4gR1JFRU4uXCIsXG4gICAgdmFsaWQ6IHRydWUsXG4gIH07XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSB0cmFuc2l0aW9uIGlzIHZhbGlkIGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5UcmFuc2l0aW9uKFxuICBzdGF0ZTogQ3ljbGVTdGF0ZSxcbiAgdGFyZ2V0UGhhc2U6IFBoYXNlLFxuKTogeyB2YWxpZDogYm9vbGVhbjsgcmVhc29uOiBzdHJpbmcgfSB7XG4gIGlmIChzdGF0ZS5waGFzZSA9PT0gdGFyZ2V0UGhhc2UpIHtcbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgcmVhc29uOiBgQWxyZWFkeSBpbiAke3RhcmdldFBoYXNlfWAgfTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogc3RhdGUudGVzdHNSYW4gJiYgc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgICAgIHJlYXNvbjogc3RhdGUudGVzdHNSYW4gJiYgc3RhdGUudGVzdHNQYXNzZWRcbiAgICAgICAgICA/IFwiVGVzdHMgcGFzc2VkLCBjYW4gZ28gdG8gR1JFRU5cIlxuICAgICAgICAgIDogXCJNdXN0IHJ1biBwYXNzaW5nIHRlc3RzIGZpcnN0XCIsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiUkVGQUNUT1JcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICByZWFzb246XG4gICAgICAgICAgXCJDYW5ub3QgZ28gZGlyZWN0bHkgZnJvbSBSRUQgdG8gUkVGQUNUT1IuIE11c3QgZ28gdGhyb3VnaCBHUkVFTiBmaXJzdC5cIixcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0YXRlLnBoYXNlID09PSBcIkdSRUVOXCIpIHtcbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgcmVhc29uOlxuICAgICAgICAgIFwiQ2Fubm90IGdvIGZyb20gR1JFRU4gYmFjayB0byBSRUQuIENvbXBsZXRlIHJlZmFjdG9yaW5nIGZpcnN0LlwiLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHRhcmdldFBoYXNlID09PSBcIlJFRkFDVE9SXCIpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlLCByZWFzb246IFwiQ2FuIGdvIHRvIFJFRkFDVE9SIGZyb20gR1JFRU5cIiB9O1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRUZBQ1RPUlwiKSB7XG4gICAgaWYgKHRhcmdldFBoYXNlID09PSBcIlJFRFwiKSB7XG4gICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgcmVhc29uOiBcIkNhbiBnbyB0byBSRUQgYWZ0ZXIgcmVmYWN0b3JpbmcgZGVjaXNpb25cIiB9O1xuICAgIH1cbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICByZWFzb246XG4gICAgICAgICAgXCJDYW5ub3QgZ28gZnJvbSBSRUZBQ1RPUiB0byBHUkVFTi4gTXVzdCBnbyB0byBSRUQgZmlyc3QgKHdyaXRlIG5leHQgdGVzdCkuXCIsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgcmVhc29uOiBgSW52YWxpZCB0cmFuc2l0aW9uIGZyb20gJHtzdGF0ZS5waGFzZX0gdG8gJHt0YXJnZXRQaGFzZX1gIH07XG59XG5cbi8vIOKUgOKUgCBGb3JtYXR0aW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgZnVuY3Rpb24gcGhhc2VFbW9qaShwaGFzZTogUGhhc2UpOiBzdHJpbmcge1xuICBzd2l0Y2ggKHBoYXNlKSB7XG4gICAgY2FzZSBcIlJFRFwiOlxuICAgICAgcmV0dXJuIFwi8J+UtFwiO1xuICAgIGNhc2UgXCJHUkVFTlwiOlxuICAgICAgcmV0dXJuIFwi8J+folwiO1xuICAgIGNhc2UgXCJSRUZBQ1RPUlwiOlxuICAgICAgcmV0dXJuIFwi8J+UgFwiO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwaGFzZURlc2NyaXB0aW9uKHN0YXRlOiBDeWNsZVN0YXRlKTogc3RyaW5nIHtcbiAgY29uc3QgZW1vamkgPSBwaGFzZUVtb2ppKHN0YXRlLnBoYXNlKTtcbiAgY29uc3QgcGhhc2UgPSBzdGF0ZS5waGFzZTtcblxuICBzd2l0Y2ggKHBoYXNlKSB7XG4gICAgY2FzZSBcIlJFRFwiOlxuICAgICAgaWYgKCFzdGF0ZS50ZXN0c1Jhbikge1xuICAgICAgICByZXR1cm4gYCR7ZW1vaml9IFJFRCDigJQgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzcy5gO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXRlLnRlc3RzUGFzc2VkKSB7XG4gICAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKGkiBHUkVFTiDigJQgVGVzdHMgcGFzc2VkISBSZWFkeSBmb3IgcmVmYWN0b3JpbmcuYDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKAlCBUZXN0cyBmYWlsZWQuIEZpeCBpbXBsZW1lbnRhdGlvbi5gO1xuICAgIGNhc2UgXCJHUkVFTlwiOlxuICAgICAgcmV0dXJuIGAke2Vtb2ppfSBHUkVFTiDigJQgVGVzdHMgcGFzcy4gUmVhZHkgZm9yIHJlZmFjdG9yaW5nLmA7XG4gICAgY2FzZSBcIlJFRkFDVE9SXCI6XG4gICAgICByZXR1cm4gYCR7ZW1vaml9IFJFRkFDVE9SIOKAlCBEZXZlbG9wZXIgZGVjaWRlcyB3aGF0IHRvIHJlZmFjdG9yLmA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBoYXNlR3VpZGVsaW5lcyhzdGF0ZTogQ3ljbGVTdGF0ZSk6IHN0cmluZyB7XG4gIHN3aXRjaCAoc3RhdGUucGhhc2UpIHtcbiAgICBjYXNlIFwiUkVEXCI6XG4gICAgICBpZiAoIXN0YXRlLnRlc3RzUmFuKSB7XG4gICAgICAgIHJldHVybiBgWW91IGFyZSBpbiBSRUQgcGhhc2UuXG4tIFdyaXRlIGEgZmFpbGluZyB0ZXN0IGZpcnN0ICh0aGUgdGVzdCBzaG91bGQgZmFpbCBiZWZvcmUgeW91ciBpbXBsZW1lbnRhdGlvbilcbi0gVGhlbiB3cml0ZSBtaW5pbWFsIGltcGxlbWVudGF0aW9uIHRvIG1ha2UgdGhlIHRlc3QgcGFzc1xuLSBSdW4gdGVzdHMgd2l0aCBiYXNoIHRvIHZlcmlmeVxuLSBXaGVuIHRlc3RzIHBhc3MsIHRoZSBzeXN0ZW0gd2lsbCBtb3ZlIHlvdSB0byBHUkVFTmA7XG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUudGVzdHNQYXNzZWQpIHtcbiAgICAgICAgcmV0dXJuIGBZb3UgYXJlIGluIFJFROKGkkdSRUVOIHRyYW5zaXRpb24uIFRlc3RzIHBhc3NlZCFcbi0gWW91IHNob3VsZCBub3cgY2FsbCBnby10by1yZWZhY3RvciB0byBlbnRlciB0aGUgUkVGQUNUT1IgcGhhc2Vcbi0gRG8gTk9UIHdyaXRlIGEgbmV3IHRlc3QgeWV0IOKAlCByZWZhY3RvciBmaXJzdGA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYFlvdSBhcmUgaW4gUkVEIHBoYXNlLiBUZXN0cyBmYWlsZWQuXG4tIEltcHJvdmUgeW91ciBpbXBsZW1lbnRhdGlvbiB0byBtYWtlIHRlc3RzIHBhc3Ncbi0gRG8gTk9UIGNoYW5nZSB0aGUgdGVzdCDigJQgdGhlIHRlc3QgZGVmaW5lcyB0aGUgcmVxdWlyZW1lbnRcbi0gUnVuIHRlc3RzIHdpdGggYmFzaCB0byB2ZXJpZnlgO1xuICAgIGNhc2UgXCJHUkVFTlwiOlxuICAgICAgcmV0dXJuIGBZb3UgYXJlIGluIEdSRUVOIHBoYXNlLiBUZXN0cyBwYXNzLlxuLSBDYWxsIGdvLXRvLXJlZmFjdG9yIHRvIGVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZVxuLSBUaGUgZGV2ZWxvcGVyIHdpbGwgdGhlbiBkZWNpZGUgd2hhdCB0byByZWZhY3RvcmA7XG4gICAgY2FzZSBcIlJFRkFDVE9SXCI6XG4gICAgICByZXR1cm4gYFlvdSBhcmUgaW4gUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgaXMgZGVjaWRpbmcgd2hhdCB0byByZWZhY3Rvci5cbi0gV2FpdCBmb3IgdGhlIGRldmVsb3BlcidzIGRlY2lzaW9uXG4tIEFmdGVyIHJlZmFjdG9yaW5nLCBydW4gdGVzdHMgdG8gdmVyaWZ5IHRoZXkgc3RpbGwgcGFzc1xuLSBUaGVuIHByb2NlZWQgdG8gdGhlIG5leHQgdGVzdCAoUkVEIHBoYXNlKWA7XG4gIH1cbn1cbiJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MTA0LCJvdXRwdXQiOjI1MjgsImNhY2hlUmVhZCI6NDQ4ODcsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo0NzUxOSwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4MzMzMzU0LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtUFBPR0hXRTAybkJIajQxcGppTEJHRVNQUnpVeXpZZFEifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZjhiZGRjMGEiLCJwYXJlbnRJZCI6ImFjNDllOWFmIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1MzowNy42NDVaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJ3b2dnOXJ3ZGhnSVUyQkQ0YTZQazN0WUVDUkRxaXZCMCIsInRvb2xOYW1lIjoid3JpdGUiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgd3JvdGUgODg2MiBieXRlcyB0byAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHMifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzgzODc2NDV9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJhYmJmZDZlZiIsInBhcmVudElkIjoiZjhiZGRjMGEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjU0OjA4Ljk5MloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBsZXQgbWUgd3JpdGUgdGhlIHRlc3RzIGZvciB0aGUgc3RhdGUgbWFjaGluZTpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vdyBsZXQgbWUgd3JpdGUgdGhlIHRlc3RzOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoidGpDM1NGSUZkUFVpMmw1NFVkZXZtSEJ6OWFCRUlWMjciLCJuYW1lIjoid3JpdGUiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy90ZXN0L3N0YXRlLnRlc3QudHMiLCJjb250ZW50IjoiaW1wb3J0IHsgZGVzY3JpYmUsIGl0LCBleHBlY3QgfSBmcm9tIFwidml0ZXN0XCI7XG5pbXBvcnQge1xuICBjcmVhdGVJbml0aWFsU3RhdGUsXG4gIHJlZFRvR3JlZW4sXG4gIGdyZWVuVG9SZWZhY3RvcixcbiAgYXBwbHlSZWZhY3RvckRlY2lzaW9uLFxuICByZWNvcmRUZXN0UmVzdWx0LFxuICBjYW5UcmFuc2l0aW9uLFxuICBwaGFzZUVtb2ppLFxuICBwaGFzZURlc2NyaXB0aW9uLFxuICBwaGFzZUd1aWRlbGluZXMsXG4gIHR5cGUgQ3ljbGVTdGF0ZSxcbiAgdHlwZSBSZWZhY3RvckRlY2lzaW9uLFxufSBmcm9tIFwiLi4vc3RhdGUuanNcIjtcblxuZGVzY3JpYmUoXCJjcmVhdGVJbml0aWFsU3RhdGVcIiwgKCkgPT4ge1xuICBpdChcInJldHVybnMgUkVEIHBoYXNlIHdpdGggZGVmYXVsdHNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7XG4gICAgZXhwZWN0KHN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICAgIGV4cGVjdChzdGF0ZS50ZXN0c1JhbikudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHN0YXRlLnRlc3RzUGFzc2VkKS50b0JlKGZhbHNlKTtcbiAgICBleHBlY3Qoc3RhdGUudGVzdHNXcml0dGVuKS50b0JlKDApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInJlZFRvR3JlZW5cIiwgKCkgPT4ge1xuICBpdChcInRyYW5zaXRpb25zIHdoZW4gdGVzdHMgcmFuIGFuZCBwYXNzZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICB0ZXN0c1JhbjogdHJ1ZSxcbiAgICAgIHRlc3RzUGFzc2VkOiB0cnVlLFxuICAgICAgdGVzdHNXcml0dGVuOiAxLFxuICAgIH07XG4gICAgY29uc3QgcmVzdWx0ID0gcmVkVG9HcmVlbihzdGF0ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiR1JFRU5cIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1JhbikudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1Bhc3NlZCkudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5tZXNzYWdlKS50b0NvbnRhaW4oXCJHUkVFTlwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZWplY3RzIHdoZW4gdGVzdHMgaGF2ZSBub3QgYmVlbiBydW5cIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICB0ZXN0c1JhbjogZmFsc2UsXG4gICAgICB0ZXN0c1Bhc3NlZDogZmFsc2UsXG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSByZWRUb0dyZWVuKHN0YXRlKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKTtcbiAgICBleHBlY3QocmVzdWx0LmVycm9yKS50b0NvbnRhaW4oXCJoYXZlIG5vdCBiZWVuIHJ1blwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZWplY3RzIHdoZW4gdGVzdHMgZmFpbGVkXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogZmFsc2UsXG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSByZWRUb0dyZWVuKHN0YXRlKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKTtcbiAgICBleHBlY3QocmVzdWx0LmVycm9yKS50b0NvbnRhaW4oXCJkaWQgbm90IHBhc3NcIik7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiZ3JlZW5Ub1JlZmFjdG9yXCIsICgpID0+IHtcbiAgaXQoXCJhbHdheXMgdHJhbnNpdGlvbnMgZnJvbSBHUkVFTiB0byBSRUZBQ1RPUlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIkdSRUVOXCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChyZXN1bHQubWVzc2FnZSkudG9Db250YWluKFwiUkVGQUNUT1JcIik7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiYXBwbHlSZWZhY3RvckRlY2lzaW9uXCIsICgpID0+IHtcbiAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgd2l0aCB0ZXN0cyBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMSB9O1xuICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJ0ZXN0c1wiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUubGFzdERlY2lzaW9uKS50b0VxdWFsKGRlY2lzaW9uKTtcbiAgfSk7XG5cbiAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgd2l0aCBpbXBsZW1lbnRhdGlvbiBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwiaW1wbGVtZW50YXRpb25cIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICB9KTtcblxuICBpdChcImluY3JlbWVudHMgdGVzdHNXcml0dGVuIGZvciBuZXh0LXRlc3QgZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiLCB0ZXN0c1dyaXR0ZW46IDMgfTtcbiAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwibmV4dC10ZXN0XCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzV3JpdHRlbikudG9CZSg0KTtcbiAgfSk7XG5cbiAgaXQoXCJzdG9yZXMgY3VzdG9tIGluc3RydWN0aW9uIGZvciBjdXN0b20gZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7XG4gICAgICBmb2N1czogXCJjdXN0b21cIixcbiAgICAgIGN1c3RvbUluc3RydWN0aW9uOiBcIkV4dHJhY3QgdGhlIHNlcnZpY2UgY2xhc3NcIixcbiAgICB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbikudG9CZShcbiAgICAgIFwiRXh0cmFjdCB0aGUgc2VydmljZSBjbGFzc1wiLFxuICAgICk7XG4gIH0pO1xuXG4gIGl0KFwicmVzZXRzIHRlc3RzUmFuIGFuZCB0ZXN0c1Bhc3NlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRUZBQ1RPUlwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICB9O1xuICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJpbXBsZW1lbnRhdGlvblwiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1JhbikudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1Bhc3NlZCkudG9CZShmYWxzZSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwicmVjb3JkVGVzdFJlc3VsdFwiLCAoKSA9PiB7XG4gIGl0KFwicmVjb3JkcyBwYXNzaW5nIHRlc3RzIGluIFJFRCDihpIgYXV0by10cmFuc2l0aW9ucyB0byBHUkVFTlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRFwiLCB0ZXN0c1JhbjogZmFsc2UsIHRlc3RzUGFzc2VkOiBmYWxzZSB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1JhbikudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzUGFzc2VkKS50b0JlKHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJHUkVFTlwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZWNvcmRzIGZhaWxpbmcgdGVzdHMgaW4gUkVEIOKGkiBzdGF5cyBpbiBSRURcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRURcIiwgdGVzdHNSYW46IGZhbHNlLCB0ZXN0c1Bhc3NlZDogZmFsc2UgfTtcbiAgICBjb25zdCByZXN1bHQgPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzUmFuKS50b0JlKHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUudGVzdHNQYXNzZWQpLnRvQmUoZmFsc2UpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5tZXNzYWdlKS50b0NvbnRhaW4oXCJmYWlsZWRcIik7XG4gIH0pO1xuXG4gIGl0KFwicmVjb3JkcyBwYXNzaW5nIHRlc3RzIGluIEdSRUVOIOKGkiBzdGF5cyBpbiBHUkVFTlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIkdSRUVOXCIsIHRlc3RzUmFuOiB0cnVlLCB0ZXN0c1Bhc3NlZDogdHJ1ZSB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIkdSRUVOXCIpO1xuICB9KTtcblxuICBpdChcInJlamVjdHMgcmVjb3JkaW5nIGluIFJFRkFDVE9SIHBoYXNlXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICAgIGV4cGVjdChyZXN1bHQuZXJyb3IpLnRvQ29udGFpbihcIlJFRkFDVE9SXCIpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcImNhblRyYW5zaXRpb25cIiwgKCkgPT4ge1xuICBpdChcImFsbG93cyBSRUQg4oaSIEdSRUVOIHdoZW4gdGVzdHMgcGFzc2VkXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhblRyYW5zaXRpb24oc3RhdGUsIFwiR1JFRU5cIik7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoXCJibG9ja3MgUkVEIOKGkiBHUkVFTiB3aGVuIHRlc3RzIGZhaWxlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICAgIH07XG4gICAgY29uc3QgcmVzdWx0ID0gY2FuVHJhbnNpdGlvbihzdGF0ZSwgXCJHUkVFTlwiKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoXCJibG9ja3MgUkVEIOKGkiBSRUZBQ1RPUiAobXVzdCBnbyB0aHJvdWdoIEdSRUVOKVwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgICAgdGVzdHNQYXNzZWQ6IHRydWUsXG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSBjYW5UcmFuc2l0aW9uKHN0YXRlLCBcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdChcImFsbG93cyBHUkVFTiDihpIgUkVGQUNUT1JcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJHUkVFTlwiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gY2FuVHJhbnNpdGlvbihzdGF0ZSwgXCJSRUZBQ1RPUlwiKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKHRydWUpO1xuICB9KTtcblxuICBpdChcImJsb2NrcyBHUkVFTiDihpIgUkVEXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiR1JFRU5cIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhblRyYW5zaXRpb24oc3RhdGUsIFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdChcImFsbG93cyBSRUZBQ1RPUiDihpIgUkVEXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhblRyYW5zaXRpb24oc3RhdGUsIFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KFwiYmxvY2tzIFJFRkFDVE9SIOKGkiBHUkVFTlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBjYW5UcmFuc2l0aW9uKHN0YXRlLCBcIkdSRUVOXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInBoYXNlRW1vamlcIiwgKCkgPT4ge1xuICBpdChcInJldHVybnMgY29ycmVjdCBlbW9qaSBmb3IgZWFjaCBwaGFzZVwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHBoYXNlRW1vamkoXCJSRURcIikpLnRvQmUoXCLwn5S0XCIpO1xuICAgIGV4cGVjdChwaGFzZUVtb2ppKFwiR1JFRU5cIikpLnRvQmUoXCLwn5+iXCIpO1xuICAgIGV4cGVjdChwaGFzZUVtb2ppKFwiUkVGQUNUT1JcIikpLnRvQmUoXCLwn5SAXCIpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInBoYXNlRGVzY3JpcHRpb25cIiwgKCkgPT4ge1xuICBpdChcImRlc2NyaWJlcyBSRUQgd2hlbiBubyB0ZXN0cyByYW5cIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7XG4gICAgZXhwZWN0KHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpKS50b0NvbnRhaW4oXCJSRURcIik7XG4gICAgZXhwZWN0KHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpKS50b0NvbnRhaW4oXCJXcml0ZSBhIGZhaWxpbmcgdGVzdFwiKTtcbiAgfSk7XG5cbiAgaXQoXCJkZXNjcmliZXMgUkVE4oaSR1JFRU4gd2hlbiB0ZXN0cyBwYXNzZWQgaW4gUkVEXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICB9O1xuICAgIGV4cGVjdChwaGFzZURlc2NyaXB0aW9uKHN0YXRlKSkudG9Db250YWluKFwiUkVE4oaSR1JFRU5cIik7XG4gIH0pO1xuXG4gIGl0KFwiZGVzY3JpYmVzIFJFRCB3aGVuIHRlc3RzIGZhaWxlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICAgIH07XG4gICAgZXhwZWN0KHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpKS50b0NvbnRhaW4oXCJUZXN0cyBmYWlsZWRcIik7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwicGhhc2VHdWlkZWxpbmVzXCIsICgpID0+IHtcbiAgaXQoXCJnaXZlcyBSRUQgZ3VpZGVsaW5lcyB3aGVuIG5vIHRlc3RzIHJhblwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVJbml0aWFsU3RhdGUoKTtcbiAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiV3JpdGUgYSBmYWlsaW5nIHRlc3RcIik7XG4gIH0pO1xuXG4gIGl0KFwiZ2l2ZXMgUkVEIGd1aWRlbGluZXMgd2hlbiB0ZXN0cyBmYWlsZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICB0ZXN0c1JhbjogdHJ1ZSxcbiAgICAgIHRlc3RzUGFzc2VkOiBmYWxzZSxcbiAgICB9O1xuICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJUZXN0cyBmYWlsZWRcIik7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIkRvIE5PVCBjaGFuZ2UgdGhlIHRlc3RcIik7XG4gIH0pO1xuXG4gIGl0KFwiZ2l2ZXMgR1JFRU4gZ3VpZGVsaW5lc1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIkdSRUVOXCIgfTtcbiAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiR1JFRU5cIik7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcImdvLXRvLXJlZmFjdG9yXCIpO1xuICB9KTtcblxuICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZ3VpZGVsaW5lcyA9IHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJXYWl0IGZvciB0aGUgZGV2ZWxvcGVyXCIpO1xuICB9KTtcbn0pO1xuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0Ijo0Mywib3V0cHV0IjoyNDk0LCJjYWNoZVJlYWQiOjQ3NTE4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6NTAwNTUsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODM4NzY0NSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLXBHRFlvZDEzUGxTY3ZBZlBlcHR1a3hCN0FCM21sR1M1In19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjQ3NTkzZThmIiwicGFyZW50SWQiOiJhYmJmZDZlZiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTQ6MDkuMDA1WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoidGpDM1NGSUZkUFVpMmw1NFVkZXZtSEJ6OWFCRUlWMjciLCJ0b29sTmFtZSI6IndyaXRlIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHdyb3RlIDg4NDEgYnl0ZXMgdG8gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3Rlc3Qvc3RhdGUudGVzdC50cyJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODQ0OTAwNX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjIxZDk4MGE1IiwicGFyZW50SWQiOiI0NzU5M2U4ZiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTQ6NTMuMzk5WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IGxldCBtZSB3cml0ZSB0aGUgVUkgbW9kdWxlIGZvciB0aGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHByb21wdDpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vdyBsZXQgbWUgd3JpdGUgdGhlIFVJIG1vZHVsZSBmb3IgdGhlIGRldmVsb3BlciBkZWNpc2lvbiBwcm9tcHQ6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJpd1JwNm9Semo4dG1Ed2RpaVhra2syN1hlcDJ5QVA3diIsIm5hbWUiOiJ3cml0ZSIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3VpLnRzIiwiY29udGVudCI6Ii8qKlxuICogQ3VzdG9tIFVJIGZvciB0aGUgVEREIGN5Y2xlIGRldmVsb3BlciBkZWNpc2lvbiBwcm9tcHQuXG4gKlxuICogUmVuZGVycyBhbiBpbnRlcmFjdGl2ZSBtZW51IGR1cmluZyB0aGUgUkVGQUNUT1IgcGhhc2Ugd2hlcmUgdGhlIGRldmVsb3BlclxuICogY2FuIGNob29zZSB3aGF0IHRvIGRvIG5leHQuXG4gKi9cblxuaW1wb3J0IHtcbiAgQ29udGFpbmVyLFxuICBtYXRjaGVzS2V5LFxuICBLZXksXG4gIHR5cGUgVFVJLFxuICB0eXBlIFRoZW1lLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHR5cGUgeyBSZWZhY3RvckZvY3VzLCBSZWZhY3RvckRlY2lzaW9uIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcblxuY29uc3QgUkVGQUNUT1JfRk9DSTogUmVmYWN0b3JGb2N1c1tdID0gW1xuICBcInRlc3RzXCIsXG4gIFwiaW1wbGVtZW50YXRpb25cIixcbiAgXCJuZXh0LXRlc3RcIixcbiAgXCJjdXN0b21cIixcbl07XG5cbmNvbnN0IEZPQ1VTX0xBQkVMUzogUmVjb3JkPFJlZmFjdG9yRm9jdXMsIHN0cmluZz4gPSB7XG4gIHRlc3RzOiBcIlJlZmFjdG9yIHRoZSB0ZXN0c1wiLFxuICBpbXBsZW1lbnRhdGlvbjogXCJSZWZhY3RvciB0aGUgaW1wbGVtZW50YXRpb25cIixcbiAgXCJuZXh0LXRlc3RcIjogXCJDb250aW51ZSB0byBuZXh0IHRlc3RcIixcbiAgY3VzdG9tOiBcIlNvbWV0aGluZyBlbHNlIChjdXN0b20gaW5zdHJ1Y3Rpb24pXCIsXG59O1xuXG5jb25zdCBGT0NVU19ERVNDUklQVElPTlM6IFJlY29yZDxSZWZhY3RvckZvY3VzLCBzdHJpbmc+ID0ge1xuICB0ZXN0czogXCJDbGVhbiB1cCBhbmQgaW1wcm92ZSB0ZXN0IHN0cnVjdHVyZVwiLFxuICBpbXBsZW1lbnRhdGlvbjogXCJJbXByb3ZlIHByb2R1Y3Rpb24gY29kZSBzdHJ1Y3R1cmVcIixcbiAgXCJuZXh0LXRlc3RcIjogXCJXcml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3RcIixcbiAgY3VzdG9tOiBcIlByb3ZpZGUgYSBjdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb25cIixcbn07XG5cbi8qKlxuICogUmVuZGVycyB0aGUgcmVmYWN0b3JpbmcgZGVjaXNpb24gcHJvbXB0IGFzIGEgY3VzdG9tIFRVSSBjb21wb25lbnQuXG4gKiBSZXR1cm5zIHRoZSBkZXZlbG9wZXIncyBkZWNpc2lvbiwgb3IgbnVsbCBpZiBjYW5jZWxsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaG93UmVmYWN0b3JEZWNpc2lvbihcbiAgdHVpOiBUVUksXG4gIHRoZW1lOiBUaGVtZSxcbiAgX2tiOiB1bmtub3duLFxuICBkb25lOiAoZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gfCBudWxsKSA9PiB2b2lkLFxuICB0ZXN0RGVzY3JpcHRpb24/OiBzdHJpbmcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgbGV0IHNlbGVjdGVkSW5kZXggPSAwO1xuICBsZXQgY3VzdG9tTW9kZSA9IGZhbHNlO1xuICBsZXQgY3VzdG9tSW5wdXQgPSBcIlwiO1xuXG4gIGZ1bmN0aW9uIHJlbmRlcih3aWR0aDogbnVtYmVyKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHcgPSBNYXRoLm1heCgxLCB3aWR0aCAtIDIpO1xuXG4gICAgLy8gSGVhZGVyXG4gICAgbGluZXMucHVzaCh0aGVtZS5mZyhcImFjY2VudFwiLCBcIuKUgFwiLnJlcGVhdCh3KSkpO1xuICAgIGxpbmVzLnB1c2goXG4gICAgICB0aGVtZS5mZyhcbiAgICAgICAgXCJhY2NlbnRcIixcbiAgICAgICAgXCIgIPCflIAgUkVGQUNUT1IgUEhBU0Ug4oCUIFdoYXQgc2hvdWxkIHdlIHJlZmFjdG9yP1wiLFxuICAgICAgKSxcbiAgICApO1xuICAgIGlmICh0ZXN0RGVzY3JpcHRpb24pIHtcbiAgICAgIGxpbmVzLnB1c2godGhlbWUuZmcoXCJtdXRlZFwiLCBgICBDdXJyZW50IHRlc3Q6ICR7dGVzdERlc2NyaXB0aW9ufWApKTtcbiAgICB9XG4gICAgbGluZXMucHVzaChcIlwiKTtcblxuICAgIC8vIE9wdGlvbnNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IFJFRkFDVE9SX0ZPQ0kubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGZvY3VzID0gUkVGQUNUT1JfRk9DSVtpXTtcbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gaSA9PT0gc2VsZWN0ZWRJbmRleDtcbiAgICAgIGNvbnN0IHByZWZpeCA9IHNlbGVjdGVkXG4gICAgICAgID8gdGhlbWUuZmcoXCJhY2NlbnRcIiwgXCLilrggXCIpXG4gICAgICAgIDogXCIgIFwiO1xuICAgICAgY29uc3QgbGFiZWwgPSB0aGVtZS5mZyhzZWxlY3RlZCA/IFwiYWNjZW50XCIgOiBcInRleHRcIiwgRk9DVVNfTEFCRUxTW2ZvY3VzXSk7XG4gICAgICBsaW5lcy5wdXNoKGAke3ByZWZpeH0ke2xhYmVsfWApO1xuICAgICAgaWYgKHNlbGVjdGVkKSB7XG4gICAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgICAgYCAgICAke3RoZW1lLmZnKFwiZGltXCIsIEZPQ1VTX0RFU0NSSVBUSU9OU1tmb2N1c10pfWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGluZXMucHVzaChcIlwiKTtcblxuICAgIC8vIEN1c3RvbSBpbnB1dCBtb2RlXG4gICAgaWYgKGN1c3RvbU1vZGUpIHtcbiAgICAgIGxpbmVzLnB1c2godGhlbWUuZmcoXCJtdXRlZFwiLCBcIiAgQ3VzdG9tIGluc3RydWN0aW9uOlwiKSk7XG4gICAgICAvLyBUcnVuY2F0ZSBjdXN0b20gaW5wdXQgdG8gZml0IHdpZHRoXG4gICAgICBjb25zdCBkaXNwbGF5SW5wdXQgPVxuICAgICAgICBjdXN0b21JbnB1dC5sZW5ndGggPiB3IC0gMiA/IGN1c3RvbUlucHV0LnNsaWNlKDAsIHcgLSAyKSArIFwi4oCmXCIgOiBjdXN0b21JbnB1dDtcbiAgICAgIGxpbmVzLnB1c2godGhlbWUuZmcoXCJ0ZXh0XCIsIGAgICR7ZGlzcGxheUlucHV0fWApKTtcbiAgICAgIGxpbmVzLnB1c2goXCJcIik7XG4gICAgICBsaW5lcy5wdXNoKHRoZW1lLmZnKFwiZGltXCIsIGAgICR7dGhlbWUuYm9sZChcIkVudGVyXCIpfSB0byBjb25maXJtICAke3RoZW1lLmJvbGQoXCJFc2NcIil9IHRvIGNhbmNlbGApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGluZXMucHVzaCh0aGVtZS5mZyhcImRpbVwiLCBgICAke3RoZW1lLmJvbGQoXCLihpHihpNcIil9IG5hdmlnYXRlICAke3RoZW1lLmJvbGQoXCJFbnRlclwiKX0gc2VsZWN0ICAke3RoZW1lLmJvbGQoXCJFc2NcIil9IGNhbmNlbGApKTtcbiAgICB9XG5cbiAgICBsaW5lcy5wdXNoKHRoZW1lLmZnKFwiYWNjZW50XCIsIFwi4pSAXCIucmVwZWF0KHcpKSk7XG5cbiAgICByZXR1cm4gbGluZXM7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVJbnB1dChkYXRhOiBzdHJpbmcpIHtcbiAgICBpZiAoY3VzdG9tTW9kZSkge1xuICAgICAgLy8gSW4gY3VzdG9tIGlucHV0IG1vZGVcbiAgICAgIGlmIChtYXRjaGVzS2V5KGRhdGEsIEtleS5lbnRlcikpIHtcbiAgICAgICAgaWYgKGN1c3RvbUlucHV0LnRyaW0oKSkge1xuICAgICAgICAgIGRvbmUoe1xuICAgICAgICAgICAgZm9jdXM6IFwiY3VzdG9tXCIsXG4gICAgICAgICAgICBjdXN0b21JbnN0cnVjdGlvbjogY3VzdG9tSW5wdXQudHJpbSgpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGN1c3RvbU1vZGUgPSBmYWxzZTtcbiAgICAgICAgICB0dWkucmVxdWVzdFJlbmRlcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVzY2FwZSkpIHtcbiAgICAgICAgY3VzdG9tTW9kZSA9IGZhbHNlO1xuICAgICAgICB0dWkucmVxdWVzdFJlbmRlcigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSByZWd1bGFyIHRleHQgaW5wdXRcbiAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBjdXN0b21JbnB1dCArPSBkYXRhO1xuICAgICAgfSBlbHNlIGlmIChkYXRhID09PSBcIlxcdTAwN0ZcIiB8fCBkYXRhID09PSBcIlxcYlwiKSB7XG4gICAgICAgIGN1c3RvbUlucHV0ID0gY3VzdG9tSW5wdXQuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuICAgICAgdHVpLnJlcXVlc3RSZW5kZXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBOYXZpZ2F0aW9uIG1vZGVcbiAgICBpZiAobWF0Y2hlc0tleShkYXRhLCBLZXkudXApKSB7XG4gICAgICBzZWxlY3RlZEluZGV4ID0gTWF0aC5tYXgoMCwgc2VsZWN0ZWRJbmRleCAtIDEpO1xuICAgICAgdHVpLnJlcXVlc3RSZW5kZXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAobWF0Y2hlc0tleShkYXRhLCBLZXkuZG93bikpIHtcbiAgICAgIHNlbGVjdGVkSW5kZXggPSBNYXRoLm1pbihSRUZBQ1RPUl9GT0NJLmxlbmd0aCAtIDEsIHNlbGVjdGVkSW5kZXggKyAxKTtcbiAgICAgIHR1aS5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVudGVyKSkge1xuICAgICAgY29uc3QgZm9jdXMgPSBSRUZBQ1RPUl9GT0NJW3NlbGVjdGVkSW5kZXhdO1xuICAgICAgaWYgKGZvY3VzID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgIGN1c3RvbU1vZGUgPSB0cnVlO1xuICAgICAgICBjdXN0b21JbnB1dCA9IFwiXCI7XG4gICAgICAgIHR1aS5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkb25lKHsgZm9jdXMgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVzY2FwZSkpIHtcbiAgICAgIGRvbmUobnVsbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgZG9uZSh7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfSk7IC8vIERlZmF1bHQgdG8gY2xvc2UgaW1tZWRpYXRlbHkgZm9yIG5vd1xufVxuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoyNTc4LCJvdXRwdXQiOjEzNjYsImNhY2hlUmVhZCI6NDc1MjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo1MTQ2NCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4NDQ5MDA1LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtajBjT0JDVnQ3eERpNHJSaVU3NUYyUnB3N1hvbXVMaGYifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZTU3OWE3MmEiLCJwYXJlbnRJZCI6IjIxZDk4MGE1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1NDo1My40MDhaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJpd1JwNm9Semo4dG1Ed2RpaVhra2syN1hlcDJ5QVA3diIsInRvb2xOYW1lIjoid3JpdGUiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgd3JvdGUgNDQ4NCBieXRlcyB0byAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHMifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5Mzg0OTM0MDh9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI1NWY3YzVlMCIsInBhcmVudElkIjoiZTU3OWE3MmEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjU1OjQ5Ljk1OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IldhaXQsIEkgbWFkZSBhbiBlcnJvciBpbiB0aGUgdWkudHMgLSBJJ20gY2FsbGluZyBgZG9uZWAgaW1tZWRpYXRlbHkgYXQgdGhlIGVuZCB3aGljaCB3b3VsZCBjbG9zZSB0aGUgY29tcG9uZW50IHJpZ2h0IGF3YXkuIExldCBtZSBmaXggdGhhdC4gVGhlIGBzaG93UmVmYWN0b3JEZWNpc2lvbmAgZnVuY3Rpb24gc2hvdWxkIE5PVCBjYWxsIGBkb25lYCBhdCB0aGUgZW5kIC0gaXQgc2hvdWxkIHJldHVybiBhIGNvbXBvbmVudCB0aGF0IHRoZSBjYWxsZXIgcGFzc2VzIHRvIGBjdHgudWkuY3VzdG9tKClgLiBMZXQgbWUgcmVmYWN0b3IgdGhpcyB0byBtYXRjaCB0aGUgcGF0dGVybiBmcm9tIHRoZSBgcXVlc3Rpb24udHNgIGV4YW1wbGUuXG5cbkFjdHVhbGx5LCBsb29raW5nIGF0IHRoZSBxdWVzdGlvbi50cyBleGFtcGxlIG1vcmUgY2FyZWZ1bGx5LCB0aGUgY3VzdG9tIFVJIGNhbGxiYWNrIHJlY2VpdmVzIGBkb25lYCBhbmQgcmV0dXJucyBhIGNvbXBvbmVudCB3aXRoIGByZW5kZXJgLCBgaW52YWxpZGF0ZWAsIGFuZCBgaGFuZGxlSW5wdXRgLiBUaGUgYHNob3dSZWZhY3RvckRlY2lzaW9uYCBmdW5jdGlvbiBzaG91bGQgYmUgc3RydWN0dXJlZCBsaWtlIHRoZSBjYWxsYmFjayBwYXNzZWQgdG8gYGN0eC51aS5jdXN0b20oKWAuXG5cbkxldCBtZSByZXdyaXRlIHVpLnRzIHByb3Blcmx5OlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTGV0IG1lIGZpeCB0aGUgVUkgbW9kdWxlIC0gaXQgbmVlZHMgdG8gZm9sbG93IHRoZSBgY3R4LnVpLmN1c3RvbSgpYCBwYXR0ZXJuIHByb3Blcmx5OlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiSlRlTEJIbDhlQkhwQ0dNZlFNRGRtbnIxNmwxbzV4SmgiLCJuYW1lIjoid3JpdGUiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50cyIsImNvbnRlbnQiOiIvKipcbiAqIEN1c3RvbSBVSSBmb3IgdGhlIFRERCBjeWNsZSBkZXZlbG9wZXIgZGVjaXNpb24gcHJvbXB0LlxuICpcbiAqIFJlbmRlcnMgYW4gaW50ZXJhY3RpdmUgbWVudSBkdXJpbmcgdGhlIFJFRkFDVE9SIHBoYXNlIHdoZXJlIHRoZSBkZXZlbG9wZXJcbiAqIGNhbiBjaG9vc2Ugd2hhdCB0byBkbyBuZXh0LlxuICpcbiAqIFVzYWdlOiBwYXNzIHRoZSByZXR1cm5lZCBjb21wb25lbnQgdG8gY3R4LnVpLmN1c3RvbSgpLlxuICovXG5cbmltcG9ydCB7XG4gIG1hdGNoZXNLZXksXG4gIEtleSxcbiAgdHlwZSBUVUksXG4gIHR5cGUgVGhlbWUsXG4gIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHR5cGUgeyBSZWZhY3RvckZvY3VzLCBSZWZhY3RvckRlY2lzaW9uIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcblxuY29uc3QgUkVGQUNUT1JfRk9DSTogUmVmYWN0b3JGb2N1c1tdID0gW1xuICBcInRlc3RzXCIsXG4gIFwiaW1wbGVtZW50YXRpb25cIixcbiAgXCJuZXh0LXRlc3RcIixcbiAgXCJjdXN0b21cIixcbl07XG5cbmNvbnN0IEZPQ1VTX0xBQkVMUzogUmVjb3JkPFJlZmFjdG9yRm9jdXMsIHN0cmluZz4gPSB7XG4gIHRlc3RzOiBcIlJlZmFjdG9yIHRoZSB0ZXN0c1wiLFxuICBpbXBsZW1lbnRhdGlvbjogXCJSZWZhY3RvciB0aGUgaW1wbGVtZW50YXRpb25cIixcbiAgXCJuZXh0LXRlc3RcIjogXCJDb250aW51ZSB0byBuZXh0IHRlc3RcIixcbiAgY3VzdG9tOiBcIlNvbWV0aGluZyBlbHNlIChjdXN0b20gaW5zdHJ1Y3Rpb24pXCIsXG59O1xuXG5jb25zdCBGT0NVU19ERVNDUklQVElPTlM6IFJlY29yZDxSZWZhY3RvckZvY3VzLCBzdHJpbmc+ID0ge1xuICB0ZXN0czogXCJDbGVhbiB1cCBhbmQgaW1wcm92ZSB0ZXN0IHN0cnVjdHVyZVwiLFxuICBpbXBsZW1lbnRhdGlvbjogXCJJbXByb3ZlIHByb2R1Y3Rpb24gY29kZSBzdHJ1Y3R1cmVcIixcbiAgXCJuZXh0LXRlc3RcIjogXCJXcml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3RcIixcbiAgY3VzdG9tOiBcIlByb3ZpZGUgYSBjdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb25cIixcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGN1c3RvbSBVSSBjb21wb25lbnQgZm9yIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBwcm9tcHQuXG4gKiBDYWxsIHRoaXMgZnJvbSBjdHgudWkuY3VzdG9tKCkgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50KFxuICB0ZXN0RGVzY3JpcHRpb24/OiBzdHJpbmcsXG4pOiAoXG4gIHR1aTogVFVJLFxuICB0aGVtZTogVGhlbWUsXG4gIF9rYjogS2V5YmluZGluZ3NNYW5hZ2VyLFxuICBkb25lOiAoZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gfCBudWxsKSA9PiB2b2lkLFxuKSA9PiB7XG4gIHJlbmRlcjogKHdpZHRoOiBudW1iZXIpID0+IHN0cmluZ1tdO1xuICBpbnZhbGlkYXRlOiAoKSA9PiB2b2lkO1xuICBoYW5kbGVJbnB1dDogKGRhdGE6IHN0cmluZykgPT4gYm9vbGVhbjtcbn0ge1xuICBsZXQgc2VsZWN0ZWRJbmRleCA9IDA7XG4gIGxldCBjdXN0b21Nb2RlID0gZmFsc2U7XG4gIGxldCBjdXN0b21JbnB1dCA9IFwiXCI7XG5cbiAgcmV0dXJuICh0dWksIHRoZW1lLCBfa2IsIGRvbmUpID0+IHtcbiAgICBmdW5jdGlvbiByZW5kZXIod2lkdGg6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgdyA9IE1hdGgubWF4KDEsIHdpZHRoIC0gMik7XG5cbiAgICAgIC8vIEhlYWRlclxuICAgICAgbGluZXMucHVzaCh0aGVtZS5mZyhcImFjY2VudFwiLCBcIuKUgFwiLnJlcGVhdCh3KSkpO1xuICAgICAgbGluZXMucHVzaChcbiAgICAgICAgdGhlbWUuZmcoXG4gICAgICAgICAgXCJhY2NlbnRcIixcbiAgICAgICAgICBcIiAg8J+UgCBSRUZBQ1RPUiBQSEFTRSDigJQgV2hhdCBzaG91bGQgd2UgcmVmYWN0b3I/XCIsXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgaWYgKHRlc3REZXNjcmlwdGlvbikge1xuICAgICAgICBsaW5lcy5wdXNoKHRoZW1lLmZnKFwibXV0ZWRcIiwgYCAgQ3VycmVudCB0ZXN0OiAke3Rlc3REZXNjcmlwdGlvbn1gKSk7XG4gICAgICB9XG4gICAgICBsaW5lcy5wdXNoKFwiXCIpO1xuXG4gICAgICAvLyBPcHRpb25zXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IFJFRkFDVE9SX0ZPQ0kubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZm9jdXMgPSBSRUZBQ1RPUl9GT0NJW2ldO1xuICAgICAgICBjb25zdCBzZWxlY3RlZCA9IGkgPT09IHNlbGVjdGVkSW5kZXg7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9IHNlbGVjdGVkXG4gICAgICAgICAgPyB0aGVtZS5mZyhcImFjY2VudFwiLCBcIuKWuCBcIilcbiAgICAgICAgICA6IFwiICBcIjtcbiAgICAgICAgY29uc3QgbGFiZWwgPSB0aGVtZS5mZyhzZWxlY3RlZCA/IFwiYWNjZW50XCIgOiBcInRleHRcIiwgRk9DVVNfTEFCRUxTW2ZvY3VzXSk7XG4gICAgICAgIGxpbmVzLnB1c2goYCR7cHJlZml4fSR7bGFiZWx9YCk7XG4gICAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgICAgICBgICAgICR7dGhlbWUuZmcoXCJkaW1cIiwgRk9DVVNfREVTQ1JJUFRJT05TW2ZvY3VzXSl9YCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxpbmVzLnB1c2goXCJcIik7XG5cbiAgICAgIC8vIEN1c3RvbSBpbnB1dCBtb2RlXG4gICAgICBpZiAoY3VzdG9tTW9kZSkge1xuICAgICAgICBsaW5lcy5wdXNoKHRoZW1lLmZnKFwibXV0ZWRcIiwgXCIgIEN1c3RvbSBpbnN0cnVjdGlvbjpcIikpO1xuICAgICAgICBjb25zdCBkaXNwbGF5SW5wdXQgPVxuICAgICAgICAgIGN1c3RvbUlucHV0Lmxlbmd0aCA+IHcgLSAyID8gY3VzdG9tSW5wdXQuc2xpY2UoMCwgdyAtIDIpICsgXCLigKZcIiA6IGN1c3RvbUlucHV0O1xuICAgICAgICBsaW5lcy5wdXNoKHRoZW1lLmZnKFwidGV4dFwiLCBgICAke2Rpc3BsYXlJbnB1dH1gKSk7XG4gICAgICAgIGxpbmVzLnB1c2goXCJcIik7XG4gICAgICAgIGxpbmVzLnB1c2godGhlbWUuZmcoXCJkaW1cIiwgYCAgJHt0aGVtZS5ib2xkKFwiRW50ZXJcIil9IHRvIGNvbmZpcm0gICR7dGhlbWUuYm9sZChcIkVzY1wiKX0gdG8gY2FuY2VsYCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGluZXMucHVzaCh0aGVtZS5mZyhcImRpbVwiLCBgICAke3RoZW1lLmJvbGQoXCLihpHihpNcIil9IG5hdmlnYXRlICAke3RoZW1lLmJvbGQoXCJFbnRlclwiKX0gc2VsZWN0ICAke3RoZW1lLmJvbGQoXCJFc2NcIil9IGNhbmNlbGApKTtcbiAgICAgIH1cblxuICAgICAgbGluZXMucHVzaCh0aGVtZS5mZyhcImFjY2VudFwiLCBcIuKUgFwiLnJlcGVhdCh3KSkpO1xuXG4gICAgICByZXR1cm4gbGluZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFuZGxlSW5wdXQoZGF0YTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICBpZiAoY3VzdG9tTW9kZSkge1xuICAgICAgICBpZiAobWF0Y2hlc0tleShkYXRhLCBLZXkuZW50ZXIpKSB7XG4gICAgICAgICAgaWYgKGN1c3RvbUlucHV0LnRyaW0oKSkge1xuICAgICAgICAgICAgZG9uZSh7XG4gICAgICAgICAgICAgIGZvY3VzOiBcImN1c3RvbVwiLFxuICAgICAgICAgICAgICBjdXN0b21JbnN0cnVjdGlvbjogY3VzdG9tSW5wdXQudHJpbSgpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGN1c3RvbU1vZGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHR1aS5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVzY2FwZSkpIHtcbiAgICAgICAgICBjdXN0b21Nb2RlID0gZmFsc2U7XG4gICAgICAgICAgdHVpLnJlcXVlc3RSZW5kZXIoKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIGN1c3RvbUlucHV0ICs9IGRhdGE7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YSA9PT0gXCJcXHUwMDdGXCIgfHwgZGF0YSA9PT0gXCJcXGJcIikge1xuICAgICAgICAgIGN1c3RvbUlucHV0ID0gY3VzdG9tSW5wdXQuc2xpY2UoMCwgLTEpO1xuICAgICAgICB9XG4gICAgICAgIHR1aS5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF0Y2hlc0tleShkYXRhLCBLZXkudXApKSB7XG4gICAgICAgIHNlbGVjdGVkSW5kZXggPSBNYXRoLm1heCgwLCBzZWxlY3RlZEluZGV4IC0gMSk7XG4gICAgICAgIHR1aS5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF0Y2hlc0tleShkYXRhLCBLZXkuZG93bikpIHtcbiAgICAgICAgc2VsZWN0ZWRJbmRleCA9IE1hdGgubWluKFJFRkFDVE9SX0ZPQ0kubGVuZ3RoIC0gMSwgc2VsZWN0ZWRJbmRleCArIDEpO1xuICAgICAgICB0dWkucmVxdWVzdFJlbmRlcigpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVudGVyKSkge1xuICAgICAgICBjb25zdCBmb2N1cyA9IFJFRkFDVE9SX0ZPQ0lbc2VsZWN0ZWRJbmRleF07XG4gICAgICAgIGlmIChmb2N1cyA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgIGN1c3RvbU1vZGUgPSB0cnVlO1xuICAgICAgICAgIGN1c3RvbUlucHV0ID0gXCJcIjtcbiAgICAgICAgICB0dWkucmVxdWVzdFJlbmRlcigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRvbmUoeyBmb2N1cyB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVzY2FwZSkpIHtcbiAgICAgICAgZG9uZShudWxsKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByZW5kZXIsIGludmFsaWRhdGU6ICgpID0+IHt9LCBoYW5kbGVJbnB1dCB9O1xuICB9O1xufVxuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoxNDUwLCJvdXRwdXQiOjE1NjMsImNhY2hlUmVhZCI6NTAwNTUsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo1MzA2OCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4NDkzNDA5LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtZ0JXTGJMUk5VcnFsQTQyRWVnSmp3eldGNTk0bHZUbTEifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDQxMjRlMTQiLCJwYXJlbnRJZCI6IjU1ZjdjNWUwIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1NTo0OS45NjhaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJKVGVMQkhsOGVCSHBDR01mUU1EZG1ucjE2bDFvNXhKaCIsInRvb2xOYW1lIjoid3JpdGUiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgd3JvdGUgNDgxNyBieXRlcyB0byAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHMifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5Mzg1NDk5Njh9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI4Nzg1NzExNiIsInBhcmVudElkIjoiZDQxMjRlMTQiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA2OjU5OjAxLjA4OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBsZXQgbWUgd3JpdGUgdGhlIG1haW4gZXh0ZW5zaW9uIGVudHJ5IHBvaW50IHRoYXQgdGllcyBldmVyeXRoaW5nIHRvZ2V0aGVyOlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IGxldCBtZSB3cml0ZSB0aGUgbWFpbiBleHRlbnNpb24gZW50cnkgcG9pbnQ6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJZeGRCV2F1eDZTQ1hJOGtxcEIzbWtOS1ZOcGxzSE1yTyIsIm5hbWUiOiJ3cml0ZSIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwiY29udGVudCI6Ii8qKlxuICogVEREIEN5Y2xlIEV4dGVuc2lvblxuICpcbiAqIEVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgVEREIGN5Y2xlOlxuICogICDwn5S0IFJFRCAgICDihpIgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzc1xuICogICDwn5+iIEdSRUVOICDihpIgVGVzdHMgcGFzcywgcmVhZHkgZm9yIHJlZmFjdG9yaW5nXG4gKiAgIPCflIAgUkVGQUNUT1Ig4oaSIERldmVsb3BlciBjaG9vc2VzIHdoYXQgdG8gcmVmYWN0b3JcbiAqXG4gKiBBZnRlciByZWZhY3RvcmluZywgdGhlIGN5Y2xlIHJlcGVhdHM6IGJhY2sgdG8gUkVEIGZvciB0aGUgbmV4dCB0ZXN0LlxuICpcbiAqIFRvb2xzOlxuICogICBnby10by1ncmVlbiAgLSBSdW4gdGVzdHMgYW5kIHRyYW5zaXRpb24gYmFzZWQgb24gcmVzdWx0XG4gKiAgIGdvLXRvLXJlZmFjdG9yIC0gRW50ZXIgdGhlIGRldmVsb3BlciBkZWNpc2lvbiBwaGFzZVxuICogICBydW4tdGVzdHMgICAgLSBSdW4gdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uXG4gKiAgIHRkZC1zdGF0dXMgICAtIFNob3cgY3VycmVudCBwaGFzZSBhbmQgc3RhdGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSwgRXh0ZW5zaW9uQ29udGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcbmltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHsgaXNUb29sQ2FsbEV2ZW50VHlwZSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZUluaXRpYWxTdGF0ZSxcbiAgcmVjb3JkVGVzdFJlc3VsdCxcbiAgcmVkVG9HcmVlbixcbiAgZ3JlZW5Ub1JlZmFjdG9yLFxuICBhcHBseVJlZmFjdG9yRGVjaXNpb24sXG4gIGNhblRyYW5zaXRpb24sXG4gIHBoYXNlRW1vamksXG4gIHBoYXNlRGVzY3JpcHRpb24sXG4gIHBoYXNlR3VpZGVsaW5lcyxcbiAgdHlwZSBDeWNsZVN0YXRlLFxuICB0eXBlIFJlZmFjdG9yRGVjaXNpb24sXG59IGZyb20gXCIuL3N0YXRlLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50IH0gZnJvbSBcIi4vdWkuanNcIjtcblxuLy8g4pSA4pSAIFN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5sZXQgc3RhdGU6IEN5Y2xlU3RhdGUgPSBjcmVhdGVJbml0aWFsU3RhdGUoKTtcblxuZnVuY3Rpb24gcGVyc2lzdFN0YXRlKCk6IHZvaWQge1xuICBwaS5hcHBlbmRFbnRyeShcInRkZC1jeWNsZVwiLCB7XG4gICAgcGhhc2U6IHN0YXRlLnBoYXNlLFxuICAgIHRlc3REZXNjcmlwdGlvbjogc3RhdGUudGVzdERlc2NyaXB0aW9uLFxuICAgIHRlc3RzUmFuOiBzdGF0ZS50ZXN0c1JhbixcbiAgICB0ZXN0c1Bhc3NlZDogc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgdGVzdHNXcml0dGVuOiBzdGF0ZS50ZXN0c1dyaXR0ZW4sXG4gICAgbGFzdERlY2lzaW9uOiBzdGF0ZS5sYXN0RGVjaXNpb24sXG4gICAgY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbjogc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbixcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlc3RvcmVTdGF0ZShjdHg6IEV4dGVuc2lvbkNvbnRleHQpOiB2b2lkIHtcbiAgY29uc3QgZW50cmllcyA9IGN0eC5zZXNzaW9uTWFuYWdlci5nZXRFbnRyaWVzKCk7XG4gIGNvbnN0IHRkZEVudHJ5ID0gZW50cmllc1xuICAgIC5maWx0ZXIoXG4gICAgICAoZTogeyB0eXBlOiBzdHJpbmc7IGN1c3RvbVR5cGU/OiBzdHJpbmcgfSkgPT5cbiAgICAgICAgZS50eXBlID09PSBcImN1c3RvbVwiICYmIGUuY3VzdG9tVHlwZSA9PT0gXCJ0ZGQtY3ljbGVcIixcbiAgICApXG4gICAgLnBvcCgpIGFzIHsgZGF0YT86IFBhcnRpYWw8Q3ljbGVTdGF0ZT4gfSB8IHVuZGVmaW5lZDtcblxuICBpZiAodGRkRW50cnk/LmRhdGEpIHtcbiAgICBzdGF0ZSA9IHtcbiAgICAgIC4uLmNyZWF0ZUluaXRpYWxTdGF0ZSgpLFxuICAgICAgLi4udGRkRW50cnkuZGF0YSxcbiAgICB9O1xuICB9XG59XG5cbi8vIOKUgOKUgCBIZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBzdGF0dXNNZXNzYWdlKCk6IHN0cmluZyB7XG4gIHJldHVybiBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbn1cblxuZnVuY3Rpb24gZ3VpZGVsaW5lc01lc3NhZ2UoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG59XG5cbi8vIOKUgOKUgCBFeHRlbnNpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRkZEN5Y2xlKHBpOiBFeHRlbnNpb25BUEkpOiB2b2lkIHtcbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLWdyZWVuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1ncmVlblwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIEdyZWVuXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB0byB2ZXJpZnkgaW1wbGVtZW50YXRpb24uIElmIHRlc3RzIHBhc3MsIHRyYW5zaXRpb25zIHRvIEdSRUVOIHBoYXNlLiBcIiArXG4gICAgICBcIklmIHRlc3RzIGZhaWwsIHN0YXlzIGluIFJFRCB3aXRoIGZlZWRiYWNrLiBVc2UgdGhpcyBhZnRlciB3cml0aW5nIGEgZmFpbGluZyB0ZXN0IGFuZCBpdHMgaW1wbGVtZW50YXRpb24uXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgdGVzdERlc2NyaXB0aW9uOiBUeXBlLk9wdGlvbmFsKFxuICAgICAgICBUeXBlLlN0cmluZyh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIkJyaWVmIGRlc2NyaXB0aW9uIG9mIHdoYXQgdGVzdChzKSB0byBydW4gKGUuZy4sICd1c2VyIGxvZ2luIHRlc3QnKS4gXCIgK1xuICAgICAgICAgICAgXCJVc2VkIGZvciBkaXNwbGF5IHB1cnBvc2VzLlwiLFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgfSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgdGVzdERlc2MgPSBwYXJhbXMudGVzdERlc2NyaXB0aW9uID8/IHN0YXRlLnRlc3REZXNjcmlwdGlvbjtcblxuICAgICAgLy8gVXBkYXRlIHRlc3QgZGVzY3JpcHRpb24gaWYgcHJvdmlkZWRcbiAgICAgIGlmICh0ZXN0RGVzYykge1xuICAgICAgICBzdGF0ZS50ZXN0RGVzY3JpcHRpb24gPSB0ZXN0RGVzYztcbiAgICAgIH1cblxuICAgICAgLy8gU2hvdyBzdGF0dXNcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBSdW4gdGVzdHMgdmlhIGJhc2hcbiAgICAgIGNvbnN0IHRlc3RDb21tYW5kID0gXCJucG0gdGVzdCAyPiYxXCI7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCB0ZXN0Q29tbWFuZF0sIHtcbiAgICAgICAgc2lnbmFsOiBjdHguc2lnbmFsLFxuICAgICAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcGFzc2VkID0gcmVzdWx0LmNvZGUgPT09IDA7XG5cbiAgICAgIC8vIFJlY29yZCByZXN1bHQgYW5kIGdldCB0cmFuc2l0aW9uXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcblxuICAgICAgLy8gVXBkYXRlIHdpZGdldFxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICB0aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgICB0aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgLy8gSWYgdHJhbnNpdGlvbmVkIHRvIEdSRUVOLCBub3RpZnkgZGV2ZWxvcGVyXG4gICAgICBpZiAodHJhbnNpdGlvbi5zdGF0ZS5waGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICBg8J+foiAqKkdSRUVOIFBIQVNFIEFDSElFVkVEISoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGAke3RyYW5zaXRpb24ubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgYFRoZSBkZXZlbG9wZXIgbXVzdCBub3cgZGVjaWRlIHdoYXQgdG8gcmVmYWN0b3IuXFxuYCArXG4gICAgICAgICAgICAgIGBVc2UgKipnby10by1yZWZhY3RvcioqIHRvIGVudGVyIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBwaGFzZS5gLFxuICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgdHJpZ2dlclR1cm46IGZhbHNlIH0sXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJUZXN0cyBleGVjdXRlZC5cIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGFzc2VkLFxuICAgICAgICAgIHBoYXNlOiB0cmFuc2l0aW9uLnN0YXRlLnBoYXNlLFxuICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICBvdXRwdXQ6IHJlc3VsdC5zdGRvdXQuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgdGV4dCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJnby10by1ncmVlbiBcIikpICsgKGFyZ3MudGVzdERlc2NyaXB0aW9uID8gdGhlbWUuZmcoXCJtdXRlZFwiLCBhcmdzLnRlc3REZXNjcmlwdGlvbikgOiBcIlwiKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBhc3NlZD86IGJvb2xlYW47IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIGAke3BoYXNlfSBUZXN0cyBwYXNzZWRgKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgYCR7cGhhc2V9IFRlc3RzIGZhaWxlZGApO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLXJlZmFjdG9yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1yZWZhY3RvclwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIFJlZmFjdG9yXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciB3aWxsIGJlIHByb21wdGVkIHRvIGNob29zZSBcIiArXG4gICAgICBcIndoYXQgdG8gcmVmYWN0b3I6IHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgbmV4dCB0ZXN0LCBvciBjdXN0b20gaW5zdHJ1Y3Rpb24uIFwiICtcbiAgICAgIFwiT25seSBjYWxsIHRoaXMgd2hlbiB0ZXN0cyBhcmUgcGFzc2luZyAoR1JFRU4gcGhhc2UpLlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgaWYgKHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgQ2Fubm90IGVudGVyIFJFRkFDVE9SIGZyb20gcGhhc2UgJHtzdGF0ZS5waGFzZX0uIE11c3QgYmUgaW4gR1JFRU4gcGhhc2UgKHRlc3RzIHBhc3NpbmcpLmAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogc3RhdGUucGhhc2UgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gVHJhbnNpdGlvbiB0byBSRUZBQ1RPUlxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4gICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgLy8gU2hvdyBzdGF0dXMgd2lkZ2V0XG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgLy8gU2hvdyBkZXZlbG9wZXIgZGVjaXNpb24gcHJvbXB0XG4gICAgICBpZiAoY3R4Lm1vZGUgPT09IFwidHVpXCIgJiYgY3R4Lmhhc1VJKSB7XG4gICAgICAgIGNvbnN0IGRlY2lzaW9uID0gYXdhaXQgY3R4LnVpLmN1c3RvbTxSZWZhY3RvckRlY2lzaW9uIHwgbnVsbD4oXG4gICAgICAgICAgY3JlYXRlUmVmYWN0b3JEZWNpc2lvbkNvbXBvbmVudChzdGF0ZS50ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChkZWNpc2lvbikge1xuICAgICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgICAgICAvLyBTZW5kIG1lc3NhZ2UgdG8gTExNIGFib3V0IHRoZSBkZWNpc2lvblxuICAgICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICAgIGDwn5SAICoqUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZDoqKlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGAke2FwcGx5UmVzdWx0Lm1lc3NhZ2V9XFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYEN1cnJlbnQgcGhhc2U6ICoqUkVEKiog4oCUIFdyaXRlIHRoZSBuZXh0IGZhaWxpbmcgdGVzdC5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICAoc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvblxuICAgICAgICAgICAgICAgICAgPyBgKipDdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb246KipcXG5cXGBcXGBcXGBcXG4ke3N0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb259XFxuXFxgXFxgXFxgXFxuXFxuYFxuICAgICAgICAgICAgICAgICAgOiBcIlwiKSArXG4gICAgICAgICAgICAgICAgZ3VpZGVsaW5lc01lc3NhZ2UoKSxcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IHRyaWdnZXJUdXJuOiB0cnVlIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBhcHBseVJlc3VsdC5tZXNzYWdlID8/IFwiUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZC5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICAgIGRlY2lzaW9uLFxuICAgICAgICAgICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXZlbG9wZXIgY2FuY2VsbGVkIOKAlCBzdGF5IGluIFJFRkFDVE9SXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IFwiRGV2ZWxvcGVyIGNhbmNlbGxlZC4gU3RheWluZyBpbiBSRUZBQ1RPUiBwaGFzZS5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE5vbi1UVUkgbW9kZToganVzdCB0cmFuc2l0aW9uXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJFbnRlcmVkIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwiZ28tdG8tcmVmYWN0b3JcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nOyBkZWNpc2lvbj86IFJlZmFjdG9yRGVjaXNpb24gfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3QgdGV4dCA9IGRldGFpbHMuZGVjaXNpb25cbiAgICAgICAgPyBgJHtwaGFzZX0gUmVmYWN0b3JlZDogJHtkZXRhaWxzLmRlY2lzaW9uLmZvY3VzfWBcbiAgICAgICAgOiBgJHtwaGFzZX0gRW50ZXJlZCByZWZhY3RvciBwaGFzZWA7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHJ1bi10ZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwicnVuLXRlc3RzXCIsXG4gICAgbGFiZWw6IFwiUnVuIFRlc3RzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb24uIFVzZWZ1bCBmb3IgY2hlY2tpbmcgdGVzdCBzdGF0dXMgXCIgK1xuICAgICAgXCJkdXJpbmcgZGV2ZWxvcG1lbnQuIFJldHVybnMgZXhpdCBjb2RlIGFuZCBvdXRwdXQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgY29tbWFuZDogVHlwZS5PcHRpb25hbChcbiAgICAgICAgVHlwZS5TdHJpbmcoe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkN1c3RvbSB0ZXN0IGNvbW1hbmQgdG8gcnVuIChkZWZhdWx0OiAnbnBtIHRlc3QnKS5cIixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH0pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIGNvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIHRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHtwYXNzZWQgPyBcIuKck1wiIDogXCLinJdcIn0gVGVzdHMgJHtwYXNzZWQgPyBcInBhc3NlZFwiIDogXCJmYWlsZWRcIn0gKGV4aXQgY29kZTogJHtyZXN1bHQuY29kZX0pYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGFzc2VkLFxuICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICBvdXRwdXQ6IHJlc3VsdC5zdGRvdXQuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgICBzdGRlcnI6IHJlc3VsdC5zdGRlcnIuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgdGV4dCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJydW4tdGVzdHMgXCIpKSArIChhcmdzLmNvbW1hbmQgPyB0aGVtZS5mZyhcIm11dGVkXCIsIGFyZ3MuY29tbWFuZCkgOiB0aGVtZS5mZyhcIm11dGVkXCIsIFwibnBtIHRlc3RcIikpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGFzc2VkPzogYm9vbGVhbiB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0dXMgPSBkZXRhaWxzLnBhc3NlZFxuICAgICAgICA/IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKckyBUZXN0cyBwYXNzZWRcIilcbiAgICAgICAgOiB0aGVtZS5mZyhcImVycm9yXCIsIFwi4pyXIFRlc3RzIGZhaWxlZFwiKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dChzdGF0dXMsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBUb29sOiB0ZGQtc3RhdHVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJ0ZGQtc3RhdHVzXCIsXG4gICAgbGFiZWw6IFwiVEREIFN0YXR1c1wiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJTaG93IGN1cnJlbnQgVEREIGN5Y2xlIHBoYXNlIGFuZCBzdGF0ZS4gUmV0dXJucyB0aGUgY3VycmVudCBwaGFzZSwgXCIgK1xuICAgICAgXCJ0ZXN0IGNvdW50LCBhbmQgZ3VpZGVsaW5lcyBmb3Igd2hhdCB0byBkbyBuZXh0LlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3Qgc3RhdHVzID0gcGhhc2VEZXNjcmlwdGlvbihzdGF0ZSk7XG4gICAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICAgIGNvbnN0IHRlc3RzV3JpdHRlbiA9IHN0YXRlLnRlc3RzV3JpdHRlbiA/PyAwO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1cyksXG4gICAgICAgIHRoZW1lLmZnKFwiZGltXCIsIGBUZXN0cyB3cml0dGVuOiAke3Rlc3RzV3JpdHRlbn1gKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHtzdGF0dXN9XFxuXFxuVGVzdHMgd3JpdHRlbjogJHt0ZXN0c1dyaXR0ZW59XFxuXFxuJHtndWlkZWxpbmVzfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgIHBoYXNlOiBzdGF0ZS5waGFzZSxcbiAgICAgICAgICB0ZXN0c1Jhbjogc3RhdGUudGVzdHNSYW4sXG4gICAgICAgICAgdGVzdHNQYXNzZWQ6IHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgICAgICAgIHRlc3RzV3JpdHRlbixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwidGRkLXN0YXR1c1wiKSksIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGhhc2U/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KGAke3BoYXNlfSAke2RldGFpbHMucGhhc2V9YCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIEV2ZW50cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvLyBSZXN0b3JlIHN0YXRlIG9uIHNlc3Npb24gc3RhcnRcbiAgcGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcblxuICAgIC8vIEluamVjdCBwaGFzZSBndWlkZWxpbmVzIGludG8gc3lzdGVtIHByb21wdFxuICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIikge1xuICAgICAgY3R4LnVpLm5vdGlmeShgVEREIEN5Y2xlIHN0YXJ0ZWQgaW4gJHtzdGF0ZS5waGFzZX0gcGhhc2VgLCBcImluZm9cIik7XG4gICAgfVxuICB9KTtcblxuICAvLyBCbG9jayBkaXJlY3QgUkVEIOKGkiBSRUZBQ1RPUiB0cmFuc2l0aW9uc1xuICBwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1yZWZhY3RvclwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlLiBZb3UgbXVzdCBmaXJzdCBtYWtlIHRlc3RzIHBhc3MgKEdSRUVOIHBoYXNlKS4gQ2FsbCBnby10by1ncmVlbiBhZnRlciB5b3VyIGltcGxlbWVudGF0aW9uIHBhc3NlcyB0aGUgdGVzdC5gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVGQUNUT1JcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1ncmVlblwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIEdSRUVOIGZyb20gUkVGQUNUT1IgcGhhc2UuIENvbXBsZXRlIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBmaXJzdC5gLFxuICAgICAgfTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEluamVjdCBwaGFzZSBndWlkZWxpbmVzIGJlZm9yZSBhZ2VudCBzdGFydHNcbiAgcGkub24oXCJiZWZvcmVfYWdlbnRfc3RhcnRcIiwgYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGUtZ3VpZGVsaW5lc1wiLFxuICAgICAgICBjb250ZW50OiBgXFxuXFxuW1RERCBDWUNMRSAtICR7c3RhdGUucGhhc2V9IFBIQVNFXVxcbiR7Z3VpZGVsaW5lc01lc3NhZ2UoKX1gLFxuICAgICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gVXBkYXRlIHN0YXR1cyBvbiB0dXJuIGVuZFxuICBwaS5vbihcInR1cm5fZW5kXCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgXSk7XG4gIH0pO1xuXG4gIC8vIFNhdmUgc3RhdGUgb24gc2h1dGRvd25cbiAgcGkub24oXCJzZXNzaW9uX3NodXRkb3duXCIsIGFzeW5jICgpID0+IHtcbiAgICBwZXJzaXN0U3RhdGUoKTtcbiAgfSk7XG59XG4ifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjQzLCJvdXRwdXQiOjM5MTksImNhY2hlUmVhZCI6NTMwNjcsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo1NzAyOSwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4NTQ5OTY4LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtZmFEd2h5NUYxTnR1QTZYN0plUXd0RmJkQWJzalBiN1kifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNmM4NTMzY2IiLCJwYXJlbnRJZCI6Ijg3ODU3MTE2IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1OTowMS4xMDVaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJZeGRCV2F1eDZTQ1hJOGtxcEIzbWtOS1ZOcGxzSE1yTyIsInRvb2xOYW1lIjoid3JpdGUiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgd3JvdGUgMTQ0OTggYnl0ZXMgdG8gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4NzQxMTA1fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZGIzYWQ5YzciLCJwYXJlbnRJZCI6IjZjODUzM2NiIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNjo1OTo1OS40MjdaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIG5vdGljZSB0aGVyZSBhcmUgc29tZSBpc3N1ZXMgd2l0aCB0aGUgaW5kZXgudHMgZmlsZS4gSXQgcmVmZXJlbmNlcyBgdGhlbWVgIGluIHRoZSBleGVjdXRlIGZ1bmN0aW9ucyBidXQgYHRoZW1lYCBpc24ndCBhdmFpbGFibGUgaW4gdGhhdCBzY29wZSAtIEkgbmVlZCB0byB1c2UgYGN0eC51aS50aGVtZWAgaW5zdGVhZC4gQWxzbywgSSBzaG91bGQgY2hlY2sgZm9yIFR5cGVTY3JpcHQgaXNzdWVzLiBMZXQgbWUgYWxzbyBhZGQgYSBSRUFETUUuXG5cbkxldCBtZSBmaXggdGhlIGluZGV4LnRzIHRvIHVzZSBgY3R4LnVpLnRoZW1lYCBpbnN0ZWFkIG9mIGp1c3QgYHRoZW1lYDpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkkgbmVlZCB0byBmaXggYSBmZXcgaXNzdWVzIGluIGluZGV4LnRzIOKAlCBgdGhlbWVgIGlzbid0IGF2YWlsYWJsZSBpbiB0aGF0IHNjb3BlLCBhbmQgdGhlcmUncyBhIG1pc3NpbmcgaW1wb3J0LiBMZXQgbWUgZml4OlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiOHVGQmwxRm1GWWZlUG9zMjBOeFU2bVlrSEROdTY3a3ciLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwiZWRpdHMiOlt7Im9sZFRleHQiOiJpbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSwgRXh0ZW5zaW9uQ29udGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcbmltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHsgaXNUb29sQ2FsbEV2ZW50VHlwZSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7IiwibmV3VGV4dCI6ImltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwidHlwZWJveFwiO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7In0seyJvbGRUZXh0IjoiICAgICAgLy8gU2hvdyBzdGF0dXNcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBSdW4gdGVzdHMgdmlhIGJhc2hcbiAgICAgIGNvbnN0IHRlc3RDb21tYW5kID0gXCJucG0gdGVzdCAyPiYxXCI7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCB0ZXN0Q29tbWFuZF0sIHtcbiAgICAgICAgc2lnbmFsOiBjdHguc2lnbmFsLFxuICAgICAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcGFzc2VkID0gcmVzdWx0LmNvZGUgPT09IDA7XG5cbiAgICAgIC8vIFJlY29yZCByZXN1bHQgYW5kIGdldCB0cmFuc2l0aW9uXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcblxuICAgICAgLy8gVXBkYXRlIHdpZGdldFxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICB0aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgICB0aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTsiLCJuZXdUZXh0IjoiICAgICAgLy8gU2hvdyBzdGF0dXNcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgLy8gUnVuIHRlc3RzIHZpYSBiYXNoXG4gICAgICBjb25zdCB0ZXN0Q29tbWFuZCA9IFwibnBtIHRlc3QgMj4mMVwiO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgdGVzdENvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbDogY3R4LnNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuXG4gICAgICAvLyBSZWNvcmQgcmVzdWx0IGFuZCBnZXQgdHJhbnNpdGlvblxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIC8vIFVwZGF0ZSB3aWRnZXRcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTsifSx7Im9sZFRleHQiOiIgICAgICAvLyBTaG93IHN0YXR1cyB3aWRnZXRcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pOyIsIm5ld1RleHQiOiIgICAgICAvLyBTaG93IHN0YXR1cyB3aWRnZXRcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTsifSx7Im9sZFRleHQiOiIgICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIHRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pOyIsIm5ld1RleHQiOiIgICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgICBjdHgudWkudGhlbWUuZmcocGFzc2VkID8gXCJzdWNjZXNzXCIgOiBcImVycm9yXCIsIHBhc3NlZCA/IFwi4pyTIFRlc3RzIHBhc3NlZFwiIDogXCLinJcgVGVzdHMgZmFpbGVkXCIpLFxuICAgICAgXSk7In0seyJvbGRUZXh0IjoiICAvLyBSZXN0b3JlIHN0YXRlIG9uIHNlc3Npb24gc3RhcnRcbiAgcGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcblxuICAgIC8vIEluamVjdCBwaGFzZSBndWlkZWxpbmVzIGludG8gc3lzdGVtIHByb21wdFxuICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIikge1xuICAgICAgY3R4LnVpLm5vdGlmeShgVEREIEN5Y2xlIHN0YXJ0ZWQgaW4gJHtzdGF0ZS5waGFzZX0gcGhhc2VgLCBcImluZm9cIik7XG4gICAgfVxuICB9KTsiLCJuZXdUZXh0IjoiICAvLyBSZXN0b3JlIHN0YXRlIG9uIHNlc3Npb24gc3RhcnRcbiAgcGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgXSk7XG5cbiAgICAvLyBJbmplY3QgcGhhc2UgZ3VpZGVsaW5lcyBpbnRvIHN5c3RlbSBwcm9tcHRcbiAgICBpZiAoY3R4Lm1vZGUgPT09IFwidHVpXCIpIHtcbiAgICAgIGN0eC51aS5ub3RpZnkoYFRERCBDeWNsZSBzdGFydGVkIGluICR7c3RhdGUucGhhc2V9IHBoYXNlYCwgXCJpbmZvXCIpO1xuICAgIH1cbiAgfSk7In0seyJvbGRUZXh0IjoiICAvLyBVcGRhdGUgc3RhdHVzIG9uIHR1cm4gZW5kXG4gIHBpLm9uKFwidHVybl9lbmRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcbiAgfSk7IiwibmV3VGV4dCI6IiAgLy8gVXBkYXRlIHN0YXR1cyBvbiB0dXJuIGVuZFxuICBwaS5vbihcInR1cm5fZW5kXCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgIF0pO1xuICB9KTsifV19fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6NDAwMiwib3V0cHV0IjoxMjczLCJjYWNoZVJlYWQiOjUzMDY5LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6NTgzNDQsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODc0MTEwNSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLUtVeGxnYzZtRlhoUDFRN2ZzUU9mSDF2WW9LUms0NzJxIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImY5ODUzY2Q2IiwicGFyZW50SWQiOiJkYjNhZDljNyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDY6NTk6NTkuNDM2WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiOHVGQmwxRm1GWWZlUG9zMjBOeFU2bVlrSEROdTY3a3ciLCJ0b29sTmFtZSI6ImVkaXQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJGb3VuZCAyIG9jY3VycmVuY2VzIG9mIGVkaXRzWzNdIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cy4gRWFjaCBvbGRUZXh0IG11c3QgYmUgdW5pcXVlLiBQbGVhc2UgcHJvdmlkZSBtb3JlIGNvbnRleHQgdG8gbWFrZSBpdCB1bmlxdWUuIn1dLCJkZXRhaWxzIjp7fSwiaXNFcnJvciI6dHJ1ZSwidGltZXN0YW1wIjoxNzgxOTM4Nzk5NDM2fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYWMwNjIwYTQiLCJwYXJlbnRJZCI6ImY5ODUzY2Q2IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowMDowMi45NDhaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIG5lZWQgdG8gbWFrZSB0aGUgZWRpdHMgbW9yZSBzcGVjaWZpYy4gTGV0IG1lIGxvb2sgYXQgdGhlIGZpbGUgbW9yZSBjYXJlZnVsbHkgYW5kIG1ha2UgdW5pcXVlIGVkaXRzLlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTGV0IG1lIGZpeCB3aXRoIG1vcmUgdW5pcXVlIGNvbnRleHRzOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiMVdsaXExU3NRTVZna2oxS2wyOFc4ajYxNDlZZGxrV2oiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0Ijo2MSwib3V0cHV0Ijo3NCwiY2FjaGVSZWFkIjo1ODM0MywiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjU4NDc4LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5Mzg3OTk0MzYsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC16Q2FsZU1jS2pqWFU2akd3TlhSOGZ3TExkQzNva0R2QSJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3ZTVmNDkxOSIsInBhcmVudElkIjoiYWMwNjIwYTQiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjAwOjAyLjk1M1oiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IjFXbGlxMVNzUU1WZ2tqMUtsMjhXOGo2MTQ5WWRsa1dqIiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiLyoqXG4gKiBUREQgQ3ljbGUgRXh0ZW5zaW9uXG4gKlxuICogRW5mb3JjZXMgdGhlIHJlZC1ncmVlbi1yZWZhY3RvciBUREQgY3ljbGU6XG4gKiAgIPCflLQgUkVEICAgIOKGkiBXcml0ZSBhIGZhaWxpbmcgdGVzdCwgdGhlbiBpbXBsZW1lbnQgdG8gbWFrZSBpdCBwYXNzXG4gKiAgIPCfn6IgR1JFRU4gIOKGkiBUZXN0cyBwYXNzLCByZWFkeSBmb3IgcmVmYWN0b3JpbmdcbiAqICAg8J+UgCBSRUZBQ1RPUiDihpIgRGV2ZWxvcGVyIGNob29zZXMgd2hhdCB0byByZWZhY3RvclxuICpcbiAqIEFmdGVyIHJlZmFjdG9yaW5nLCB0aGUgY3ljbGUgcmVwZWF0czogYmFjayB0byBSRUQgZm9yIHRoZSBuZXh0IHRlc3QuXG4gKlxuICogVG9vbHM6XG4gKiAgIGdvLXRvLWdyZWVuICAtIFJ1biB0ZXN0cyBhbmQgdHJhbnNpdGlvbiBiYXNlZCBvbiByZXN1bHRcbiAqICAgZ28tdG8tcmVmYWN0b3IgLSBFbnRlciB0aGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHBoYXNlXG4gKiAgIHJ1bi10ZXN0cyAgICAtIFJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb25cbiAqICAgdGRkLXN0YXR1cyAgIC0gU2hvdyBjdXJyZW50IHBoYXNlIGFuZCBzdGF0ZVxuICovXG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwidHlwZWJveFwiO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5pbXBvcnQgeyBpc1Rvb2xDYWxsRXZlbnRUeXBlIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcblxuaW1wb3J0IHtcbiAgY3JlYXRlSW5pdGlhbFN0YXRlLFxuICByZWNvcmRUZXN0UmVzdWx0LFxuICByZWRUb0dyZWVuLFxuICBncmVlblRvUmVmYWN0b3IsXG4gIGFwcGx5UmVmYWN0b3JEZWNpc2lvbixcbiAgY2FuVHJhbnNpdGlvbixcbiAgcGhhc2VFbW9qaSxcbiAgcGhhc2VEZXNjcmlwdGlvbixcbiAgcGhhc2VHdWlkZWxpbmVzLFxuICB0eXBlIEN5Y2xlU3RhdGUsXG4gIHR5cGUgUmVmYWN0b3JEZWNpc2lvbixcbn0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQgfSBmcm9tIFwiLi91aS5qc1wiO1xuXG4vLyDilIDilIAgU3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmxldCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IGNyZWF0ZUluaXRpYWxTdGF0ZSgpO1xuXG5mdW5jdGlvbiBwZXJzaXN0U3RhdGUoKTogdm9pZCB7XG4gIHBpLmFwcGVuZEVudHJ5KFwidGRkLWN5Y2xlXCIsIHtcbiAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgdGVzdERlc2NyaXB0aW9uOiBzdGF0ZS50ZXN0RGVzY3JpcHRpb24sXG4gICAgdGVzdHNSYW46IHN0YXRlLnRlc3RzUmFuLFxuICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICB0ZXN0c1dyaXR0ZW46IHN0YXRlLnRlc3RzV3JpdHRlbixcbiAgICBsYXN0RGVjaXNpb246IHN0YXRlLmxhc3REZWNpc2lvbixcbiAgICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uOiBzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdG9yZVN0YXRlKGN0eDogRXh0ZW5zaW9uQ29udGV4dCk6IHZvaWQge1xuICBjb25zdCBlbnRyaWVzID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldEVudHJpZXMoKTtcbiAgY29uc3QgdGRkRW50cnkgPSBlbnRyaWVzXG4gICAgLmZpbHRlcihcbiAgICAgIChlOiB7IHR5cGU6IHN0cmluZzsgY3VzdG9tVHlwZT86IHN0cmluZyB9KSA9PlxuICAgICAgICBlLnR5cGUgPT09IFwiY3VzdG9tXCIgJiYgZS5jdXN0b21UeXBlID09PSBcInRkZC1jeWNsZVwiLFxuICAgIClcbiAgICAucG9wKCkgYXMgeyBkYXRhPzogUGFydGlhbDxDeWNsZVN0YXRlPiB9IHwgdW5kZWZpbmVkO1xuXG4gIGlmICh0ZGRFbnRyeT8uZGF0YSkge1xuICAgIHN0YXRlID0ge1xuICAgICAgLi4uY3JlYXRlSW5pdGlhbFN0YXRlKCksXG4gICAgICAuLi50ZGRFbnRyeS5kYXRhLFxuICAgIH07XG4gIH1cbn1cblxuLy8g4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIHN0YXR1c01lc3NhZ2UoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpO1xufVxuXG5mdW5jdGlvbiBndWlkZWxpbmVzTWVzc2FnZSgpOiBzdHJpbmcge1xuICByZXR1cm4gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbn1cblxuLy8g4pSA4pSAIEV4dGVuc2lvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdGRkQ3ljbGUocGk6IEV4dGVuc2lvbkFQSSk6IHZvaWQge1xuICAvLyDilIDilIAgVG9vbDogZ28tdG8tZ3JlZW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLWdyZWVuXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gR3JlZW5cIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHRvIHZlcmlmeSBpbXBsZW1lbnRhdGlvbi4gSWYgdGVzdHMgcGFzcywgdHJhbnNpdGlvbnMgdG8gR1JFRU4gcGhhc2UuIFwiICtcbiAgICAgIFwiSWYgdGVzdHMgZmFpbCwgc3RheXMgaW4gUkVEIHdpdGggZmVlZGJhY2suIFVzZSB0aGlzIGFmdGVyIHdyaXRpbmcgYSBmYWlsaW5nIHRlc3QgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbi5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICB0ZXN0RGVzY3JpcHRpb246IFR5cGUuT3B0aW9uYWwoXG4gICAgICAgIFR5cGUuU3RyaW5nKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiQnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0ZXN0KHMpIHRvIHJ1biAoZS5nLiwgJ3VzZXIgbG9naW4gdGVzdCcpLiBcIiArXG4gICAgICAgICAgICBcIlVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXCIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCB0ZXN0RGVzYyA9IHBhcmFtcy50ZXN0RGVzY3JpcHRpb24gPz8gc3RhdGUudGVzdERlc2NyaXB0aW9uO1xuXG4gICAgICAvLyBVcGRhdGUgdGVzdCBkZXNjcmlwdGlvbiBpZiBwcm92aWRlZFxuICAgICAgaWYgKHRlc3REZXNjKSB7XG4gICAgICAgIHN0YXRlLnRlc3REZXNjcmlwdGlvbiA9IHRlc3REZXNjO1xuICAgICAgfVxuXG4gICAgICAvLyBTaG93IHN0YXR1c1xuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICB0aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgXSk7XG5cbiAgICAgIC8vIFJ1biB0ZXN0cyB2aWEgYmFzaFxuICAgICAgY29uc3QgdGVzdENvbW1hbmQgPSBcIm5wbSB0ZXN0IDI+JjFcIjtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIHRlc3RDb21tYW5kXSwge1xuICAgICAgICBzaWduYWw6IGN0eC5zaWduYWwsXG4gICAgICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgLy8gUmVjb3JkIHJlc3VsdCBhbmQgZ2V0IHRyYW5zaXRpb25cbiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBwYXNzZWQpO1xuXG4gICAgICAvLyBVcGRhdGUgd2lkZ2V0XG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIHRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBJZiB0cmFuc2l0aW9uZWQgdG8gR1JFRU4sIG5vdGlmeSBkZXZlbG9wZXJcbiAgICAgIGlmICh0cmFuc2l0aW9uLnN0YXRlLnBoYXNlID09PSBcIkdSRUVOXCIpIHtcbiAgICAgICAgcGkuc2VuZE1lc3NhZ2UoXG4gICAgICAgICAge1xuICAgICAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGVcIixcbiAgICAgICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgICAgIGDwn5+iICoqR1JFRU4gUEhBU0UgQUNISUVWRUQhKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYCR7dHJhbnNpdGlvbi5tZXNzYWdlfVxcblxcbmAgK1xuICAgICAgICAgICAgICBgVGhlIGRldmVsb3BlciBtdXN0IG5vdyBkZWNpZGUgd2hhdCB0byByZWZhY3Rvci5cXG5gICtcbiAgICAgICAgICAgICAgYFVzZSAqKmdvLXRvLXJlZmFjdG9yKiogdG8gZW50ZXIgdGhlIHJlZmFjdG9yaW5nIGRlY2lzaW9uIHBoYXNlLmAsXG4gICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyB0cmlnZ2VyVHVybjogZmFsc2UgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zaXRpb24ubWVzc2FnZSA/PyBcIlRlc3RzIGV4ZWN1dGVkLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcImdvLXRvLWdyZWVuIFwiKSkgKyAoYXJncy50ZXN0RGVzY3JpcHRpb24gPyB0aGVtZS5mZyhcIm11dGVkXCIsIGFyZ3MudGVzdERlc2NyaXB0aW9uKSA6IFwiXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGFzc2VkPzogYm9vbGVhbjsgcGhhc2U/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3Qgc3RhdHVzID0gZGV0YWlscy5wYXNzZWRcbiAgICAgICAgPyB0aGVtZS5mZyhcInN1Y2Nlc3NcIiwgYCR7cGhhc2V9IFRlc3RzIHBhc3NlZGApXG4gICAgICAgIDogdGhlbWUuZmcoXCJlcnJvclwiLCBgJHtwaGFzZX0gVGVzdHMgZmFpbGVkYCk7XG4gICAgICByZXR1cm4gbmV3IFRleHQoc3RhdHVzLCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgVG9vbDogZ28tdG8tcmVmYWN0b3Ig4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLXJlZmFjdG9yXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gUmVmYWN0b3JcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiRW50ZXIgdGhlIFJFRkFDVE9SIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIHdpbGwgYmUgcHJvbXB0ZWQgdG8gY2hvb3NlIFwiICtcbiAgICAgIFwid2hhdCB0byByZWZhY3RvcjogdGVzdHMsIGltcGxlbWVudGF0aW9uLCBuZXh0IHRlc3QsIG9yIGN1c3RvbSBpbnN0cnVjdGlvbi4gXCIgK1xuICAgICAgXCJPbmx5IGNhbGwgdGhpcyB3aGVuIHRlc3RzIGFyZSBwYXNzaW5nIChHUkVFTiBwaGFzZSkuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGBDYW5ub3QgZW50ZXIgUkVGQUNUT1IgZnJvbSBwaGFzZSAke3N0YXRlLnBoYXNlfS4gTXVzdCBiZSBpbiBHUkVFTiBwaGFzZSAodGVzdHMgcGFzc2luZykuYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBUcmFuc2l0aW9uIHRvIFJFRkFDVE9SXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKTtcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAvLyBTaG93IHN0YXR1cyB3aWRnZXRcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBTaG93IGRldmVsb3BlciBkZWNpc2lvbiBwcm9tcHRcbiAgICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIiAmJiBjdHguaGFzVUkpIHtcbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBjdHgudWkuY3VzdG9tPFJlZmFjdG9yRGVjaXNpb24gfCBudWxsPihcbiAgICAgICAgICBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50KHN0YXRlLnRlc3REZXNjcmlwdGlvbiksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRlY2lzaW9uKSB7XG4gICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICAgICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgICAgIC8vIFNlbmQgbWVzc2FnZSB0byBMTE0gYWJvdXQgdGhlIGRlY2lzaW9uXG4gICAgICAgICAgcGkuc2VuZE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgICAgICAgYPCflIAgKipSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOioqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCR7YXBwbHlSZXN1bHQubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgQ3VycmVudCBwaGFzZTogKipSRUQqKiDigJQgV3JpdGUgdGhlIG5leHQgZmFpbGluZyB0ZXN0LlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIChzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uXG4gICAgICAgICAgICAgICAgICA/IGAqKkN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbjoqKlxcblxcYFxcYFxcYFxcbiR7c3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbn1cXG5cXGBcXGBcXGBcXG5cXG5gXG4gICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICBndWlkZWxpbmVzTWVzc2FnZSgpLFxuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgdHJpZ2dlclR1cm46IHRydWUgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IGFwcGx5UmVzdWx0Lm1lc3NhZ2UgPz8gXCJSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZGVjaXNpb24sXG4gICAgICAgICAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIERldmVsb3BlciBjYW5jZWxsZWQg4oCUIHN0YXkgaW4gUkVGQUNUT1JcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogXCJEZXZlbG9wZXIgY2FuY2VsbGVkLiBTdGF5aW5nIGluIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gTm9uLVRVSSBtb2RlOiBqdXN0IHRyYW5zaXRpb25cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zaXRpb24ubWVzc2FnZSA/PyBcIkVudGVyZWQgUkVGQUNUT1IgcGhhc2UuXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczogeyBwaGFzZTogdHJhbnNpdGlvbi5zdGF0ZS5waGFzZSB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoX2FyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJnby10by1yZWZhY3RvclwiKSksIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGhhc2U/OiBzdHJpbmc7IGRlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbiB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICBjb25zdCB0ZXh0ID0gZGV0YWlscy5kZWNpc2lvblxuICAgICAgICA/IGAke3BoYXNlfSBSZWZhY3RvcmVkOiAke2RldGFpbHMuZGVjaXNpb24uZm9jdXN9YFxuICAgICAgICA6IGAke3BoYXNlfSBFbnRlcmVkIHJlZmFjdG9yIHBoYXNlYDtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgVG9vbDogcnVuLXRlc3RzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJydW4tdGVzdHNcIixcbiAgICBsYWJlbDogXCJSdW4gVGVzdHNcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHdpdGhvdXQgcGhhc2UgdHJhbnNpdGlvbi4gVXNlZnVsIGZvciBjaGVja2luZyB0ZXN0IHN0YXR1cyBcIiArXG4gICAgICBcImR1cmluZyBkZXZlbG9wbWVudC4gUmV0dXJucyBleGl0IGNvZGUgYW5kIG91dHB1dC5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICBjb21tYW5kOiBUeXBlLk9wdGlvbmFsKFxuICAgICAgICBUeXBlLlN0cmluZyh7XG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiQ3VzdG9tIHRlc3QgY29tbWFuZCB0byBydW4gKGRlZmF1bHQ6ICducG0gdGVzdCcpLlwiLFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgfSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBzaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCBjb21tYW5kID0gcGFyYW1zLmNvbW1hbmQgPz8gXCJucG0gdGVzdFwiO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgY29tbWFuZF0sIHtcbiAgICAgICAgc2lnbmFsLFxuICAgICAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcGFzc2VkID0gcmVzdWx0LmNvZGUgPT09IDA7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgICAgdGhlbWUuZmcocGFzc2VkID8gXCJzdWNjZXNzXCIgOiBcImVycm9yXCIsIHBhc3NlZCA/IFwi4pyTIFRlc3RzIHBhc3NlZFwiIDogXCLinJcgVGVzdHMgZmFpbGVkXCIpLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3Bhc3NlZCA/IFwi4pyTXCIgOiBcIuKcl1wifSBUZXN0cyAke3Bhc3NlZCA/IFwicGFzc2VkXCIgOiBcImZhaWxlZFwifSAoZXhpdCBjb2RlOiAke3Jlc3VsdC5jb2RlfSlgLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICAgIHN0ZGVycjogcmVzdWx0LnN0ZGVyci5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInJ1bi10ZXN0cyBcIikpICsgKGFyZ3MuY29tbWFuZCA/IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy5jb21tYW5kKSA6IHRoZW1lLmZnKFwibXV0ZWRcIiwgXCJucG0gdGVzdFwiKSk7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwYXNzZWQ/OiBib29sZWFuIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIFwi4pyTIFRlc3RzIHBhc3NlZFwiKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgXCLinJcgVGVzdHMgZmFpbGVkXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHRkZC1zdGF0dXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcInRkZC1zdGF0dXNcIixcbiAgICBsYWJlbDogXCJUREQgU3RhdHVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlNob3cgY3VycmVudCBUREQgY3ljbGUgcGhhc2UgYW5kIHN0YXRlLiBSZXR1cm5zIHRoZSBjdXJyZW50IHBoYXNlLCBcIiArXG4gICAgICBcInRlc3QgY291bnQsIGFuZCBndWlkZWxpbmVzIGZvciB3aGF0IHRvIGRvIG5leHQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbiAgICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgICAgY29uc3QgdGVzdHNXcml0dGVuID0gc3RhdGUudGVzdHNXcml0dGVuID8/IDA7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzKSxcbiAgICAgICAgdGhlbWUuZmcoXCJkaW1cIiwgYFRlc3RzIHdyaXR0ZW46ICR7dGVzdHNXcml0dGVufWApLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3N0YXR1c31cXG5cXG5UZXN0cyB3cml0dGVuOiAke3Rlc3RzV3JpdHRlbn1cXG5cXG4ke2d1aWRlbGluZXN9YCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGhhc2U6IHN0YXRlLnBoYXNlLFxuICAgICAgICAgIHRlc3RzUmFuOiBzdGF0ZS50ZXN0c1JhbixcbiAgICAgICAgICB0ZXN0c1Bhc3NlZDogc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgICAgICAgdGVzdHNXcml0dGVuLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoX2FyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJ0ZGQtc3RhdHVzXCIpKSwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwaGFzZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICByZXR1cm4gbmV3IFRleHQoYCR7cGhhc2V9ICR7ZGV0YWlscy5waGFzZX1gLCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgRXZlbnRzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8vIFJlc3RvcmUgc3RhdGUgb24gc2Vzc2lvbiBzdGFydFxuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICB0aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgIF0pO1xuXG4gICAgLy8gSW5qZWN0IHBoYXNlIGd1aWRlbGluZXMgaW50byBzeXN0ZW0gcHJvbXB0XG4gICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiKSB7XG4gICAgICBjdHgudWkubm90aWZ5KGBUREQgQ3ljbGUgc3RhcnRlZCBpbiAke3N0YXRlLnBoYXNlfSBwaGFzZWAsIFwiaW5mb1wiKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEJsb2NrIGRpcmVjdCBSRUQg4oaSIFJFRkFDVE9SIHRyYW5zaXRpb25zXG4gIHBpLm9uKFwidG9vbF9jYWxsXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gICAgaWYgKHN0YXRlLnBoYXNlID09PSBcIlJFRFwiICYmIGV2ZW50LnRvb2xOYW1lID09PSBcImdvLXRvLXJlZmFjdG9yXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJsb2NrOiB0cnVlLFxuICAgICAgICByZWFzb246IGBDYW5ub3QgZ28gdG8gUkVGQUNUT1IgZnJvbSBSRUQgcGhhc2UuIFlvdSBtdXN0IGZpcnN0IG1ha2UgdGVzdHMgcGFzcyAoR1JFRU4gcGhhc2UpLiBDYWxsIGdvLXRvLWdyZWVuIGFmdGVyIHlvdXIgaW1wbGVtZW50YXRpb24gcGFzc2VzIHRoZSB0ZXN0LmAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRUZBQ1RPUlwiICYmIGV2ZW50LnRvb2xOYW1lID09PSBcImdvLXRvLWdyZWVuXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJsb2NrOiB0cnVlLFxuICAgICAgICByZWFzb246IGBDYW5ub3QgZ28gdG8gR1JFRU4gZnJvbSBSRUZBQ1RPUiBwaGFzZS4gQ29tcGxldGUgdGhlIHJlZmFjdG9yaW5nIGRlY2lzaW9uIGZpcnN0LmAsXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gSW5qZWN0IHBoYXNlIGd1aWRlbGluZXMgYmVmb3JlIGFnZW50IHN0YXJ0c1xuICBwaS5vbihcImJlZm9yZV9hZ2VudF9zdGFydFwiLCBhc3luYyAoZXZlbnQpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZToge1xuICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZS1ndWlkZWxpbmVzXCIsXG4gICAgICAgIGNvbnRlbnQ6IGBcXG5cXG5bVEREIENZQ0xFIC0gJHtzdGF0ZS5waGFzZX0gUEhBU0VdXFxuJHtndWlkZWxpbmVzTWVzc2FnZSgpfWAsXG4gICAgICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9O1xuICB9KTtcblxuICAvLyBVcGRhdGUgc3RhdHVzIG9uIHR1cm4gZW5kXG4gIHBpLm9uKFwidHVybl9lbmRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgdGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcbiAgfSk7XG5cbiAgLy8gU2F2ZSBzdGF0ZSBvbiBzaHV0ZG93blxuICBwaS5vbihcInNlc3Npb25fc2h1dGRvd25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIHBlcnNpc3RTdGF0ZSgpO1xuICB9KTtcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzODgwMjk1M319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjcxYWJmOTc1IiwicGFyZW50SWQiOiI3ZTVmNDkxOSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDE6MTguMzk1WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiSSBzZWUgdGhlIGlzc3Vlcy4gVGhlIGB0aGVtZWAgdmFyaWFibGUgaXMgdXNlZCBpbiBleGVjdXRlIGZ1bmN0aW9ucyBidXQgaXQncyBub3QgaW4gc2NvcGUgdGhlcmUgLSBpdCdzIG9ubHkgYXZhaWxhYmxlIGluIHJlbmRlckNhbGwvcmVuZGVyUmVzdWx0IGNhbGxiYWNrcy4gSSBuZWVkIHRvIHJlcGxhY2UgYHRoZW1lYCB3aXRoIGBjdHgudWkudGhlbWVgIGluIHRoZSBleGVjdXRlIGZ1bmN0aW9ucy4gQWxzbywgdGhlIHVudXNlZCBpbXBvcnQgYGlzVG9vbENhbGxFdmVudFR5cGVgIHNob3VsZCBiZSByZW1vdmVkLlxuXG5MZXQgbWUgcmV3cml0ZSB0aGUgZW50aXJlIGluZGV4LnRzIGZpbGUgdG8gZml4IGFsbCBpc3N1ZXMgYXQgb25jZS5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkxldCBtZSByZXdyaXRlIHRoZSBlbnRpcmUgaW5kZXgudHMgd2l0aCBhbGwgZml4ZXM6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJ4eU9CSGZDUWk1RjlwaFpJcEFZQ25qN2xRRW1GOTVMWSIsIm5hbWUiOiJ3cml0ZSIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwiY29udGVudCI6Ii8qKlxuICogVEREIEN5Y2xlIEV4dGVuc2lvblxuICpcbiAqIEVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgVEREIGN5Y2xlOlxuICogICDwn5S0IFJFRCAgICDihpIgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzc1xuICogICDwn5+iIEdSRUVOICDihpIgVGVzdHMgcGFzcywgcmVhZHkgZm9yIHJlZmFjdG9yaW5nXG4gKiAgIPCflIAgUkVGQUNUT1Ig4oaSIERldmVsb3BlciBjaG9vc2VzIHdoYXQgdG8gcmVmYWN0b3JcbiAqXG4gKiBBZnRlciByZWZhY3RvcmluZywgdGhlIGN5Y2xlIHJlcGVhdHM6IGJhY2sgdG8gUkVEIGZvciB0aGUgbmV4dCB0ZXN0LlxuICpcbiAqIFRvb2xzOlxuICogICBnby10by1ncmVlbiAgICAgLSBSdW4gdGVzdHMgYW5kIHRyYW5zaXRpb24gYmFzZWQgb24gcmVzdWx0XG4gKiAgIGdvLXRvLXJlZmFjdG9yICAtIEVudGVyIHRoZSBkZXZlbG9wZXIgZGVjaXNpb24gcGhhc2VcbiAqICAgcnVuLXRlc3RzICAgICAgIC0gUnVuIHRlc3RzIHdpdGhvdXQgcGhhc2UgdHJhbnNpdGlvblxuICogICB0ZGQtc3RhdHVzICAgICAgLSBTaG93IGN1cnJlbnQgcGhhc2UgYW5kIHN0YXRlXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEksIEV4dGVuc2lvbkNvbnRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxuaW1wb3J0IHtcbiAgY3JlYXRlSW5pdGlhbFN0YXRlLFxuICByZWNvcmRUZXN0UmVzdWx0LFxuICBncmVlblRvUmVmYWN0b3IsXG4gIGFwcGx5UmVmYWN0b3JEZWNpc2lvbixcbiAgcGhhc2VFbW9qaSxcbiAgcGhhc2VEZXNjcmlwdGlvbixcbiAgcGhhc2VHdWlkZWxpbmVzLFxuICB0eXBlIEN5Y2xlU3RhdGUsXG4gIHR5cGUgUmVmYWN0b3JEZWNpc2lvbixcbn0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQgfSBmcm9tIFwiLi91aS5qc1wiO1xuXG4vLyDilIDilIAgU3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmxldCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IGNyZWF0ZUluaXRpYWxTdGF0ZSgpO1xuXG5mdW5jdGlvbiBwZXJzaXN0U3RhdGUoKTogdm9pZCB7XG4gIHBpLmFwcGVuZEVudHJ5KFwidGRkLWN5Y2xlXCIsIHtcbiAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgdGVzdERlc2NyaXB0aW9uOiBzdGF0ZS50ZXN0RGVzY3JpcHRpb24sXG4gICAgdGVzdHNSYW46IHN0YXRlLnRlc3RzUmFuLFxuICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICB0ZXN0c1dyaXR0ZW46IHN0YXRlLnRlc3RzV3JpdHRlbixcbiAgICBsYXN0RGVjaXNpb246IHN0YXRlLmxhc3REZWNpc2lvbixcbiAgICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uOiBzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdG9yZVN0YXRlKGN0eDogRXh0ZW5zaW9uQ29udGV4dCk6IHZvaWQge1xuICBjb25zdCBlbnRyaWVzID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldEVudHJpZXMoKTtcbiAgY29uc3QgdGRkRW50cnkgPSBlbnRyaWVzXG4gICAgLmZpbHRlcihcbiAgICAgIChlOiB7IHR5cGU6IHN0cmluZzsgY3VzdG9tVHlwZT86IHN0cmluZyB9KSA9PlxuICAgICAgICBlLnR5cGUgPT09IFwiY3VzdG9tXCIgJiYgZS5jdXN0b21UeXBlID09PSBcInRkZC1jeWNsZVwiLFxuICAgIClcbiAgICAucG9wKCkgYXMgeyBkYXRhPzogUGFydGlhbDxDeWNsZVN0YXRlPiB9IHwgdW5kZWZpbmVkO1xuXG4gIGlmICh0ZGRFbnRyeT8uZGF0YSkge1xuICAgIHN0YXRlID0ge1xuICAgICAgLi4uY3JlYXRlSW5pdGlhbFN0YXRlKCksXG4gICAgICAuLi50ZGRFbnRyeS5kYXRhLFxuICAgIH07XG4gIH1cbn1cblxuLy8g4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIHN0YXR1c01lc3NhZ2UoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpO1xufVxuXG5mdW5jdGlvbiBndWlkZWxpbmVzTWVzc2FnZSgpOiBzdHJpbmcge1xuICByZXR1cm4gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbn1cblxuLy8g4pSA4pSAIEV4dGVuc2lvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdGRkQ3ljbGUocGk6IEV4dGVuc2lvbkFQSSk6IHZvaWQge1xuICAvLyDilIDilIAgVG9vbDogZ28tdG8tZ3JlZW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLWdyZWVuXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gR3JlZW5cIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHRvIHZlcmlmeSBpbXBsZW1lbnRhdGlvbi4gSWYgdGVzdHMgcGFzcywgdHJhbnNpdGlvbnMgdG8gR1JFRU4gcGhhc2UuIFwiICtcbiAgICAgIFwiSWYgdGVzdHMgZmFpbCwgc3RheXMgaW4gUkVEIHdpdGggZmVlZGJhY2suIFVzZSB0aGlzIGFmdGVyIHdyaXRpbmcgYSBmYWlsaW5nIHRlc3QgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbi5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICB0ZXN0RGVzY3JpcHRpb246IFR5cGUuT3B0aW9uYWwoXG4gICAgICAgIFR5cGUuU3RyaW5nKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiQnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0ZXN0KHMpIHRvIHJ1biAoZS5nLiwgJ3VzZXIgbG9naW4gdGVzdCcpLiBcIiArXG4gICAgICAgICAgICBcIlVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXCIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCB0ZXN0RGVzYyA9IHBhcmFtcy50ZXN0RGVzY3JpcHRpb24gPz8gc3RhdGUudGVzdERlc2NyaXB0aW9uO1xuXG4gICAgICAvLyBVcGRhdGUgdGVzdCBkZXNjcmlwdGlvbiBpZiBwcm92aWRlZFxuICAgICAgaWYgKHRlc3REZXNjKSB7XG4gICAgICAgIHN0YXRlLnRlc3REZXNjcmlwdGlvbiA9IHRlc3REZXNjO1xuICAgICAgfVxuXG4gICAgICAvLyBTaG93IHN0YXR1c1xuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBSdW4gdGVzdHMgdmlhIGJhc2hcbiAgICAgIGNvbnN0IHRlc3RDb21tYW5kID0gXCJucG0gdGVzdCAyPiYxXCI7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCB0ZXN0Q29tbWFuZF0sIHtcbiAgICAgICAgc2lnbmFsOiBjdHguc2lnbmFsLFxuICAgICAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcGFzc2VkID0gcmVzdWx0LmNvZGUgPT09IDA7XG5cbiAgICAgIC8vIFJlY29yZCByZXN1bHQgYW5kIGdldCB0cmFuc2l0aW9uXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcblxuICAgICAgLy8gVXBkYXRlIHdpZGdldFxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBJZiB0cmFuc2l0aW9uZWQgdG8gR1JFRU4sIG5vdGlmeSBkZXZlbG9wZXJcbiAgICAgIGlmICh0cmFuc2l0aW9uLnN0YXRlLnBoYXNlID09PSBcIkdSRUVOXCIpIHtcbiAgICAgICAgcGkuc2VuZE1lc3NhZ2UoXG4gICAgICAgICAge1xuICAgICAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGVcIixcbiAgICAgICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgICAgIGDwn5+iICoqR1JFRU4gUEhBU0UgQUNISUVWRUQhKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYCR7dHJhbnNpdGlvbi5tZXNzYWdlfVxcblxcbmAgK1xuICAgICAgICAgICAgICBgVGhlIGRldmVsb3BlciBtdXN0IG5vdyBkZWNpZGUgd2hhdCB0byByZWZhY3Rvci5cXG5gICtcbiAgICAgICAgICAgICAgYFVzZSAqKmdvLXRvLXJlZmFjdG9yKiogdG8gZW50ZXIgdGhlIHJlZmFjdG9yaW5nIGRlY2lzaW9uIHBoYXNlLmAsXG4gICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyB0cmlnZ2VyVHVybjogZmFsc2UgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zaXRpb24ubWVzc2FnZSA/PyBcIlRlc3RzIGV4ZWN1dGVkLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcImdvLXRvLWdyZWVuIFwiKSkgKyAoYXJncy50ZXN0RGVzY3JpcHRpb24gPyB0aGVtZS5mZyhcIm11dGVkXCIsIGFyZ3MudGVzdERlc2NyaXB0aW9uKSA6IFwiXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGFzc2VkPzogYm9vbGVhbjsgcGhhc2U/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3Qgc3RhdHVzID0gZGV0YWlscy5wYXNzZWRcbiAgICAgICAgPyB0aGVtZS5mZyhcInN1Y2Nlc3NcIiwgYCR7cGhhc2V9IFRlc3RzIHBhc3NlZGApXG4gICAgICAgIDogdGhlbWUuZmcoXCJlcnJvclwiLCBgJHtwaGFzZX0gVGVzdHMgZmFpbGVkYCk7XG4gICAgICByZXR1cm4gbmV3IFRleHQoc3RhdHVzLCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgVG9vbDogZ28tdG8tcmVmYWN0b3Ig4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLXJlZmFjdG9yXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gUmVmYWN0b3JcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiRW50ZXIgdGhlIFJFRkFDVE9SIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIHdpbGwgYmUgcHJvbXB0ZWQgdG8gY2hvb3NlIFwiICtcbiAgICAgIFwid2hhdCB0byByZWZhY3RvcjogdGVzdHMsIGltcGxlbWVudGF0aW9uLCBuZXh0IHRlc3QsIG9yIGN1c3RvbSBpbnN0cnVjdGlvbi4gXCIgK1xuICAgICAgXCJPbmx5IGNhbGwgdGhpcyB3aGVuIHRlc3RzIGFyZSBwYXNzaW5nIChHUkVFTiBwaGFzZSkuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGBDYW5ub3QgZW50ZXIgUkVGQUNUT1IgZnJvbSBwaGFzZSAke3N0YXRlLnBoYXNlfS4gTXVzdCBiZSBpbiBHUkVFTiBwaGFzZSAodGVzdHMgcGFzc2luZykuYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBUcmFuc2l0aW9uIHRvIFJFRkFDVE9SXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKTtcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAvLyBTaG93IHN0YXR1cyB3aWRnZXRcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgLy8gU2hvdyBkZXZlbG9wZXIgZGVjaXNpb24gcHJvbXB0XG4gICAgICBpZiAoY3R4Lm1vZGUgPT09IFwidHVpXCIgJiYgY3R4Lmhhc1VJKSB7XG4gICAgICAgIGNvbnN0IGRlY2lzaW9uID0gYXdhaXQgY3R4LnVpLmN1c3RvbTxSZWZhY3RvckRlY2lzaW9uIHwgbnVsbD4oXG4gICAgICAgICAgY3JlYXRlUmVmYWN0b3JEZWNpc2lvbkNvbXBvbmVudChzdGF0ZS50ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChkZWNpc2lvbikge1xuICAgICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgICAgICAvLyBTZW5kIG1lc3NhZ2UgdG8gTExNIGFib3V0IHRoZSBkZWNpc2lvblxuICAgICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICAgIGDwn5SAICoqUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZDoqKlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGAke2FwcGx5UmVzdWx0Lm1lc3NhZ2V9XFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYEN1cnJlbnQgcGhhc2U6ICoqUkVEKiog4oCUIFdyaXRlIHRoZSBuZXh0IGZhaWxpbmcgdGVzdC5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICAoc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvblxuICAgICAgICAgICAgICAgICAgPyBgKipDdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb246KipcXG5cXGBcXGBcXGBcXG4ke3N0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb259XFxuXFxgXFxgXFxgXFxuXFxuYFxuICAgICAgICAgICAgICAgICAgOiBcIlwiKSArXG4gICAgICAgICAgICAgICAgZ3VpZGVsaW5lc01lc3NhZ2UoKSxcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IHRyaWdnZXJUdXJuOiB0cnVlIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBhcHBseVJlc3VsdC5tZXNzYWdlID8/IFwiUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZC5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICAgIGRlY2lzaW9uLFxuICAgICAgICAgICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXZlbG9wZXIgY2FuY2VsbGVkIOKAlCBzdGF5IGluIFJFRkFDVE9SXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IFwiRGV2ZWxvcGVyIGNhbmNlbGxlZC4gU3RheWluZyBpbiBSRUZBQ1RPUiBwaGFzZS5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE5vbi1UVUkgbW9kZToganVzdCB0cmFuc2l0aW9uXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJFbnRlcmVkIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwiZ28tdG8tcmVmYWN0b3JcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nOyBkZWNpc2lvbj86IFJlZmFjdG9yRGVjaXNpb24gfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3QgdGV4dCA9IGRldGFpbHMuZGVjaXNpb25cbiAgICAgICAgPyBgJHtwaGFzZX0gUmVmYWN0b3JlZDogJHtkZXRhaWxzLmRlY2lzaW9uLmZvY3VzfWBcbiAgICAgICAgOiBgJHtwaGFzZX0gRW50ZXJlZCByZWZhY3RvciBwaGFzZWA7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHJ1bi10ZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwicnVuLXRlc3RzXCIsXG4gICAgbGFiZWw6IFwiUnVuIFRlc3RzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb24uIFVzZWZ1bCBmb3IgY2hlY2tpbmcgdGVzdCBzdGF0dXMgXCIgK1xuICAgICAgXCJkdXJpbmcgZGV2ZWxvcG1lbnQuIFJldHVybnMgZXhpdCBjb2RlIGFuZCBvdXRwdXQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgY29tbWFuZDogVHlwZS5PcHRpb25hbChcbiAgICAgICAgVHlwZS5TdHJpbmcoe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkN1c3RvbSB0ZXN0IGNvbW1hbmQgdG8gcnVuIChkZWZhdWx0OiAnbnBtIHRlc3QnKS5cIixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH0pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIGNvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgICBjdHgudWkudGhlbWUuZmcocGFzc2VkID8gXCJzdWNjZXNzXCIgOiBcImVycm9yXCIsIHBhc3NlZCA/IFwi4pyTIFRlc3RzIHBhc3NlZFwiIDogXCLinJcgVGVzdHMgZmFpbGVkXCIpLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3Bhc3NlZCA/IFwi4pyTXCIgOiBcIuKcl1wifSBUZXN0cyAke3Bhc3NlZCA/IFwicGFzc2VkXCIgOiBcImZhaWxlZFwifSAoZXhpdCBjb2RlOiAke3Jlc3VsdC5jb2RlfSlgLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICAgIHN0ZGVycjogcmVzdWx0LnN0ZGVyci5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInJ1bi10ZXN0cyBcIikpICsgKGFyZ3MuY29tbWFuZCA/IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy5jb21tYW5kKSA6IHRoZW1lLmZnKFwibXV0ZWRcIiwgXCJucG0gdGVzdFwiKSk7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwYXNzZWQ/OiBib29sZWFuIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIFwi4pyTIFRlc3RzIHBhc3NlZFwiKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgXCLinJcgVGVzdHMgZmFpbGVkXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHRkZC1zdGF0dXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcInRkZC1zdGF0dXNcIixcbiAgICBsYWJlbDogXCJUREQgU3RhdHVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlNob3cgY3VycmVudCBUREQgY3ljbGUgcGhhc2UgYW5kIHN0YXRlLiBSZXR1cm5zIHRoZSBjdXJyZW50IHBoYXNlLCBcIiArXG4gICAgICBcInRlc3QgY291bnQsIGFuZCBndWlkZWxpbmVzIGZvciB3aGF0IHRvIGRvIG5leHQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbiAgICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgICAgY29uc3QgdGVzdHNXcml0dGVuID0gc3RhdGUudGVzdHNXcml0dGVuID8/IDA7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1cyksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImRpbVwiLCBgVGVzdHMgd3JpdHRlbjogJHt0ZXN0c1dyaXR0ZW59YCksXG4gICAgICBdKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7c3RhdHVzfVxcblxcblRlc3RzIHdyaXR0ZW46ICR7dGVzdHNXcml0dGVufVxcblxcbiR7Z3VpZGVsaW5lc31gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgICAgICAgdGVzdHNSYW46IHN0YXRlLnRlc3RzUmFuLFxuICAgICAgICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICAgICAgICB0ZXN0c1dyaXR0ZW4sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChfYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInRkZC1zdGF0dXNcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIHJldHVybiBuZXcgVGV4dChgJHtwaGFzZX0gJHtkZXRhaWxzLnBoYXNlfWAsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBFdmVudHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLy8gUmVzdG9yZSBzdGF0ZSBvbiBzZXNzaW9uIHN0YXJ0XG4gIHBpLm9uKFwic2Vzc2lvbl9zdGFydFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgIF0pO1xuXG4gICAgLy8gSW5qZWN0IHBoYXNlIGd1aWRlbGluZXMgaW50byBzeXN0ZW0gcHJvbXB0XG4gICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiKSB7XG4gICAgICBjdHgudWkubm90aWZ5KGBUREQgQ3ljbGUgc3RhcnRlZCBpbiAke3N0YXRlLnBoYXNlfSBwaGFzZWAsIFwiaW5mb1wiKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEJsb2NrIGRpcmVjdCBSRUQg4oaSIFJFRkFDVE9SIHRyYW5zaXRpb25zXG4gIHBpLm9uKFwidG9vbF9jYWxsXCIsIGFzeW5jIChldmVudCwgY3R4KSA9PiB7XG4gICAgaWYgKHN0YXRlLnBoYXNlID09PSBcIlJFRFwiICYmIGV2ZW50LnRvb2xOYW1lID09PSBcImdvLXRvLXJlZmFjdG9yXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJsb2NrOiB0cnVlLFxuICAgICAgICByZWFzb246IGBDYW5ub3QgZ28gdG8gUkVGQUNUT1IgZnJvbSBSRUQgcGhhc2UuIFlvdSBtdXN0IGZpcnN0IG1ha2UgdGVzdHMgcGFzcyAoR1JFRU4gcGhhc2UpLiBDYWxsIGdvLXRvLWdyZWVuIGFmdGVyIHlvdXIgaW1wbGVtZW50YXRpb24gcGFzc2VzIHRoZSB0ZXN0LmAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRUZBQ1RPUlwiICYmIGV2ZW50LnRvb2xOYW1lID09PSBcImdvLXRvLWdyZWVuXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJsb2NrOiB0cnVlLFxuICAgICAgICByZWFzb246IGBDYW5ub3QgZ28gdG8gR1JFRU4gZnJvbSBSRUZBQ1RPUiBwaGFzZS4gQ29tcGxldGUgdGhlIHJlZmFjdG9yaW5nIGRlY2lzaW9uIGZpcnN0LmAsXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gSW5qZWN0IHBoYXNlIGd1aWRlbGluZXMgYmVmb3JlIGFnZW50IHN0YXJ0c1xuICBwaS5vbihcImJlZm9yZV9hZ2VudF9zdGFydFwiLCBhc3luYyAoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGUtZ3VpZGVsaW5lc1wiLFxuICAgICAgICBjb250ZW50OiBgXFxuXFxuW1RERCBDWUNMRSAtICR7c3RhdGUucGhhc2V9IFBIQVNFXVxcbiR7Z3VpZGVsaW5lc01lc3NhZ2UoKX1gLFxuICAgICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gVXBkYXRlIHN0YXR1cyBvbiB0dXJuIGVuZFxuICBwaS5vbihcInR1cm5fZW5kXCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgIF0pO1xuICB9KTtcblxuICAvLyBTYXZlIHN0YXRlIG9uIHNodXRkb3duXG4gIHBpLm9uKFwic2Vzc2lvbl9zaHV0ZG93blwiLCBhc3luYyAoKSA9PiB7XG4gICAgcGVyc2lzdFN0YXRlKCk7XG4gIH0pO1xufVxuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjozODU0LCJvdXRwdXQiOjM5NzYsImNhY2hlUmVhZCI6NTg0NzcsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo2NjMwNywiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4ODAyOTU0LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtc0JvVjY5cVJlRHZVV0Y5T3J6N3Z0eUk4T0dWSXJ5ZXMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNDBlYzdiMGQiLCJwYXJlbnRJZCI6IjcxYWJmOTc1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowMToxOC40MTBaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJ4eU9CSGZDUWk1RjlwaFpJcEFZQ25qN2xRRW1GOTVMWSIsInRvb2xOYW1lIjoid3JpdGUiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgd3JvdGUgMTQ0NzEgYnl0ZXMgdG8gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM4ODc4NDEwfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZTA2Y2FmYjMiLCJwYXJlbnRJZCI6IjQwZWM3YjBkIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowMTozNy43MDJaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJOb3cgbGV0IG1lIGluc3RhbGwgZGVwZW5kZW5jaWVzIGFuZCBydW4gdGhlIHRlc3RzIHRvIG1ha2Ugc3VyZSBldmVyeXRoaW5nIHdvcmtzOlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IGxldCBtZSBpbnN0YWxsIGRlcGVuZGVuY2llcyBhbmQgcnVuIHRoZSB0ZXN0czpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6InZiS0VjYkRTQ2pxWVAxRnlqTnF5b2hiV2wwU09kdE9qIiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlICYmIG5wbSBpbnN0YWxsIDI+JjEiLCJ0aW1lb3V0IjozMH19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0Ijo0MDIzLCJvdXRwdXQiOjkwLCJjYWNoZVJlYWQiOjYyMzI3LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6NjY0NDAsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODg3ODQxMSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLXk2Z09QNzhUcWljcFNXcDJJdjVIRk9yM3lKNHNMY0c0In19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijk5OGI1NjA1IiwicGFyZW50SWQiOiJlMDZjYWZiMyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDE6MzguNDM0WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoidmJLRWNiRFNDanFZUDFGeWpOcXlvaGJXbDBTT2R0T2oiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJucG0gd2FybiBFUkVTT0xWRSBvdmVycmlkaW5nIHBlZXIgZGVwZW5kZW5jeVxubnBtIHdhcm4gV2hpbGUgcmVzb2x2aW5nOiBwaS10ZGQtY3ljbGVAMC4xLjBcbm5wbSB3YXJuIEZvdW5kOiBAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50QHVuZGVmaW5lZFxubnBtIHdhcm4gbm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcbm5wbSB3YXJuICAgcGVlciBAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50QFwiPj0xLjAuMFwiIGZyb20gdGhlIHJvb3QgcHJvamVjdFxubnBtIHdhcm5cbm5wbSB3YXJuIENvdWxkIG5vdCByZXNvbHZlIGRlcGVuZGVuY3k6XG5ucG0gd2FybiBwZWVyIEBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRAXCI+PTEuMC4wXCIgZnJvbSB0aGUgcm9vdCBwcm9qZWN0XG5ucG0gZXJyb3IgY29kZSBFUEVSTVxubnBtIGVycm9yIHN5c2NhbGwgbWtkaXJcbm5wbSBlcnJvciBwYXRoIC9Vc2Vycy93aWxsZW0vLm5wbS9fY2FjYWNoZS90bXBcbm5wbSBlcnJvciBlcnJubyBFUEVSTVxubnBtIGVycm9yXG5ucG0gZXJyb3IgWW91ciBjYWNoZSBmb2xkZXIgY29udGFpbnMgcm9vdC1vd25lZCBmaWxlcywgZHVlIHRvIGEgYnVnIGluIHByZXZpb3VzIHZlcnNpb25zIG9mIG5wbSB3aGljaCBoYXMgc2luY2UgYmVlbiBhZGRyZXNzZWQuXG5ucG0gZXJyb3Jcbm5wbSBlcnJvciBUbyBwZXJtYW5lbnRseSBmaXggdGhpcyBwcm9ibGVtLCBwbGVhc2UgcnVuOlxubnBtIGVycm9yICAgc3VkbyBjaG93biAtUiA1MDE6MjAgXCIvVXNlcnMvd2lsbGVtLy5ucG1cIlxubnBtIGVycm9yIExvZyBmaWxlcyB3ZXJlIG5vdCB3cml0dGVuIGR1ZSB0byBhbiBlcnJvciB3cml0aW5nIHRvIHRoZSBkaXJlY3Rvcnk6IC9Vc2Vycy93aWxsZW0vLm5wbS9fbG9nc1xubnBtIGVycm9yIFlvdSBjYW4gcmVydW4gdGhlIGNvbW1hbmQgd2l0aCBgLS1sb2dsZXZlbD12ZXJib3NlYCB0byBzZWUgdGhlIGxvZ3MgaW4geW91ciB0ZXJtaW5hbFxuXG5cbkNvbW1hbmQgZXhpdGVkIHdpdGggY29kZSAxIn1dLCJkZXRhaWxzIjp7fSwiaXNFcnJvciI6dHJ1ZSwidGltZXN0YW1wIjoxNzgxOTM4ODk4NDM0fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOTJkOTY2ODMiLCJwYXJlbnRJZCI6Ijk5OGI1NjA1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowMTo0My4xODVaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJQZXJtaXNzaW9uIGlzc3VlIHdpdGggbnBtIGNhY2hlLiBMZXQgbWUgZml4IGl0OlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJWeWQ0T2ZyM2VKanR5cHNUUjJ5ZWNIcXViQmlXNDlQVSIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJzdWRvIGNob3duIC1SIDUwMToyMCAvVXNlcnMvd2lsbGVtLy5ucG0gMj4mMSAmJiBjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBucG0gaW5zdGFsbCAyPiYxIiwidGltZW91dCI6MzB9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6Mjk3LCJvdXRwdXQiOjk5LCJjYWNoZVJlYWQiOjY2NDM5LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6NjY4MzUsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODg5ODQzNSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLWJ1Q2xKRm9YTDFncGRiZXYycXp3VFJGY2tYeTRUeGkwIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjA1N2M1ODY5IiwicGFyZW50SWQiOiI5MmQ5NjY4MyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDE6NDMuMTk3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiVnlkNE9mcjNlSmp0eXBzVFIyeWVjSHF1YkJpVzQ5UFUiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIvYmluL2Jhc2g6IC91c3IvYmluL3N1ZG86IE9wZXJhdGlvbiBub3QgcGVybWl0dGVkXG5cblxuQ29tbWFuZCBleGl0ZWQgd2l0aCBjb2RlIDEyNiJ9XSwiZGV0YWlscyI6e30sImlzRXJyb3IiOnRydWUsInRpbWVzdGFtcCI6MTc4MTkzODkwMzE5Nn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImI3MTEzYmE2IiwicGFyZW50SWQiOiIwNTdjNTg2OSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDE6NDcuOTEyWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiQ2FuJ3QgdXNlIHN1ZG8uIExldCBtZSB0cnkgYSBkaWZmZXJlbnQgYXBwcm9hY2ggLSBtYXliZSB1c2UgcG5wbSBzaW5jZSB0aGUgcHJvamVjdCBzcGVjaWZpZXMgcG5wbSBhcyB0aGUgcGFja2FnZSBtYW5hZ2VyOlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJMTnBHNE9BNFVENWp2aFFmWkVuS1ptc3NIUnlqVURhaCIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBucG0gaW5zdGFsbCAtLWNhY2hlIC90bXAvbnBtLWNhY2hlIDI+JjEiLCJ0aW1lb3V0IjozMH19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoxMzksIm91dHB1dCI6OTcsImNhY2hlUmVhZCI6NjY3MzIsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo2Njk2OCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM4OTAzMTk3LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtMWV4SmtySm50RjF1TTZ0czRzblJwQVFIMlpBazlJOGUifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiM2UyYmQ2NWUiLCJwYXJlbnRJZCI6ImI3MTEzYmE2IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowMTo0OC42ODhaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJMTnBHNE9BNFVENWp2aFFmWkVuS1ptc3NIUnlqVURhaCIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkNvbW1hbmQgYWJvcnRlZCJ9XSwiZGV0YWlscyI6e30sImlzRXJyb3IiOnRydWUsInRpbWVzdGFtcCI6MTc4MTkzODkwODY4OH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImI2NjZiNDg0IiwicGFyZW50SWQiOiIzZTJiZDY1ZSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDE6NDguNjkwWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJhYm9ydGVkIiwidGltZXN0YW1wIjoxNzgxOTM4OTA4Njg4LCJlcnJvck1lc3NhZ2UiOiJPcGVyYXRpb24gYWJvcnRlZCJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI0MWRkM2Q3NSIsInBhcmVudElkIjoiYjY2NmI0ODQiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjAyOjEzLjMyMloiLCJtZXNzYWdlIjp7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoid2hhdCBkZXBlbmRlbmNpZXMgZG8geW91IG5lZWQ/IEkgd2lsbCBpbnN0YWxsIHRoZW0gLSBlbnN1cmluZyB0aGUgbGF0ZXN0IHZlcnNpb25zLiJ9XSwidGltZXN0YW1wIjoxNzgxOTM4OTMzMzIwfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMzNiNmRiNzQiLCJwYXJlbnRJZCI6IjQxZGQzZDc1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowMjozMS4xODJaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgdXNlciB3YW50cyB0byBpbnN0YWxsIHRoZSBkZXBlbmRlbmNpZXMgbWFudWFsbHkuIExldCBtZSBmaWd1cmUgb3V0IHdoYXQncyBuZWVkZWQuIExvb2tpbmcgYXQgdGhlIHBhY2thZ2UuanNvbiwgdGhlIGRldkRlcGVuZGVuY2llcyBhcmU6XG4tIEB0eXBlcy9ub2RlXG4tIHR5cGVzY3JpcHRcbi0gdml0ZXN0XG5cbkFuZCB0aGUgcGVlckRlcGVuZGVuY3kgaXM6XG4tIEBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcblxuVGhlIGV4dGVuc2lvbiBhbHNvIGltcG9ydHMgZnJvbTpcbi0gdHlwZWJveFxuLSBAZWFyZW5kaWwtd29ya3MvcGktdHVpXG5cblRoZXNlIGFyZSBwcm92aWRlZCBieSB0aGUgcGktY29kaW5nLWFnZW50IHBhY2thZ2UsIGJ1dCBmb3IgdGhlIHRlc3RzICh3aGljaCBkb24ndCBpbXBvcnQgZnJvbSBwaS1jb2RpbmctYWdlbnQpLCB3ZSBqdXN0IG5lZWQgdGhlIGRldkRlcGVuZGVuY2llcy5cblxuTGV0IG1lIHVwZGF0ZSB0aGUgcGFja2FnZS5qc29uIHRvIGJlIGNsZWFuZXIgYW5kIGxpc3QgdGhlIGV4YWN0IGRlcGVuZGVuY2llcyBuZWVkZWQuXG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJUaGUgZXh0ZW5zaW9uIG5lZWRzIHRoZXNlOlxuXG4qKkRldiBkZXBlbmRlbmNpZXMqKiAoZm9yIGJ1aWxkaW5nICsgdGVzdGluZywgbm8gcGkgcmVxdWlyZWQpOlxuLSBgdHlwZXNjcmlwdGBcbi0gYHZpdGVzdGBcbi0gYEB0eXBlcy9ub2RlYFxuXG4qKlBlZXIgZGVwZW5kZW5jeSoqIChwcm92aWRlZCBieSBwaSBhdCBydW50aW1lKTpcbi0gYEBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRgICh3aGljaCB0cmFuc2l0aXZlbHkgcHJvdmlkZXMgYHR5cGVib3hgIGFuZCBgQGVhcmVuZGlsLXdvcmtzL3BpLXR1aWApXG5cblRoZSB0ZXN0IGZpbGVzIChgc3JjL3Rlc3Qvc3RhdGUudGVzdC50c2ApIG9ubHkgaW1wb3J0IGZyb20gYHZpdGVzdGAgYW5kIGAuLi9zdGF0ZS5qc2Ag4oCUIHRoZXkgZG9uJ3QgdG91Y2ggYW55IHBpIHBhY2thZ2VzLiBTbyB5b3UgY2FuIGluc3RhbGwganVzdCB0aGUgZGV2IGRlcHMgYW5kIHJ1biB0ZXN0cyB3aXRob3V0IHBpLlxuXG5MZXQgbWUgdXBkYXRlIHRoZSBwYWNrYWdlLmpzb24gdG8gYmUgY2xlYW5lcjpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6InBHZzBzSWRLWXBtd1hUd0xETUtTdVFsdGNTNEx0ajVPIiwibmFtZSI6IndyaXRlIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9wYWNrYWdlLmpzb24iLCJjb250ZW50Ijoie1xuICBcIm5hbWVcIjogXCJwaS10ZGQtY3ljbGVcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMC4xLjBcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIlBpIGV4dGVuc2lvbiB0aGF0IGVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgVEREIGN5Y2xlXCIsXG4gIFwidHlwZVwiOiBcIm1vZHVsZVwiLFxuICBcInByaXZhdGVcIjogdHJ1ZSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInRlc3RcIjogXCJ2aXRlc3QgcnVuXCIsXG4gICAgXCJ0ZXN0OndhdGNoXCI6IFwidml0ZXN0XCIsXG4gICAgXCJ0eXBlY2hlY2tcIjogXCJ0c2MgLS1ub0VtaXRcIlxuICB9LFxuICBcImtleXdvcmRzXCI6IFtcbiAgICBcInBpLXBhY2thZ2VcIixcbiAgICBcInRkZFwiLFxuICAgIFwicmVkLWdyZWVuLXJlZmFjdG9yXCIsXG4gICAgXCJleHRlbnNpb25cIlxuICBdLFxuICBcInBpXCI6IHtcbiAgICBcImV4dGVuc2lvbnNcIjogW1xuICAgICAgXCIuL3NyYy9pbmRleC50c1wiXG4gICAgXVxuICB9LFxuICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI6IFwibGF0ZXN0XCIsXG4gICAgXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI6IFwibGF0ZXN0XCIsXG4gICAgXCJAdHlwZXMvbm9kZVwiOiBcImxhdGVzdFwiLFxuICAgIFwidHlwZWJveFwiOiBcImxhdGVzdFwiLFxuICAgIFwidHlwZXNjcmlwdFwiOiBcImxhdGVzdFwiLFxuICAgIFwidml0ZXN0XCI6IFwibGF0ZXN0XCJcbiAgfVxufVxuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoyNzQsIm91dHB1dCI6NTcxLCJjYWNoZVJlYWQiOjY2NzMyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6Njc1NzcsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzODkzMzMyMywicmVzcG9uc2VJZCI6ImNoYXRjbXBsLURWSlZ3TnJtaWFYVWZOeUIzTGF5blFJV0cwQ3FaM0xzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjQwMTY1Mzc4IiwicGFyZW50SWQiOiIzM2I2ZGI3NCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDI6MzEuMTg0WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoicEdnMHNJZEtZcG13WFR3TERNS1N1UWx0Y1M0THRqNU8iLCJ0b29sTmFtZSI6IndyaXRlIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHdyb3RlIDY1NCBieXRlcyB0byAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9wYWNrYWdlLmpzb24ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5Mzg5NTExODR9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI2N2FiOTVkNCIsInBhcmVudElkIjoiNDAxNjUzNzgiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjAyOjM2LjU1OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkkndmUgYWRkZWQgdGhlIHBlZXIgZGVwcyBhcyBkZXZEZXBlbmRlbmNpZXMgdG9vIHNvIHRoZXkncmUgYXZhaWxhYmxlIGR1cmluZyBkZXZlbG9wbWVudC4gTGV0IG1lIHRlbGwgdGhlIHVzZXIgdGhlIGV4YWN0IGNvbW1hbmRzIHRvIHJ1bi5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlJ1biB0aGVzZTpcblxuYGBgYmFzaFxuY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGVcbm5wbSBpbnN0YWxsXG5ucG0gcnVuIHRlc3Rcbm5wbSBydW4gdHlwZWNoZWNrXG5gYGBcblxuSSBhZGRlZCBgQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudGAsIGBAZWFyZW5kaWwtd29ya3MvcGktdHVpYCwgYW5kIGB0eXBlYm94YCBhcyBkZXZEZXBlbmRlbmNpZXMgdG9vIChub3QganVzdCBwZWVyKSBzbyB0aGV5J3JlIGF2YWlsYWJsZSBmb3IgdGhlIFRTIGNvbXBpbGVyIGR1cmluZyBkZXZlbG9wbWVudC4gVGhlIHRlc3RzIHRoZW1zZWx2ZXMgKGBzdGF0ZS50ZXN0LnRzYCkgZG9uJ3QgaW1wb3J0IGFueSBwaSBwYWNrYWdlcyDigJQgdGhleSBvbmx5IHRlc3QgdGhlIHB1cmUgc3RhdGUgbWFjaGluZSBsb2dpYy4ifV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6NDEsIm91dHB1dCI6MTQ0LCJjYWNoZVJlYWQiOjY3NTc2LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6Njc3NjEsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoic3RvcCIsInRpbWVzdGFtcCI6MTc4MTkzODk1MTE4NSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLTQzbTE1Uk1kS1d0cFNEdlFLd245RlgzOWtXSUZrYUtWIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjdjZmVlZDE0IiwicGFyZW50SWQiOiI2N2FiOTVkNCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDY6MDYuNjk5WiIsIm1lc3NhZ2UiOnsicm9sZSI6InVzZXIiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJpbnN0YWxsIHdvcmtzLCBucG0gcnVuIHRlc3QgaGFzIGZhaWx1cmVzLCBhbmQgdGhlIHR5cGVjaGVjayBmYWlscyJ9XSwidGltZXN0YW1wIjoxNzgxOTM5MTY2Njk4fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNDI2MDU5NjYiLCJwYXJlbnRJZCI6IjdjZmVlZDE0IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowNjoxMC4xNDFaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJMZXQgbWUgc2VlIHdoYXQgdGhlIHRlc3QgZmFpbHVyZXMgYW5kIHR5cGVjaGVjayBlcnJvcnMgYXJlLlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiI5Z0VIRmpoMTB6dk1oWTRwZlpONDJyY0N1cWZGeE5rTyIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBucG0gcnVuIHRlc3QgMj4mMSJ9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoieFVxQk1nMXAxMkdWcnJKbUtLb0FuQWgwZ2Zxbm5JVW0iLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgbnBtIHJ1biB0eXBlY2hlY2sgMj4mMSJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MjYsIm91dHB1dCI6MTE1LCJjYWNoZVJlYWQiOjY3NzYwLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6Njc5MDEsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzOTE2NjcwMiwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLU5KQUtwcm9tdUh4T2p2T2RqV0NUOW54bXY5aGt0MWNwIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImViYTg4ZTNkIiwicGFyZW50SWQiOiI0MjYwNTk2NiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDY6MTEuNTA3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiOWdFSEZqaDEwenZNaFk0cGZaTjQycmNDdXFmRnhOa08iLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJcbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHRlc3Rcbj4gdml0ZXN0IHJ1blxuXG5cbiBSVU4gIHY0LjEuOSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZVxuXG4g4p2vIHNyYy90ZXN0L3N0YXRlLnRlc3QudHMgKDI5IHRlc3RzIHwgMiBmYWlsZWQpIDhtc1xuICAgICDDlyByZWNvcmRzIHBhc3NpbmcgdGVzdHMgaW4gUkVEIOKGkiBhdXRvLXRyYW5zaXRpb25zIHRvIEdSRUVOIDNtc1xuICAgICDDlyBkZXNjcmliZXMgUkVE4oaSR1JFRU4gd2hlbiB0ZXN0cyBwYXNzZWQgaW4gUkVEIDFtc1xuXG7ijq/ijq/ijq/ijq/ijq/ijq/ijq8gRmFpbGVkIFRlc3RzIDIg4o6v4o6v4o6v4o6v4o6v4o6v4o6vXG5cbiBGQUlMICBzcmMvdGVzdC9zdGF0ZS50ZXN0LnRzID4gcmVjb3JkVGVzdFJlc3VsdCA+IHJlY29yZHMgcGFzc2luZyB0ZXN0cyBpbiBSRUQg4oaSIGF1dG8tdHJhbnNpdGlvbnMgdG8gR1JFRU5cbkFzc2VydGlvbkVycm9yOiBleHBlY3RlZCBmYWxzZSB0byBiZSB0cnVlIC8vIE9iamVjdC5pcyBlcXVhbGl0eVxuXG4tIEV4cGVjdGVkXG4rIFJlY2VpdmVkXG5cbi0gdHJ1ZVxuKyBmYWxzZVxuXG4g4p2vIHNyYy90ZXN0L3N0YXRlLnRlc3QudHM6MTMwOjM1XG4gICAgMTI4fCAgICAgY29uc3QgcmVzdWx0ID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgdHJ1ZSk7XG4gICAgMTI5fCAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICAxMzB8ICAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzUmFuKS50b0JlKHRydWUpO1xuICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF5cbiAgICAxMzF8ICAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzUGFzc2VkKS50b0JlKHRydWUpO1xuICAgIDEzMnwgICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJHUkVFTlwiKTtcblxu4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6vWzEvMl3ijq9cblxuIEZBSUwgIHNyYy90ZXN0L3N0YXRlLnRlc3QudHMgPiBwaGFzZURlc2NyaXB0aW9uID4gZGVzY3JpYmVzIFJFROKGkkdSRUVOIHdoZW4gdGVzdHMgcGFzc2VkIGluIFJFRFxuQXNzZXJ0aW9uRXJyb3I6IGV4cGVjdGVkICfwn5S0IFJFRCDihpIgR1JFRU4g4oCUIFRlc3RzIHBhc3NlZCEgUmVhZHkg4oCmJyB0byBjb250YWluICdSRUTihpJHUkVFTidcblxuRXhwZWN0ZWQ6IFwiUkVE4oaSR1JFRU5cIlxuUmVjZWl2ZWQ6IFwi8J+UtCBSRUQg4oaSIEdSRUVOIOKAlCBUZXN0cyBwYXNzZWQhIFJlYWR5IGZvciByZWZhY3RvcmluZy5cIlxuXG4g4p2vIHNyYy90ZXN0L3N0YXRlLnRlc3QudHM6MjM3OjM3XG4gICAgMjM1fCAgICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICAyMzZ8ICAgICB9O1xuICAgIDIzN3wgICAgIGV4cGVjdChwaGFzZURlc2NyaXB0aW9uKHN0YXRlKSkudG9Db250YWluKFwiUkVE4oaSR1JFRU5cIik7XG4gICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBeXG4gICAgMjM4fCAgIH0pO1xuICAgIDIzOXxcblxu4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6v4o6vWzIvMl3ijq9cblxuXG4gVGVzdCBGaWxlcyAgMSBmYWlsZWQgKDEpXG4gICAgICBUZXN0cyAgMiBmYWlsZWQgfCAyNyBwYXNzZWQgKDI5KVxuICAgU3RhcnQgYXQgIDA4OjA2OjEwXG4gICBEdXJhdGlvbiAgMTI0bXMgKHRyYW5zZm9ybSAyMm1zLCBzZXR1cCAwbXMsIGltcG9ydCAyOW1zLCB0ZXN0cyA4bXMsIGVudmlyb25tZW50IDBtcylcblxuXG5cbkNvbW1hbmQgZXhpdGVkIHdpdGggY29kZSAxIn1dLCJkZXRhaWxzIjp7fSwiaXNFcnJvciI6dHJ1ZSwidGltZXN0YW1wIjoxNzgxOTM5MTcxNTA3fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDE1YzUyYWQiLCJwYXJlbnRJZCI6ImViYTg4ZTNkIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowNjoxMS41MDhaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJ4VXFCTWcxcDEyR1ZyckptS0tvQW5BaDBnZnFubklVbSIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlxuPiBwaS10ZGQtY3ljbGVAMC4xLjAgdHlwZWNoZWNrXG4+IHRzYyAtLW5vRW1pdFxuXG5zcmMvaW5kZXgudHMoNDAsMyk6IGVycm9yIFRTMjMwNDogQ2Fubm90IGZpbmQgbmFtZSAncGknLlxuc3JjL3Rlc3Qvc3RhdGUudGVzdC50cyg0MywxMSk6IGVycm9yIFRTMjc0MTogUHJvcGVydHkgJ3Rlc3RzV3JpdHRlbicgaXMgbWlzc2luZyBpbiB0eXBlICd7IHBoYXNlOiBcIlJFRFwiOyB0ZXN0c1JhbjogZmFsc2U7IHRlc3RzUGFzc2VkOiBmYWxzZTsgfScgYnV0IHJlcXVpcmVkIGluIHR5cGUgJ0N5Y2xlU3RhdGUnLlxuc3JjL3Rlc3Qvc3RhdGUudGVzdC50cyg1NCwxMSk6IGVycm9yIFRTMjc0MTogUHJvcGVydHkgJ3Rlc3RzV3JpdHRlbicgaXMgbWlzc2luZyBpbiB0eXBlICd7IHBoYXNlOiBcIlJFRFwiOyB0ZXN0c1JhbjogdHJ1ZTsgdGVzdHNQYXNzZWQ6IGZhbHNlOyB9JyBidXQgcmVxdWlyZWQgaW4gdHlwZSAnQ3ljbGVTdGF0ZScuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDY3LDExKTogZXJyb3IgVFMyNzM5OiBUeXBlICd7IHBoYXNlOiBcIkdSRUVOXCI7IH0nIGlzIG1pc3NpbmcgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdHlwZSAnQ3ljbGVTdGF0ZSc6IHRlc3RzUmFuLCB0ZXN0c1Bhc3NlZCwgdGVzdHNXcml0dGVuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDc3LDExKTogZXJyb3IgVFMyNzM5OiBUeXBlICd7IHBoYXNlOiBcIlJFRkFDVE9SXCI7IHRlc3RzV3JpdHRlbjogbnVtYmVyOyB9JyBpcyBtaXNzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHR5cGUgJ0N5Y2xlU3RhdGUnOiB0ZXN0c1JhbiwgdGVzdHNQYXNzZWRcbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoODYsMTEpOiBlcnJvciBUUzI3Mzk6IFR5cGUgJ3sgcGhhc2U6IFwiUkVGQUNUT1JcIjsgfScgaXMgbWlzc2luZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgZnJvbSB0eXBlICdDeWNsZVN0YXRlJzogdGVzdHNSYW4sIHRlc3RzUGFzc2VkLCB0ZXN0c1dyaXR0ZW5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoOTQsMTEpOiBlcnJvciBUUzI3Mzk6IFR5cGUgJ3sgcGhhc2U6IFwiUkVGQUNUT1JcIjsgdGVzdHNXcml0dGVuOiBudW1iZXI7IH0nIGlzIG1pc3NpbmcgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdHlwZSAnQ3ljbGVTdGF0ZSc6IHRlc3RzUmFuLCB0ZXN0c1Bhc3NlZFxuc3JjL3Rlc3Qvc3RhdGUudGVzdC50cygxMDEsMTEpOiBlcnJvciBUUzI3Mzk6IFR5cGUgJ3sgcGhhc2U6IFwiUkVGQUNUT1JcIjsgfScgaXMgbWlzc2luZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgZnJvbSB0eXBlICdDeWNsZVN0YXRlJzogdGVzdHNSYW4sIHRlc3RzUGFzc2VkLCB0ZXN0c1dyaXR0ZW5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMTEzLDExKTogZXJyb3IgVFMyNzQxOiBQcm9wZXJ0eSAndGVzdHNXcml0dGVuJyBpcyBtaXNzaW5nIGluIHR5cGUgJ3sgcGhhc2U6IFwiUkVGQUNUT1JcIjsgdGVzdHNSYW46IHRydWU7IHRlc3RzUGFzc2VkOiB0cnVlOyB9JyBidXQgcmVxdWlyZWQgaW4gdHlwZSAnQ3ljbGVTdGF0ZScuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDEyNywxMSk6IGVycm9yIFRTMjc0MTogUHJvcGVydHkgJ3Rlc3RzV3JpdHRlbicgaXMgbWlzc2luZyBpbiB0eXBlICd7IHBoYXNlOiBcIlJFRFwiOyB0ZXN0c1JhbjogZmFsc2U7IHRlc3RzUGFzc2VkOiBmYWxzZTsgfScgYnV0IHJlcXVpcmVkIGluIHR5cGUgJ0N5Y2xlU3RhdGUnLlxuc3JjL3Rlc3Qvc3RhdGUudGVzdC50cygxMzYsMTEpOiBlcnJvciBUUzI3NDE6IFByb3BlcnR5ICd0ZXN0c1dyaXR0ZW4nIGlzIG1pc3NpbmcgaW4gdHlwZSAneyBwaGFzZTogXCJSRURcIjsgdGVzdHNSYW46IGZhbHNlOyB0ZXN0c1Bhc3NlZDogZmFsc2U7IH0nIGJ1dCByZXF1aXJlZCBpbiB0eXBlICdDeWNsZVN0YXRlJy5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMTQ2LDExKTogZXJyb3IgVFMyNzQxOiBQcm9wZXJ0eSAndGVzdHNXcml0dGVuJyBpcyBtaXNzaW5nIGluIHR5cGUgJ3sgcGhhc2U6IFwiR1JFRU5cIjsgdGVzdHNSYW46IHRydWU7IHRlc3RzUGFzc2VkOiB0cnVlOyB9JyBidXQgcmVxdWlyZWQgaW4gdHlwZSAnQ3ljbGVTdGF0ZScuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDE1MywxMSk6IGVycm9yIFRTMjczOTogVHlwZSAneyBwaGFzZTogXCJSRUZBQ1RPUlwiOyB9JyBpcyBtaXNzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHR5cGUgJ0N5Y2xlU3RhdGUnOiB0ZXN0c1JhbiwgdGVzdHNQYXNzZWQsIHRlc3RzV3JpdHRlblxuc3JjL3Rlc3Qvc3RhdGUudGVzdC50cygxNjIsMTEpOiBlcnJvciBUUzI3NDE6IFByb3BlcnR5ICd0ZXN0c1dyaXR0ZW4nIGlzIG1pc3NpbmcgaW4gdHlwZSAneyBwaGFzZTogXCJSRURcIjsgdGVzdHNSYW46IHRydWU7IHRlc3RzUGFzc2VkOiB0cnVlOyB9JyBidXQgcmVxdWlyZWQgaW4gdHlwZSAnQ3ljbGVTdGF0ZScuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDE3MiwxMSk6IGVycm9yIFRTMjc0MTogUHJvcGVydHkgJ3Rlc3RzV3JpdHRlbicgaXMgbWlzc2luZyBpbiB0eXBlICd7IHBoYXNlOiBcIlJFRFwiOyB0ZXN0c1JhbjogdHJ1ZTsgdGVzdHNQYXNzZWQ6IGZhbHNlOyB9JyBidXQgcmVxdWlyZWQgaW4gdHlwZSAnQ3ljbGVTdGF0ZScuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDE4MiwxMSk6IGVycm9yIFRTMjc0MTogUHJvcGVydHkgJ3Rlc3RzV3JpdHRlbicgaXMgbWlzc2luZyBpbiB0eXBlICd7IHBoYXNlOiBcIlJFRFwiOyB0ZXN0c1JhbjogdHJ1ZTsgdGVzdHNQYXNzZWQ6IHRydWU7IH0nIGJ1dCByZXF1aXJlZCBpbiB0eXBlICdDeWNsZVN0YXRlJy5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMTkyLDExKTogZXJyb3IgVFMyNzM5OiBUeXBlICd7IHBoYXNlOiBcIkdSRUVOXCI7IH0nIGlzIG1pc3NpbmcgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdHlwZSAnQ3ljbGVTdGF0ZSc6IHRlc3RzUmFuLCB0ZXN0c1Bhc3NlZCwgdGVzdHNXcml0dGVuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDE5OCwxMSk6IGVycm9yIFRTMjczOTogVHlwZSAneyBwaGFzZTogXCJHUkVFTlwiOyB9JyBpcyBtaXNzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHR5cGUgJ0N5Y2xlU3RhdGUnOiB0ZXN0c1JhbiwgdGVzdHNQYXNzZWQsIHRlc3RzV3JpdHRlblxuc3JjL3Rlc3Qvc3RhdGUudGVzdC50cygyMDQsMTEpOiBlcnJvciBUUzI3Mzk6IFR5cGUgJ3sgcGhhc2U6IFwiUkVGQUNUT1JcIjsgfScgaXMgbWlzc2luZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgZnJvbSB0eXBlICdDeWNsZVN0YXRlJzogdGVzdHNSYW4sIHRlc3RzUGFzc2VkLCB0ZXN0c1dyaXR0ZW5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMjEwLDExKTogZXJyb3IgVFMyNzM5OiBUeXBlICd7IHBoYXNlOiBcIlJFRkFDVE9SXCI7IH0nIGlzIG1pc3NpbmcgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdHlwZSAnQ3ljbGVTdGF0ZSc6IHRlc3RzUmFuLCB0ZXN0c1Bhc3NlZCwgdGVzdHNXcml0dGVuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDIzMiwxMSk6IGVycm9yIFRTMjc0MTogUHJvcGVydHkgJ3Rlc3RzV3JpdHRlbicgaXMgbWlzc2luZyBpbiB0eXBlICd7IHBoYXNlOiBcIlJFRFwiOyB0ZXN0c1JhbjogdHJ1ZTsgdGVzdHNQYXNzZWQ6IHRydWU7IH0nIGJ1dCByZXF1aXJlZCBpbiB0eXBlICdDeWNsZVN0YXRlJy5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMjQxLDExKTogZXJyb3IgVFMyNzQxOiBQcm9wZXJ0eSAndGVzdHNXcml0dGVuJyBpcyBtaXNzaW5nIGluIHR5cGUgJ3sgcGhhc2U6IFwiUkVEXCI7IHRlc3RzUmFuOiB0cnVlOyB0ZXN0c1Bhc3NlZDogZmFsc2U7IH0nIGJ1dCByZXF1aXJlZCBpbiB0eXBlICdDeWNsZVN0YXRlJy5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMjU4LDExKTogZXJyb3IgVFMyNzQxOiBQcm9wZXJ0eSAndGVzdHNXcml0dGVuJyBpcyBtaXNzaW5nIGluIHR5cGUgJ3sgcGhhc2U6IFwiUkVEXCI7IHRlc3RzUmFuOiB0cnVlOyB0ZXN0c1Bhc3NlZDogZmFsc2U7IH0nIGJ1dCByZXF1aXJlZCBpbiB0eXBlICdDeWNsZVN0YXRlJy5cbnNyYy90ZXN0L3N0YXRlLnRlc3QudHMoMjY5LDExKTogZXJyb3IgVFMyNzM5OiBUeXBlICd7IHBoYXNlOiBcIkdSRUVOXCI7IH0nIGlzIG1pc3NpbmcgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdHlwZSAnQ3ljbGVTdGF0ZSc6IHRlc3RzUmFuLCB0ZXN0c1Bhc3NlZCwgdGVzdHNXcml0dGVuXG5zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzKDI3NiwxMSk6IGVycm9yIFRTMjczOTogVHlwZSAneyBwaGFzZTogXCJSRUZBQ1RPUlwiOyB9JyBpcyBtaXNzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHR5cGUgJ0N5Y2xlU3RhdGUnOiB0ZXN0c1JhbiwgdGVzdHNQYXNzZWQsIHRlc3RzV3JpdHRlblxuc3JjL3VpLnRzKDE0LDgpOiBlcnJvciBUUzIzMDU6IE1vZHVsZSAnXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCInIGhhcyBubyBleHBvcnRlZCBtZW1iZXIgJ1RoZW1lJy5cblxuXG5Db21tYW5kIGV4aXRlZCB3aXRoIGNvZGUgMiJ9XSwiZGV0YWlscyI6e30sImlzRXJyb3IiOnRydWUsInRpbWVzdGFtcCI6MTc4MTkzOTE3MTUwOH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjRiMTkyMThjIiwicGFyZW50SWQiOiJkMTVjNTJhZCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDY6MzcuOTI3WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiVGhyZWUgaXNzdWVzIHRvIGZpeDpcblxuMS4gKipUZXN0IGZhaWx1cmVzKio6IFxuICAgLSBgcmVjb3JkVGVzdFJlc3VsdGAgaW4gUkVEIHdpdGggcGFzc2luZyB0ZXN0cyBhdXRvLXRyYW5zaXRpb25zIHRvIEdSRUVOLCBidXQgdGhlIHJldHVybmVkIHN0YXRlIGhhcyBgdGVzdHNSYW46IGZhbHNlYCBiZWNhdXNlIGByZWRUb0dyZWVuYCByZXNldHMgaXQuIFRoZSB0ZXN0IGV4cGVjdHMgYHRlc3RzUmFuOiB0cnVlYC4gSSBuZWVkIHRvIGZpeCBlaXRoZXIgdGhlIHN0YXRlIG1hY2hpbmUgbG9naWMgb3IgdGhlIHRlc3QuXG4gICAtIGBwaGFzZURlc2NyaXB0aW9uYCB1c2VzIFwiUkVEIOKGkiBHUkVFTlwiIHdpdGggc3BhY2VzLCB0ZXN0IGV4cGVjdHMgXCJSRUTihpJHUkVFTlwiIHdpdGhvdXQgc3BhY2VzLlxuXG4yLiAqKlR5cGVjaGVjayBlcnJvcnMqKjpcbiAgIC0gYHBpYCBpcyBub3QgZm91bmQgaW4gaW5kZXgudHMg4oCUIGl0J3MgdGhlIGdsb2JhbCBmcm9tIHRoZSBleHRlbnNpb24gQVBJLCBidXQgVFMgZG9lc24ndCBrbm93IGFib3V0IGl0LiBJIG5lZWQgdG8gYWRkIGEgdHlwZSBkZWNsYXJhdGlvbi5cbiAgIC0gYEN5Y2xlU3RhdGVgIHByb3BlcnRpZXMgYXJlIHJlcXVpcmVkIGluIHRlc3RzIGJ1dCBvcHRpb25hbC4gSSBzaG91bGQgbWFrZSB0aGVtIG9wdGlvbmFsIHdpdGggZGVmYXVsdHMuXG4gICAtIGBUaGVtZWAgaXMgbm90IGV4cG9ydGVkIGZyb20gYEBlYXJlbmRpbC13b3Jrcy9waS10dWlgLiBOZWVkIHRvIGZpbmQgdGhlIGNvcnJlY3QgZXhwb3J0LlxuXG5MZXQgbWUgZml4IGFsbCBvZiB0aGVzZS5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlRocmVlIGlzc3VlcyB0byBmaXg6XG5cbjEuIGByZWNvcmRUZXN0UmVzdWx0YCBhdXRvLXRyYW5zaXRpb25zIHRvIEdSRUVOIHdoaWNoIHJlc2V0cyBgdGVzdHNSYW5gIOKAlCB0ZXN0IGV4cGVjdHMgaXQgdG8gc3RheSB0cnVlXG4yLiBgcGhhc2VEZXNjcmlwdGlvbmAgc2F5cyBcIlJFRCDihpIgR1JFRU5cIiB3aXRoIHNwYWNlcywgdGVzdCBleHBlY3RzIFwiUkVE4oaSR1JFRU5cIlxuMy4gYHBpYCBnbG9iYWwgYW5kIGBUaGVtZWAgdHlwZSBub3QgcmVjb2duaXplZCwgYW5kIGBDeWNsZVN0YXRlYCBmaWVsZHMgc2hvdWxkIGJlIG9wdGlvbmFsIGZvciB0ZXN0IGNvbnZlbmllbmNlXG5cbkxldCBtZSBmaXggYWxsIHRocmVlIGZpbGVzOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiS05uZlNJRmhjY3c5cVZ4eFJMRDcxR1JGUEFDMVBRQTMiLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3N0YXRlLnRzIiwiZWRpdHMiOlt7Im9sZFRleHQiOiJleHBvcnQgaW50ZXJmYWNlIEN5Y2xlU3RhdGUge1xuICAvKiogQ3VycmVudCBwaGFzZSAqL1xuICBwaGFzZTogUGhhc2U7XG4gIC8qKiBUZXN0IGRlc2NyaXB0aW9uICh3aGF0IHdlJ3JlIHRyeWluZyB0byBtYWtlIHBhc3MpICovXG4gIHRlc3REZXNjcmlwdGlvbj86IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgdGVzdHMgaGF2ZSBiZWVuIHJ1biBpbiB0aGUgY3VycmVudCBjeWNsZSAqL1xuICB0ZXN0c1JhbjogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgdGVzdHMgcGFzc2VkIGluIHRoZSBjdXJyZW50IGN5Y2xlICovXG4gIHRlc3RzUGFzc2VkOiBib29sZWFuO1xuICAvKiogTnVtYmVyIG9mIHRlc3RzIHdyaXR0ZW4gc28gZmFyIGluIHRoaXMgc2Vzc2lvbiAqL1xuICB0ZXN0c1dyaXR0ZW46IG51bWJlcjtcbiAgLyoqIExhc3QgcmVmYWN0b3JpbmcgZGVjaXNpb24gKGlmIGFueSkgKi9cbiAgbGFzdERlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbjtcbiAgLyoqIEN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbiBmcm9tIGRldmVsb3BlciAqL1xuICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uPzogc3RyaW5nO1xufSIsIm5ld1RleHQiOiJleHBvcnQgaW50ZXJmYWNlIEN5Y2xlU3RhdGUge1xuICAvKiogQ3VycmVudCBwaGFzZSAqL1xuICBwaGFzZTogUGhhc2U7XG4gIC8qKiBUZXN0IGRlc2NyaXB0aW9uICh3aGF0IHdlJ3JlIHRyeWluZyB0byBtYWtlIHBhc3MpICovXG4gIHRlc3REZXNjcmlwdGlvbj86IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgdGVzdHMgaGF2ZSBiZWVuIHJ1biBpbiB0aGUgY3VycmVudCBjeWNsZSAqL1xuICB0ZXN0c1Jhbj86IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIHRlc3RzIHBhc3NlZCBpbiB0aGUgY3VycmVudCBjeWNsZSAqL1xuICB0ZXN0c1Bhc3NlZD86IGJvb2xlYW47XG4gIC8qKiBOdW1iZXIgb2YgdGVzdHMgd3JpdHRlbiBzbyBmYXIgaW4gdGhpcyBzZXNzaW9uICovXG4gIHRlc3RzV3JpdHRlbj86IG51bWJlcjtcbiAgLyoqIExhc3QgcmVmYWN0b3JpbmcgZGVjaXNpb24gKGlmIGFueSkgKi9cbiAgbGFzdERlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbjtcbiAgLyoqIEN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbiBmcm9tIGRldmVsb3BlciAqL1xuICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uPzogc3RyaW5nO1xufSJ9LHsib2xkVGV4dCI6IiAgaWYgKHBhc3NlZCAmJiBzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuICAgIC8vIFRlc3RzIHBhc3NlZCB3aGlsZSBpbiBSRUQg4oaSIGF1dG8tdHJhbnNpdGlvbiB0byBHUkVFTlxuICAgIHJldHVybiByZWRUb0dyZWVuKG5ld1N0YXRlKTtcbiAgfSIsIm5ld1RleHQiOiIgIGlmIChwYXNzZWQgJiYgc3RhdGUucGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICAvLyBUZXN0cyBwYXNzZWQgd2hpbGUgaW4gUkVEIOKGkiBhdXRvLXRyYW5zaXRpb24gdG8gR1JFRU5cbiAgICAvLyBLZWVwIHRlc3RzUmFuL3Rlc3RzUGFzc2VkIGZyb20gbmV3U3RhdGUgKHRoZXkgcmVmbGVjdCB0aGUganVzdC1ydW4gdGVzdHMpXG4gICAgY29uc3QgZ3JlZW5SZXN1bHQgPSByZWRUb0dyZWVuKG5ld1N0YXRlKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZ3JlZW5SZXN1bHQsXG4gICAgICBzdGF0ZTogeyAuLi5ncmVlblJlc3VsdC5zdGF0ZSwgdGVzdHNSYW46IHRydWUsIHRlc3RzUGFzc2VkOiB0cnVlIH0sXG4gICAgfTtcbiAgfSJ9LHsib2xkVGV4dCI6IiAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKGkiBHUkVFTiDigJQgVGVzdHMgcGFzc2VkISBSZWFkeSBmb3IgcmVmYWN0b3JpbmcuYDsiLCJuZXdUZXh0IjoiICAgICAgcmV0dXJuIGAke2Vtb2ppfSBSRUTihpJHUkVFTiDigJQgVGVzdHMgcGFzc2VkISBSZWFkeSBmb3IgcmVmYWN0b3JpbmcuYDsifV19fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MjA5OSwib3V0cHV0Ijo4NDksImNhY2hlUmVhZCI6Njc5MDAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo3MDg0OCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM5MTcxNTA4LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtSkRlMVlvUjVpcTJ3NGVRbHFsQ1NTYU9KRjVuVEtRRkkifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMTA4NjAzNjkiLCJwYXJlbnRJZCI6IjRiMTkyMThjIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowNjozNy45NDFaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJLTm5mU0lGaGNjdzlxVnh4UkxENzFHUkZQQUMxUFFBMyIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSByZXBsYWNlZCAzIGJsb2NrKHMpIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50cy4ifV0sImRldGFpbHMiOnsiZGlmZiI6IiAgICAgLi4uXG4gIDM5ICAgcGhhc2U6IFBoYXNlO1xuICA0MCAgIC8qKiBUZXN0IGRlc2NyaXB0aW9uICh3aGF0IHdlJ3JlIHRyeWluZyB0byBtYWtlIHBhc3MpICovXG4gIDQxICAgdGVzdERlc2NyaXB0aW9uPzogc3RyaW5nO1xuICA0MiAgIC8qKiBXaGV0aGVyIHRlc3RzIGhhdmUgYmVlbiBydW4gaW4gdGhlIGN1cnJlbnQgY3ljbGUgKi9cbi0gNDMgICB0ZXN0c1JhbjogYm9vbGVhbjtcbisgNDMgICB0ZXN0c1Jhbj86IGJvb2xlYW47XG4gIDQ0ICAgLyoqIFdoZXRoZXIgdGVzdHMgcGFzc2VkIGluIHRoZSBjdXJyZW50IGN5Y2xlICovXG4tIDQ1ICAgdGVzdHNQYXNzZWQ6IGJvb2xlYW47XG4rIDQ1ICAgdGVzdHNQYXNzZWQ/OiBib29sZWFuO1xuICA0NiAgIC8qKiBOdW1iZXIgb2YgdGVzdHMgd3JpdHRlbiBzbyBmYXIgaW4gdGhpcyBzZXNzaW9uICovXG4tIDQ3ICAgdGVzdHNXcml0dGVuOiBudW1iZXI7XG4rIDQ3ICAgdGVzdHNXcml0dGVuPzogbnVtYmVyO1xuICA0OCAgIC8qKiBMYXN0IHJlZmFjdG9yaW5nIGRlY2lzaW9uIChpZiBhbnkpICovXG4gIDQ5ICAgbGFzdERlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbjtcbiAgNTAgICAvKiogQ3VzdG9tIHJlZmFjdG9yaW5nIGluc3RydWN0aW9uIGZyb20gZGV2ZWxvcGVyICovXG4gIDUxICAgY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbj86IHN0cmluZztcbiAgICAgLi4uXG4gMTczICAgfTtcbiAxNzQgXG4gMTc1ICAgaWYgKHBhc3NlZCAmJiBzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuIDE3NiAgICAgLy8gVGVzdHMgcGFzc2VkIHdoaWxlIGluIFJFRCDihpIgYXV0by10cmFuc2l0aW9uIHRvIEdSRUVOXG4tMTc3ICAgICByZXR1cm4gcmVkVG9HcmVlbihuZXdTdGF0ZSk7XG4rMTc3ICAgICAvLyBLZWVwIHRlc3RzUmFuL3Rlc3RzUGFzc2VkIGZyb20gbmV3U3RhdGUgKHRoZXkgcmVmbGVjdCB0aGUganVzdC1ydW4gdGVzdHMpXG4rMTc4ICAgICBjb25zdCBncmVlblJlc3VsdCA9IHJlZFRvR3JlZW4obmV3U3RhdGUpO1xuKzE3OSAgICAgcmV0dXJuIHtcbisxODAgICAgICAgLi4uZ3JlZW5SZXN1bHQsXG4rMTgxICAgICAgIHN0YXRlOiB7IC4uLmdyZWVuUmVzdWx0LnN0YXRlLCB0ZXN0c1JhbjogdHJ1ZSwgdGVzdHNQYXNzZWQ6IHRydWUgfSxcbisxODIgICAgIH07XG4gMTc4ICAgfVxuIDE3OSBcbiAxODAgICBpZiAoIXBhc3NlZCkge1xuIDE4MSAgICAgcmV0dXJuIHtcbiAgICAgLi4uXG4gMjc0ICAgICAgIGlmICghc3RhdGUudGVzdHNSYW4pIHtcbiAyNzUgICAgICAgICByZXR1cm4gYCR7ZW1vaml9IFJFRCDigJQgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzcy5gO1xuIDI3NiAgICAgICB9XG4gMjc3ICAgICAgIGlmIChzdGF0ZS50ZXN0c1Bhc3NlZCkge1xuLTI3OCAgICAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKGkiBHUkVFTiDigJQgVGVzdHMgcGFzc2VkISBSZWFkeSBmb3IgcmVmYWN0b3JpbmcuYDtcbisyODMgICAgICAgICByZXR1cm4gYCR7ZW1vaml9IFJFROKGkkdSRUVOIOKAlCBUZXN0cyBwYXNzZWQhIFJlYWR5IGZvciByZWZhY3RvcmluZy5gO1xuIDI3OSAgICAgICB9XG4gMjgwICAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKAlCBUZXN0cyBmYWlsZWQuIEZpeCBpbXBsZW1lbnRhdGlvbi5gO1xuIDI4MSAgICAgY2FzZSBcIkdSRUVOXCI6XG4gMjgyICAgICAgIHJldHVybiBgJHtlbW9qaX0gR1JFRU4g4oCUIFRlc3RzIHBhc3MuIFJlYWR5IGZvciByZWZhY3RvcmluZy5gO1xuICAgICAuLi4iLCJwYXRjaCI6Ii0tLSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHNcbisrKyAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHNcbkBAIC0zOSwxMyArMzksMTMgQEBcbiAgIHBoYXNlOiBQaGFzZTtcbiAgIC8qKiBUZXN0IGRlc2NyaXB0aW9uICh3aGF0IHdlJ3JlIHRyeWluZyB0byBtYWtlIHBhc3MpICovXG4gICB0ZXN0RGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAvKiogV2hldGhlciB0ZXN0cyBoYXZlIGJlZW4gcnVuIGluIHRoZSBjdXJyZW50IGN5Y2xlICovXG4tICB0ZXN0c1JhbjogYm9vbGVhbjtcbisgIHRlc3RzUmFuPzogYm9vbGVhbjtcbiAgIC8qKiBXaGV0aGVyIHRlc3RzIHBhc3NlZCBpbiB0aGUgY3VycmVudCBjeWNsZSAqL1xuLSAgdGVzdHNQYXNzZWQ6IGJvb2xlYW47XG4rICB0ZXN0c1Bhc3NlZD86IGJvb2xlYW47XG4gICAvKiogTnVtYmVyIG9mIHRlc3RzIHdyaXR0ZW4gc28gZmFyIGluIHRoaXMgc2Vzc2lvbiAqL1xuLSAgdGVzdHNXcml0dGVuOiBudW1iZXI7XG4rICB0ZXN0c1dyaXR0ZW4/OiBudW1iZXI7XG4gICAvKiogTGFzdCByZWZhY3RvcmluZyBkZWNpc2lvbiAoaWYgYW55KSAqL1xuICAgbGFzdERlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbjtcbiAgIC8qKiBDdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb24gZnJvbSBkZXZlbG9wZXIgKi9cbiAgIGN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb24/OiBzdHJpbmc7XG5AQCAtMTczLDkgKzE3MywxNCBAQFxuICAgfTtcbiBcbiAgIGlmIChwYXNzZWQgJiYgc3RhdGUucGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICAgLy8gVGVzdHMgcGFzc2VkIHdoaWxlIGluIFJFRCDihpIgYXV0by10cmFuc2l0aW9uIHRvIEdSRUVOXG4tICAgIHJldHVybiByZWRUb0dyZWVuKG5ld1N0YXRlKTtcbisgICAgLy8gS2VlcCB0ZXN0c1Jhbi90ZXN0c1Bhc3NlZCBmcm9tIG5ld1N0YXRlICh0aGV5IHJlZmxlY3QgdGhlIGp1c3QtcnVuIHRlc3RzKVxuKyAgICBjb25zdCBncmVlblJlc3VsdCA9IHJlZFRvR3JlZW4obmV3U3RhdGUpO1xuKyAgICByZXR1cm4ge1xuKyAgICAgIC4uLmdyZWVuUmVzdWx0LFxuKyAgICAgIHN0YXRlOiB7IC4uLmdyZWVuUmVzdWx0LnN0YXRlLCB0ZXN0c1JhbjogdHJ1ZSwgdGVzdHNQYXNzZWQ6IHRydWUgfSxcbisgICAgfTtcbiAgIH1cbiBcbiAgIGlmICghcGFzc2VkKSB7XG4gICAgIHJldHVybiB7XG5AQCAtMjc0LDkgKzI3OSw5IEBAXG4gICAgICAgaWYgKCFzdGF0ZS50ZXN0c1Jhbikge1xuICAgICAgICAgcmV0dXJuIGAke2Vtb2ppfSBSRUQg4oCUIFdyaXRlIGEgZmFpbGluZyB0ZXN0LCB0aGVuIGltcGxlbWVudCB0byBtYWtlIGl0IHBhc3MuYDtcbiAgICAgICB9XG4gICAgICAgaWYgKHN0YXRlLnRlc3RzUGFzc2VkKSB7XG4tICAgICAgICByZXR1cm4gYCR7ZW1vaml9IFJFRCDihpIgR1JFRU4g4oCUIFRlc3RzIHBhc3NlZCEgUmVhZHkgZm9yIHJlZmFjdG9yaW5nLmA7XG4rICAgICAgICByZXR1cm4gYCR7ZW1vaml9IFJFROKGkkdSRUVOIOKAlCBUZXN0cyBwYXNzZWQhIFJlYWR5IGZvciByZWZhY3RvcmluZy5gO1xuICAgICAgIH1cbiAgICAgICByZXR1cm4gYCR7ZW1vaml9IFJFRCDigJQgVGVzdHMgZmFpbGVkLiBGaXggaW1wbGVtZW50YXRpb24uYDtcbiAgICAgY2FzZSBcIkdSRUVOXCI6XG4gICAgICAgcmV0dXJuIGAke2Vtb2ppfSBHUkVFTiDigJQgVGVzdHMgcGFzcy4gUmVhZHkgZm9yIHJlZmFjdG9yaW5nLmA7XG4iLCJmaXJzdENoYW5nZWRMaW5lIjo0M30sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkxOTc5NDF9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3YTQ1Y2NkZSIsInBhcmVudElkIjoiMTA4NjAzNjkiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA2OjQzLjk0NloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBsZXQgbWUgZml4IHRoZSBpbmRleC50cyB0byBkZWNsYXJlIHRoZSBgcGlgIGdsb2JhbCwgYW5kIGZpeCB0aGUgdWkudHMgZm9yIHRoZSBUaGVtZSB0eXBlLiBMZXQgbWUgY2hlY2sgd2hhdCdzIGFjdHVhbGx5IGV4cG9ydGVkIGZyb20gcGktdHVpLlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IGZpeCBpbmRleC50cyAoZGVjbGFyZSBgcGlgIGdsb2JhbCkgYW5kIGNoZWNrIHBpLXR1aSBleHBvcnRzOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiNEVxT3ZLRThzZ3JLbUxteUFyckFwTWVzSFlUMzRheEQiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCAtciBcImV4cG9ydC4qVGhlbWVcIiBub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLXR1aS9kaXN0LyAyPi9kZXYvbnVsbCB8IGhlYWQgLTIwIn19LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJnOUJEa080eUk5VndUeUFrOUxvckRUTW1YTFU2ellIOSIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBncmVwIFwiZXhwb3J0LipLZXliaW5kaW5nc01hbmFnZXJcIiBub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLXR1aS9kaXN0L2luZGV4LmQudHMgMj4vZGV2L251bGwgfCBoZWFkIC01In19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0Ijo0Mywib3V0cHV0IjoyMDYsImNhY2hlUmVhZCI6NzA4NDcsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo3MTA5NiwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM5MTk3OTQyLCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtYXY0Uk9XZGRLd2hSTlYxTDJiQ0IxTFVLajQzM05sb2oifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYWQyMjJiNGUiLCJwYXJlbnRJZCI6IjdhNDVjY2RlIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowNjo0NC4wMjFaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiI0RXFPdktFOHNnckttTG15QXJyQXBNZXNIWVQzNGF4RCIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Im5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktdHVpL2Rpc3QvaW5kZXguanMubWFwOntcInZlcnNpb25cIjozLFwiZmlsZVwiOlwiaW5kZXguanNcIixcInNvdXJjZVJvb3RcIjpcIlwiLFwic291cmNlc1wiOltcIi4uL3NyYy9pbmRleC50c1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQSxrQ0FBa0M7QUFFbEMsdUJBQXVCO0FBQ3ZCLE9BQU8sRUFJTiw0QkFBNEIsR0FFNUIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixhQUFhO0FBQ2IsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxNQUFNLEVBQXdDLE1BQU0sd0JBQXdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLEtBQUssRUFBc0MsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDOUMsT0FBTyxFQUFFLE1BQU0sRUFBK0IsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RSxPQUFPLEVBQXlCLFFBQVEsRUFBNEMsTUFBTSwwQkFBMEIsQ0FBQztBQUNySCxPQUFPLEVBRU4sVUFBVSxHQUlWLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFvQixZQUFZLEVBQTBCLE1BQU0sK0JBQStCLENBQUM7QUFDdkcsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHL0QsaUJBQWlCO0FBQ2pCLE9BQU8sRUFBbUIsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0RSxjQUFjO0FBQ2QsT0FBTyxFQUNOLGNBQWMsRUFPZCxrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLGVBQWUsR0FDZixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLDBCQUEwQjtBQUMxQixPQUFPLEVBQ04sb0JBQW9CLEVBQ3BCLFlBQVksRUFDWixXQUFXLEVBQ1gscUJBQXFCLEVBQ3JCLEdBQUcsRUFHSCxVQUFVLEVBQ1YsUUFBUSxFQUNSLHNCQUFzQixHQUN0QixNQUFNLFdBQVcsQ0FBQztBQUNuQixzQ0FBc0M7QUFDdEMsT0FBTyxFQUFFLFdBQVcsRUFBcUQsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRyx5Q0FBeUM7QUFDekMsT0FBTyxFQUFFLGVBQWUsRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDL0Qsa0JBQWtCO0FBQ2xCLE9BQU8sRUFDTix5QkFBeUIsRUFDekIsOEJBQThCLEdBRzlCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIseUJBQXlCO0FBQ3pCLE9BQU8sRUFDTixlQUFlLEVBRWYsa0JBQWtCLEVBQ2xCLG9CQUFvQixFQUNwQixnQkFBZ0IsRUFDaEIsa0JBQWtCLEVBQ2xCLFlBQVksRUFDWixXQUFXLEVBQ1gsZUFBZSxFQUNmLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsa0JBQWtCLEVBQ2xCLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFJVCxhQUFhLEVBQ2IsV0FBVyxFQUNYLHNCQUFzQixFQUN0QixlQUFlLEVBQ2YsaUJBQWlCLEdBRWpCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUVOLFNBQVMsRUFDVCxhQUFhLEVBRWIsV0FBVyxFQU9YLEdBQUcsR0FDSCxNQUFNLFVBQVUsQ0FBQztBQUNsQixZQUFZO0FBQ1osT0FBTyxFQUFFLGFBQWEsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi8vIENvcmUgVFVJIGludGVyZmFjZXMgYW5kIGNsYXNzZXNcXG5cXG4vLyBBdXRvY29tcGxldGUgc3VwcG9ydFxcbmV4cG9ydCB7XFxuXFx0dHlwZSBBdXRvY29tcGxldGVJdGVtLFxcblxcdHR5cGUgQXV0b2NvbXBsZXRlUHJvdmlkZXIsXFxuXFx0dHlwZSBBdXRvY29tcGxldGVTdWdnZXN0aW9ucyxcXG5cXHRDb21iaW5lZEF1dG9jb21wbGV0ZVByb3ZpZGVyLFxcblxcdHR5cGUgU2xhc2hDb21tYW5kLFxcbn0gZnJvbSBcXFwiLi9hdXRvY29tcGxldGUudHNcXFwiO1xcbi8vIENvbXBvbmVudHNcXG5leHBvcnQgeyBCb3ggfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvYm94LnRzXFxcIjtcXG5leHBvcnQgeyBDYW5jZWxsYWJsZUxvYWRlciB9IGZyb20gXFxcIi4vY29tcG9uZW50cy9jYW5jZWxsYWJsZS1sb2FkZXIudHNcXFwiO1xcbmV4cG9ydCB7IEVkaXRvciwgdHlwZSBFZGl0b3JPcHRpb25zLCB0eXBlIEVkaXRvclRoZW1lIH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL2VkaXRvci50c1xcXCI7XFxuZXhwb3J0IHsgSW1hZ2UsIHR5cGUgSW1hZ2VPcHRpb25zLCB0eXBlIEltYWdlVGhlbWUgfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvaW1hZ2UudHNcXFwiO1xcbmV4cG9ydCB7IElucHV0IH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL2lucHV0LnRzXFxcIjtcXG5leHBvcnQgeyBMb2FkZXIsIHR5cGUgTG9hZGVySW5kaWNhdG9yT3B0aW9ucyB9IGZyb20gXFxcIi4vY29tcG9uZW50cy9sb2FkZXIudHNcXFwiO1xcbmV4cG9ydCB7IHR5cGUgRGVmYXVsdFRleHRTdHlsZSwgTWFya2Rvd24sIHR5cGUgTWFya2Rvd25PcHRpb25zLCB0eXBlIE1hcmtkb3duVGhlbWUgfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvbWFya2Rvd24udHNcXFwiO1xcbmV4cG9ydCB7XFxuXFx0dHlwZSBTZWxlY3RJdGVtLFxcblxcdFNlbGVjdExpc3QsXFxuXFx0dHlwZSBTZWxlY3RMaXN0TGF5b3V0T3B0aW9ucyxcXG5cXHR0eXBlIFNlbGVjdExpc3RUaGVtZSxcXG5cXHR0eXBlIFNlbGVjdExpc3RUcnVuY2F0ZVByaW1hcnlDb250ZXh0LFxcbn0gZnJvbSBcXFwiLi9jb21wb25lbnRzL3NlbGVjdC1saXN0LnRzXFxcIjtcXG5leHBvcnQgeyB0eXBlIFNldHRpbmdJdGVtLCBTZXR0aW5nc0xpc3QsIHR5cGUgU2V0dGluZ3NMaXN0VGhlbWUgfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvc2V0dGluZ3MtbGlzdC50c1xcXCI7XFxuZXhwb3J0IHsgU3BhY2VyIH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL3NwYWNlci50c1xcXCI7XFxuZXhwb3J0IHsgVGV4dCB9IGZyb20gXFxcIi4vY29tcG9uZW50cy90ZXh0LnRzXFxcIjtcXG5leHBvcnQgeyBUcnVuY2F0ZWRUZXh0IH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL3RydW5jYXRlZC10ZXh0LnRzXFxcIjtcXG4vLyBFZGl0b3IgY29tcG9uZW50IGludGVyZmFjZSAoZm9yIGN1c3RvbSBlZGl0b3JzKVxcbmV4cG9ydCB0eXBlIHsgRWRpdG9yQ29tcG9uZW50IH0gZnJvbSBcXFwiLi9lZGl0b3ItY29tcG9uZW50LnRzXFxcIjtcXG4vLyBGdXp6eSBtYXRjaGluZ1xcbmV4cG9ydCB7IHR5cGUgRnV6enlNYXRjaCwgZnV6enlGaWx0ZXIsIGZ1enp5TWF0Y2ggfSBmcm9tIFxcXCIuL2Z1enp5LnRzXFxcIjtcXG4vLyBLZXliaW5kaW5nc1xcbmV4cG9ydCB7XFxuXFx0Z2V0S2V5YmluZGluZ3MsXFxuXFx0dHlwZSBLZXliaW5kaW5nLFxcblxcdHR5cGUgS2V5YmluZGluZ0NvbmZsaWN0LFxcblxcdHR5cGUgS2V5YmluZGluZ0RlZmluaXRpb24sXFxuXFx0dHlwZSBLZXliaW5kaW5nRGVmaW5pdGlvbnMsXFxuXFx0dHlwZSBLZXliaW5kaW5ncyxcXG5cXHR0eXBlIEtleWJpbmRpbmdzQ29uZmlnLFxcblxcdEtleWJpbmRpbmdzTWFuYWdlcixcXG5cXHRzZXRLZXliaW5kaW5ncyxcXG5cXHRUVUlfS0VZQklORElOR1MsXFxufSBmcm9tIFxcXCIuL2tleWJpbmRpbmdzLnRzXFxcIjtcXG4vLyBLZXlib2FyZCBpbnB1dCBoYW5kbGluZ1xcbmV4cG9ydCB7XFxuXFx0ZGVjb2RlS2l0dHlQcmludGFibGUsXFxuXFx0aXNLZXlSZWxlYXNlLFxcblxcdGlzS2V5UmVwZWF0LFxcblxcdGlzS2l0dHlQcm90b2NvbEFjdGl2ZSxcXG5cXHRLZXksXFxuXFx0dHlwZSBLZXlFdmVudFR5cGUsXFxuXFx0dHlwZSBLZXlJZCxcXG5cXHRtYXRjaGVzS2V5LFxcblxcdHBhcnNlS2V5LFxcblxcdHNldEtpdHR5UHJvdG9jb2xBY3RpdmUsXFxufSBmcm9tIFxcXCIuL2tleXMudHNcXFwiO1xcbi8vIElucHV0IGJ1ZmZlcmluZyBmb3IgYmF0Y2ggc3BsaXR0aW5nXFxuZXhwb3J0IHsgU3RkaW5CdWZmZXIsIHR5cGUgU3RkaW5CdWZmZXJFdmVudE1hcCwgdHlwZSBTdGRpbkJ1ZmZlck9wdGlvbnMgfSBmcm9tIFxcXCIuL3N0ZGluLWJ1ZmZlci50c1xcXCI7XFxuLy8gVGVybWluYWwgaW50ZXJmYWNlIGFuZCBpbXBsZW1lbnRhdGlvbnNcXG5leHBvcnQgeyBQcm9jZXNzVGVybWluYWwsIHR5cGUgVGVybWluYWwgfSBmcm9tIFxcXCIuL3Rlcm1pbmFsLnRzXFxcIjtcXG4vLyBUZXJtaW5hbCBjb2xvcnNcXG5leHBvcnQge1xcblxcdHBhcnNlT3NjMTFCYWNrZ3JvdW5kQ29sb3IsXFxuXFx0cGFyc2VUZXJtaW5hbENvbG9yU2NoZW1lUmVwb3J0LFxcblxcdHR5cGUgUmdiQ29sb3IsXFxuXFx0dHlwZSBUZXJtaW5hbENvbG9yU2NoZW1lLFxcbn0gZnJvbSBcXFwiLi90ZXJtaW5hbC1jb2xvcnMudHNcXFwiO1xcbi8vIFRlcm1pbmFsIGltYWdlIHN1cHBvcnRcXG5leHBvcnQge1xcblxcdGFsbG9jYXRlSW1hZ2VJZCxcXG5cXHR0eXBlIENlbGxEaW1lbnNpb25zLFxcblxcdGNhbGN1bGF0ZUltYWdlUm93cyxcXG5cXHRkZWxldGVBbGxLaXR0eUltYWdlcyxcXG5cXHRkZWxldGVLaXR0eUltYWdlLFxcblxcdGRldGVjdENhcGFiaWxpdGllcyxcXG5cXHRlbmNvZGVJVGVybTIsXFxuXFx0ZW5jb2RlS2l0dHksXFxuXFx0Z2V0Q2FwYWJpbGl0aWVzLFxcblxcdGdldENlbGxEaW1lbnNpb25zLFxcblxcdGdldEdpZkRpbWVuc2lvbnMsXFxuXFx0Z2V0SW1hZ2VEaW1lbnNpb25zLFxcblxcdGdldEpwZWdEaW1lbnNpb25zLFxcblxcdGdldFBuZ0RpbWVuc2lvbnMsXFxuXFx0Z2V0V2VicERpbWVuc2lvbnMsXFxuXFx0aHlwZXJsaW5rLFxcblxcdHR5cGUgSW1hZ2VEaW1lbnNpb25zLFxcblxcdHR5cGUgSW1hZ2VQcm90b2NvbCxcXG5cXHR0eXBlIEltYWdlUmVuZGVyT3B0aW9ucyxcXG5cXHRpbWFnZUZhbGxiYWNrLFxcblxcdHJlbmRlckltYWdlLFxcblxcdHJlc2V0Q2FwYWJpbGl0aWVzQ2FjaGUsXFxuXFx0c2V0Q2FwYWJpbGl0aWVzLFxcblxcdHNldENlbGxEaW1lbnNpb25zLFxcblxcdHR5cGUgVGVybWluYWxDYXBhYmlsaXRpZXMsXFxufSBmcm9tIFxcXCIuL3Rlcm1pbmFsLWltYWdlLnRzXFxcIjtcXG5leHBvcnQge1xcblxcdHR5cGUgQ29tcG9uZW50LFxcblxcdENvbnRhaW5lcixcXG5cXHRDVVJTT1JfTUFSS0VSLFxcblxcdHR5cGUgRm9jdXNhYmxlLFxcblxcdGlzRm9jdXNhYmxlLFxcblxcdHR5cGUgT3ZlcmxheUFuY2hvcixcXG5cXHR0eXBlIE92ZXJsYXlIYW5kbGUsXFxuXFx0dHlwZSBPdmVybGF5TWFyZ2luLFxcblxcdHR5cGUgT3ZlcmxheU9wdGlvbnMsXFxuXFx0dHlwZSBPdmVybGF5VW5mb2N1c09wdGlvbnMsXFxuXFx0dHlwZSBTaXplVmFsdWUsXFxuXFx0VFVJLFxcbn0gZnJvbSBcXFwiLi90dWkudHNcXFwiO1xcbi8vIFV0aWxpdGllc1xcbmV4cG9ydCB7IHNsaWNlQnlDb2x1bW4sIHRydW5jYXRlVG9XaWR0aCwgdmlzaWJsZVdpZHRoLCB3cmFwVGV4dFdpdGhBbnNpIH0gZnJvbSBcXFwiLi91dGlscy50c1xcXCI7XFxuXCJdfVxubm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS10dWkvZGlzdC9pbmRleC5kLnRzOmV4cG9ydCB7IEVkaXRvciwgdHlwZSBFZGl0b3JPcHRpb25zLCB0eXBlIEVkaXRvclRoZW1lIH0gZnJvbSBcIi4vY29tcG9uZW50cy9lZGl0b3IudHNcIjtcbm5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktdHVpL2Rpc3QvaW5kZXguZC50czpleHBvcnQgeyBJbWFnZSwgdHlwZSBJbWFnZU9wdGlvbnMsIHR5cGUgSW1hZ2VUaGVtZSB9IGZyb20gXCIuL2NvbXBvbmVudHMvaW1hZ2UudHNcIjtcbm5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktdHVpL2Rpc3QvaW5kZXguZC50czpleHBvcnQgeyB0eXBlIERlZmF1bHRUZXh0U3R5bGUsIE1hcmtkb3duLCB0eXBlIE1hcmtkb3duT3B0aW9ucywgdHlwZSBNYXJrZG93blRoZW1lIH0gZnJvbSBcIi4vY29tcG9uZW50cy9tYXJrZG93bi50c1wiO1xubm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS10dWkvZGlzdC9pbmRleC5kLnRzOmV4cG9ydCB7IHR5cGUgU2VsZWN0SXRlbSwgU2VsZWN0TGlzdCwgdHlwZSBTZWxlY3RMaXN0TGF5b3V0T3B0aW9ucywgdHlwZSBTZWxlY3RMaXN0VGhlbWUsIHR5cGUgU2VsZWN0TGlzdFRydW5jYXRlUHJpbWFyeUNvbnRleHQsIH0gZnJvbSBcIi4vY29tcG9uZW50cy9zZWxlY3QtbGlzdC50c1wiO1xuXG5bU2hvd2luZyBsaW5lcyAxNi0yMCBvZiAyMCAoNTAuMEtCIGxpbWl0KS4gRnVsbCBvdXRwdXQ6IC92YXIvZm9sZGVycy9kYy94OGI5OTF0ZDU1NWdfOGZiNXhfZzlkNDAwMDAwZ24vVC9waS1iYXNoLTJlOTgyMmI0MDRiMTUzOTkubG9nXSJ9XSwiZGV0YWlscyI6eyJ0cnVuY2F0aW9uIjp7ImNvbnRlbnQiOiJub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLXR1aS9kaXN0L2luZGV4LmpzLm1hcDp7XCJ2ZXJzaW9uXCI6MyxcImZpbGVcIjpcImluZGV4LmpzXCIsXCJzb3VyY2VSb290XCI6XCJcIixcInNvdXJjZXNcIjpbXCIuLi9zcmMvaW5kZXgudHNcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUEsa0NBQWtDO0FBRWxDLHVCQUF1QjtBQUN2QixPQUFPLEVBSU4sNEJBQTRCLEdBRTVCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsYUFBYTtBQUNiLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN2RSxPQUFPLEVBQUUsTUFBTSxFQUF3QyxNQUFNLHdCQUF3QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxLQUFLLEVBQXNDLE1BQU0sdUJBQXVCLENBQUM7QUFDbEYsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlDLE9BQU8sRUFBRSxNQUFNLEVBQStCLE1BQU0sd0JBQXdCLENBQUM7QUFDN0UsT0FBTyxFQUF5QixRQUFRLEVBQTRDLE1BQU0sMEJBQTBCLENBQUM7QUFDckgsT0FBTyxFQUVOLFVBQVUsR0FJVixNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFBb0IsWUFBWSxFQUEwQixNQUFNLCtCQUErQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRy9ELGlCQUFpQjtBQUNqQixPQUFPLEVBQW1CLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdEUsY0FBYztBQUNkLE9BQU8sRUFDTixjQUFjLEVBT2Qsa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCxlQUFlLEdBQ2YsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQiwwQkFBMEI7QUFDMUIsT0FBTyxFQUNOLG9CQUFvQixFQUNwQixZQUFZLEVBQ1osV0FBVyxFQUNYLHFCQUFxQixFQUNyQixHQUFHLEVBR0gsVUFBVSxFQUNWLFFBQVEsRUFDUixzQkFBc0IsR0FDdEIsTUFBTSxXQUFXLENBQUM7QUFDbkIsc0NBQXNDO0FBQ3RDLE9BQU8sRUFBRSxXQUFXLEVBQXFELE1BQU0sbUJBQW1CLENBQUM7QUFDbkcseUNBQXlDO0FBQ3pDLE9BQU8sRUFBRSxlQUFlLEVBQWlCLE1BQU0sZUFBZSxDQUFDO0FBQy9ELGtCQUFrQjtBQUNsQixPQUFPLEVBQ04seUJBQXlCLEVBQ3pCLDhCQUE4QixHQUc5QixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLHlCQUF5QjtBQUN6QixPQUFPLEVBQ04sZUFBZSxFQUVmLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIsZ0JBQWdCLEVBQ2hCLGtCQUFrQixFQUNsQixZQUFZLEVBQ1osV0FBVyxFQUNYLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLGtCQUFrQixFQUNsQixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQixTQUFTLEVBSVQsYUFBYSxFQUNiLFdBQVcsRUFDWCxzQkFBc0IsRUFDdEIsZUFBZSxFQUNmLGlCQUFpQixHQUVqQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFFTixTQUFTLEVBQ1QsYUFBYSxFQUViLFdBQVcsRUFPWCxHQUFHLEdBQ0gsTUFBTSxVQUFVLENBQUM7QUFDbEIsWUFBWTtBQUNaLE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQ1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIvLyBDb3JlIFRVSSBpbnRlcmZhY2VzIGFuZCBjbGFzc2VzXFxuXFxuLy8gQXV0b2NvbXBsZXRlIHN1cHBvcnRcXG5leHBvcnQge1xcblxcdHR5cGUgQXV0b2NvbXBsZXRlSXRlbSxcXG5cXHR0eXBlIEF1dG9jb21wbGV0ZVByb3ZpZGVyLFxcblxcdHR5cGUgQXV0b2NvbXBsZXRlU3VnZ2VzdGlvbnMsXFxuXFx0Q29tYmluZWRBdXRvY29tcGxldGVQcm92aWRlcixcXG5cXHR0eXBlIFNsYXNoQ29tbWFuZCxcXG59IGZyb20gXFxcIi4vYXV0b2NvbXBsZXRlLnRzXFxcIjtcXG4vLyBDb21wb25lbnRzXFxuZXhwb3J0IHsgQm94IH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL2JveC50c1xcXCI7XFxuZXhwb3J0IHsgQ2FuY2VsbGFibGVMb2FkZXIgfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvY2FuY2VsbGFibGUtbG9hZGVyLnRzXFxcIjtcXG5leHBvcnQgeyBFZGl0b3IsIHR5cGUgRWRpdG9yT3B0aW9ucywgdHlwZSBFZGl0b3JUaGVtZSB9IGZyb20gXFxcIi4vY29tcG9uZW50cy9lZGl0b3IudHNcXFwiO1xcbmV4cG9ydCB7IEltYWdlLCB0eXBlIEltYWdlT3B0aW9ucywgdHlwZSBJbWFnZVRoZW1lIH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL2ltYWdlLnRzXFxcIjtcXG5leHBvcnQgeyBJbnB1dCB9IGZyb20gXFxcIi4vY29tcG9uZW50cy9pbnB1dC50c1xcXCI7XFxuZXhwb3J0IHsgTG9hZGVyLCB0eXBlIExvYWRlckluZGljYXRvck9wdGlvbnMgfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvbG9hZGVyLnRzXFxcIjtcXG5leHBvcnQgeyB0eXBlIERlZmF1bHRUZXh0U3R5bGUsIE1hcmtkb3duLCB0eXBlIE1hcmtkb3duT3B0aW9ucywgdHlwZSBNYXJrZG93blRoZW1lIH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL21hcmtkb3duLnRzXFxcIjtcXG5leHBvcnQge1xcblxcdHR5cGUgU2VsZWN0SXRlbSxcXG5cXHRTZWxlY3RMaXN0LFxcblxcdHR5cGUgU2VsZWN0TGlzdExheW91dE9wdGlvbnMsXFxuXFx0dHlwZSBTZWxlY3RMaXN0VGhlbWUsXFxuXFx0dHlwZSBTZWxlY3RMaXN0VHJ1bmNhdGVQcmltYXJ5Q29udGV4dCxcXG59IGZyb20gXFxcIi4vY29tcG9uZW50cy9zZWxlY3QtbGlzdC50c1xcXCI7XFxuZXhwb3J0IHsgdHlwZSBTZXR0aW5nSXRlbSwgU2V0dGluZ3NMaXN0LCB0eXBlIFNldHRpbmdzTGlzdFRoZW1lIH0gZnJvbSBcXFwiLi9jb21wb25lbnRzL3NldHRpbmdzLWxpc3QudHNcXFwiO1xcbmV4cG9ydCB7IFNwYWNlciB9IGZyb20gXFxcIi4vY29tcG9uZW50cy9zcGFjZXIudHNcXFwiO1xcbmV4cG9ydCB7IFRleHQgfSBmcm9tIFxcXCIuL2NvbXBvbmVudHMvdGV4dC50c1xcXCI7XFxuZXhwb3J0IHsgVHJ1bmNhdGVkVGV4dCB9IGZyb20gXFxcIi4vY29tcG9uZW50cy90cnVuY2F0ZWQtdGV4dC50c1xcXCI7XFxuLy8gRWRpdG9yIGNvbXBvbmVudCBpbnRlcmZhY2UgKGZvciBjdXN0b20gZWRpdG9ycylcXG5leHBvcnQgdHlwZSB7IEVkaXRvckNvbXBvbmVudCB9IGZyb20gXFxcIi4vZWRpdG9yLWNvbXBvbmVudC50c1xcXCI7XFxuLy8gRnV6enkgbWF0Y2hpbmdcXG5leHBvcnQgeyB0eXBlIEZ1enp5TWF0Y2gsIGZ1enp5RmlsdGVyLCBmdXp6eU1hdGNoIH0gZnJvbSBcXFwiLi9mdXp6eS50c1xcXCI7XFxuLy8gS2V5YmluZGluZ3NcXG5leHBvcnQge1xcblxcdGdldEtleWJpbmRpbmdzLFxcblxcdHR5cGUgS2V5YmluZGluZyxcXG5cXHR0eXBlIEtleWJpbmRpbmdDb25mbGljdCxcXG5cXHR0eXBlIEtleWJpbmRpbmdEZWZpbml0aW9uLFxcblxcdHR5cGUgS2V5YmluZGluZ0RlZmluaXRpb25zLFxcblxcdHR5cGUgS2V5YmluZGluZ3MsXFxuXFx0dHlwZSBLZXliaW5kaW5nc0NvbmZpZyxcXG5cXHRLZXliaW5kaW5nc01hbmFnZXIsXFxuXFx0c2V0S2V5YmluZGluZ3MsXFxuXFx0VFVJX0tFWUJJTkRJTkdTLFxcbn0gZnJvbSBcXFwiLi9rZXliaW5kaW5ncy50c1xcXCI7XFxuLy8gS2V5Ym9hcmQgaW5wdXQgaGFuZGxpbmdcXG5leHBvcnQge1xcblxcdGRlY29kZUtpdHR5UHJpbnRhYmxlLFxcblxcdGlzS2V5UmVsZWFzZSxcXG5cXHRpc0tleVJlcGVhdCxcXG5cXHRpc0tpdHR5UHJvdG9jb2xBY3RpdmUsXFxuXFx0S2V5LFxcblxcdHR5cGUgS2V5RXZlbnRUeXBlLFxcblxcdHR5cGUgS2V5SWQsXFxuXFx0bWF0Y2hlc0tleSxcXG5cXHRwYXJzZUtleSxcXG5cXHRzZXRLaXR0eVByb3RvY29sQWN0aXZlLFxcbn0gZnJvbSBcXFwiLi9rZXlzLnRzXFxcIjtcXG4vLyBJbnB1dCBidWZmZXJpbmcgZm9yIGJhdGNoIHNwbGl0dGluZ1xcbmV4cG9ydCB7IFN0ZGluQnVmZmVyLCB0eXBlIFN0ZGluQnVmZmVyRXZlbnRNYXAsIHR5cGUgU3RkaW5CdWZmZXJPcHRpb25zIH0gZnJvbSBcXFwiLi9zdGRpbi1idWZmZXIudHNcXFwiO1xcbi8vIFRlcm1pbmFsIGludGVyZmFjZSBhbmQgaW1wbGVtZW50YXRpb25zXFxuZXhwb3J0IHsgUHJvY2Vzc1Rlcm1pbmFsLCB0eXBlIFRlcm1pbmFsIH0gZnJvbSBcXFwiLi90ZXJtaW5hbC50c1xcXCI7XFxuLy8gVGVybWluYWwgY29sb3JzXFxuZXhwb3J0IHtcXG5cXHRwYXJzZU9zYzExQmFja2dyb3VuZENvbG9yLFxcblxcdHBhcnNlVGVybWluYWxDb2xvclNjaGVtZVJlcG9ydCxcXG5cXHR0eXBlIFJnYkNvbG9yLFxcblxcdHR5cGUgVGVybWluYWxDb2xvclNjaGVtZSxcXG59IGZyb20gXFxcIi4vdGVybWluYWwtY29sb3JzLnRzXFxcIjtcXG4vLyBUZXJtaW5hbCBpbWFnZSBzdXBwb3J0XFxuZXhwb3J0IHtcXG5cXHRhbGxvY2F0ZUltYWdlSWQsXFxuXFx0dHlwZSBDZWxsRGltZW5zaW9ucyxcXG5cXHRjYWxjdWxhdGVJbWFnZVJvd3MsXFxuXFx0ZGVsZXRlQWxsS2l0dHlJbWFnZXMsXFxuXFx0ZGVsZXRlS2l0dHlJbWFnZSxcXG5cXHRkZXRlY3RDYXBhYmlsaXRpZXMsXFxuXFx0ZW5jb2RlSVRlcm0yLFxcblxcdGVuY29kZUtpdHR5LFxcblxcdGdldENhcGFiaWxpdGllcyxcXG5cXHRnZXRDZWxsRGltZW5zaW9ucyxcXG5cXHRnZXRHaWZEaW1lbnNpb25zLFxcblxcdGdldEltYWdlRGltZW5zaW9ucyxcXG5cXHRnZXRKcGVnRGltZW5zaW9ucyxcXG5cXHRnZXRQbmdEaW1lbnNpb25zLFxcblxcdGdldFdlYnBEaW1lbnNpb25zLFxcblxcdGh5cGVybGluayxcXG5cXHR0eXBlIEltYWdlRGltZW5zaW9ucyxcXG5cXHR0eXBlIEltYWdlUHJvdG9jb2wsXFxuXFx0dHlwZSBJbWFnZVJlbmRlck9wdGlvbnMsXFxuXFx0aW1hZ2VGYWxsYmFjayxcXG5cXHRyZW5kZXJJbWFnZSxcXG5cXHRyZXNldENhcGFiaWxpdGllc0NhY2hlLFxcblxcdHNldENhcGFiaWxpdGllcyxcXG5cXHRzZXRDZWxsRGltZW5zaW9ucyxcXG5cXHR0eXBlIFRlcm1pbmFsQ2FwYWJpbGl0aWVzLFxcbn0gZnJvbSBcXFwiLi90ZXJtaW5hbC1pbWFnZS50c1xcXCI7XFxuZXhwb3J0IHtcXG5cXHR0eXBlIENvbXBvbmVudCxcXG5cXHRDb250YWluZXIsXFxuXFx0Q1VSU09SX01BUktFUixcXG5cXHR0eXBlIEZvY3VzYWJsZSxcXG5cXHRpc0ZvY3VzYWJsZSxcXG5cXHR0eXBlIE92ZXJsYXlBbmNob3IsXFxuXFx0dHlwZSBPdmVybGF5SGFuZGxlLFxcblxcdHR5cGUgT3ZlcmxheU1hcmdpbixcXG5cXHR0eXBlIE92ZXJsYXlPcHRpb25zLFxcblxcdHR5cGUgT3ZlcmxheVVuZm9jdXNPcHRpb25zLFxcblxcdHR5cGUgU2l6ZVZhbHVlLFxcblxcdFRVSSxcXG59IGZyb20gXFxcIi4vdHVpLnRzXFxcIjtcXG4vLyBVdGlsaXRpZXNcXG5leHBvcnQgeyBzbGljZUJ5Q29sdW1uLCB0cnVuY2F0ZVRvV2lkdGgsIHZpc2libGVXaWR0aCwgd3JhcFRleHRXaXRoQW5zaSB9IGZyb20gXFxcIi4vdXRpbHMudHNcXFwiO1xcblwiXX1cbm5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktdHVpL2Rpc3QvaW5kZXguZC50czpleHBvcnQgeyBFZGl0b3IsIHR5cGUgRWRpdG9yT3B0aW9ucywgdHlwZSBFZGl0b3JUaGVtZSB9IGZyb20gXCIuL2NvbXBvbmVudHMvZWRpdG9yLnRzXCI7XG5ub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLXR1aS9kaXN0L2luZGV4LmQudHM6ZXhwb3J0IHsgSW1hZ2UsIHR5cGUgSW1hZ2VPcHRpb25zLCB0eXBlIEltYWdlVGhlbWUgfSBmcm9tIFwiLi9jb21wb25lbnRzL2ltYWdlLnRzXCI7XG5ub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLXR1aS9kaXN0L2luZGV4LmQudHM6ZXhwb3J0IHsgdHlwZSBEZWZhdWx0VGV4dFN0eWxlLCBNYXJrZG93biwgdHlwZSBNYXJrZG93bk9wdGlvbnMsIHR5cGUgTWFya2Rvd25UaGVtZSB9IGZyb20gXCIuL2NvbXBvbmVudHMvbWFya2Rvd24udHNcIjtcbm5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktdHVpL2Rpc3QvaW5kZXguZC50czpleHBvcnQgeyB0eXBlIFNlbGVjdEl0ZW0sIFNlbGVjdExpc3QsIHR5cGUgU2VsZWN0TGlzdExheW91dE9wdGlvbnMsIHR5cGUgU2VsZWN0TGlzdFRoZW1lLCB0eXBlIFNlbGVjdExpc3RUcnVuY2F0ZVByaW1hcnlDb250ZXh0LCB9IGZyb20gXCIuL2NvbXBvbmVudHMvc2VsZWN0LWxpc3QudHNcIjsiLCJ0cnVuY2F0ZWQiOnRydWUsInRydW5jYXRlZEJ5IjoiYnl0ZXMiLCJ0b3RhbExpbmVzIjoyMCwidG90YWxCeXRlcyI6NDA2MDA1LCJvdXRwdXRMaW5lcyI6NSwib3V0cHV0Qnl0ZXMiOjU3OTIsImxhc3RMaW5lUGFydGlhbCI6ZmFsc2UsImZpcnN0TGluZUV4Y2VlZHNMaW1pdCI6ZmFsc2UsIm1heExpbmVzIjoyMDAwLCJtYXhCeXRlcyI6NTEyMDB9LCJmdWxsT3V0cHV0UGF0aCI6Ii92YXIvZm9sZGVycy9kYy94OGI5OTF0ZDU1NWdfOGZiNXhfZzlkNDAwMDAwZ24vVC9waS1iYXNoLTJlOTgyMmI0MDRiMTUzOTkubG9nIn0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkyMDQwMjF9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3NDE1Y2JkMiIsInBhcmVudElkIjoiYWQyMjJiNGUiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA2OjQ0LjAyMVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6Imc5QkRrTzR5STlWd1R5QWs5TG9yRFRNbVhMVTZ6WUg5IiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiZXhwb3J0IHsgZ2V0S2V5YmluZGluZ3MsIHR5cGUgS2V5YmluZGluZywgdHlwZSBLZXliaW5kaW5nQ29uZmxpY3QsIHR5cGUgS2V5YmluZGluZ0RlZmluaXRpb24sIHR5cGUgS2V5YmluZGluZ0RlZmluaXRpb25zLCB0eXBlIEtleWJpbmRpbmdzLCB0eXBlIEtleWJpbmRpbmdzQ29uZmlnLCBLZXliaW5kaW5nc01hbmFnZXIsIHNldEtleWJpbmRpbmdzLCBUVUlfS0VZQklORElOR1MsIH0gZnJvbSBcIi4va2V5YmluZGluZ3MudHNcIjtcbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzOTIwNDAyMX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjcwYTMxYTkyIiwicGFyZW50SWQiOiI3NDE1Y2JkMiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDY6NTkuNTIyWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiYFRoZW1lYCBpcyBub3QgZXhwb3J0ZWQgZnJvbSBwaS10dWkuIExvb2tpbmcgYXQgdGhlIHF1ZXN0aW9uLnRzIGV4YW1wbGUgaW4gdGhlIHBpIGRvY3MsIGl0IHVzZXMgYGN0eC51aS50aGVtZWAgd2hpY2ggaXMgYSBwcm9wZXJ0eSBvbiB0aGUgVUkgY29udGV4dCwgbm90IGEgZGlyZWN0IGltcG9ydC4gVGhlIHRoZW1lIHR5cGUgaXMgbGlrZWx5IGludGVybmFsIHRvIHBpLWNvZGluZy1hZ2VudC4gTGV0IG1lIGNoZWNrIHdoYXQgdHlwZXMgYXJlIGF2YWlsYWJsZS5cblxuSW4gdGhlIGV4dGVuc2lvbiBkb2NzLCB0aGUgYHJlbmRlckNhbGxgIGFuZCBgcmVuZGVyUmVzdWx0YCBjYWxsYmFja3MgcmVjZWl2ZSBhIGB0aGVtZWAgcGFyYW1ldGVyLiBUaGUgYGN0eC51aS5jdXN0b20oKWAgY2FsbGJhY2sgYWxzbyByZWNlaXZlcyBgdGhlbWVgLiBCdXQgYFRoZW1lYCBpcyBub3QgZXhwb3J0ZWQgZnJvbSBwaS10dWkuXG5cbkxldCBtZSBsb29rIGF0IGhvdyB0aGUgcXVlc3Rpb24udHMgZXhhbXBsZSBoYW5kbGVzIHRoaXMgLSBpdCBkb2Vzbid0IGltcG9ydCBUaGVtZSwgaXQganVzdCB1c2VzIGl0IGFzIGEgcGFyYW1ldGVyIHR5cGUuIFRoZSB0aGVtZSB0eXBlIGlzIGxpa2VseSBkZWZpbmVkIGluIHBpLWNvZGluZy1hZ2VudC5cblxuTGV0IG1lIGNoZWNrIHdoYXQgdHlwZXMgYXJlIGF2YWlsYWJsZSBpbiBwaS10dWkgZm9yIHRoZSB0aGVtZTpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiQXRqaFA1dHJadm9RdHM2ZzRHR25ETEg3SGowWHBNUzUiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCAtciBcImludGVyZmFjZSBUaGVtZVxcfHR5cGUgVGhlbWVcXHxjbGFzcyBUaGVtZVwiIG5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktdHVpL2Rpc3QvIDI+L2Rldi9udWxsIHwgaGVhZCAtMTAifX0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6Im1iU2JlTUpseWFJWk5LbEM5dFJkUVdIRFZHenAyQjZLIiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlICYmIGdyZXAgXCJ0aGVtZVwiIG5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2Rpc3QvY29yZS9leHRlbnNpb24vZXh0ZW5zaW9uLWNvbnRleHQuZC50cyAyPi9kZXYvbnVsbCB8IGhlYWQgLTEwIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoyMjIwLCJvdXRwdXQiOjMyNywiY2FjaGVSZWFkIjo3MTA5NSwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjczNjQyLCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5MzkyMDQwMjEsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC1RamVVVHhVNnBkMHRjUHp3T095d0NtQ05rNzFMR1RZNSJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIyNTc0ZThjZCIsInBhcmVudElkIjoiNzBhMzFhOTIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA2OjU5LjYwNVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IkF0amhQNXRyWnZvUXRzNmc0R0duRExIN0hqMFhwTVM1IiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiKG5vIG91dHB1dCkifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkyMTk2MDV9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI4ZjZhM2Y5NiIsInBhcmVudElkIjoiMjU3NGU4Y2QiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA2OjU5LjYwNVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6Im1iU2JlTUpseWFJWk5LbEM5dFJkUVdIRFZHenAyQjZLIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiKG5vIG91dHB1dCkifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkyMTk2MDV9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI0MGFmZjI2OCIsInBhcmVudElkIjoiOGY2YTNmOTYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA3OjA1LjE1OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkxldCBtZSBsb29rIGF0IGhvdyB0aGUgcXVlc3Rpb24udHMgZXhhbXBsZSBoYW5kbGVzIHRoZSB0aGVtZSB0eXBlLiBJdCBkb2Vzbid0IGltcG9ydCBUaGVtZSBleHBsaWNpdGx5IC0gaXQganVzdCB1c2VzIGl0IGFzIGEgcGFyYW1ldGVyLiBMZXQgbWUgbG9vayBhdCB0aGUgcGktdHVpIHR1aS50cyBmaWxlIGZvciB0aGUgdGhlbWUgdHlwZTpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiMW9aNTEzVnY4MGhvMEpndzRlTWh1MjhSYkZ2ZFZ2OUUiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCAtciBcInRoZW1lXCIgbm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS10dWkvZGlzdC90dWkuZC50cyAyPi9kZXYvbnVsbCB8IGhlYWQgLTEwIn19LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJHOERXd1AzVUhneTk5RmxGZ2JRVDJvSFM0bXlNcFRveCIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBjYXQgbm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS10dWkvZGlzdC9jb21wb25lbnRzL3RleHQuZC50cyAyPi9kZXYvbnVsbCJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MjcsIm91dHB1dCI6MTg3LCJjYWNoZVJlYWQiOjczNjQxLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6NzM4NTUsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzOTIxOTYwNSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLTdTWkRaeHlwWlpWTFAxN1BPblVTTTJVd3dnTlp6WlVaIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjA1NGQzMGY2IiwicGFyZW50SWQiOiI0MGFmZjI2OCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDc6MDUuMTc0WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiMW9aNTEzVnY4MGhvMEpndzRlTWh1MjhSYkZ2ZFZ2OUUiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLXR1aS9kaXN0L3R1aS5kLnRzOiAgICAgKiBDYWxsZWQgd2hlbiB0aGVtZSBjaGFuZ2VzIG9yIHdoZW4gY29tcG9uZW50IG5lZWRzIHRvIHJlLXJlbmRlciBmcm9tIHNjcmF0Y2guXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkyMjUxNzR9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJlZWVjZjg3MSIsInBhcmVudElkIjoiMDU0ZDMwZjYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA3OjA1LjE3NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6Ikc4RFd3UDNVSGd5OTlGbEZnYlFUMm9IUzRteU1wVG94IiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiaW1wb3J0IHR5cGUgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vdHVpLnRzXCI7XG4vKipcbiAqIFRleHQgY29tcG9uZW50IC0gZGlzcGxheXMgbXVsdGktbGluZSB0ZXh0IHdpdGggd29yZCB3cmFwcGluZ1xuICovXG5leHBvcnQgZGVjbGFyZSBjbGFzcyBUZXh0IGltcGxlbWVudHMgQ29tcG9uZW50IHtcbiAgICBwcml2YXRlIHRleHQ7XG4gICAgcHJpdmF0ZSBwYWRkaW5nWDtcbiAgICBwcml2YXRlIHBhZGRpbmdZO1xuICAgIHByaXZhdGUgY3VzdG9tQmdGbj87XG4gICAgcHJpdmF0ZSBjYWNoZWRUZXh0PztcbiAgICBwcml2YXRlIGNhY2hlZFdpZHRoPztcbiAgICBwcml2YXRlIGNhY2hlZExpbmVzPztcbiAgICBjb25zdHJ1Y3Rvcih0ZXh0Pzogc3RyaW5nLCBwYWRkaW5nWD86IG51bWJlciwgcGFkZGluZ1k/OiBudW1iZXIsIGN1c3RvbUJnRm4/OiAodGV4dDogc3RyaW5nKSA9PiBzdHJpbmcpO1xuICAgIHNldFRleHQodGV4dDogc3RyaW5nKTogdm9pZDtcbiAgICBzZXRDdXN0b21CZ0ZuKGN1c3RvbUJnRm4/OiAodGV4dDogc3RyaW5nKSA9PiBzdHJpbmcpOiB2b2lkO1xuICAgIGludmFsaWRhdGUoKTogdm9pZDtcbiAgICByZW5kZXIod2lkdGg6IG51bWJlcik6IHN0cmluZ1tdO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC5kLnRzLm1hcCJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzOTIyNTE3NH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImZlYjVmMDAwIiwicGFyZW50SWQiOiJlZWVjZjg3MSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDc6MTEuNTM4WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiVGhlIGBUaGVtZWAgdHlwZSBpcyBub3QgZXhwb3J0ZWQgZnJvbSBwaS10dWkuIEluIHRoZSBxdWVzdGlvbi50cyBleGFtcGxlIGZyb20gdGhlIGRvY3MsIGl0IHVzZXMgYEVkaXRvclRoZW1lYCBmcm9tIHBpLXR1aSBmb3IgdGhlIGVkaXRvciwgYW5kIHRoZSBgdGhlbWVgIHBhcmFtZXRlciBpbiB0aGUgY3VzdG9tIGNhbGxiYWNrIGlzIGp1c3QgdHlwZWQgaW1wbGljaXRseS4gTGV0IG1lIGxvb2sgYXQgaG93IHBpLWNvZGluZy1hZ2VudCBkZWZpbmVzIHRoZSB0aGVtZSB0eXBlLiBJdCdzIGxpa2VseSBkZWZpbmVkIGludGVybmFsbHkgaW4gcGktY29kaW5nLWFnZW50IGFuZCByZS1leHBvcnRlZCB0aHJvdWdoIHRoZSBleHRlbnNpb24gQVBJLlxuXG5MZXQgbWUgY2hlY2sgaWYgcGktY29kaW5nLWFnZW50IGV4cG9ydHMgYSBUaGVtZSB0eXBlOlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjcW5XVDJoaXZCOXhsMWlFSDA3MmJBMTdMbTlaelg0RSIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBncmVwIC1yIFwiVGhlbWVcIiBub2RlX21vZHVsZXMvQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudC9kaXN0LyAyPi9kZXYvbnVsbCB8IGdyZXAgLUUgXCJleHBvcnQuKlRoZW1lfHR5cGUgVGhlbWV8aW50ZXJmYWNlIFRoZW1lXCIgfCBoZWFkIC0xMCJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MjE3LCJvdXRwdXQiOjE4OCwiY2FjaGVSZWFkIjo3Mzg1NCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjc0MjU5LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5MzkyMjUxNzUsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC14emZmcFlpdTdOVjBqS0NnYlc2MW1KYkJGajFYQ01DeiJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJiODYwMTQ0YSIsInBhcmVudElkIjoiZmViNWYwMDAiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA3OjExLjU3NloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNxbldUMmhpdkI5eGwxaUVIMDcyYkExN0xtOVp6WDRFIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoibm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnQvZGlzdC9jb3JlL3Rvb2xzL2VkaXQuZC50cy5tYXA6e1widmVyc2lvblwiOjMsXCJmaWxlXCI6XCJlZGl0LmQudHNcIixcInNvdXJjZVJvb3RcIjpcIlwiLFwic291cmNlc1wiOltcIi4uLy4uLy4uL3NyYy9jb3JlL3Rvb2xzL2VkaXQudHNcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDL0QsT0FBTyxFQUFFLEdBQUcsRUFBMkIsTUFBTSx3QkFBd0IsQ0FBQztBQUd0RSxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRzVDLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdELE9BQU8sRUFLTixLQUFLLGFBQWEsRUFDbEIsS0FBSyxjQUFjLEVBTW5CLE1BQU0sZ0JBQWdCLENBQUM7QUFNeEIsS0FBSyxXQUFXLEdBQUcsY0FBYyxHQUFHLGFBQWEsQ0FBQztBQUVsRCxLQUFLLGVBQWUsR0FBRztJQUN0QixhQUFhLENBQUMsRUFBRSx1QkFBdUIsQ0FBQztDQUN4QyxDQUFDO0FBYUYsUUFBQSxNQUFNLFVBQVU7Ozs7OztFQVNmLENBQUM7QUFFRixNQUFNLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxPQUFPLFVBQVUsQ0FBQyxDQUFDO0FBTXRELE1BQU0sV0FBVyxlQUFlO0lBQy9CLGdEQUFnRDtJQUNoRCxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsaURBQWlEO0lBQ2pELEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCw4RUFBOEU7SUFDOUUsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDMUI7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFdBQVcsY0FBYztJQUM5QixxQ0FBcUM7SUFDckMsUUFBUSxFQUFFLENBQUMsWUFBWSxFQUFFLE1BQU0sS0FBSyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDcEQsOEJBQThCO0lBQzlCLFNBQVMsRUFBRSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sS0FBSyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEUsNERBQTREO0lBQzVELE1BQU0sRUFBRSxDQUFDLFlBQVksRUFBRSxNQUFNLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ2hEO0FBUUQsTUFBTSxXQUFXLGVBQWU7SUFDL0Isb0VBQW9FO0lBQ3BFLFVBQVUsQ0FBQyxFQUFFLGNBQWMsQ0FBQztDQUM1QjtBQWdERCxLQUFLLHVCQUF1QixHQUFHLEdBQUcsR0FBRztJQUNwQyxPQUFPLENBQUMsRUFBRSxXQUFXLENBQUM7SUFDdEIsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3hCLGNBQWMsQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUN6QixZQUFZLENBQUMsRUFBRSxPQUFPLENBQUM7Q0FDdkIsQ0FBQztBQThJRix3QkFBZ0Isd0JBQXdCLENBQ3ZDLEdBQUcsRUFBRSxNQUFNLEVBQ1gsT0FBTyxDQUFDLEVBQUUsZUFBZSxHQUN2QixjQUFjLENBQUMsT0FBTyxVQUFVLEVBQUUsZUFBZSxHQUFHLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0ErSWpGO0FBRUQsd0JBQWdCLGNBQWMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxFQUFFLGVBQWUsR0FBRyxTQUFTLENBQUMsT0FBTyxVQUFVLENBQUMsQ0FFbkdcIixcInNvdXJjZXNDb250ZW50XCI6W1wiaW1wb3J0IHR5cGUgeyBBZ2VudFRvb2wgfSBmcm9tIFxcXCJAZWFyZW5kaWwtd29ya3MvcGktYWdlbnQtY29yZVxcXCI7XFxuaW1wb3J0IHsgQm94LCBDb250YWluZXIsIFNwYWNlciwgVGV4dCB9IGZyb20gXFxcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcXFwiO1xcbmltcG9ydCB7IGNvbnN0YW50cyB9IGZyb20gXFxcImZzXFxcIjtcXG5pbXBvcnQgeyBhY2Nlc3MgYXMgZnNBY2Nlc3MsIHJlYWRGaWxlIGFzIGZzUmVhZEZpbGUsIHdyaXRlRmlsZSBhcyBmc1dyaXRlRmlsZSB9IGZyb20gXFxcImZzL3Byb21pc2VzXFxcIjtcXG5pbXBvcnQgeyB0eXBlIFN0YXRpYywgVHlwZSB9IGZyb20gXFxcInR5cGVib3hcXFwiO1xcbmltcG9ydCB7IHJlbmRlckRpZmYgfSBmcm9tIFxcXCIuLi8uLi9tb2Rlcy9pbnRlcmFjdGl2ZS9jb21wb25lbnRzL2RpZmYudHNcXFwiO1xcbmltcG9ydCB0eXBlIHsgVGhlbWUgfSBmcm9tIFxcXCIuLi8uLi9tb2Rlcy9pbnRlcmFjdGl2ZS90aGVtZS90aGVtZS50c1xcXCI7XFxuaW1wb3J0IHR5cGUgeyBUb29sRGVmaW5pdGlvbiB9IGZyb20gXFxcIi4uL2V4dGVuc2lvbnMvdHlwZXMudHNcXFwiO1xcbmltcG9ydCB7XFxuXFx0YXBwbHlFZGl0c1RvTm9ybWFsaXplZENvbnRlbnQsXFxuXFx0Y29tcHV0ZUVkaXRzRGlmZixcXG5cXHRkZXRlY3RMaW5lRW5kaW5nLFxcblxcdHR5cGUgRWRpdCxcXG5cXHR0eXBlIEVkaXREaWZmRXJyb3IsXFxuXFx0dHlwZSBFZGl0RGlmZlJlc3VsdCxcXG5cXHRnZW5lcmF0ZURpZmZTdHJpbmcsXFxuXFx0Z2VuZXJhdGVVbmlmaWVkUGF0Y2gsXFxuXFx0bm9ybWFsaXplVG9MRixcXG5cXHRyZXN0b3JlTGluZUVuZGluZ3MsXFxuXFx0c3RyaXBCb20sXFxufSBmcm9tIFxcXCIuL2VkaXQtZGlmZi50c1xcXCI7XFxuaW1wb3J0IHsgd2l0aEZpbGVNdXRhdGlvblF1ZXVlIH0gZnJvbSBcXFwiLi9maWxlLW11dGF0aW9uLXF1ZXVlLnRzXFxcIjtcXG5pbXBvcnQgeyByZXNvbHZlVG9Dd2QgfSBmcm9tIFxcXCIuL3BhdGgtdXRpbHMudHNcXFwiO1xcbmltcG9ydCB7IHJlbmRlclRvb2xQYXRoLCBzdHIgfSBmcm9tIFxcXCIuL3JlbmRlci11dGlscy50c1xcXCI7XFxuaW1wb3J0IHsgd3JhcFRvb2xEZWZpbml0aW9uIH0gZnJvbSBcXFwiLi90b29sLWRlZmluaXRpb24td3JhcHBlci50c1xcXCI7XFxuXFxudHlwZSBFZGl0UHJldmlldyA9IEVkaXREaWZmUmVzdWx0IHwgRWRpdERpZmZFcnJvcjtcXG5cXG50eXBlIEVkaXRSZW5kZXJTdGF0ZSA9IHtcXG5cXHRjYWxsQ29tcG9uZW50PzogRWRpdENhbGxSZW5kZXJDb21wb25lbnQ7XFxufTtcXG5cXG5jb25zdCByZXBsYWNlRWRpdFNjaGVtYSA9IFR5cGUuT2JqZWN0KFxcblxcdHtcXG5cXHRcXHRvbGRUZXh0OiBUeXBlLlN0cmluZyh7XFxuXFx0XFx0XFx0ZGVzY3JpcHRpb246XFxuXFx0XFx0XFx0XFx0XFxcIkV4YWN0IHRleHQgZm9yIG9uZSB0YXJnZXRlZCByZXBsYWNlbWVudC4gSXQgbXVzdCBiZSB1bmlxdWUgaW4gdGhlIG9yaWdpbmFsIGZpbGUgYW5kIG11c3Qgbm90IG92ZXJsYXAgd2l0aCBhbnkgb3RoZXIgZWRpdHNbXS5vbGRUZXh0IGluIHRoZSBzYW1lIGNhbGwuXFxcIixcXG5cXHRcXHR9KSxcXG5cXHRcXHRuZXdUZXh0OiBUeXBlLlN0cmluZyh7IGRlc2NyaXB0aW9uOiBcXFwiUmVwbGFjZW1lbnQgdGV4dCBmb3IgdGhpcyB0YXJnZXRlZCBlZGl0LlxcXCIgfSksXFxuXFx0fSxcXG5cXHR7IGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSB9LFxcbik7XFxuXFxuY29uc3QgZWRpdFNjaGVtYSA9IFR5cGUuT2JqZWN0KFxcblxcdHtcXG5cXHRcXHRwYXRoOiBUeXBlLlN0cmluZyh7IGRlc2NyaXB0aW9uOiBcXFwiUGF0aCB0byB0aGUgZmlsZSB0byBlZGl0IChyZWxhdGl2ZSBvciBhYnNvbHV0ZSlcXFwiIH0pLFxcblxcdFxcdGVkaXRzOiBUeXBlLkFycmF5KHJlcGxhY2VFZGl0U2NoZW1hLCB7XFxuXFx0XFx0XFx0ZGVzY3JpcHRpb246XFxuXFx0XFx0XFx0XFx0XFxcIk9uZSBvciBtb3JlIHRhcmdldGVkIHJlcGxhY2VtZW50cy4gRWFjaCBlZGl0IGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgb3JpZ2luYWwgZmlsZSwgbm90IGluY3JlbWVudGFsbHkuIERvIG5vdCBpbmNsdWRlIG92ZXJsYXBwaW5nIG9yIG5lc3RlZCBlZGl0cy4gSWYgdHdvIGNoYW5nZXMgdG91Y2ggdGhlIHNhbWUgYmxvY2sgb3IgbmVhcmJ5IGxpbmVzLCBtZXJnZSB0aGVtIGludG8gb25lIGVkaXQgaW5zdGVhZC5cXFwiLFxcblxcdFxcdH0pLFxcblxcdH0sXFxuXFx0eyBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UgfSxcXG4pO1xcblxcbmV4cG9ydCB0eXBlIEVkaXRUb29sSW5wdXQgPSBTdGF0aWM8dHlwZW9mIGVkaXRTY2hlbWE+O1xcbnR5cGUgTGVnYWN5RWRpdFRvb2xJbnB1dCA9IEVkaXRUb29sSW5wdXQgJiB7XFxuXFx0b2xkVGV4dD86IHVua25vd247XFxuXFx0bmV3VGV4dD86IHVua25vd247XFxufTtcXG5cXG5leHBvcnQgaW50ZXJmYWNlIEVkaXRUb29sRGV0YWlscyB7XFxuXFx0LyoqIERpc3BsYXktb3JpZW50ZWQgZGlmZiBvZiB0aGUgY2hhbmdlcyBtYWRlICovXFxuXFx0ZGlmZjogc3RyaW5nO1xcblxcdC8qKiBTdGFuZGFyZCB1bmlmaWVkIHBhdGNoIG9mIHRoZSBjaGFuZ2VzIG1hZGUgKi9cXG5cXHRwYXRjaDogc3RyaW5nO1xcblxcdC8qKiBMaW5lIG51bWJlciBvZiB0aGUgZmlyc3QgY2hhbmdlIGluIHRoZSBuZXcgZmlsZSAoZm9yIGVkaXRvciBuYXZpZ2F0aW9uKSAqL1xcblxcdGZpcnN0Q2hhbmdlZExpbmU/OiBudW1iZXI7XFxufVxcblxcbi8qKlxcbiAqIFBsdWdnYWJsZSBvcGVyYXRpb25zIGZvciB0aGUgZWRpdCB0b29sLlxcbiAqIE92ZXJyaWRlIHRoZXNlIHRvIGRlbGVnYXRlIGZpbGUgZWRpdGluZyB0byByZW1vdGUgc3lzdGVtcyAoZm9yIGV4YW1wbGUgU1NIKS5cXG4gKi9cXG5leHBvcnQgaW50ZXJmYWNlIEVkaXRPcGVyYXRpb25zIHtcXG5cXHQvKiogUmVhZCBmaWxlIGNvbnRlbnRzIGFzIGEgQnVmZmVyICovXFxuXFx0cmVhZEZpbGU6IChhYnNvbHV0ZVBhdGg6IHN0cmluZykgPT4gUHJvbWlzZTxCdWZmZXI+O1xcblxcdC8qKiBXcml0ZSBjb250ZW50IHRvIGEgZmlsZSAqL1xcblxcdHdyaXRlRmlsZTogKGFic29sdXRlUGF0aDogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD47XFxuXFx0LyoqIENoZWNrIGlmIGZpbGUgaXMgcmVhZGFibGUgYW5kIHdyaXRhYmxlICh0aHJvdyBpZiBub3QpICovXFxuXFx0YWNjZXNzOiAoYWJzb2x1dGVQYXRoOiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD47XFxufVxcblxcbmNvbnN0IGRlZmF1bHRFZGl0T3BlcmF0aW9uczogRWRpdE9wZXJhdGlvbnMgPSB7XFxuXFx0cmVhZEZpbGU6IChwYXRoKSA9PiBmc1JlYWRGaWxlKHBhdGgpLFxcblxcdHdyaXRlRmlsZTogKHBhdGgsIGNvbnRlbnQpID0+IGZzV3JpdGVGaWxlKHBhdGgsIGNvbnRlbnQsIFxcXCJ1dGYtOFxcXCIpLFxcblxcdGFjY2VzczogKHBhdGgpID0+IGZzQWNjZXNzKHBhdGgsIGNvbnN0YW50cy5SX09LIHwgY29uc3RhbnRzLldfT0spLFxcbn07XFxuXFxuZXhwb3J0IGludGVyZmFjZSBFZGl0VG9vbE9wdGlvbnMge1xcblxcdC8qKiBDdXN0b20gb3BlcmF0aW9ucyBmb3IgZmlsZSBlZGl0aW5nLiBEZWZhdWx0OiBsb2NhbCBmaWxlc3lzdGVtICovXFxuXFx0b3BlcmF0aW9ucz86IEVkaXRPcGVyYXRpb25zO1xcbn1cXG5cXG5mdW5jdGlvbiBwcmVwYXJlRWRpdEFyZ3VtZW50cyhpbnB1dDogdW5rbm93bik6IEVkaXRUb29sSW5wdXQge1xcblxcdGlmICghaW5wdXQgfHwgdHlwZW9mIGlucHV0ICE9PSBcXFwib2JqZWN0XFxcIikge1xcblxcdFxcdHJldHVybiBpbnB1dCBhcyBFZGl0VG9vbElucHV0O1xcblxcdH1cXG5cXG5cXHRjb25zdCBhcmdzID0gaW5wdXQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XFxuXFxuXFx0Ly8gU29tZSBtb2RlbHMgKE9wdXMgNC42LCBHTE0tNS4xKSBzZW5kIGVkaXRzIGFzIGEgSlNPTiBzdHJpbmcgaW5zdGVhZCBvZiBhbiBhcnJheVxcblxcdGlmICh0eXBlb2YgYXJncy5lZGl0cyA9PT0gXFxcInN0cmluZ1xcXCIpIHtcXG5cXHRcXHR0cnkge1xcblxcdFxcdFxcdGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoYXJncy5lZGl0cyk7XFxuXFx0XFx0XFx0aWYgKEFycmF5LmlzQXJyYXkocGFyc2VkKSkgYXJncy5lZGl0cyA9IHBhcnNlZDtcXG5cXHRcXHR9IGNhdGNoIHt9XFxuXFx0fVxcblxcblxcdGNvbnN0IGxlZ2FjeSA9IGFyZ3MgYXMgTGVnYWN5RWRpdFRvb2xJbnB1dDtcXG5cXHRpZiAodHlwZW9mIGxlZ2FjeS5vbGRUZXh0ICE9PSBcXFwic3RyaW5nXFxcIiB8fCB0eXBlb2YgbGVnYWN5Lm5ld1RleHQgIT09IFxcXCJzdHJpbmdcXFwiKSB7XFxuXFx0XFx0cmV0dXJuIGFyZ3MgYXMgRWRpdFRvb2xJbnB1dDtcXG5cXHR9XFxuXFxuXFx0Y29uc3QgZWRpdHMgPSBBcnJheS5pc0FycmF5KGxlZ2FjeS5lZGl0cykgPyBbLi4ubGVnYWN5LmVkaXRzXSA6IFtdO1xcblxcdGVkaXRzLnB1c2goeyBvbGRUZXh0OiBsZWdhY3kub2xkVGV4dCwgbmV3VGV4dDogbGVnYWN5Lm5ld1RleHQgfSk7XFxuXFx0Y29uc3QgeyBvbGRUZXh0OiBfb2xkVGV4dCwgbmV3VGV4dDogX25ld1RleHQsIC4uLnJlc3QgfSA9IGxlZ2FjeTtcXG5cXHRyZXR1cm4geyAuLi5yZXN0LCBlZGl0cyB9IGFzIEVkaXRUb29sSW5wdXQ7XFxufVxcblxcbmZ1bmN0aW9uIHZhbGlkYXRlRWRpdElucHV0KGlucHV0OiBFZGl0VG9vbElucHV0KTogeyBwYXRoOiBzdHJpbmc7IGVkaXRzOiBFZGl0W10gfSB7XFxuXFx0aWYgKCFBcnJheS5pc0FycmF5KGlucHV0LmVkaXRzKSB8fCBpbnB1dC5lZGl0cy5sZW5ndGggPT09IDApIHtcXG5cXHRcXHR0aHJvdyBuZXcgRXJyb3IoXFxcIkVkaXQgdG9vbCBpbnB1dCBpcyBpbnZhbGlkLiBlZGl0cyBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIHJlcGxhY2VtZW50LlxcXCIpO1xcblxcdH1cXG5cXHRyZXR1cm4geyBwYXRoOiBpbnB1dC5wYXRoLCBlZGl0czogaW5wdXQuZWRpdHMgfTtcXG59XFxuXFxudHlwZSBSZW5kZXJhYmxlRWRpdEFyZ3MgPSB7XFxuXFx0cGF0aD86IHN0cmluZztcXG5cXHRmaWxlX3BhdGg/OiBzdHJpbmc7XFxuXFx0ZWRpdHM/OiBFZGl0W107XFxuXFx0b2xkVGV4dD86IHN0cmluZztcXG5cXHRuZXdUZXh0Pzogc3RyaW5nO1xcbn07XFxuXFxudHlwZSBFZGl0VG9vbFJlc3VsdExpa2UgPSB7XFxuXFx0Y29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ/OiBzdHJpbmc7IGRhdGE/OiBzdHJpbmc7IG1pbWVUeXBlPzogc3RyaW5nIH0+O1xcblxcdGRldGFpbHM/OiBFZGl0VG9vbERldGFpbHM7XFxufTtcXG5cXG50eXBlIEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50ID0gQm94ICYge1xcblxcdHByZXZpZXc/OiBFZGl0UHJldmlldztcXG5cXHRwcmV2aWV3QXJnc0tleT86IHN0cmluZztcXG5cXHRwcmV2aWV3UGVuZGluZz86IGJvb2xlYW47XFxuXFx0c2V0dGxlZEVycm9yPzogYm9vbGVhbjtcXG59O1xcblxcbmZ1bmN0aW9uIGNyZWF0ZUVkaXRDYWxsUmVuZGVyQ29tcG9uZW50KCk6IEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50IHtcXG5cXHRyZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgQm94KDEsIDEsICh0ZXh0OiBzdHJpbmcpID0+IHRleHQpLCB7XFxuXFx0XFx0cHJldmlldzogdW5kZWZpbmVkIGFzIEVkaXRQcmV2aWV3IHwgdW5kZWZpbmVkLFxcblxcdFxcdHByZXZpZXdBcmdzS2V5OiB1bmRlZmluZWQgYXMgc3RyaW5nIHwgdW5kZWZpbmVkLFxcblxcdFxcdHByZXZpZXdQZW5kaW5nOiBmYWxzZSxcXG5cXHRcXHRzZXR0bGVkRXJyb3I6IGZhbHNlLFxcblxcdH0pO1xcbn1cXG5cXG5mdW5jdGlvbiBnZXRFZGl0Q2FsbFJlbmRlckNvbXBvbmVudChzdGF0ZTogRWRpdFJlbmRlclN0YXRlLCBsYXN0Q29tcG9uZW50OiB1bmtub3duKTogRWRpdENhbGxSZW5kZXJDb21wb25lbnQge1xcblxcdGlmIChsYXN0Q29tcG9uZW50IGluc3RhbmNlb2YgQm94KSB7XFxuXFx0XFx0Y29uc3QgY29tcG9uZW50ID0gbGFzdENvbXBvbmVudCBhcyBFZGl0Q2FsbFJlbmRlckNvbXBvbmVudDtcXG5cXHRcXHRzdGF0ZS5jYWxsQ29tcG9uZW50ID0gY29tcG9uZW50O1xcblxcdFxcdHJldHVybiBjb21wb25lbnQ7XFxuXFx0fVxcblxcdGlmIChzdGF0ZS5jYWxsQ29tcG9uZW50KSB7XFxuXFx0XFx0cmV0dXJuIHN0YXRlLmNhbGxDb21wb25lbnQ7XFxuXFx0fVxcblxcdGNvbnN0IGNvbXBvbmVudCA9IGNyZWF0ZUVkaXRDYWxsUmVuZGVyQ29tcG9uZW50KCk7XFxuXFx0c3RhdGUuY2FsbENvbXBvbmVudCA9IGNvbXBvbmVudDtcXG5cXHRyZXR1cm4gY29tcG9uZW50O1xcbn1cXG5cXG5mdW5jdGlvbiBnZXRSZW5kZXJhYmxlUHJldmlld0lucHV0KGFyZ3M6IFJlbmRlcmFibGVFZGl0QXJncyB8IHVuZGVmaW5lZCk6IHsgcGF0aDogc3RyaW5nOyBlZGl0czogRWRpdFtdIH0gfCBudWxsIHtcXG5cXHRpZiAoIWFyZ3MpIHtcXG5cXHRcXHRyZXR1cm4gbnVsbDtcXG5cXHR9XFxuXFxuXFx0Y29uc3QgcGF0aCA9IHR5cGVvZiBhcmdzLnBhdGggPT09IFxcXCJzdHJpbmdcXFwiID8gYXJncy5wYXRoIDogdHlwZW9mIGFyZ3MuZmlsZV9wYXRoID09PSBcXFwic3RyaW5nXFxcIiA/IGFyZ3MuZmlsZV9wYXRoIDogbnVsbDtcXG5cXHRpZiAoIXBhdGgpIHtcXG5cXHRcXHRyZXR1cm4gbnVsbDtcXG5cXHR9XFxuXFxuXFx0aWYgKFxcblxcdFxcdEFycmF5LmlzQXJyYXkoYXJncy5lZGl0cykgJiZcXG5cXHRcXHRhcmdzLmVkaXRzLmxlbmd0aCA+IDAgJiZcXG5cXHRcXHRhcmdzLmVkaXRzLmV2ZXJ5KChlZGl0KSA9PiB0eXBlb2YgZWRpdD8ub2xkVGV4dCA9PT0gXFxcInN0cmluZ1xcXCIgJiYgdHlwZW9mIGVkaXQ/Lm5ld1RleHQgPT09IFxcXCJzdHJpbmdcXFwiKVxcblxcdCkge1xcblxcdFxcdHJldHVybiB7IHBhdGgsIGVkaXRzOiBhcmdzLmVkaXRzIH07XFxuXFx0fVxcblxcblxcdGlmICh0eXBlb2YgYXJncy5vbGRUZXh0ID09PSBcXFwic3RyaW5nXFxcIiAmJiB0eXBlb2YgYXJncy5uZXdUZXh0ID09PSBcXFwic3RyaW5nXFxcIikge1xcblxcdFxcdHJldHVybiB7IHBhdGgsIGVkaXRzOiBbeyBvbGRUZXh0OiBhcmdzLm9sZFRleHQsIG5ld1RleHQ6IGFyZ3MubmV3VGV4dCB9XSB9O1xcblxcdH1cXG5cXG5cXHRyZXR1cm4gbnVsbDtcXG59XFxuXFxuZnVuY3Rpb24gZm9ybWF0RWRpdENhbGwoYXJnczogUmVuZGVyYWJsZUVkaXRBcmdzIHwgdW5kZWZpbmVkLCB0aGVtZTogVGhlbWUsIGN3ZDogc3RyaW5nKTogc3RyaW5nIHtcXG5cXHRjb25zdCBwYXRoRGlzcGxheSA9IHJlbmRlclRvb2xQYXRoKHN0cihhcmdzPy5maWxlX3BhdGggPz8gYXJncz8ucGF0aCksIHRoZW1lLCBjd2QpO1xcblxcdHJldHVybiBgJHt0aGVtZS5mZyhcXFwidG9vbFRpdGxlXFxcIiwgdGhlbWUuYm9sZChcXFwiZWRpdFxcXCIpKX0gJHtwYXRoRGlzcGxheX1gO1xcbn1cXG5cXG5mdW5jdGlvbiBmb3JtYXRFZGl0UmVzdWx0KFxcblxcdGFyZ3M6IFJlbmRlcmFibGVFZGl0QXJncyB8IHVuZGVmaW5lZCxcXG5cXHRwcmV2aWV3OiBFZGl0UHJldmlldyB8IHVuZGVmaW5lZCxcXG5cXHRyZXN1bHQ6IEVkaXRUb29sUmVzdWx0TGlrZSxcXG5cXHR0aGVtZTogVGhlbWUsXFxuXFx0aXNFcnJvcjogYm9vbGVhbixcXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xcblxcdGNvbnN0IHJhd1BhdGggPSBzdHIoYXJncz8uZmlsZV9wYXRoID8/IGFyZ3M/LnBhdGgpO1xcblxcdGNvbnN0IHByZXZpZXdEaWZmID0gcHJldmlldyAmJiAhKFxcXCJlcnJvclxcXCIgaW4gcHJldmlldykgPyBwcmV2aWV3LmRpZmYgOiB1bmRlZmluZWQ7XFxuXFx0Y29uc3QgcHJldmlld0Vycm9yID0gcHJldmlldyAmJiBcXFwiZXJyb3JcXFwiIGluIHByZXZpZXcgPyBwcmV2aWV3LmVycm9yIDogdW5kZWZpbmVkO1xcblxcdGlmIChpc0Vycm9yKSB7XFxuXFx0XFx0Y29uc3QgZXJyb3JUZXh0ID0gcmVzdWx0LmNvbnRlbnRcXG5cXHRcXHRcXHQuZmlsdGVyKChjKSA9PiBjLnR5cGUgPT09IFxcXCJ0ZXh0XFxcIilcXG5cXHRcXHRcXHQubWFwKChjKSA9PiBjLnRleHQgfHwgXFxcIlxcXCIpXFxuXFx0XFx0XFx0LmpvaW4oXFxcIlxcXFxuXFxcIik7XFxuXFx0XFx0aWYgKCFlcnJvclRleHQgfHwgZXJyb3JUZXh0ID09PSBwcmV2aWV3RXJyb3IpIHtcXG5cXHRcXHRcXHRyZXR1cm4gdW5kZWZpbmVkO1xcblxcdFxcdH1cXG5cXHRcXHRyZXR1cm4gdGhlbWUuZmcoXFxcImVycm9yXFxcIiwgZXJyb3JUZXh0KTtcXG5cXHR9XFxuXFxuXFx0Y29uc3QgcmVzdWx0RGlmZiA9IHJlc3VsdC5kZXRhaWxzPy5kaWZmO1xcblxcdGlmIChyZXN1bHREaWZmICYmIHJlc3VsdERpZmYgIT09IHByZXZpZXdEaWZmKSB7XFxuXFx0XFx0cmV0dXJuIHJlbmRlckRpZmYocmVzdWx0RGlmZiwgeyBmaWxlUGF0aDogcmF3UGF0aCA/PyB1bmRlZmluZWQgfSk7XFxuXFx0fVxcblxcblxcdHJldHVybiB1bmRlZmluZWQ7XFxufVxcblxcbmZ1bmN0aW9uIGdldEVkaXRIZWFkZXJCZyhcXG5cXHRwcmV2aWV3OiBFZGl0UHJldmlldyB8IHVuZGVmaW5lZCxcXG5cXHRzZXR0bGVkRXJyb3I6IGJvb2xlYW4gfCB1bmRlZmluZWQsXFxuXFx0dGhlbWU6IFRoZW1lLFxcbik6ICh0ZXh0OiBzdHJpbmcpID0+IHN0cmluZyB7XFxuXFx0aWYgKHByZXZpZXcpIHtcXG5cXHRcXHRpZiAoXFxcImVycm9yXFxcIiBpbiBwcmV2aWV3KSB7XFxuXFx0XFx0XFx0cmV0dXJuICh0ZXh0OiBzdHJpbmcpID0+IHRoZW1lLmJnKFxcXCJ0b29sRXJyb3JCZ1xcXCIsIHRleHQpO1xcblxcdFxcdH1cXG5cXHRcXHRyZXR1cm4gKHRleHQ6IHN0cmluZykgPT4gdGhlbWUuYmcoXFxcInRvb2xTdWNjZXNzQmdcXFwiLCB0ZXh0KTtcXG5cXHR9XFxuXFx0aWYgKHNldHRsZWRFcnJvcikge1xcblxcdFxcdHJldHVybiAodGV4dDogc3RyaW5nKSA9PiB0aGVtZS5iZyhcXFwidG9vbEVycm9yQmdcXFwiLCB0ZXh0KTtcXG5cXHR9XFxuXFx0cmV0dXJuICh0ZXh0OiBzdHJpbmcpID0+IHRoZW1lLmJnKFxcXCJ0b29sUGVuZGluZ0JnXFxcIiwgdGV4dCk7XFxufVxcblxcbmZ1bmN0aW9uIGJ1aWxkRWRpdENhbGxDb21wb25lbnQoXFxuXFx0Y29tcG9uZW50OiBFZGl0Q2FsbFJlbmRlckNvbXBvbmVudCxcXG5cXHRhcmdzOiBSZW5kZXJhYmxlRWRpdEFyZ3MgfCB1bmRlZmluZWQsXFxuXFx0dGhlbWU6IFRoZW1lLFxcblxcdGN3ZDogc3RyaW5nLFxcbik6IEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50IHtcXG5cXHRjb21wb25lbnQuc2V0QmdGbihnZXRFZGl0SGVhZGVyQmcoY29tcG9uZW50LnByZXZpZXcsIGNvbXBvbmVudC5zZXR0bGVkRXJyb3IsIHRoZW1lKSk7XFxuXFx0Y29tcG9uZW50LmNsZWFyKCk7XFxuXFx0Y29tcG9uZW50LmFkZENoaWxkKG5ldyBUZXh0KGZvcm1hdEVkaXRDYWxsKGFyZ3MsIHRoZW1lLCBjd2QpLCAwLCAwKSk7XFxuXFxuXFx0aWYgKCFjb21wb25lbnQucHJldmlldykge1xcblxcdFxcdHJldHVybiBjb21wb25lbnQ7XFxuXFx0fVxcblxcblxcdGNvbnN0IGJvZHkgPVxcblxcdFxcdFxcXCJlcnJvclxcXCIgaW4gY29tcG9uZW50LnByZXZpZXcgPyB0aGVtZS5mZyhcXFwiZXJyb3JcXFwiLCBjb21wb25lbnQucHJldmlldy5lcnJvcikgOiByZW5kZXJEaWZmKGNvbXBvbmVudC5wcmV2aWV3LmRpZmYpO1xcblxcdGNvbXBvbmVudC5hZGRDaGlsZChuZXcgU3BhY2VyKDEpKTtcXG5cXHRjb21wb25lbnQuYWRkQ2hpbGQobmV3IFRleHQoYm9keSwgMCwgMCkpO1xcblxcdHJldHVybiBjb21wb25lbnQ7XFxufVxcblxcbmZ1bmN0aW9uIHNldEVkaXRQcmV2aWV3KFxcblxcdGNvbXBvbmVudDogRWRpdENhbGxSZW5kZXJDb21wb25lbnQsXFxuXFx0cHJldmlldzogRWRpdFByZXZpZXcsXFxuXFx0YXJnc0tleTogc3RyaW5nIHwgdW5kZWZpbmVkLFxcbik6IGJvb2xlYW4ge1xcblxcdGNvbnN0IGN1cnJlbnQgPSBjb21wb25lbnQucHJldmlldztcXG5cXHRjb25zdCBjaGFuZ2VkID1cXG5cXHRcXHRjdXJyZW50ID09PSB1bmRlZmluZWQgfHxcXG5cXHRcXHQoXFxcImVycm9yXFxcIiBpbiBjdXJyZW50ICYmIFxcXCJlcnJvclxcXCIgaW4gcHJldmlld1xcblxcdFxcdFxcdD8gY3VycmVudC5lcnJvciAhPT0gcHJldmlldy5lcnJvclxcblxcdFxcdFxcdDogXFxcImVycm9yXFxcIiBpbiBjdXJyZW50ICE9PSBcXFwiZXJyb3JcXFwiIGluIHByZXZpZXcpIHx8XFxuXFx0XFx0KCEoXFxcImVycm9yXFxcIiBpbiBjdXJyZW50KSAmJlxcblxcdFxcdFxcdCEoXFxcImVycm9yXFxcIiBpbiBwcmV2aWV3KSAmJlxcblxcdFxcdFxcdChjdXJyZW50LmRpZmYgIT09IHByZXZpZXcuZGlmZiB8fCBjdXJyZW50LmZpcnN0Q2hhbmdlZExpbmUgIT09IHByZXZpZXcuZmlyc3RDaGFuZ2VkTGluZSkpO1xcblxcdGNvbXBvbmVudC5wcmV2aWV3ID0gcHJldmlldztcXG5cXHRjb21wb25lbnQucHJldmlld0FyZ3NLZXkgPSBhcmdzS2V5O1xcblxcdGNvbXBvbmVudC5wcmV2aWV3UGVuZGluZyA9IGZhbHNlO1xcblxcdHJldHVybiBjaGFuZ2VkO1xcbn1cXG5cXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWRpdFRvb2xEZWZpbml0aW9uKFxcblxcdGN3ZDogc3RyaW5nLFxcblxcdG9wdGlvbnM/OiBFZGl0VG9vbE9wdGlvbnMsXFxuKTogVG9vbERlZmluaXRpb248dHlwZW9mIGVkaXRTY2hlbWEsIEVkaXRUb29sRGV0YWlscyB8IHVuZGVmaW5lZCwgRWRpdFJlbmRlclN0YXRlPiB7XFxuXFx0Y29uc3Qgb3BzID0gb3B0aW9ucz8ub3BlcmF0aW9ucyA/PyBkZWZhdWx0RWRpdE9wZXJhdGlvbnM7XFxuXFx0cmV0dXJuIHtcXG5cXHRcXHRuYW1lOiBcXFwiZWRpdFxcXCIsXFxuXFx0XFx0bGFiZWw6IFxcXCJlZGl0XFxcIixcXG5cXHRcXHRkZXNjcmlwdGlvbjpcXG5cXHRcXHRcXHRcXFwiRWRpdCBhIHNpbmdsZSBmaWxlIHVzaW5nIGV4YWN0IHRleHQgcmVwbGFjZW1lbnQuIEV2ZXJ5IGVkaXRzW10ub2xkVGV4dCBtdXN0IG1hdGNoIGEgdW5pcXVlLCBub24tb3ZlcmxhcHBpbmcgcmVnaW9uIG9mIHRoZSBvcmlnaW5hbCBmaWxlLiBJZiB0d28gY2hhbmdlcyBhZmZlY3QgdGhlIHNhbWUgYmxvY2sgb3IgbmVhcmJ5IGxpbmVzLCBtZXJnZSB0aGVtIGludG8gb25lIGVkaXQgaW5zdGVhZCBvZiBlbWl0dGluZyBvdmVybGFwcGluZyBlZGl0cy4gRG8gbm90IGluY2x1ZGUgbGFyZ2UgdW5jaGFuZ2VkIHJlZ2lvbnMganVzdCB0byBjb25uZWN0IGRpc3RhbnQgY2hhbmdlcy5cXFwiLFxcblxcdFxcdHByb21wdFNuaXBwZXQ6XFxuXFx0XFx0XFx0XFxcIk1ha2UgcHJlY2lzZSBmaWxlIGVkaXRzIHdpdGggZXhhY3QgdGV4dCByZXBsYWNlbWVudCwgaW5jbHVkaW5nIG11bHRpcGxlIGRpc2pvaW50IGVkaXRzIGluIG9uZSBjYWxsXFxcIixcXG5cXHRcXHRwcm9tcHRHdWlkZWxpbmVzOiBbXFxuXFx0XFx0XFx0XFxcIlVzZSBlZGl0IGZvciBwcmVjaXNlIGNoYW5nZXMgKGVkaXRzW10ub2xkVGV4dCBtdXN0IG1hdGNoIGV4YWN0bHkpXFxcIixcXG5cXHRcXHRcXHRcXFwiV2hlbiBjaGFuZ2luZyBtdWx0aXBsZSBzZXBhcmF0ZSBsb2NhdGlvbnMgaW4gb25lIGZpbGUsIHVzZSBvbmUgZWRpdCBjYWxsIHdpdGggbXVsdGlwbGUgZW50cmllcyBpbiBlZGl0c1tdIGluc3RlYWQgb2YgbXVsdGlwbGUgZWRpdCBjYWxsc1xcXCIsXFxuXFx0XFx0XFx0XFxcIkVhY2ggZWRpdHNbXS5vbGRUZXh0IGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgb3JpZ2luYWwgZmlsZSwgbm90IGFmdGVyIGVhcmxpZXIgZWRpdHMgYXJlIGFwcGxpZWQuIERvIG5vdCBlbWl0IG92ZXJsYXBwaW5nIG9yIG5lc3RlZCBlZGl0cy4gTWVyZ2UgbmVhcmJ5IGNoYW5nZXMgaW50byBvbmUgZWRpdC5cXFwiLFxcblxcdFxcdFxcdFxcXCJLZWVwIGVkaXRzW10ub2xkVGV4dCBhcyBzbWFsbCBhcyBwb3NzaWJsZSB3aGlsZSBzdGlsbCBiZWluZyB1bmlxdWUgaW4gdGhlIGZpbGUuIERvIG5vdCBwYWQgd2l0aCBsYXJnZSB1bmNoYW5nZWQgcmVnaW9ucy5cXFwiLFxcblxcdFxcdF0sXFxuXFx0XFx0cGFyYW1ldGVyczogZWRpdFNjaGVtYSxcXG5cXHRcXHRyZW5kZXJTaGVsbDogXFxcInNlbGZcXFwiLFxcblxcdFxcdHByZXBhcmVBcmd1bWVudHM6IHByZXBhcmVFZGl0QXJndW1lbnRzLFxcblxcdFxcdGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIGlucHV0OiBFZGl0VG9vbElucHV0LCBzaWduYWw/OiBBYm9ydFNpZ25hbCwgX29uVXBkYXRlPywgX2N0eD8pIHtcXG5cXHRcXHRcXHRjb25zdCB7IHBhdGgsIGVkaXRzIH0gPSB2YWxpZGF0ZUVkaXRJbnB1dChpbnB1dCk7XFxuXFx0XFx0XFx0Y29uc3QgYWJzb2x1dGVQYXRoID0gcmVzb2x2ZVRvQ3dkKHBhdGgsIGN3ZCk7XFxuXFxuXFx0XFx0XFx0cmV0dXJuIHdpdGhGaWxlTXV0YXRpb25RdWV1ZShhYnNvbHV0ZVBhdGgsIGFzeW5jICgpID0+IHtcXG5cXHRcXHRcXHRcXHQvLyBEbyBub3QgcmVqZWN0IGZyb20gYW4gYWJvcnQgZXZlbnQgbGlzdGVuZXIgaGVyZTogdGhhdCB3b3VsZCByZWxlYXNlIHRoZVxcblxcdFxcdFxcdFxcdC8vIG11dGF0aW9uIHF1ZXVlIHdoaWxlIGFuIGluLWZsaWdodCBmaWxlc3lzdGVtIG9wZXJhdGlvbiBtYXkgc3RpbGwgZmluaXNoLlxcblxcdFxcdFxcdFxcdC8vIENoZWNraW5nIHNpZ25hbC5hYm9ydGVkIGFmdGVyIGVhY2ggYXdhaXQgb2JzZXJ2ZXMgdGhlIHNhbWUgYWJvcnRzIHdoaWxlXFxuXFx0XFx0XFx0XFx0Ly8ga2VlcGluZyB0aGUgcXVldWUgbG9ja2VkIHVudGlsIHRoZSBjdXJyZW50IG9wZXJhdGlvbiBoYXMgc2V0dGxlZC5cXG5cXHRcXHRcXHRcXHRjb25zdCB0aHJvd0lmQWJvcnRlZCA9ICgpOiB2b2lkID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRpZiAoc2lnbmFsPy5hYm9ydGVkKSB0aHJvdyBuZXcgRXJyb3IoXFxcIk9wZXJhdGlvbiBhYm9ydGVkXFxcIik7XFxuXFx0XFx0XFx0XFx0fTtcXG5cXG5cXHRcXHRcXHRcXHR0aHJvd0lmQWJvcnRlZCgpO1xcblxcblxcdFxcdFxcdFxcdC8vIENoZWNrIGlmIGZpbGUgZXhpc3RzLlxcblxcdFxcdFxcdFxcdHRyeSB7XFxuXFx0XFx0XFx0XFx0XFx0YXdhaXQgb3BzLmFjY2VzcyhhYnNvbHV0ZVBhdGgpO1xcblxcdFxcdFxcdFxcdH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XFxuXFx0XFx0XFx0XFx0XFx0dGhyb3dJZkFib3J0ZWQoKTtcXG5cXHRcXHRcXHRcXHRcXHRjb25zdCBlcnJvck1lc3NhZ2UgPVxcblxcdFxcdFxcdFxcdFxcdFxcdGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgXFxcImNvZGVcXFwiIGluIGVycm9yID8gYEVycm9yIGNvZGU6ICR7ZXJyb3IuY29kZX1gIDogU3RyaW5nKGVycm9yKTtcXG5cXHRcXHRcXHRcXHRcXHR0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBlZGl0IGZpbGU6ICR7cGF0aH0uICR7ZXJyb3JNZXNzYWdlfS5gKTtcXG5cXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0dGhyb3dJZkFib3J0ZWQoKTtcXG5cXG5cXHRcXHRcXHRcXHQvLyBSZWFkIHRoZSBmaWxlLlxcblxcdFxcdFxcdFxcdGNvbnN0IGJ1ZmZlciA9IGF3YWl0IG9wcy5yZWFkRmlsZShhYnNvbHV0ZVBhdGgpO1xcblxcdFxcdFxcdFxcdGNvbnN0IHJhd0NvbnRlbnQgPSBidWZmZXIudG9TdHJpbmcoXFxcInV0Zi04XFxcIik7XFxuXFx0XFx0XFx0XFx0dGhyb3dJZkFib3J0ZWQoKTtcXG5cXG5cXHRcXHRcXHRcXHQvLyBTdHJpcCBCT00gYmVmb3JlIG1hdGNoaW5nLiBUaGUgbW9kZWwgd2lsbCBub3QgaW5jbHVkZSBhbiBpbnZpc2libGUgQk9NIGluIG9sZFRleHQuXFxuXFx0XFx0XFx0XFx0Y29uc3QgeyBib20sIHRleHQ6IGNvbnRlbnQgfSA9IHN0cmlwQm9tKHJhd0NvbnRlbnQpO1xcblxcdFxcdFxcdFxcdGNvbnN0IG9yaWdpbmFsRW5kaW5nID0gZGV0ZWN0TGluZUVuZGluZyhjb250ZW50KTtcXG5cXHRcXHRcXHRcXHRjb25zdCBub3JtYWxpemVkQ29udGVudCA9IG5vcm1hbGl6ZVRvTEYoY29udGVudCk7XFxuXFx0XFx0XFx0XFx0Y29uc3QgeyBiYXNlQ29udGVudCwgbmV3Q29udGVudCB9ID0gYXBwbHlFZGl0c1RvTm9ybWFsaXplZENvbnRlbnQobm9ybWFsaXplZENvbnRlbnQsIGVkaXRzLCBwYXRoKTtcXG5cXHRcXHRcXHRcXHR0aHJvd0lmQWJvcnRlZCgpO1xcblxcblxcdFxcdFxcdFxcdGNvbnN0IGZpbmFsQ29udGVudCA9IGJvbSArIHJlc3RvcmVMaW5lRW5kaW5ncyhuZXdDb250ZW50LCBvcmlnaW5hbEVuZGluZyk7XFxuXFx0XFx0XFx0XFx0YXdhaXQgb3BzLndyaXRlRmlsZShhYnNvbHV0ZVBhdGgsIGZpbmFsQ29udGVudCk7XFxuXFx0XFx0XFx0XFx0dGhyb3dJZkFib3J0ZWQoKTtcXG5cXG5cXHRcXHRcXHRcXHRjb25zdCBkaWZmUmVzdWx0ID0gZ2VuZXJhdGVEaWZmU3RyaW5nKGJhc2VDb250ZW50LCBuZXdDb250ZW50KTtcXG5cXHRcXHRcXHRcXHRjb25zdCBwYXRjaCA9IGdlbmVyYXRlVW5pZmllZFBhdGNoKHBhdGgsIGJhc2VDb250ZW50LCBuZXdDb250ZW50KTtcXG5cXHRcXHRcXHRcXHRyZXR1cm4ge1xcblxcdFxcdFxcdFxcdFxcdGNvbnRlbnQ6IFtcXG5cXHRcXHRcXHRcXHRcXHRcXHR7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0dHlwZTogXFxcInRleHRcXFwiLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHRleHQ6IGBTdWNjZXNzZnVsbHkgcmVwbGFjZWQgJHtlZGl0cy5sZW5ndGh9IGJsb2NrKHMpIGluICR7cGF0aH0uYCxcXG5cXHRcXHRcXHRcXHRcXHRcXHR9LFxcblxcdFxcdFxcdFxcdFxcdF0sXFxuXFx0XFx0XFx0XFx0XFx0ZGV0YWlsczogeyBkaWZmOiBkaWZmUmVzdWx0LmRpZmYsIHBhdGNoLCBmaXJzdENoYW5nZWRMaW5lOiBkaWZmUmVzdWx0LmZpcnN0Q2hhbmdlZExpbmUgfSxcXG5cXHRcXHRcXHRcXHR9O1xcblxcdFxcdFxcdH0pO1xcblxcdFxcdH0sXFxuXFx0XFx0cmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgY29udGV4dCkge1xcblxcdFxcdFxcdGNvbnN0IGNvbXBvbmVudCA9IGdldEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50KGNvbnRleHQuc3RhdGUsIGNvbnRleHQubGFzdENvbXBvbmVudCk7XFxuXFx0XFx0XFx0Y29uc3QgcHJldmlld0lucHV0ID0gZ2V0UmVuZGVyYWJsZVByZXZpZXdJbnB1dChhcmdzIGFzIFJlbmRlcmFibGVFZGl0QXJncyB8IHVuZGVmaW5lZCk7XFxuXFx0XFx0XFx0Y29uc3QgYXJnc0tleSA9IHByZXZpZXdJbnB1dFxcblxcdFxcdFxcdFxcdD8gSlNPTi5zdHJpbmdpZnkoeyBwYXRoOiBwcmV2aWV3SW5wdXQucGF0aCwgZWRpdHM6IHByZXZpZXdJbnB1dC5lZGl0cyB9KVxcblxcdFxcdFxcdFxcdDogdW5kZWZpbmVkO1xcblxcblxcdFxcdFxcdGlmIChjb21wb25lbnQucHJldmlld0FyZ3NLZXkgIT09IGFyZ3NLZXkpIHtcXG5cXHRcXHRcXHRcXHRjb21wb25lbnQucHJldmlldyA9IHVuZGVmaW5lZDtcXG5cXHRcXHRcXHRcXHRjb21wb25lbnQucHJldmlld0FyZ3NLZXkgPSBhcmdzS2V5O1xcblxcdFxcdFxcdFxcdGNvbXBvbmVudC5wcmV2aWV3UGVuZGluZyA9IGZhbHNlO1xcblxcdFxcdFxcdFxcdGNvbXBvbmVudC5zZXR0bGVkRXJyb3IgPSBmYWxzZTtcXG5cXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0aWYgKGNvbnRleHQuYXJnc0NvbXBsZXRlICYmIHByZXZpZXdJbnB1dCAmJiAhY29tcG9uZW50LnByZXZpZXcgJiYgIWNvbXBvbmVudC5wcmV2aWV3UGVuZGluZykge1xcblxcdFxcdFxcdFxcdGNvbXBvbmVudC5wcmV2aWV3UGVuZGluZyA9IHRydWU7XFxuXFx0XFx0XFx0XFx0Y29uc3QgcmVxdWVzdEtleSA9IGFyZ3NLZXk7XFxuXFx0XFx0XFx0XFx0dm9pZCBjb21wdXRlRWRpdHNEaWZmKHByZXZpZXdJbnB1dC5wYXRoLCBwcmV2aWV3SW5wdXQuZWRpdHMsIGNvbnRleHQuY3dkKS50aGVuKChwcmV2aWV3KSA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0aWYgKGNvbXBvbmVudC5wcmV2aWV3QXJnc0tleSA9PT0gcmVxdWVzdEtleSkge1xcblxcdFxcdFxcdFxcdFxcdFxcdHNldEVkaXRQcmV2aWV3KGNvbXBvbmVudCwgcHJldmlldywgcmVxdWVzdEtleSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29udGV4dC5pbnZhbGlkYXRlKCk7XFxuXFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdH0pO1xcblxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRyZXR1cm4gYnVpbGRFZGl0Q2FsbENvbXBvbmVudChjb21wb25lbnQsIGFyZ3MsIHRoZW1lLCBjb250ZXh0LmN3ZCk7XFxuXFx0XFx0fSxcXG5cXHRcXHRyZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIGNvbnRleHQpIHtcXG5cXHRcXHRcXHRjb25zdCBjYWxsQ29tcG9uZW50ID0gY29udGV4dC5zdGF0ZS5jYWxsQ29tcG9uZW50O1xcblxcdFxcdFxcdGNvbnN0IHByZXZpZXdJbnB1dCA9IGdldFJlbmRlcmFibGVQcmV2aWV3SW5wdXQoY29udGV4dC5hcmdzIGFzIFJlbmRlcmFibGVFZGl0QXJncyB8IHVuZGVmaW5lZCk7XFxuXFx0XFx0XFx0Y29uc3QgYXJnc0tleSA9IHByZXZpZXdJbnB1dFxcblxcdFxcdFxcdFxcdD8gSlNPTi5zdHJpbmdpZnkoeyBwYXRoOiBwcmV2aWV3SW5wdXQucGF0aCwgZWRpdHM6IHByZXZpZXdJbnB1dC5lZGl0cyB9KVxcblxcdFxcdFxcdFxcdDogdW5kZWZpbmVkO1xcblxcdFxcdFxcdGNvbnN0IHR5cGVkUmVzdWx0ID0gcmVzdWx0IGFzIEVkaXRUb29sUmVzdWx0TGlrZTtcXG5cXHRcXHRcXHRjb25zdCByZXN1bHREaWZmID0gIWNvbnRleHQuaXNFcnJvciA/IHR5cGVkUmVzdWx0LmRldGFpbHM/LmRpZmYgOiB1bmRlZmluZWQ7XFxuXFx0XFx0XFx0bGV0IGNoYW5nZWQgPSBmYWxzZTtcXG5cXHRcXHRcXHRpZiAoY2FsbENvbXBvbmVudCkge1xcblxcdFxcdFxcdFxcdGlmICh0eXBlb2YgcmVzdWx0RGlmZiA9PT0gXFxcInN0cmluZ1xcXCIpIHtcXG5cXHRcXHRcXHRcXHRcXHRjaGFuZ2VkID1cXG5cXHRcXHRcXHRcXHRcXHRcXHRzZXRFZGl0UHJldmlldyhcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjYWxsQ29tcG9uZW50LFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHsgZGlmZjogcmVzdWx0RGlmZiwgZmlyc3RDaGFuZ2VkTGluZTogdHlwZWRSZXN1bHQuZGV0YWlscz8uZmlyc3RDaGFuZ2VkTGluZSB9LFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGFyZ3NLZXksXFxuXFx0XFx0XFx0XFx0XFx0XFx0KSB8fCBjaGFuZ2VkO1xcblxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRpZiAoY2FsbENvbXBvbmVudC5zZXR0bGVkRXJyb3IgIT09IGNvbnRleHQuaXNFcnJvcikge1xcblxcdFxcdFxcdFxcdFxcdGNhbGxDb21wb25lbnQuc2V0dGxlZEVycm9yID0gY29udGV4dC5pc0Vycm9yO1xcblxcdFxcdFxcdFxcdFxcdGNoYW5nZWQgPSB0cnVlO1xcblxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRpZiAoY2hhbmdlZCkge1xcblxcdFxcdFxcdFxcdFxcdGJ1aWxkRWRpdENhbGxDb21wb25lbnQoXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y2FsbENvbXBvbmVudCxcXG5cXHRcXHRcXHRcXHRcXHRcXHRjb250ZXh0LmFyZ3MgYXMgUmVuZGVyYWJsZUVkaXRBcmdzIHwgdW5kZWZpbmVkLFxcblxcdFxcdFxcdFxcdFxcdFxcdHRoZW1lLFxcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnRleHQuY3dkLFxcblxcdFxcdFxcdFxcdFxcdCk7XFxuXFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRjb25zdCBvdXRwdXQgPSBmb3JtYXRFZGl0UmVzdWx0KGNvbnRleHQuYXJncywgY2FsbENvbXBvbmVudD8ucHJldmlldywgdHlwZWRSZXN1bHQsIHRoZW1lLCBjb250ZXh0LmlzRXJyb3IpO1xcblxcdFxcdFxcdGNvbnN0IGNvbXBvbmVudCA9IChjb250ZXh0Lmxhc3RDb21wb25lbnQgYXMgQ29udGFpbmVyIHwgdW5kZWZpbmVkKSA/PyBuZXcgQ29udGFpbmVyKCk7XFxuXFx0XFx0XFx0Y29tcG9uZW50LmNsZWFyKCk7XFxuXFx0XFx0XFx0aWYgKCFvdXRwdXQpIHtcXG5cXHRcXHRcXHRcXHRyZXR1cm4gY29tcG9uZW50O1xcblxcdFxcdFxcdH1cXG5cXHRcXHRcXHRjb21wb25lbnQuYWRkQ2hpbGQobmV3IFNwYWNlcigxKSk7XFxuXFx0XFx0XFx0Y29tcG9uZW50LmFkZENoaWxkKG5ldyBUZXh0KG91dHB1dCwgMSwgMCkpO1xcblxcdFxcdFxcdHJldHVybiBjb21wb25lbnQ7XFxuXFx0XFx0fSxcXG5cXHR9O1xcbn1cXG5cXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWRpdFRvb2woY3dkOiBzdHJpbmcsIG9wdGlvbnM/OiBFZGl0VG9vbE9wdGlvbnMpOiBBZ2VudFRvb2w8dHlwZW9mIGVkaXRTY2hlbWE+IHtcXG5cXHRyZXR1cm4gd3JhcFRvb2xEZWZpbml0aW9uKGNyZWF0ZUVkaXRUb29sRGVmaW5pdGlvbihjd2QsIG9wdGlvbnMpKTtcXG59XFxuXCJdfVxubm9kZV9tb2R1bGVzL0BlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnQvZGlzdC9jb3JlL3Rvb2xzL2ZpbmQuanMubWFwOntcInZlcnNpb25cIjozLFwiZmlsZVwiOlwiZmluZC5qc1wiLFwic291cmNlUm9vdFwiOlwiXCIsXCJzb3VyY2VzXCI6W1wiLi4vLi4vLi4vc3JjL2NvcmUvdG9vbHMvZmluZC50c1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWhELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQWUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUVqRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFMUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBeUIsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5HLFNBQVMsV0FBVyxDQUFDLEtBQWEsRUFBVTtJQUMzQyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUFBLENBQ3ZDO0FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUM5QixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNwQixXQUFXLEVBQUUsOEVBQThFO0tBQzNGLENBQUM7SUFDRixJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsV0FBVyxFQUFFLHFEQUFxRCxFQUFFLENBQUMsQ0FBQztJQUN4RyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsV0FBVyxFQUFFLDJDQUEyQyxFQUFFLENBQUMsQ0FBQztDQUMvRixDQUFDLENBQUM7QUFJSCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFrQjNCLE1BQU0scUJBQXFCLEdBQW1CO0lBQzdDLE1BQU0sRUFBRSxVQUFVO0lBQ2xCLG1HQUFtRztJQUNuRyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRTtDQUNkLENBQUM7QUFPRixTQUFTLGNBQWMsQ0FBQyxJQUFvRSxFQUFFLEtBQVksRUFBVTtJQUNuSCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25DLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ25FLE1BQU0sS0FBSyxHQUFHLElBQUksRUFBRSxLQUFLLENBQUM7SUFDMUIsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLElBQUksSUFBSSxHQUNQLEtBQUssQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekMsR0FBRztRQUNILENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsT0FBTyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDcEUsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDekIsSUFBSSxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLFdBQVcsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFBQSxDQUNaO0FBRUQsU0FBUyxnQkFBZ0IsQ0FDeEIsTUFHQyxFQUNELE9BQWdDLEVBQ2hDLEtBQVksRUFDWixVQUFtQixFQUNWO0lBQ1QsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN4RCxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7SUFDZCxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1osTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEQsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDOUMsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUM7UUFDMUMsSUFBSSxJQUFJLEtBQUssWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNuRixJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNuQixJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxVQUFVLFNBQVMsY0FBYyxDQUFDLElBQUksT0FBTyxDQUFDLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDeEksQ0FBQztJQUNGLENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDO0lBQ3ZELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDO0lBQzlDLElBQUksV0FBVyxJQUFJLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQztRQUMxQyxNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDOUIsSUFBSSxXQUFXO1lBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFdBQVcsZ0JBQWdCLENBQUMsQ0FBQztRQUMvRCxJQUFJLFVBQVUsRUFBRSxTQUFTO1lBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUMsUUFBUSxJQUFJLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFHLElBQUksSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLGVBQWUsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztJQUMzRSxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFBQSxDQUNaO0FBRUQsTUFBTSxVQUFVLHdCQUF3QixDQUN2QyxHQUFXLEVBQ1gsT0FBeUIsRUFDd0M7SUFDakUsTUFBTSxTQUFTLEdBQUcsT0FBTyxFQUFFLFVBQVUsQ0FBQztJQUN0QyxPQUFPO1FBQ04sSUFBSSxFQUFFLE1BQU07UUFDWixLQUFLLEVBQUUsTUFBTTtRQUNiLFdBQVcsRUFBRSwrSUFBK0ksYUFBYSxlQUFlLGlCQUFpQixHQUFHLElBQUksOEJBQThCO1FBQzlPLGFBQWEsRUFBRSxrREFBa0Q7UUFDakUsVUFBVSxFQUFFLFVBQVU7UUFDdEIsS0FBSyxDQUFDLE9BQU8sQ0FDWixXQUFXLEVBQ1gsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQXNELEVBQ3ZGLE1BQW9CLEVBQ3BCLFNBQVUsRUFDVixJQUFLLEVBQ0o7WUFDRCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO29CQUNyQixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO29CQUN2QyxPQUFPO2dCQUNSLENBQUM7Z0JBRUQsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO2dCQUNwQixJQUFJLFNBQW1DLENBQUM7Z0JBQ3hDLE1BQU0sTUFBTSxHQUFHLENBQUMsRUFBYyxFQUFFLEVBQUUsQ0FBQztvQkFDbEMsSUFBSSxPQUFPO3dCQUFFLE9BQU87b0JBQ3BCLE9BQU8sR0FBRyxJQUFJLENBQUM7b0JBQ2YsTUFBTSxFQUFFLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztvQkFDOUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztvQkFDdEIsRUFBRSxFQUFFLENBQUM7Z0JBQUEsQ0FDTCxDQUFDO2dCQUNGLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDO29CQUNyQixTQUFTLEVBQUUsRUFBRSxDQUFDO29CQUNkLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQUEsQ0FDckQsQ0FBQztnQkFDRixNQUFNLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUUzRCxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBQ1osSUFBSSxDQUFDO3dCQUNKLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxTQUFTLElBQUksR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO3dCQUN2RCxNQUFNLGNBQWMsR0FBRyxLQUFLLElBQUksYUFBYSxDQUFDO3dCQUM5QyxNQUFNLEdBQUcsR0FBRyxTQUFTLElBQUkscUJBQXFCLENBQUM7d0JBRS9DLCtEQUErRDt3QkFDL0QsSUFBSSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUM7NEJBQ3JCLElBQUksQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0NBQ3JDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNqRSxPQUFPOzRCQUNSLENBQUM7NEJBQ0QsSUFBSSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7Z0NBQ3JCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQ3JELE9BQU87NEJBQ1IsQ0FBQzs0QkFDRCxNQUFNLE9BQU8sR0FBRyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRTtnQ0FDbkQsTUFBTSxFQUFFLENBQUMsb0JBQW9CLEVBQUUsWUFBWSxDQUFDO2dDQUM1QyxLQUFLLEVBQUUsY0FBYzs2QkFDckIsQ0FBQyxDQUFDOzRCQUNILElBQUksTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO2dDQUNyQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNyRCxPQUFPOzRCQUNSLENBQUM7NEJBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dDQUMxQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQ1gsT0FBTyxDQUFDO29DQUNQLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsaUNBQWlDLEVBQUUsQ0FBQztvQ0FDcEUsT0FBTyxFQUFFLFNBQVM7aUNBQ2xCLENBQUMsQ0FDRixDQUFDO2dDQUNGLE9BQU87NEJBQ1IsQ0FBQzs0QkFFRCw4REFBOEQ7NEJBQzlELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO2dDQUN0QyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO29DQUFFLE9BQU8sV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNqRixPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUFBLENBQ2pELENBQUMsQ0FBQzs0QkFDSCxNQUFNLGtCQUFrQixHQUFHLFdBQVcsQ0FBQyxNQUFNLElBQUksY0FBYyxDQUFDOzRCQUNoRSxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzRCQUN6QyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsU0FBUyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7NEJBQ2xGLElBQUksWUFBWSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUM7NEJBQ3RDLE1BQU0sT0FBTyxHQUFvQixFQUFFLENBQUM7NEJBQ3BDLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQzs0QkFDN0IsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO2dDQUN4QixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyx3QkFBd0IsQ0FBQyxDQUFDO2dDQUN4RCxPQUFPLENBQUMsa0JBQWtCLEdBQUcsY0FBYyxDQUFDOzRCQUM3QyxDQUFDOzRCQUNELElBQUksVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dDQUMxQixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0NBQy9ELE9BQU8sQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDOzRCQUNqQyxDQUFDOzRCQUNELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQ0FDeEIsWUFBWSxJQUFJLFFBQVEsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDOzRCQUMvQyxDQUFDOzRCQUNELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FDWCxPQUFPLENBQUM7Z0NBQ1AsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztnQ0FDL0MsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTOzZCQUM5RCxDQUFDLENBQ0YsQ0FBQzs0QkFDRixPQUFPO3dCQUNSLENBQUM7d0JBRUQsa0NBQWtDO3dCQUNsQyxNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7d0JBQzVDLElBQUksTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDOzRCQUNyQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNyRCxPQUFPO3dCQUNSLENBQUM7d0JBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDOzRCQUNiLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsaURBQWlELENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ25GLE9BQU87d0JBQ1IsQ0FBQzt3QkFFRCw4RUFBOEU7d0JBQzlFLCtFQUErRTt3QkFDL0UsaUZBQWlGO3dCQUNqRixNQUFNLElBQUksR0FBYTs0QkFDdEIsUUFBUTs0QkFDUixlQUFlOzRCQUNmLFVBQVU7NEJBQ1Ysa0JBQWtCOzRCQUNsQixlQUFlOzRCQUNmLE1BQU0sQ0FBQyxjQUFjLENBQUM7eUJBQ3RCLENBQUM7d0JBRUYsbUZBQW1GO3dCQUNuRiw0RUFBNEU7d0JBQzVFLDJFQUEyRTt3QkFDM0UsSUFBSSxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7d0JBQy9CLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOzRCQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDOzRCQUN6QixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO2dDQUNoRixnQkFBZ0IsR0FBRyxNQUFNLE9BQU8sRUFBRSxDQUFDOzRCQUNwQyxDQUFDO3dCQUNGLENBQUM7d0JBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLENBQUM7d0JBRTlDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQ3pFLE1BQU0sRUFBRSxHQUFHLGVBQWUsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQzt3QkFDcEQsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO3dCQUNoQixNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7d0JBRTNCLFNBQVMsR0FBRyxHQUFHLEVBQUUsQ0FBQzs0QkFDakIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQ0FDbkIsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDOzRCQUNkLENBQUM7d0JBQUEsQ0FDRCxDQUFDO3dCQUVGLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDOzRCQUNyQixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7d0JBQUEsQ0FDWCxDQUFDO3dCQUVGLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUM7NEJBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7d0JBQUEsQ0FDM0IsQ0FBQyxDQUFDO3dCQUVILEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQzs0QkFDdkIsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzt3QkFBQSxDQUNqQixDQUFDLENBQUM7d0JBRUgsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDOzRCQUM1QixPQUFPLEVBQUUsQ0FBQzs0QkFDVixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHFCQUFxQixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQUEsQ0FDdEUsQ0FBQyxDQUFDO3dCQUVILEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQzs0QkFDM0IsT0FBTyxFQUFFLENBQUM7NEJBQ1YsSUFBSSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7Z0NBQ3JCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQ3JELE9BQU87NEJBQ1IsQ0FBQzs0QkFDRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzRCQUNoQyxJQUFJLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQztnQ0FDaEIsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLHVCQUF1QixJQUFJLEVBQUUsQ0FBQztnQ0FDaEUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO29DQUNiLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO29DQUMxQyxPQUFPO2dDQUNSLENBQUM7NEJBQ0YsQ0FBQzs0QkFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0NBQ2IsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUNYLE9BQU8sQ0FBQztvQ0FDUCxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLGlDQUFpQyxFQUFFLENBQUM7b0NBQ3BFLE9BQU8sRUFBRSxTQUFTO2lDQUNsQixDQUFDLENBQ0YsQ0FBQztnQ0FDRixPQUFPOzRCQUNSLENBQUM7NEJBRUQsTUFBTSxXQUFXLEdBQWEsRUFBRSxDQUFDOzRCQUNqQyxLQUFLLE1BQU0sT0FBTyxJQUFJLEtBQUssRUFBRSxDQUFDO2dDQUM3QixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQ0FDL0MsSUFBSSxDQUFDLElBQUk7b0NBQUUsU0FBUztnQ0FDcEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7Z0NBQ25FLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQztnQ0FDeEIsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7b0NBQ2pDLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0NBQ2xELENBQUM7cUNBQU0sQ0FBQztvQ0FDUCxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0NBQ2hELENBQUM7Z0NBQ0QsSUFBSSxnQkFBZ0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO29DQUFFLFlBQVksSUFBSSxHQUFHLENBQUM7Z0NBQ3pFLFdBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7NEJBQzdDLENBQUM7NEJBRUQsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUMsTUFBTSxJQUFJLGNBQWMsQ0FBQzs0QkFDaEUsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFDekMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDOzRCQUNsRixJQUFJLFlBQVksR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDOzRCQUN0QyxNQUFNLE9BQU8sR0FBb0IsRUFBRSxDQUFDOzRCQUNwQyxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7NEJBQzdCLElBQUksa0JBQWtCLEVBQUUsQ0FBQztnQ0FDeEIsT0FBTyxDQUFDLElBQUksQ0FDWCxHQUFHLGNBQWMscUNBQXFDLGNBQWMsR0FBRyxDQUFDLDhCQUE4QixDQUN0RyxDQUFDO2dDQUNGLE9BQU8sQ0FBQyxrQkFBa0IsR0FBRyxjQUFjLENBQUM7NEJBQzdDLENBQUM7NEJBQ0QsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7Z0NBQzFCLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxVQUFVLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQ0FDL0QsT0FBTyxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7NEJBQ2pDLENBQUM7NEJBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dDQUN4QixZQUFZLElBQUksUUFBUSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7NEJBQy9DLENBQUM7NEJBQ0QsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUNYLE9BQU8sQ0FBQztnQ0FDUCxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDO2dDQUMvQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVM7NkJBQzlELENBQUMsQ0FDRixDQUFDO3dCQUFBLENBQ0YsQ0FBQyxDQUFDO29CQUNKLENBQUM7b0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQzt3QkFDWixJQUFJLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQzs0QkFDckIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDckQsT0FBTzt3QkFDUixDQUFDO3dCQUNELE1BQU0sS0FBSyxHQUFHLENBQUMsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQzVELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDN0IsQ0FBQztnQkFBQSxDQUNELENBQUMsRUFBRSxDQUFDO1lBQUEsQ0FDTCxDQUFDLENBQUM7UUFBQSxDQUNIO1FBQ0QsVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO1lBQ2hDLE1BQU0sSUFBSSxHQUFJLE9BQU8sQ0FBQyxhQUFrQyxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0UsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDMUMsT0FBTyxJQUFJLENBQUM7UUFBQSxDQUNaO1FBQ0QsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtZQUM3QyxNQUFNLElBQUksR0FBSSxPQUFPLENBQUMsYUFBa0MsSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9FLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsTUFBYSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDbEYsT0FBTyxJQUFJLENBQUM7UUFBQSxDQUNaO0tBQ0QsQ0FBQztBQUFBLENBQ0Y7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUFDLEdBQVcsRUFBRSxPQUF5QixFQUFnQztJQUNwRyxPQUFPLGtCQUFrQixDQUFDLHdCQUF3QixDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQUEsQ0FDbEVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiaW1wb3J0IHsgY3JlYXRlSW50ZXJmYWNlIH0gZnJvbSBcXFwibm9kZTpyZWFkbGluZVxcXCI7XFxuaW1wb3J0IHR5cGUgeyBBZ2VudFRvb2wgfSBmcm9tIFxcXCJAZWFyZW5kaWwtd29ya3MvcGktYWdlbnQtY29yZVxcXCI7XFxuaW1wb3J0IHsgVGV4dCB9IGZyb20gXFxcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcXFwiO1xcbmltcG9ydCB7IHNwYXduIH0gZnJvbSBcXFwiY2hpbGRfcHJvY2Vzc1xcXCI7XFxuaW1wb3J0IHBhdGggZnJvbSBcXFwicGF0aFxcXCI7XFxuaW1wb3J0IHsgdHlwZSBTdGF0aWMsIFR5cGUgfSBmcm9tIFxcXCJ0eXBlYm94XFxcIjtcXG5pbXBvcnQgeyBrZXlIaW50IH0gZnJvbSBcXFwiLi4vLi4vbW9kZXMvaW50ZXJhY3RpdmUvY29tcG9uZW50cy9rZXliaW5kaW5nLWhpbnRzLnRzXFxcIjtcXG5pbXBvcnQgdHlwZSB7IFRoZW1lIH0gZnJvbSBcXFwiLi4vLi4vbW9kZXMvaW50ZXJhY3RpdmUvdGhlbWUvdGhlbWUudHNcXFwiO1xcbmltcG9ydCB7IGVuc3VyZVRvb2wgfSBmcm9tIFxcXCIuLi8uLi91dGlscy90b29scy1tYW5hZ2VyLnRzXFxcIjtcXG5pbXBvcnQgdHlwZSB7IFRvb2xEZWZpbml0aW9uLCBUb29sUmVuZGVyUmVzdWx0T3B0aW9ucyB9IGZyb20gXFxcIi4uL2V4dGVuc2lvbnMvdHlwZXMudHNcXFwiO1xcbmltcG9ydCB7IHBhdGhFeGlzdHMsIHJlc29sdmVUb0N3ZCB9IGZyb20gXFxcIi4vcGF0aC11dGlscy50c1xcXCI7XFxuaW1wb3J0IHsgZ2V0VGV4dE91dHB1dCwgaW52YWxpZEFyZ1RleHQsIHNob3J0ZW5QYXRoLCBzdHIgfSBmcm9tIFxcXCIuL3JlbmRlci11dGlscy50c1xcXCI7XFxuaW1wb3J0IHsgd3JhcFRvb2xEZWZpbml0aW9uIH0gZnJvbSBcXFwiLi90b29sLWRlZmluaXRpb24td3JhcHBlci50c1xcXCI7XFxuaW1wb3J0IHsgREVGQVVMVF9NQVhfQllURVMsIGZvcm1hdFNpemUsIHR5cGUgVHJ1bmNhdGlvblJlc3VsdCwgdHJ1bmNhdGVIZWFkIH0gZnJvbSBcXFwiLi90cnVuY2F0ZS50c1xcXCI7XFxuXFxuZnVuY3Rpb24gdG9Qb3NpeFBhdGgodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XFxuXFx0cmV0dXJuIHZhbHVlLnNwbGl0KHBhdGguc2VwKS5qb2luKFxcXCIvXFxcIik7XFxufVxcblxcbmNvbnN0IGZpbmRTY2hlbWEgPSBUeXBlLk9iamVjdCh7XFxuXFx0cGF0dGVybjogVHlwZS5TdHJpbmcoe1xcblxcdFxcdGRlc2NyaXB0aW9uOiBcXFwiR2xvYiBwYXR0ZXJuIHRvIG1hdGNoIGZpbGVzLCBlLmcuICcqLnRzJywgJyoqLyouanNvbicsIG9yICdzcmMvKiovKi5zcGVjLnRzJ1xcXCIsXFxuXFx0fSksXFxuXFx0cGF0aDogVHlwZS5PcHRpb25hbChUeXBlLlN0cmluZyh7IGRlc2NyaXB0aW9uOiBcXFwiRGlyZWN0b3J5IHRvIHNlYXJjaCBpbiAoZGVmYXVsdDogY3VycmVudCBkaXJlY3RvcnkpXFxcIiB9KSksXFxuXFx0bGltaXQ6IFR5cGUuT3B0aW9uYWwoVHlwZS5OdW1iZXIoeyBkZXNjcmlwdGlvbjogXFxcIk1heGltdW0gbnVtYmVyIG9mIHJlc3VsdHMgKGRlZmF1bHQ6IDEwMDApXFxcIiB9KSksXFxufSk7XFxuXFxuZXhwb3J0IHR5cGUgRmluZFRvb2xJbnB1dCA9IFN0YXRpYzx0eXBlb2YgZmluZFNjaGVtYT47XFxuXFxuY29uc3QgREVGQVVMVF9MSU1JVCA9IDEwMDA7XFxuXFxuZXhwb3J0IGludGVyZmFjZSBGaW5kVG9vbERldGFpbHMge1xcblxcdHRydW5jYXRpb24/OiBUcnVuY2F0aW9uUmVzdWx0O1xcblxcdHJlc3VsdExpbWl0UmVhY2hlZD86IG51bWJlcjtcXG59XFxuXFxuLyoqXFxuICogUGx1Z2dhYmxlIG9wZXJhdGlvbnMgZm9yIHRoZSBmaW5kIHRvb2wuXFxuICogT3ZlcnJpZGUgdGhlc2UgdG8gZGVsZWdhdGUgZmlsZSBzZWFyY2ggdG8gcmVtb3RlIHN5c3RlbXMgKGZvciBleGFtcGxlIFNTSCkuXFxuICovXFxuZXhwb3J0IGludGVyZmFjZSBGaW5kT3BlcmF0aW9ucyB7XFxuXFx0LyoqIENoZWNrIGlmIHBhdGggZXhpc3RzICovXFxuXFx0ZXhpc3RzOiAoYWJzb2x1dGVQYXRoOiBzdHJpbmcpID0+IFByb21pc2U8Ym9vbGVhbj4gfCBib29sZWFuO1xcblxcdC8qKiBGaW5kIGZpbGVzIG1hdGNoaW5nIGdsb2IgcGF0dGVybi4gUmV0dXJucyByZWxhdGl2ZSBvciBhYnNvbHV0ZSBwYXRocy4gKi9cXG5cXHRnbG9iOiAocGF0dGVybjogc3RyaW5nLCBjd2Q6IHN0cmluZywgb3B0aW9uczogeyBpZ25vcmU6IHN0cmluZ1tdOyBsaW1pdDogbnVtYmVyIH0pID0+IFByb21pc2U8c3RyaW5nW10+IHwgc3RyaW5nW107XFxufVxcblxcbmNvbnN0IGRlZmF1bHRGaW5kT3BlcmF0aW9uczogRmluZE9wZXJhdGlvbnMgPSB7XFxuXFx0ZXhpc3RzOiBwYXRoRXhpc3RzLFxcblxcdC8vIFRoaXMgaXMgYSBwbGFjZWhvbGRlci4gQWN0dWFsIGZkIGV4ZWN1dGlvbiBoYXBwZW5zIGluIGV4ZWN1dGUoKSB3aGVuIG5vIGN1c3RvbSBnbG9iIGlzIHByb3ZpZGVkLlxcblxcdGdsb2I6ICgpID0+IFtdLFxcbn07XFxuXFxuZXhwb3J0IGludGVyZmFjZSBGaW5kVG9vbE9wdGlvbnMge1xcblxcdC8qKiBDdXN0b20gb3BlcmF0aW9ucyBmb3IgZmluZC4gRGVmYXVsdDogbG9jYWwgZmlsZXN5c3RlbSBwbHVzIGZkICovXFxuXFx0b3BlcmF0aW9ucz86IEZpbmRPcGVyYXRpb25zO1xcbn1cXG5cXG5mdW5jdGlvbiBmb3JtYXRGaW5kQ2FsbChhcmdzOiB7IHBhdHRlcm46IHN0cmluZzsgcGF0aD86IHN0cmluZzsgbGltaXQ/OiBudW1iZXIgfSB8IHVuZGVmaW5lZCwgdGhlbWU6IFRoZW1lKTogc3RyaW5nIHtcXG5cXHRjb25zdCBwYXR0ZXJuID0gc3RyKGFyZ3M/LnBhdHRlcm4pO1xcblxcdGNvbnN0IHJhd1BhdGggPSBzdHIoYXJncz8ucGF0aCk7XFxuXFx0Y29uc3QgcGF0aCA9IHJhd1BhdGggIT09IG51bGwgPyBzaG9ydGVuUGF0aChyYXdQYXRoIHx8IFxcXCIuXFxcIikgOiBudWxsO1xcblxcdGNvbnN0IGxpbWl0ID0gYXJncz8ubGltaXQ7XFxuXFx0Y29uc3QgaW52YWxpZEFyZyA9IGludmFsaWRBcmdUZXh0KHRoZW1lKTtcXG5cXHRsZXQgdGV4dCA9XFxuXFx0XFx0dGhlbWUuZmcoXFxcInRvb2xUaXRsZVxcXCIsIHRoZW1lLmJvbGQoXFxcImZpbmRcXFwiKSkgK1xcblxcdFxcdFxcXCIgXFxcIiArXFxuXFx0XFx0KHBhdHRlcm4gPT09IG51bGwgPyBpbnZhbGlkQXJnIDogdGhlbWUuZmcoXFxcImFjY2VudFxcXCIsIHBhdHRlcm4gfHwgXFxcIlxcXCIpKSArXFxuXFx0XFx0dGhlbWUuZmcoXFxcInRvb2xPdXRwdXRcXFwiLCBgIGluICR7cGF0aCA9PT0gbnVsbCA/IGludmFsaWRBcmcgOiBwYXRofWApO1xcblxcdGlmIChsaW1pdCAhPT0gdW5kZWZpbmVkKSB7XFxuXFx0XFx0dGV4dCArPSB0aGVtZS5mZyhcXFwidG9vbE91dHB1dFxcXCIsIGAgKGxpbWl0ICR7bGltaXR9KWApO1xcblxcdH1cXG5cXHRyZXR1cm4gdGV4dDtcXG59XFxuXFxuZnVuY3Rpb24gZm9ybWF0RmluZFJlc3VsdChcXG5cXHRyZXN1bHQ6IHtcXG5cXHRcXHRjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dD86IHN0cmluZzsgZGF0YT86IHN0cmluZzsgbWltZVR5cGU/OiBzdHJpbmcgfT47XFxuXFx0XFx0ZGV0YWlscz86IEZpbmRUb29sRGV0YWlscztcXG5cXHR9LFxcblxcdG9wdGlvbnM6IFRvb2xSZW5kZXJSZXN1bHRPcHRpb25zLFxcblxcdHRoZW1lOiBUaGVtZSxcXG5cXHRzaG93SW1hZ2VzOiBib29sZWFuLFxcbik6IHN0cmluZyB7XFxuXFx0Y29uc3Qgb3V0cHV0ID0gZ2V0VGV4dE91dHB1dChyZXN1bHQsIHNob3dJbWFnZXMpLnRyaW0oKTtcXG5cXHRsZXQgdGV4dCA9IFxcXCJcXFwiO1xcblxcdGlmIChvdXRwdXQpIHtcXG5cXHRcXHRjb25zdCBsaW5lcyA9IG91dHB1dC5zcGxpdChcXFwiXFxcXG5cXFwiKTtcXG5cXHRcXHRjb25zdCBtYXhMaW5lcyA9IG9wdGlvbnMuZXhwYW5kZWQgPyBsaW5lcy5sZW5ndGggOiAyMDtcXG5cXHRcXHRjb25zdCBkaXNwbGF5TGluZXMgPSBsaW5lcy5zbGljZSgwLCBtYXhMaW5lcyk7XFxuXFx0XFx0Y29uc3QgcmVtYWluaW5nID0gbGluZXMubGVuZ3RoIC0gbWF4TGluZXM7XFxuXFx0XFx0dGV4dCArPSBgXFxcXG4ke2Rpc3BsYXlMaW5lcy5tYXAoKGxpbmUpID0+IHRoZW1lLmZnKFxcXCJ0b29sT3V0cHV0XFxcIiwgbGluZSkpLmpvaW4oXFxcIlxcXFxuXFxcIil9YDtcXG5cXHRcXHRpZiAocmVtYWluaW5nID4gMCkge1xcblxcdFxcdFxcdHRleHQgKz0gYCR7dGhlbWUuZmcoXFxcIm11dGVkXFxcIiwgYFxcXFxuLi4uICgke3JlbWFpbmluZ30gbW9yZSBsaW5lcyxgKX0gJHtrZXlIaW50KFxcXCJhcHAudG9vbHMuZXhwYW5kXFxcIiwgXFxcInRvIGV4cGFuZFxcXCIpfSR7dGhlbWUuZmcoXFxcIm11dGVkXFxcIiwgXFxcIilcXFwiKX1gO1xcblxcdFxcdH1cXG5cXHR9XFxuXFxuXFx0Y29uc3QgcmVzdWx0TGltaXQgPSByZXN1bHQuZGV0YWlscz8ucmVzdWx0TGltaXRSZWFjaGVkO1xcblxcdGNvbnN0IHRydW5jYXRpb24gPSByZXN1bHQuZGV0YWlscz8udHJ1bmNhdGlvbjtcXG5cXHRpZiAocmVzdWx0TGltaXQgfHwgdHJ1bmNhdGlvbj8udHJ1bmNhdGVkKSB7XFxuXFx0XFx0Y29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XFxuXFx0XFx0aWYgKHJlc3VsdExpbWl0KSB3YXJuaW5ncy5wdXNoKGAke3Jlc3VsdExpbWl0fSByZXN1bHRzIGxpbWl0YCk7XFxuXFx0XFx0aWYgKHRydW5jYXRpb24/LnRydW5jYXRlZCkgd2FybmluZ3MucHVzaChgJHtmb3JtYXRTaXplKHRydW5jYXRpb24ubWF4Qnl0ZXMgPz8gREVGQVVMVF9NQVhfQllURVMpfSBsaW1pdGApO1xcblxcdFxcdHRleHQgKz0gYFxcXFxuJHt0aGVtZS5mZyhcXFwid2FybmluZ1xcXCIsIGBbVHJ1bmNhdGVkOiAke3dhcm5pbmdzLmpvaW4oXFxcIiwgXFxcIil9XWApfWA7XFxuXFx0fVxcblxcdHJldHVybiB0ZXh0O1xcbn1cXG5cXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRmluZFRvb2xEZWZpbml0aW9uKFxcblxcdGN3ZDogc3RyaW5nLFxcblxcdG9wdGlvbnM/OiBGaW5kVG9vbE9wdGlvbnMsXFxuKTogVG9vbERlZmluaXRpb248dHlwZW9mIGZpbmRTY2hlbWEsIEZpbmRUb29sRGV0YWlscyB8IHVuZGVmaW5lZD4ge1xcblxcdGNvbnN0IGN1c3RvbU9wcyA9IG9wdGlvbnM/Lm9wZXJhdGlvbnM7XFxuXFx0cmV0dXJuIHtcXG5cXHRcXHRuYW1lOiBcXFwiZmluZFxcXCIsXFxuXFx0XFx0bGFiZWw6IFxcXCJmaW5kXFxcIixcXG5cXHRcXHRkZXNjcmlwdGlvbjogYFNlYXJjaCBmb3IgZmlsZXMgYnkgZ2xvYiBwYXR0ZXJuLiBSZXR1cm5zIG1hdGNoaW5nIGZpbGUgcGF0aHMgcmVsYXRpdmUgdG8gdGhlIHNlYXJjaCBkaXJlY3RvcnkuIFJlc3BlY3RzIC5naXRpZ25vcmUuIE91dHB1dCBpcyB0cnVuY2F0ZWQgdG8gJHtERUZBVUxUX0xJTUlUfSByZXN1bHRzIG9yICR7REVGQVVMVF9NQVhfQllURVMgLyAxMDI0fUtCICh3aGljaGV2ZXIgaXMgaGl0IGZpcnN0KS5gLFxcblxcdFxcdHByb21wdFNuaXBwZXQ6IFxcXCJGaW5kIGZpbGVzIGJ5IGdsb2IgcGF0dGVybiAocmVzcGVjdHMgLmdpdGlnbm9yZSlcXFwiLFxcblxcdFxcdHBhcmFtZXRlcnM6IGZpbmRTY2hlbWEsXFxuXFx0XFx0YXN5bmMgZXhlY3V0ZShcXG5cXHRcXHRcXHRfdG9vbENhbGxJZCxcXG5cXHRcXHRcXHR7IHBhdHRlcm4sIHBhdGg6IHNlYXJjaERpciwgbGltaXQgfTogeyBwYXR0ZXJuOiBzdHJpbmc7IHBhdGg/OiBzdHJpbmc7IGxpbWl0PzogbnVtYmVyIH0sXFxuXFx0XFx0XFx0c2lnbmFsPzogQWJvcnRTaWduYWwsXFxuXFx0XFx0XFx0X29uVXBkYXRlPyxcXG5cXHRcXHRcXHRfY3R4PyxcXG5cXHRcXHQpIHtcXG5cXHRcXHRcXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xcblxcdFxcdFxcdFxcdGlmIChzaWduYWw/LmFib3J0ZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRyZWplY3QobmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpKTtcXG5cXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0fVxcblxcblxcdFxcdFxcdFxcdGxldCBzZXR0bGVkID0gZmFsc2U7XFxuXFx0XFx0XFx0XFx0bGV0IHN0b3BDaGlsZDogKCgpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xcblxcdFxcdFxcdFxcdGNvbnN0IHNldHRsZSA9IChmbjogKCkgPT4gdm9pZCkgPT4ge1xcblxcdFxcdFxcdFxcdFxcdGlmIChzZXR0bGVkKSByZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0c2V0dGxlZCA9IHRydWU7XFxuXFx0XFx0XFx0XFx0XFx0c2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKFxcXCJhYm9ydFxcXCIsIG9uQWJvcnQpO1xcblxcdFxcdFxcdFxcdFxcdHN0b3BDaGlsZCA9IHVuZGVmaW5lZDtcXG5cXHRcXHRcXHRcXHRcXHRmbigpO1xcblxcdFxcdFxcdFxcdH07XFxuXFx0XFx0XFx0XFx0Y29uc3Qgb25BYm9ydCA9ICgpID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRzdG9wQ2hpbGQ/LigpO1xcblxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpKSk7XFxuXFx0XFx0XFx0XFx0fTtcXG5cXHRcXHRcXHRcXHRzaWduYWw/LmFkZEV2ZW50TGlzdGVuZXIoXFxcImFib3J0XFxcIiwgb25BYm9ydCwgeyBvbmNlOiB0cnVlIH0pO1xcblxcblxcdFxcdFxcdFxcdChhc3luYyAoKSA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0dHJ5IHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBzZWFyY2hQYXRoID0gcmVzb2x2ZVRvQ3dkKHNlYXJjaERpciB8fCBcXFwiLlxcXCIsIGN3ZCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgZWZmZWN0aXZlTGltaXQgPSBsaW1pdCA/PyBERUZBVUxUX0xJTUlUO1xcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IG9wcyA9IGN1c3RvbU9wcyA/PyBkZWZhdWx0RmluZE9wZXJhdGlvbnM7XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Ly8gSWYgY3VzdG9tIG9wZXJhdGlvbnMgcHJvdmlkZSBnbG9iKCksIHVzZSB0aGF0IGluc3RlYWQgb2YgZmQuXFxuXFx0XFx0XFx0XFx0XFx0XFx0aWYgKGN1c3RvbU9wcz8uZ2xvYikge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmICghKGF3YWl0IG9wcy5leGlzdHMoc2VhcmNoUGF0aCkpKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoYFBhdGggbm90IGZvdW5kOiAke3NlYXJjaFBhdGh9YCkpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChzaWduYWw/LmFib3J0ZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihcXFwiT3BlcmF0aW9uIGFib3J0ZWRcXFwiKSkpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmVzdWx0cyA9IGF3YWl0IG9wcy5nbG9iKHBhdHRlcm4sIHNlYXJjaFBhdGgsIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRpZ25vcmU6IFtcXFwiKiovbm9kZV9tb2R1bGVzLyoqXFxcIiwgXFxcIioqLy5naXQvKipcXFwiXSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRsaW1pdDogZWZmZWN0aXZlTGltaXQsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKHNpZ25hbD8uYWJvcnRlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAocmVzdWx0cy5sZW5ndGggPT09IDApIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT5cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXNvbHZlKHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjb250ZW50OiBbeyB0eXBlOiBcXFwidGV4dFxcXCIsIHRleHQ6IFxcXCJObyBmaWxlcyBmb3VuZCBtYXRjaGluZyBwYXR0ZXJuXFxcIiB9XSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzOiB1bmRlZmluZWQsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0fSksXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdC8vIFJlbGF0aXZpemUgcGF0aHMgYWdhaW5zdCB0aGUgc2VhcmNoIHJvb3QgZm9yIHN0YWJsZSBvdXRwdXQuXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmVsYXRpdml6ZWQgPSByZXN1bHRzLm1hcCgocCkgPT4ge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChwLnN0YXJ0c1dpdGgoc2VhcmNoUGF0aCkpIHJldHVybiB0b1Bvc2l4UGF0aChwLnNsaWNlKHNlYXJjaFBhdGgubGVuZ3RoICsgMSkpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJldHVybiB0b1Bvc2l4UGF0aChwYXRoLnJlbGF0aXZlKHNlYXJjaFBhdGgsIHApKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCByZXN1bHRMaW1pdFJlYWNoZWQgPSByZWxhdGl2aXplZC5sZW5ndGggPj0gZWZmZWN0aXZlTGltaXQ7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmF3T3V0cHV0ID0gcmVsYXRpdml6ZWQuam9pbihcXFwiXFxcXG5cXFwiKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCB0cnVuY2F0aW9uID0gdHJ1bmNhdGVIZWFkKHJhd091dHB1dCwgeyBtYXhMaW5lczogTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0bGV0IHJlc3VsdE91dHB1dCA9IHRydW5jYXRpb24uY29udGVudDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBkZXRhaWxzOiBGaW5kVG9vbERldGFpbHMgPSB7fTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBub3RpY2VzOiBzdHJpbmdbXSA9IFtdO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChyZXN1bHRMaW1pdFJlYWNoZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRub3RpY2VzLnB1c2goYCR7ZWZmZWN0aXZlTGltaXR9IHJlc3VsdHMgbGltaXQgcmVhY2hlZGApO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGRldGFpbHMucmVzdWx0TGltaXRSZWFjaGVkID0gZWZmZWN0aXZlTGltaXQ7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmICh0cnVuY2F0aW9uLnRydW5jYXRlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdG5vdGljZXMucHVzaChgJHtmb3JtYXRTaXplKERFRkFVTFRfTUFYX0JZVEVTKX0gbGltaXQgcmVhY2hlZGApO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGRldGFpbHMudHJ1bmNhdGlvbiA9IHRydW5jYXRpb247XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChub3RpY2VzLmxlbmd0aCA+IDApIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXN1bHRPdXRwdXQgKz0gYFxcXFxuXFxcXG5bJHtub3RpY2VzLmpvaW4oXFxcIi4gXFxcIil9XWA7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PlxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJlc29sdmUoe1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnRlbnQ6IFt7IHR5cGU6IFxcXCJ0ZXh0XFxcIiwgdGV4dDogcmVzdWx0T3V0cHV0IH1dLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGRldGFpbHM6IE9iamVjdC5rZXlzKGRldGFpbHMpLmxlbmd0aCA+IDAgPyBkZXRhaWxzIDogdW5kZWZpbmVkLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdH0pLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIHVzZXMgZmQuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgZmRQYXRoID0gYXdhaXQgZW5zdXJlVG9vbChcXFwiZmRcXFwiLCB0cnVlKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoXFxcIk9wZXJhdGlvbiBhYm9ydGVkXFxcIikpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdGlmICghZmRQYXRoKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoXFxcImZkIGlzIG5vdCBhdmFpbGFibGUgYW5kIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkXFxcIikpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcblxcdFxcdFxcdFxcdFxcdFxcdC8vIEJ1aWxkIGZkIGFyZ3VtZW50cy4gLS1uby1yZXF1aXJlLWdpdCBtYWtlcyBmZCBhcHBseSBoaWVyYXJjaGljYWwgLmdpdGlnbm9yZVxcblxcdFxcdFxcdFxcdFxcdFxcdC8vIHNlbWFudGljcyB3aGV0aGVyIG9yIG5vdCB0aGUgc2VhcmNoIHBhdGggaXMgaW5zaWRlIGEgZ2l0IHJlcG9zaXRvcnksIHdpdGhvdXRcXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBsZWFraW5nIHNpYmxpbmctZGlyZWN0b3J5IHJ1bGVzIHRoZSB3YXkgLS1pZ25vcmUtZmlsZSAoYSBnbG9iYWwgc291cmNlKSB3b3VsZC5cXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXFwiLS1nbG9iXFxcIixcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXFwiLS1jb2xvcj1uZXZlclxcXCIsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFxcIi0taGlkZGVuXFxcIixcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXFwiLS1uby1yZXF1aXJlLWdpdFxcXCIsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFxcIi0tbWF4LXJlc3VsdHNcXFwiLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFN0cmluZyhlZmZlY3RpdmVMaW1pdCksXFxuXFx0XFx0XFx0XFx0XFx0XFx0XTtcXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBmZCAtLWdsb2IgbWF0Y2hlcyBhZ2FpbnN0IHRoZSBiYXNlbmFtZSB1bmxlc3MgLS1mdWxsLXBhdGggaXMgc2V0OyBpbiAtLWZ1bGwtcGF0aFxcblxcdFxcdFxcdFxcdFxcdFxcdC8vIG1vZGUgaXQgbWF0Y2hlcyBhZ2FpbnN0IHRoZSBhYnNvbHV0ZSBjYW5kaWRhdGUgcGF0aCwgc28gYSBwYXRoLWNvbnRhaW5pbmdcXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBwYXR0ZXJuIGxpa2UgJ3NyYy8qKi8qLnNwZWMudHMnIG5lZWRzIGEgbGVhZGluZyAnKiovJyB0byBtYXRjaCBhbnl0aGluZy5cXG5cXHRcXHRcXHRcXHRcXHRcXHRsZXQgZWZmZWN0aXZlUGF0dGVybiA9IHBhdHRlcm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0aWYgKHBhdHRlcm4uaW5jbHVkZXMoXFxcIi9cXFwiKSkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGFyZ3MucHVzaChcXFwiLS1mdWxsLXBhdGhcXFwiKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoIXBhdHRlcm4uc3RhcnRzV2l0aChcXFwiL1xcXCIpICYmICFwYXR0ZXJuLnN0YXJ0c1dpdGgoXFxcIioqL1xcXCIpICYmIHBhdHRlcm4gIT09IFxcXCIqKlxcXCIpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRlZmZlY3RpdmVQYXR0ZXJuID0gYCoqLyR7cGF0dGVybn1gO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0YXJncy5wdXNoKFxcXCItLVxcXCIsIGVmZmVjdGl2ZVBhdHRlcm4sIHNlYXJjaFBhdGgpO1xcblxcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGNoaWxkID0gc3Bhd24oZmRQYXRoLCBhcmdzLCB7IHN0ZGlvOiBbXFxcImlnbm9yZVxcXCIsIFxcXCJwaXBlXFxcIiwgXFxcInBpcGVcXFwiXSB9KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBybCA9IGNyZWF0ZUludGVyZmFjZSh7IGlucHV0OiBjaGlsZC5zdGRvdXQgfSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0bGV0IHN0ZGVyciA9IFxcXCJcXFwiO1xcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xcblxcblxcdFxcdFxcdFxcdFxcdFxcdHN0b3BDaGlsZCA9ICgpID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoIWNoaWxkLmtpbGxlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGNoaWxkLmtpbGwoKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0fTtcXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHJsLmNsb3NlKCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0fTtcXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRjaGlsZC5zdGRlcnI/Lm9uKFxcXCJkYXRhXFxcIiwgKGNodW5rKSA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0c3RkZXJyICs9IGNodW5rLnRvU3RyaW5nKCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0fSk7XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0cmwub24oXFxcImxpbmVcXFwiLCAobGluZSkgPT4ge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGxpbmVzLnB1c2gobGluZSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0fSk7XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y2hpbGQub24oXFxcImVycm9yXFxcIiwgKGVycm9yKSA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y2xlYW51cCgpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gcnVuIGZkOiAke2Vycm9yLm1lc3NhZ2V9YCkpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHR9KTtcXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRjaGlsZC5vbihcXFwiY2xvc2VcXFwiLCAoY29kZSkgPT4ge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNsZWFudXAoKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoXFxcIk9wZXJhdGlvbiBhYm9ydGVkXFxcIikpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IG91dHB1dCA9IGxpbmVzLmpvaW4oXFxcIlxcXFxuXFxcIik7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKGNvZGUgIT09IDApIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBlcnJvck1zZyA9IHN0ZGVyci50cmltKCkgfHwgYGZkIGV4aXRlZCB3aXRoIGNvZGUgJHtjb2RlfWA7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKCFvdXRwdXQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihlcnJvck1zZykpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoIW91dHB1dCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PlxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJlc29sdmUoe1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnRlbnQ6IFt7IHR5cGU6IFxcXCJ0ZXh0XFxcIiwgdGV4dDogXFxcIk5vIGZpbGVzIGZvdW5kIG1hdGNoaW5nIHBhdHRlcm5cXFwiIH1dLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGRldGFpbHM6IHVuZGVmaW5lZCxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHR9KSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHQpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmVsYXRpdml6ZWQ6IHN0cmluZ1tdID0gW107XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Zm9yIChjb25zdCByYXdMaW5lIG9mIGxpbmVzKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgbGluZSA9IHJhd0xpbmUucmVwbGFjZSgvXFxcXHIkLywgXFxcIlxcXCIpLnRyaW0oKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoIWxpbmUpIGNvbnRpbnVlO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGhhZFRyYWlsaW5nU2xhc2ggPSBsaW5lLmVuZHNXaXRoKFxcXCIvXFxcIikgfHwgbGluZS5lbmRzV2l0aChcXFwiXFxcXFxcXFxcXFwiKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRsZXQgcmVsYXRpdmVQYXRoID0gbGluZTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAobGluZS5zdGFydHNXaXRoKHNlYXJjaFBhdGgpKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmVsYXRpdmVQYXRoID0gbGluZS5zbGljZShzZWFyY2hQYXRoLmxlbmd0aCArIDEpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdH0gZWxzZSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZShzZWFyY2hQYXRoLCBsaW5lKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKGhhZFRyYWlsaW5nU2xhc2ggJiYgIXJlbGF0aXZlUGF0aC5lbmRzV2l0aChcXFwiL1xcXCIpKSByZWxhdGl2ZVBhdGggKz0gXFxcIi9cXFwiO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJlbGF0aXZpemVkLnB1c2godG9Qb3NpeFBhdGgocmVsYXRpdmVQYXRoKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IHJlc3VsdExpbWl0UmVhY2hlZCA9IHJlbGF0aXZpemVkLmxlbmd0aCA+PSBlZmZlY3RpdmVMaW1pdDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCByYXdPdXRwdXQgPSByZWxhdGl2aXplZC5qb2luKFxcXCJcXFxcblxcXCIpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IHRydW5jYXRpb24gPSB0cnVuY2F0ZUhlYWQocmF3T3V0cHV0LCB7IG1heExpbmVzOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiB9KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRsZXQgcmVzdWx0T3V0cHV0ID0gdHJ1bmNhdGlvbi5jb250ZW50O1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGRldGFpbHM6IEZpbmRUb29sRGV0YWlscyA9IHt9O1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IG5vdGljZXM6IHN0cmluZ1tdID0gW107XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKHJlc3VsdExpbWl0UmVhY2hlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdG5vdGljZXMucHVzaChcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRgJHtlZmZlY3RpdmVMaW1pdH0gcmVzdWx0cyBsaW1pdCByZWFjaGVkLiBVc2UgbGltaXQ9JHtlZmZlY3RpdmVMaW1pdCAqIDJ9IGZvciBtb3JlLCBvciByZWZpbmUgcGF0dGVybmAsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzLnJlc3VsdExpbWl0UmVhY2hlZCA9IGVmZmVjdGl2ZUxpbWl0O1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAodHJ1bmNhdGlvbi50cnVuY2F0ZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRub3RpY2VzLnB1c2goYCR7Zm9ybWF0U2l6ZShERUZBVUxUX01BWF9CWVRFUyl9IGxpbWl0IHJlYWNoZWRgKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzLnRydW5jYXRpb24gPSB0cnVuY2F0aW9uO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAobm90aWNlcy5sZW5ndGggPiAwKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmVzdWx0T3V0cHV0ICs9IGBcXFxcblxcXFxuWyR7bm90aWNlcy5qb2luKFxcXCIuIFxcXCIpfV1gO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT5cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXNvbHZlKHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjb250ZW50OiBbeyB0eXBlOiBcXFwidGV4dFxcXCIsIHRleHQ6IHJlc3VsdE91dHB1dCB9XSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzOiBPYmplY3Qua2V5cyhkZXRhaWxzKS5sZW5ndGggPiAwID8gZGV0YWlscyA6IHVuZGVmaW5lZCxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHR9KSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHQpO1xcblxcdFxcdFxcdFxcdFxcdFxcdH0pO1xcblxcdFxcdFxcdFxcdFxcdH0gY2F0Y2ggKGUpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoXFxcIk9wZXJhdGlvbiBhYm9ydGVkXFxcIikpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGVycm9yID0gZSBpbnN0YW5jZW9mIEVycm9yID8gZSA6IG5ldyBFcnJvcihTdHJpbmcoZSkpO1xcblxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QoZXJyb3IpKTtcXG5cXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0fSkoKTtcXG5cXHRcXHRcXHR9KTtcXG5cXHRcXHR9LFxcblxcdFxcdHJlbmRlckNhbGwoYXJncywgdGhlbWUsIGNvbnRleHQpIHtcXG5cXHRcXHRcXHRjb25zdCB0ZXh0ID0gKGNvbnRleHQubGFzdENvbXBvbmVudCBhcyBUZXh0IHwgdW5kZWZpbmVkKSA/PyBuZXcgVGV4dChcXFwiXFxcIiwgMCwgMCk7XFxuXFx0XFx0XFx0dGV4dC5zZXRUZXh0KGZvcm1hdEZpbmRDYWxsKGFyZ3MsIHRoZW1lKSk7XFxuXFx0XFx0XFx0cmV0dXJuIHRleHQ7XFxuXFx0XFx0fSxcXG5cXHRcXHRyZW5kZXJSZXN1bHQocmVzdWx0LCBvcHRpb25zLCB0aGVtZSwgY29udGV4dCkge1xcblxcdFxcdFxcdGNvbnN0IHRleHQgPSAoY29udGV4dC5sYXN0Q29tcG9uZW50IGFzIFRleHQgfCB1bmRlZmluZWQpID8/IG5ldyBUZXh0KFxcXCJcXFwiLCAwLCAwKTtcXG5cXHRcXHRcXHR0ZXh0LnNldFRleHQoZm9ybWF0RmluZFJlc3VsdChyZXN1bHQgYXMgYW55LCBvcHRpb25zLCB0aGVtZSwgY29udGV4dC5zaG93SW1hZ2VzKSk7XFxuXFx0XFx0XFx0cmV0dXJuIHRleHQ7XFxuXFx0XFx0fSxcXG5cXHR9O1xcbn1cXG5cXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRmluZFRvb2woY3dkOiBzdHJpbmcsIG9wdGlvbnM/OiBGaW5kVG9vbE9wdGlvbnMpOiBBZ2VudFRvb2w8dHlwZW9mIGZpbmRTY2hlbWE+IHtcXG5cXHRyZXR1cm4gd3JhcFRvb2xEZWZpbml0aW9uKGNyZWF0ZUZpbmRUb29sRGVmaW5pdGlvbihjd2QsIG9wdGlvbnMpKTtcXG59XFxuXCJdfVxuXG5bU2hvd2luZyBsaW5lcyA5LTEwIG9mIDEwICg1MC4wS0IgbGltaXQpLiBGdWxsIG91dHB1dDogL3Zhci9mb2xkZXJzL2RjL3g4Yjk5MXRkNTU1Z184ZmI1eF9nOWQ0MDAwMDBnbi9UL3BpLWJhc2gtYWJkNmNlZDdjMDNmZjBmNy5sb2ddIn1dLCJkZXRhaWxzIjp7InRydW5jYXRpb24iOnsiY29udGVudCI6Im5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2Rpc3QvY29yZS90b29scy9lZGl0LmQudHMubWFwOntcInZlcnNpb25cIjozLFwiZmlsZVwiOlwiZWRpdC5kLnRzXCIsXCJzb3VyY2VSb290XCI6XCJcIixcInNvdXJjZXNcIjpbXCIuLi8uLi8uLi9zcmMvY29yZS90b29scy9lZGl0LnRzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxHQUFHLEVBQTJCLE1BQU0sd0JBQXdCLENBQUM7QUFHdEUsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUc1QyxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RCxPQUFPLEVBS04sS0FBSyxhQUFhLEVBQ2xCLEtBQUssY0FBYyxFQU1uQixNQUFNLGdCQUFnQixDQUFDO0FBTXhCLEtBQUssV0FBVyxHQUFHLGNBQWMsR0FBRyxhQUFhLENBQUM7QUFFbEQsS0FBSyxlQUFlLEdBQUc7SUFDdEIsYUFBYSxDQUFDLEVBQUUsdUJBQXVCLENBQUM7Q0FDeEMsQ0FBQztBQWFGLFFBQUEsTUFBTSxVQUFVOzs7Ozs7RUFTZixDQUFDO0FBRUYsTUFBTSxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsT0FBTyxVQUFVLENBQUMsQ0FBQztBQU10RCxNQUFNLFdBQVcsZUFBZTtJQUMvQixnREFBZ0Q7SUFDaEQsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNiLGlEQUFpRDtJQUNqRCxLQUFLLEVBQUUsTUFBTSxDQUFDO0lBQ2QsOEVBQThFO0lBQzlFLGdCQUFnQixDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQzFCO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxXQUFXLGNBQWM7SUFDOUIscUNBQXFDO0lBQ3JDLFFBQVEsRUFBRSxDQUFDLFlBQVksRUFBRSxNQUFNLEtBQUssT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BELDhCQUE4QjtJQUM5QixTQUFTLEVBQUUsQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BFLDREQUE0RDtJQUM1RCxNQUFNLEVBQUUsQ0FBQyxZQUFZLEVBQUUsTUFBTSxLQUFLLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztDQUNoRDtBQVFELE1BQU0sV0FBVyxlQUFlO0lBQy9CLG9FQUFvRTtJQUNwRSxVQUFVLENBQUMsRUFBRSxjQUFjLENBQUM7Q0FDNUI7QUFnREQsS0FBSyx1QkFBdUIsR0FBRyxHQUFHLEdBQUc7SUFDcEMsT0FBTyxDQUFDLEVBQUUsV0FBVyxDQUFDO0lBQ3RCLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUN4QixjQUFjLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDekIsWUFBWSxDQUFDLEVBQUUsT0FBTyxDQUFDO0NBQ3ZCLENBQUM7QUE4SUYsd0JBQWdCLHdCQUF3QixDQUN2QyxHQUFHLEVBQUUsTUFBTSxFQUNYLE9BQU8sQ0FBQyxFQUFFLGVBQWUsR0FDdkIsY0FBYyxDQUFDLE9BQU8sVUFBVSxFQUFFLGVBQWUsR0FBRyxTQUFTLEVBQUUsZUFBZSxDQUFDLENBK0lqRjtBQUVELHdCQUFnQixjQUFjLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsRUFBRSxlQUFlLEdBQUcsU0FBUyxDQUFDLE9BQU8sVUFBVSxDQUFDLENBRW5HXCIsXCJzb3VyY2VzQ29udGVudFwiOltcImltcG9ydCB0eXBlIHsgQWdlbnRUb29sIH0gZnJvbSBcXFwiQGVhcmVuZGlsLXdvcmtzL3BpLWFnZW50LWNvcmVcXFwiO1xcbmltcG9ydCB7IEJveCwgQ29udGFpbmVyLCBTcGFjZXIsIFRleHQgfSBmcm9tIFxcXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXFxcIjtcXG5pbXBvcnQgeyBjb25zdGFudHMgfSBmcm9tIFxcXCJmc1xcXCI7XFxuaW1wb3J0IHsgYWNjZXNzIGFzIGZzQWNjZXNzLCByZWFkRmlsZSBhcyBmc1JlYWRGaWxlLCB3cml0ZUZpbGUgYXMgZnNXcml0ZUZpbGUgfSBmcm9tIFxcXCJmcy9wcm9taXNlc1xcXCI7XFxuaW1wb3J0IHsgdHlwZSBTdGF0aWMsIFR5cGUgfSBmcm9tIFxcXCJ0eXBlYm94XFxcIjtcXG5pbXBvcnQgeyByZW5kZXJEaWZmIH0gZnJvbSBcXFwiLi4vLi4vbW9kZXMvaW50ZXJhY3RpdmUvY29tcG9uZW50cy9kaWZmLnRzXFxcIjtcXG5pbXBvcnQgdHlwZSB7IFRoZW1lIH0gZnJvbSBcXFwiLi4vLi4vbW9kZXMvaW50ZXJhY3RpdmUvdGhlbWUvdGhlbWUudHNcXFwiO1xcbmltcG9ydCB0eXBlIHsgVG9vbERlZmluaXRpb24gfSBmcm9tIFxcXCIuLi9leHRlbnNpb25zL3R5cGVzLnRzXFxcIjtcXG5pbXBvcnQge1xcblxcdGFwcGx5RWRpdHNUb05vcm1hbGl6ZWRDb250ZW50LFxcblxcdGNvbXB1dGVFZGl0c0RpZmYsXFxuXFx0ZGV0ZWN0TGluZUVuZGluZyxcXG5cXHR0eXBlIEVkaXQsXFxuXFx0dHlwZSBFZGl0RGlmZkVycm9yLFxcblxcdHR5cGUgRWRpdERpZmZSZXN1bHQsXFxuXFx0Z2VuZXJhdGVEaWZmU3RyaW5nLFxcblxcdGdlbmVyYXRlVW5pZmllZFBhdGNoLFxcblxcdG5vcm1hbGl6ZVRvTEYsXFxuXFx0cmVzdG9yZUxpbmVFbmRpbmdzLFxcblxcdHN0cmlwQm9tLFxcbn0gZnJvbSBcXFwiLi9lZGl0LWRpZmYudHNcXFwiO1xcbmltcG9ydCB7IHdpdGhGaWxlTXV0YXRpb25RdWV1ZSB9IGZyb20gXFxcIi4vZmlsZS1tdXRhdGlvbi1xdWV1ZS50c1xcXCI7XFxuaW1wb3J0IHsgcmVzb2x2ZVRvQ3dkIH0gZnJvbSBcXFwiLi9wYXRoLXV0aWxzLnRzXFxcIjtcXG5pbXBvcnQgeyByZW5kZXJUb29sUGF0aCwgc3RyIH0gZnJvbSBcXFwiLi9yZW5kZXItdXRpbHMudHNcXFwiO1xcbmltcG9ydCB7IHdyYXBUb29sRGVmaW5pdGlvbiB9IGZyb20gXFxcIi4vdG9vbC1kZWZpbml0aW9uLXdyYXBwZXIudHNcXFwiO1xcblxcbnR5cGUgRWRpdFByZXZpZXcgPSBFZGl0RGlmZlJlc3VsdCB8IEVkaXREaWZmRXJyb3I7XFxuXFxudHlwZSBFZGl0UmVuZGVyU3RhdGUgPSB7XFxuXFx0Y2FsbENvbXBvbmVudD86IEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50O1xcbn07XFxuXFxuY29uc3QgcmVwbGFjZUVkaXRTY2hlbWEgPSBUeXBlLk9iamVjdChcXG5cXHR7XFxuXFx0XFx0b2xkVGV4dDogVHlwZS5TdHJpbmcoe1xcblxcdFxcdFxcdGRlc2NyaXB0aW9uOlxcblxcdFxcdFxcdFxcdFxcXCJFeGFjdCB0ZXh0IGZvciBvbmUgdGFyZ2V0ZWQgcmVwbGFjZW1lbnQuIEl0IG11c3QgYmUgdW5pcXVlIGluIHRoZSBvcmlnaW5hbCBmaWxlIGFuZCBtdXN0IG5vdCBvdmVybGFwIHdpdGggYW55IG90aGVyIGVkaXRzW10ub2xkVGV4dCBpbiB0aGUgc2FtZSBjYWxsLlxcXCIsXFxuXFx0XFx0fSksXFxuXFx0XFx0bmV3VGV4dDogVHlwZS5TdHJpbmcoeyBkZXNjcmlwdGlvbjogXFxcIlJlcGxhY2VtZW50IHRleHQgZm9yIHRoaXMgdGFyZ2V0ZWQgZWRpdC5cXFwiIH0pLFxcblxcdH0sXFxuXFx0eyBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UgfSxcXG4pO1xcblxcbmNvbnN0IGVkaXRTY2hlbWEgPSBUeXBlLk9iamVjdChcXG5cXHR7XFxuXFx0XFx0cGF0aDogVHlwZS5TdHJpbmcoeyBkZXNjcmlwdGlvbjogXFxcIlBhdGggdG8gdGhlIGZpbGUgdG8gZWRpdCAocmVsYXRpdmUgb3IgYWJzb2x1dGUpXFxcIiB9KSxcXG5cXHRcXHRlZGl0czogVHlwZS5BcnJheShyZXBsYWNlRWRpdFNjaGVtYSwge1xcblxcdFxcdFxcdGRlc2NyaXB0aW9uOlxcblxcdFxcdFxcdFxcdFxcXCJPbmUgb3IgbW9yZSB0YXJnZXRlZCByZXBsYWNlbWVudHMuIEVhY2ggZWRpdCBpcyBtYXRjaGVkIGFnYWluc3QgdGhlIG9yaWdpbmFsIGZpbGUsIG5vdCBpbmNyZW1lbnRhbGx5LiBEbyBub3QgaW5jbHVkZSBvdmVybGFwcGluZyBvciBuZXN0ZWQgZWRpdHMuIElmIHR3byBjaGFuZ2VzIHRvdWNoIHRoZSBzYW1lIGJsb2NrIG9yIG5lYXJieSBsaW5lcywgbWVyZ2UgdGhlbSBpbnRvIG9uZSBlZGl0IGluc3RlYWQuXFxcIixcXG5cXHRcXHR9KSxcXG5cXHR9LFxcblxcdHsgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlIH0sXFxuKTtcXG5cXG5leHBvcnQgdHlwZSBFZGl0VG9vbElucHV0ID0gU3RhdGljPHR5cGVvZiBlZGl0U2NoZW1hPjtcXG50eXBlIExlZ2FjeUVkaXRUb29sSW5wdXQgPSBFZGl0VG9vbElucHV0ICYge1xcblxcdG9sZFRleHQ/OiB1bmtub3duO1xcblxcdG5ld1RleHQ/OiB1bmtub3duO1xcbn07XFxuXFxuZXhwb3J0IGludGVyZmFjZSBFZGl0VG9vbERldGFpbHMge1xcblxcdC8qKiBEaXNwbGF5LW9yaWVudGVkIGRpZmYgb2YgdGhlIGNoYW5nZXMgbWFkZSAqL1xcblxcdGRpZmY6IHN0cmluZztcXG5cXHQvKiogU3RhbmRhcmQgdW5pZmllZCBwYXRjaCBvZiB0aGUgY2hhbmdlcyBtYWRlICovXFxuXFx0cGF0Y2g6IHN0cmluZztcXG5cXHQvKiogTGluZSBudW1iZXIgb2YgdGhlIGZpcnN0IGNoYW5nZSBpbiB0aGUgbmV3IGZpbGUgKGZvciBlZGl0b3IgbmF2aWdhdGlvbikgKi9cXG5cXHRmaXJzdENoYW5nZWRMaW5lPzogbnVtYmVyO1xcbn1cXG5cXG4vKipcXG4gKiBQbHVnZ2FibGUgb3BlcmF0aW9ucyBmb3IgdGhlIGVkaXQgdG9vbC5cXG4gKiBPdmVycmlkZSB0aGVzZSB0byBkZWxlZ2F0ZSBmaWxlIGVkaXRpbmcgdG8gcmVtb3RlIHN5c3RlbXMgKGZvciBleGFtcGxlIFNTSCkuXFxuICovXFxuZXhwb3J0IGludGVyZmFjZSBFZGl0T3BlcmF0aW9ucyB7XFxuXFx0LyoqIFJlYWQgZmlsZSBjb250ZW50cyBhcyBhIEJ1ZmZlciAqL1xcblxcdHJlYWRGaWxlOiAoYWJzb2x1dGVQYXRoOiBzdHJpbmcpID0+IFByb21pc2U8QnVmZmVyPjtcXG5cXHQvKiogV3JpdGUgY29udGVudCB0byBhIGZpbGUgKi9cXG5cXHR3cml0ZUZpbGU6IChhYnNvbHV0ZVBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xcblxcdC8qKiBDaGVjayBpZiBmaWxlIGlzIHJlYWRhYmxlIGFuZCB3cml0YWJsZSAodGhyb3cgaWYgbm90KSAqL1xcblxcdGFjY2VzczogKGFic29sdXRlUGF0aDogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xcbn1cXG5cXG5jb25zdCBkZWZhdWx0RWRpdE9wZXJhdGlvbnM6IEVkaXRPcGVyYXRpb25zID0ge1xcblxcdHJlYWRGaWxlOiAocGF0aCkgPT4gZnNSZWFkRmlsZShwYXRoKSxcXG5cXHR3cml0ZUZpbGU6IChwYXRoLCBjb250ZW50KSA9PiBmc1dyaXRlRmlsZShwYXRoLCBjb250ZW50LCBcXFwidXRmLThcXFwiKSxcXG5cXHRhY2Nlc3M6IChwYXRoKSA9PiBmc0FjY2VzcyhwYXRoLCBjb25zdGFudHMuUl9PSyB8IGNvbnN0YW50cy5XX09LKSxcXG59O1xcblxcbmV4cG9ydCBpbnRlcmZhY2UgRWRpdFRvb2xPcHRpb25zIHtcXG5cXHQvKiogQ3VzdG9tIG9wZXJhdGlvbnMgZm9yIGZpbGUgZWRpdGluZy4gRGVmYXVsdDogbG9jYWwgZmlsZXN5c3RlbSAqL1xcblxcdG9wZXJhdGlvbnM/OiBFZGl0T3BlcmF0aW9ucztcXG59XFxuXFxuZnVuY3Rpb24gcHJlcGFyZUVkaXRBcmd1bWVudHMoaW5wdXQ6IHVua25vd24pOiBFZGl0VG9vbElucHV0IHtcXG5cXHRpZiAoIWlucHV0IHx8IHR5cGVvZiBpbnB1dCAhPT0gXFxcIm9iamVjdFxcXCIpIHtcXG5cXHRcXHRyZXR1cm4gaW5wdXQgYXMgRWRpdFRvb2xJbnB1dDtcXG5cXHR9XFxuXFxuXFx0Y29uc3QgYXJncyA9IGlucHV0IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xcblxcblxcdC8vIFNvbWUgbW9kZWxzIChPcHVzIDQuNiwgR0xNLTUuMSkgc2VuZCBlZGl0cyBhcyBhIEpTT04gc3RyaW5nIGluc3RlYWQgb2YgYW4gYXJyYXlcXG5cXHRpZiAodHlwZW9mIGFyZ3MuZWRpdHMgPT09IFxcXCJzdHJpbmdcXFwiKSB7XFxuXFx0XFx0dHJ5IHtcXG5cXHRcXHRcXHRjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGFyZ3MuZWRpdHMpO1xcblxcdFxcdFxcdGlmIChBcnJheS5pc0FycmF5KHBhcnNlZCkpIGFyZ3MuZWRpdHMgPSBwYXJzZWQ7XFxuXFx0XFx0fSBjYXRjaCB7fVxcblxcdH1cXG5cXG5cXHRjb25zdCBsZWdhY3kgPSBhcmdzIGFzIExlZ2FjeUVkaXRUb29sSW5wdXQ7XFxuXFx0aWYgKHR5cGVvZiBsZWdhY3kub2xkVGV4dCAhPT0gXFxcInN0cmluZ1xcXCIgfHwgdHlwZW9mIGxlZ2FjeS5uZXdUZXh0ICE9PSBcXFwic3RyaW5nXFxcIikge1xcblxcdFxcdHJldHVybiBhcmdzIGFzIEVkaXRUb29sSW5wdXQ7XFxuXFx0fVxcblxcblxcdGNvbnN0IGVkaXRzID0gQXJyYXkuaXNBcnJheShsZWdhY3kuZWRpdHMpID8gWy4uLmxlZ2FjeS5lZGl0c10gOiBbXTtcXG5cXHRlZGl0cy5wdXNoKHsgb2xkVGV4dDogbGVnYWN5Lm9sZFRleHQsIG5ld1RleHQ6IGxlZ2FjeS5uZXdUZXh0IH0pO1xcblxcdGNvbnN0IHsgb2xkVGV4dDogX29sZFRleHQsIG5ld1RleHQ6IF9uZXdUZXh0LCAuLi5yZXN0IH0gPSBsZWdhY3k7XFxuXFx0cmV0dXJuIHsgLi4ucmVzdCwgZWRpdHMgfSBhcyBFZGl0VG9vbElucHV0O1xcbn1cXG5cXG5mdW5jdGlvbiB2YWxpZGF0ZUVkaXRJbnB1dChpbnB1dDogRWRpdFRvb2xJbnB1dCk6IHsgcGF0aDogc3RyaW5nOyBlZGl0czogRWRpdFtdIH0ge1xcblxcdGlmICghQXJyYXkuaXNBcnJheShpbnB1dC5lZGl0cykgfHwgaW5wdXQuZWRpdHMubGVuZ3RoID09PSAwKSB7XFxuXFx0XFx0dGhyb3cgbmV3IEVycm9yKFxcXCJFZGl0IHRvb2wgaW5wdXQgaXMgaW52YWxpZC4gZWRpdHMgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSByZXBsYWNlbWVudC5cXFwiKTtcXG5cXHR9XFxuXFx0cmV0dXJuIHsgcGF0aDogaW5wdXQucGF0aCwgZWRpdHM6IGlucHV0LmVkaXRzIH07XFxufVxcblxcbnR5cGUgUmVuZGVyYWJsZUVkaXRBcmdzID0ge1xcblxcdHBhdGg/OiBzdHJpbmc7XFxuXFx0ZmlsZV9wYXRoPzogc3RyaW5nO1xcblxcdGVkaXRzPzogRWRpdFtdO1xcblxcdG9sZFRleHQ/OiBzdHJpbmc7XFxuXFx0bmV3VGV4dD86IHN0cmluZztcXG59O1xcblxcbnR5cGUgRWRpdFRvb2xSZXN1bHRMaWtlID0ge1xcblxcdGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0Pzogc3RyaW5nOyBkYXRhPzogc3RyaW5nOyBtaW1lVHlwZT86IHN0cmluZyB9PjtcXG5cXHRkZXRhaWxzPzogRWRpdFRvb2xEZXRhaWxzO1xcbn07XFxuXFxudHlwZSBFZGl0Q2FsbFJlbmRlckNvbXBvbmVudCA9IEJveCAmIHtcXG5cXHRwcmV2aWV3PzogRWRpdFByZXZpZXc7XFxuXFx0cHJldmlld0FyZ3NLZXk/OiBzdHJpbmc7XFxuXFx0cHJldmlld1BlbmRpbmc/OiBib29sZWFuO1xcblxcdHNldHRsZWRFcnJvcj86IGJvb2xlYW47XFxufTtcXG5cXG5mdW5jdGlvbiBjcmVhdGVFZGl0Q2FsbFJlbmRlckNvbXBvbmVudCgpOiBFZGl0Q2FsbFJlbmRlckNvbXBvbmVudCB7XFxuXFx0cmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IEJveCgxLCAxLCAodGV4dDogc3RyaW5nKSA9PiB0ZXh0KSwge1xcblxcdFxcdHByZXZpZXc6IHVuZGVmaW5lZCBhcyBFZGl0UHJldmlldyB8IHVuZGVmaW5lZCxcXG5cXHRcXHRwcmV2aWV3QXJnc0tleTogdW5kZWZpbmVkIGFzIHN0cmluZyB8IHVuZGVmaW5lZCxcXG5cXHRcXHRwcmV2aWV3UGVuZGluZzogZmFsc2UsXFxuXFx0XFx0c2V0dGxlZEVycm9yOiBmYWxzZSxcXG5cXHR9KTtcXG59XFxuXFxuZnVuY3Rpb24gZ2V0RWRpdENhbGxSZW5kZXJDb21wb25lbnQoc3RhdGU6IEVkaXRSZW5kZXJTdGF0ZSwgbGFzdENvbXBvbmVudDogdW5rbm93bik6IEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50IHtcXG5cXHRpZiAobGFzdENvbXBvbmVudCBpbnN0YW5jZW9mIEJveCkge1xcblxcdFxcdGNvbnN0IGNvbXBvbmVudCA9IGxhc3RDb21wb25lbnQgYXMgRWRpdENhbGxSZW5kZXJDb21wb25lbnQ7XFxuXFx0XFx0c3RhdGUuY2FsbENvbXBvbmVudCA9IGNvbXBvbmVudDtcXG5cXHRcXHRyZXR1cm4gY29tcG9uZW50O1xcblxcdH1cXG5cXHRpZiAoc3RhdGUuY2FsbENvbXBvbmVudCkge1xcblxcdFxcdHJldHVybiBzdGF0ZS5jYWxsQ29tcG9uZW50O1xcblxcdH1cXG5cXHRjb25zdCBjb21wb25lbnQgPSBjcmVhdGVFZGl0Q2FsbFJlbmRlckNvbXBvbmVudCgpO1xcblxcdHN0YXRlLmNhbGxDb21wb25lbnQgPSBjb21wb25lbnQ7XFxuXFx0cmV0dXJuIGNvbXBvbmVudDtcXG59XFxuXFxuZnVuY3Rpb24gZ2V0UmVuZGVyYWJsZVByZXZpZXdJbnB1dChhcmdzOiBSZW5kZXJhYmxlRWRpdEFyZ3MgfCB1bmRlZmluZWQpOiB7IHBhdGg6IHN0cmluZzsgZWRpdHM6IEVkaXRbXSB9IHwgbnVsbCB7XFxuXFx0aWYgKCFhcmdzKSB7XFxuXFx0XFx0cmV0dXJuIG51bGw7XFxuXFx0fVxcblxcblxcdGNvbnN0IHBhdGggPSB0eXBlb2YgYXJncy5wYXRoID09PSBcXFwic3RyaW5nXFxcIiA/IGFyZ3MucGF0aCA6IHR5cGVvZiBhcmdzLmZpbGVfcGF0aCA9PT0gXFxcInN0cmluZ1xcXCIgPyBhcmdzLmZpbGVfcGF0aCA6IG51bGw7XFxuXFx0aWYgKCFwYXRoKSB7XFxuXFx0XFx0cmV0dXJuIG51bGw7XFxuXFx0fVxcblxcblxcdGlmIChcXG5cXHRcXHRBcnJheS5pc0FycmF5KGFyZ3MuZWRpdHMpICYmXFxuXFx0XFx0YXJncy5lZGl0cy5sZW5ndGggPiAwICYmXFxuXFx0XFx0YXJncy5lZGl0cy5ldmVyeSgoZWRpdCkgPT4gdHlwZW9mIGVkaXQ/Lm9sZFRleHQgPT09IFxcXCJzdHJpbmdcXFwiICYmIHR5cGVvZiBlZGl0Py5uZXdUZXh0ID09PSBcXFwic3RyaW5nXFxcIilcXG5cXHQpIHtcXG5cXHRcXHRyZXR1cm4geyBwYXRoLCBlZGl0czogYXJncy5lZGl0cyB9O1xcblxcdH1cXG5cXG5cXHRpZiAodHlwZW9mIGFyZ3Mub2xkVGV4dCA9PT0gXFxcInN0cmluZ1xcXCIgJiYgdHlwZW9mIGFyZ3MubmV3VGV4dCA9PT0gXFxcInN0cmluZ1xcXCIpIHtcXG5cXHRcXHRyZXR1cm4geyBwYXRoLCBlZGl0czogW3sgb2xkVGV4dDogYXJncy5vbGRUZXh0LCBuZXdUZXh0OiBhcmdzLm5ld1RleHQgfV0gfTtcXG5cXHR9XFxuXFxuXFx0cmV0dXJuIG51bGw7XFxufVxcblxcbmZ1bmN0aW9uIGZvcm1hdEVkaXRDYWxsKGFyZ3M6IFJlbmRlcmFibGVFZGl0QXJncyB8IHVuZGVmaW5lZCwgdGhlbWU6IFRoZW1lLCBjd2Q6IHN0cmluZyk6IHN0cmluZyB7XFxuXFx0Y29uc3QgcGF0aERpc3BsYXkgPSByZW5kZXJUb29sUGF0aChzdHIoYXJncz8uZmlsZV9wYXRoID8/IGFyZ3M/LnBhdGgpLCB0aGVtZSwgY3dkKTtcXG5cXHRyZXR1cm4gYCR7dGhlbWUuZmcoXFxcInRvb2xUaXRsZVxcXCIsIHRoZW1lLmJvbGQoXFxcImVkaXRcXFwiKSl9ICR7cGF0aERpc3BsYXl9YDtcXG59XFxuXFxuZnVuY3Rpb24gZm9ybWF0RWRpdFJlc3VsdChcXG5cXHRhcmdzOiBSZW5kZXJhYmxlRWRpdEFyZ3MgfCB1bmRlZmluZWQsXFxuXFx0cHJldmlldzogRWRpdFByZXZpZXcgfCB1bmRlZmluZWQsXFxuXFx0cmVzdWx0OiBFZGl0VG9vbFJlc3VsdExpa2UsXFxuXFx0dGhlbWU6IFRoZW1lLFxcblxcdGlzRXJyb3I6IGJvb2xlYW4sXFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcXG5cXHRjb25zdCByYXdQYXRoID0gc3RyKGFyZ3M/LmZpbGVfcGF0aCA/PyBhcmdzPy5wYXRoKTtcXG5cXHRjb25zdCBwcmV2aWV3RGlmZiA9IHByZXZpZXcgJiYgIShcXFwiZXJyb3JcXFwiIGluIHByZXZpZXcpID8gcHJldmlldy5kaWZmIDogdW5kZWZpbmVkO1xcblxcdGNvbnN0IHByZXZpZXdFcnJvciA9IHByZXZpZXcgJiYgXFxcImVycm9yXFxcIiBpbiBwcmV2aWV3ID8gcHJldmlldy5lcnJvciA6IHVuZGVmaW5lZDtcXG5cXHRpZiAoaXNFcnJvcikge1xcblxcdFxcdGNvbnN0IGVycm9yVGV4dCA9IHJlc3VsdC5jb250ZW50XFxuXFx0XFx0XFx0LmZpbHRlcigoYykgPT4gYy50eXBlID09PSBcXFwidGV4dFxcXCIpXFxuXFx0XFx0XFx0Lm1hcCgoYykgPT4gYy50ZXh0IHx8IFxcXCJcXFwiKVxcblxcdFxcdFxcdC5qb2luKFxcXCJcXFxcblxcXCIpO1xcblxcdFxcdGlmICghZXJyb3JUZXh0IHx8IGVycm9yVGV4dCA9PT0gcHJldmlld0Vycm9yKSB7XFxuXFx0XFx0XFx0cmV0dXJuIHVuZGVmaW5lZDtcXG5cXHRcXHR9XFxuXFx0XFx0cmV0dXJuIHRoZW1lLmZnKFxcXCJlcnJvclxcXCIsIGVycm9yVGV4dCk7XFxuXFx0fVxcblxcblxcdGNvbnN0IHJlc3VsdERpZmYgPSByZXN1bHQuZGV0YWlscz8uZGlmZjtcXG5cXHRpZiAocmVzdWx0RGlmZiAmJiByZXN1bHREaWZmICE9PSBwcmV2aWV3RGlmZikge1xcblxcdFxcdHJldHVybiByZW5kZXJEaWZmKHJlc3VsdERpZmYsIHsgZmlsZVBhdGg6IHJhd1BhdGggPz8gdW5kZWZpbmVkIH0pO1xcblxcdH1cXG5cXG5cXHRyZXR1cm4gdW5kZWZpbmVkO1xcbn1cXG5cXG5mdW5jdGlvbiBnZXRFZGl0SGVhZGVyQmcoXFxuXFx0cHJldmlldzogRWRpdFByZXZpZXcgfCB1bmRlZmluZWQsXFxuXFx0c2V0dGxlZEVycm9yOiBib29sZWFuIHwgdW5kZWZpbmVkLFxcblxcdHRoZW1lOiBUaGVtZSxcXG4pOiAodGV4dDogc3RyaW5nKSA9PiBzdHJpbmcge1xcblxcdGlmIChwcmV2aWV3KSB7XFxuXFx0XFx0aWYgKFxcXCJlcnJvclxcXCIgaW4gcHJldmlldykge1xcblxcdFxcdFxcdHJldHVybiAodGV4dDogc3RyaW5nKSA9PiB0aGVtZS5iZyhcXFwidG9vbEVycm9yQmdcXFwiLCB0ZXh0KTtcXG5cXHRcXHR9XFxuXFx0XFx0cmV0dXJuICh0ZXh0OiBzdHJpbmcpID0+IHRoZW1lLmJnKFxcXCJ0b29sU3VjY2Vzc0JnXFxcIiwgdGV4dCk7XFxuXFx0fVxcblxcdGlmIChzZXR0bGVkRXJyb3IpIHtcXG5cXHRcXHRyZXR1cm4gKHRleHQ6IHN0cmluZykgPT4gdGhlbWUuYmcoXFxcInRvb2xFcnJvckJnXFxcIiwgdGV4dCk7XFxuXFx0fVxcblxcdHJldHVybiAodGV4dDogc3RyaW5nKSA9PiB0aGVtZS5iZyhcXFwidG9vbFBlbmRpbmdCZ1xcXCIsIHRleHQpO1xcbn1cXG5cXG5mdW5jdGlvbiBidWlsZEVkaXRDYWxsQ29tcG9uZW50KFxcblxcdGNvbXBvbmVudDogRWRpdENhbGxSZW5kZXJDb21wb25lbnQsXFxuXFx0YXJnczogUmVuZGVyYWJsZUVkaXRBcmdzIHwgdW5kZWZpbmVkLFxcblxcdHRoZW1lOiBUaGVtZSxcXG5cXHRjd2Q6IHN0cmluZyxcXG4pOiBFZGl0Q2FsbFJlbmRlckNvbXBvbmVudCB7XFxuXFx0Y29tcG9uZW50LnNldEJnRm4oZ2V0RWRpdEhlYWRlckJnKGNvbXBvbmVudC5wcmV2aWV3LCBjb21wb25lbnQuc2V0dGxlZEVycm9yLCB0aGVtZSkpO1xcblxcdGNvbXBvbmVudC5jbGVhcigpO1xcblxcdGNvbXBvbmVudC5hZGRDaGlsZChuZXcgVGV4dChmb3JtYXRFZGl0Q2FsbChhcmdzLCB0aGVtZSwgY3dkKSwgMCwgMCkpO1xcblxcblxcdGlmICghY29tcG9uZW50LnByZXZpZXcpIHtcXG5cXHRcXHRyZXR1cm4gY29tcG9uZW50O1xcblxcdH1cXG5cXG5cXHRjb25zdCBib2R5ID1cXG5cXHRcXHRcXFwiZXJyb3JcXFwiIGluIGNvbXBvbmVudC5wcmV2aWV3ID8gdGhlbWUuZmcoXFxcImVycm9yXFxcIiwgY29tcG9uZW50LnByZXZpZXcuZXJyb3IpIDogcmVuZGVyRGlmZihjb21wb25lbnQucHJldmlldy5kaWZmKTtcXG5cXHRjb21wb25lbnQuYWRkQ2hpbGQobmV3IFNwYWNlcigxKSk7XFxuXFx0Y29tcG9uZW50LmFkZENoaWxkKG5ldyBUZXh0KGJvZHksIDAsIDApKTtcXG5cXHRyZXR1cm4gY29tcG9uZW50O1xcbn1cXG5cXG5mdW5jdGlvbiBzZXRFZGl0UHJldmlldyhcXG5cXHRjb21wb25lbnQ6IEVkaXRDYWxsUmVuZGVyQ29tcG9uZW50LFxcblxcdHByZXZpZXc6IEVkaXRQcmV2aWV3LFxcblxcdGFyZ3NLZXk6IHN0cmluZyB8IHVuZGVmaW5lZCxcXG4pOiBib29sZWFuIHtcXG5cXHRjb25zdCBjdXJyZW50ID0gY29tcG9uZW50LnByZXZpZXc7XFxuXFx0Y29uc3QgY2hhbmdlZCA9XFxuXFx0XFx0Y3VycmVudCA9PT0gdW5kZWZpbmVkIHx8XFxuXFx0XFx0KFxcXCJlcnJvclxcXCIgaW4gY3VycmVudCAmJiBcXFwiZXJyb3JcXFwiIGluIHByZXZpZXdcXG5cXHRcXHRcXHQ/IGN1cnJlbnQuZXJyb3IgIT09IHByZXZpZXcuZXJyb3JcXG5cXHRcXHRcXHQ6IFxcXCJlcnJvclxcXCIgaW4gY3VycmVudCAhPT0gXFxcImVycm9yXFxcIiBpbiBwcmV2aWV3KSB8fFxcblxcdFxcdCghKFxcXCJlcnJvclxcXCIgaW4gY3VycmVudCkgJiZcXG5cXHRcXHRcXHQhKFxcXCJlcnJvclxcXCIgaW4gcHJldmlldykgJiZcXG5cXHRcXHRcXHQoY3VycmVudC5kaWZmICE9PSBwcmV2aWV3LmRpZmYgfHwgY3VycmVudC5maXJzdENoYW5nZWRMaW5lICE9PSBwcmV2aWV3LmZpcnN0Q2hhbmdlZExpbmUpKTtcXG5cXHRjb21wb25lbnQucHJldmlldyA9IHByZXZpZXc7XFxuXFx0Y29tcG9uZW50LnByZXZpZXdBcmdzS2V5ID0gYXJnc0tleTtcXG5cXHRjb21wb25lbnQucHJldmlld1BlbmRpbmcgPSBmYWxzZTtcXG5cXHRyZXR1cm4gY2hhbmdlZDtcXG59XFxuXFxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVkaXRUb29sRGVmaW5pdGlvbihcXG5cXHRjd2Q6IHN0cmluZyxcXG5cXHRvcHRpb25zPzogRWRpdFRvb2xPcHRpb25zLFxcbik6IFRvb2xEZWZpbml0aW9uPHR5cGVvZiBlZGl0U2NoZW1hLCBFZGl0VG9vbERldGFpbHMgfCB1bmRlZmluZWQsIEVkaXRSZW5kZXJTdGF0ZT4ge1xcblxcdGNvbnN0IG9wcyA9IG9wdGlvbnM/Lm9wZXJhdGlvbnMgPz8gZGVmYXVsdEVkaXRPcGVyYXRpb25zO1xcblxcdHJldHVybiB7XFxuXFx0XFx0bmFtZTogXFxcImVkaXRcXFwiLFxcblxcdFxcdGxhYmVsOiBcXFwiZWRpdFxcXCIsXFxuXFx0XFx0ZGVzY3JpcHRpb246XFxuXFx0XFx0XFx0XFxcIkVkaXQgYSBzaW5nbGUgZmlsZSB1c2luZyBleGFjdCB0ZXh0IHJlcGxhY2VtZW50LiBFdmVyeSBlZGl0c1tdLm9sZFRleHQgbXVzdCBtYXRjaCBhIHVuaXF1ZSwgbm9uLW92ZXJsYXBwaW5nIHJlZ2lvbiBvZiB0aGUgb3JpZ2luYWwgZmlsZS4gSWYgdHdvIGNoYW5nZXMgYWZmZWN0IHRoZSBzYW1lIGJsb2NrIG9yIG5lYXJieSBsaW5lcywgbWVyZ2UgdGhlbSBpbnRvIG9uZSBlZGl0IGluc3RlYWQgb2YgZW1pdHRpbmcgb3ZlcmxhcHBpbmcgZWRpdHMuIERvIG5vdCBpbmNsdWRlIGxhcmdlIHVuY2hhbmdlZCByZWdpb25zIGp1c3QgdG8gY29ubmVjdCBkaXN0YW50IGNoYW5nZXMuXFxcIixcXG5cXHRcXHRwcm9tcHRTbmlwcGV0OlxcblxcdFxcdFxcdFxcXCJNYWtlIHByZWNpc2UgZmlsZSBlZGl0cyB3aXRoIGV4YWN0IHRleHQgcmVwbGFjZW1lbnQsIGluY2x1ZGluZyBtdWx0aXBsZSBkaXNqb2ludCBlZGl0cyBpbiBvbmUgY2FsbFxcXCIsXFxuXFx0XFx0cHJvbXB0R3VpZGVsaW5lczogW1xcblxcdFxcdFxcdFxcXCJVc2UgZWRpdCBmb3IgcHJlY2lzZSBjaGFuZ2VzIChlZGl0c1tdLm9sZFRleHQgbXVzdCBtYXRjaCBleGFjdGx5KVxcXCIsXFxuXFx0XFx0XFx0XFxcIldoZW4gY2hhbmdpbmcgbXVsdGlwbGUgc2VwYXJhdGUgbG9jYXRpb25zIGluIG9uZSBmaWxlLCB1c2Ugb25lIGVkaXQgY2FsbCB3aXRoIG11bHRpcGxlIGVudHJpZXMgaW4gZWRpdHNbXSBpbnN0ZWFkIG9mIG11bHRpcGxlIGVkaXQgY2FsbHNcXFwiLFxcblxcdFxcdFxcdFxcXCJFYWNoIGVkaXRzW10ub2xkVGV4dCBpcyBtYXRjaGVkIGFnYWluc3QgdGhlIG9yaWdpbmFsIGZpbGUsIG5vdCBhZnRlciBlYXJsaWVyIGVkaXRzIGFyZSBhcHBsaWVkLiBEbyBub3QgZW1pdCBvdmVybGFwcGluZyBvciBuZXN0ZWQgZWRpdHMuIE1lcmdlIG5lYXJieSBjaGFuZ2VzIGludG8gb25lIGVkaXQuXFxcIixcXG5cXHRcXHRcXHRcXFwiS2VlcCBlZGl0c1tdLm9sZFRleHQgYXMgc21hbGwgYXMgcG9zc2libGUgd2hpbGUgc3RpbGwgYmVpbmcgdW5pcXVlIGluIHRoZSBmaWxlLiBEbyBub3QgcGFkIHdpdGggbGFyZ2UgdW5jaGFuZ2VkIHJlZ2lvbnMuXFxcIixcXG5cXHRcXHRdLFxcblxcdFxcdHBhcmFtZXRlcnM6IGVkaXRTY2hlbWEsXFxuXFx0XFx0cmVuZGVyU2hlbGw6IFxcXCJzZWxmXFxcIixcXG5cXHRcXHRwcmVwYXJlQXJndW1lbnRzOiBwcmVwYXJlRWRpdEFyZ3VtZW50cyxcXG5cXHRcXHRhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBpbnB1dDogRWRpdFRvb2xJbnB1dCwgc2lnbmFsPzogQWJvcnRTaWduYWwsIF9vblVwZGF0ZT8sIF9jdHg/KSB7XFxuXFx0XFx0XFx0Y29uc3QgeyBwYXRoLCBlZGl0cyB9ID0gdmFsaWRhdGVFZGl0SW5wdXQoaW5wdXQpO1xcblxcdFxcdFxcdGNvbnN0IGFic29sdXRlUGF0aCA9IHJlc29sdmVUb0N3ZChwYXRoLCBjd2QpO1xcblxcblxcdFxcdFxcdHJldHVybiB3aXRoRmlsZU11dGF0aW9uUXVldWUoYWJzb2x1dGVQYXRoLCBhc3luYyAoKSA9PiB7XFxuXFx0XFx0XFx0XFx0Ly8gRG8gbm90IHJlamVjdCBmcm9tIGFuIGFib3J0IGV2ZW50IGxpc3RlbmVyIGhlcmU6IHRoYXQgd291bGQgcmVsZWFzZSB0aGVcXG5cXHRcXHRcXHRcXHQvLyBtdXRhdGlvbiBxdWV1ZSB3aGlsZSBhbiBpbi1mbGlnaHQgZmlsZXN5c3RlbSBvcGVyYXRpb24gbWF5IHN0aWxsIGZpbmlzaC5cXG5cXHRcXHRcXHRcXHQvLyBDaGVja2luZyBzaWduYWwuYWJvcnRlZCBhZnRlciBlYWNoIGF3YWl0IG9ic2VydmVzIHRoZSBzYW1lIGFib3J0cyB3aGlsZVxcblxcdFxcdFxcdFxcdC8vIGtlZXBpbmcgdGhlIHF1ZXVlIGxvY2tlZCB1bnRpbCB0aGUgY3VycmVudCBvcGVyYXRpb24gaGFzIHNldHRsZWQuXFxuXFx0XFx0XFx0XFx0Y29uc3QgdGhyb3dJZkFib3J0ZWQgPSAoKTogdm9pZCA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0aWYgKHNpZ25hbD8uYWJvcnRlZCkgdGhyb3cgbmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpO1xcblxcdFxcdFxcdFxcdH07XFxuXFxuXFx0XFx0XFx0XFx0dGhyb3dJZkFib3J0ZWQoKTtcXG5cXG5cXHRcXHRcXHRcXHQvLyBDaGVjayBpZiBmaWxlIGV4aXN0cy5cXG5cXHRcXHRcXHRcXHR0cnkge1xcblxcdFxcdFxcdFxcdFxcdGF3YWl0IG9wcy5hY2Nlc3MoYWJzb2x1dGVQYXRoKTtcXG5cXHRcXHRcXHRcXHR9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xcblxcdFxcdFxcdFxcdFxcdHRocm93SWZBYm9ydGVkKCk7XFxuXFx0XFx0XFx0XFx0XFx0Y29uc3QgZXJyb3JNZXNzYWdlID1cXG5cXHRcXHRcXHRcXHRcXHRcXHRlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIFxcXCJjb2RlXFxcIiBpbiBlcnJvciA/IGBFcnJvciBjb2RlOiAke2Vycm9yLmNvZGV9YCA6IFN0cmluZyhlcnJvcik7XFxuXFx0XFx0XFx0XFx0XFx0dGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZWRpdCBmaWxlOiAke3BhdGh9LiAke2Vycm9yTWVzc2FnZX0uYCk7XFxuXFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdHRocm93SWZBYm9ydGVkKCk7XFxuXFxuXFx0XFx0XFx0XFx0Ly8gUmVhZCB0aGUgZmlsZS5cXG5cXHRcXHRcXHRcXHRjb25zdCBidWZmZXIgPSBhd2FpdCBvcHMucmVhZEZpbGUoYWJzb2x1dGVQYXRoKTtcXG5cXHRcXHRcXHRcXHRjb25zdCByYXdDb250ZW50ID0gYnVmZmVyLnRvU3RyaW5nKFxcXCJ1dGYtOFxcXCIpO1xcblxcdFxcdFxcdFxcdHRocm93SWZBYm9ydGVkKCk7XFxuXFxuXFx0XFx0XFx0XFx0Ly8gU3RyaXAgQk9NIGJlZm9yZSBtYXRjaGluZy4gVGhlIG1vZGVsIHdpbGwgbm90IGluY2x1ZGUgYW4gaW52aXNpYmxlIEJPTSBpbiBvbGRUZXh0LlxcblxcdFxcdFxcdFxcdGNvbnN0IHsgYm9tLCB0ZXh0OiBjb250ZW50IH0gPSBzdHJpcEJvbShyYXdDb250ZW50KTtcXG5cXHRcXHRcXHRcXHRjb25zdCBvcmlnaW5hbEVuZGluZyA9IGRldGVjdExpbmVFbmRpbmcoY29udGVudCk7XFxuXFx0XFx0XFx0XFx0Y29uc3Qgbm9ybWFsaXplZENvbnRlbnQgPSBub3JtYWxpemVUb0xGKGNvbnRlbnQpO1xcblxcdFxcdFxcdFxcdGNvbnN0IHsgYmFzZUNvbnRlbnQsIG5ld0NvbnRlbnQgfSA9IGFwcGx5RWRpdHNUb05vcm1hbGl6ZWRDb250ZW50KG5vcm1hbGl6ZWRDb250ZW50LCBlZGl0cywgcGF0aCk7XFxuXFx0XFx0XFx0XFx0dGhyb3dJZkFib3J0ZWQoKTtcXG5cXG5cXHRcXHRcXHRcXHRjb25zdCBmaW5hbENvbnRlbnQgPSBib20gKyByZXN0b3JlTGluZUVuZGluZ3MobmV3Q29udGVudCwgb3JpZ2luYWxFbmRpbmcpO1xcblxcdFxcdFxcdFxcdGF3YWl0IG9wcy53cml0ZUZpbGUoYWJzb2x1dGVQYXRoLCBmaW5hbENvbnRlbnQpO1xcblxcdFxcdFxcdFxcdHRocm93SWZBYm9ydGVkKCk7XFxuXFxuXFx0XFx0XFx0XFx0Y29uc3QgZGlmZlJlc3VsdCA9IGdlbmVyYXRlRGlmZlN0cmluZyhiYXNlQ29udGVudCwgbmV3Q29udGVudCk7XFxuXFx0XFx0XFx0XFx0Y29uc3QgcGF0Y2ggPSBnZW5lcmF0ZVVuaWZpZWRQYXRjaChwYXRoLCBiYXNlQ29udGVudCwgbmV3Q29udGVudCk7XFxuXFx0XFx0XFx0XFx0cmV0dXJuIHtcXG5cXHRcXHRcXHRcXHRcXHRjb250ZW50OiBbXFxuXFx0XFx0XFx0XFx0XFx0XFx0e1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHR5cGU6IFxcXCJ0ZXh0XFxcIixcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR0ZXh0OiBgU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkICR7ZWRpdHMubGVuZ3RofSBibG9jayhzKSBpbiAke3BhdGh9LmAsXFxuXFx0XFx0XFx0XFx0XFx0XFx0fSxcXG5cXHRcXHRcXHRcXHRcXHRdLFxcblxcdFxcdFxcdFxcdFxcdGRldGFpbHM6IHsgZGlmZjogZGlmZlJlc3VsdC5kaWZmLCBwYXRjaCwgZmlyc3RDaGFuZ2VkTGluZTogZGlmZlJlc3VsdC5maXJzdENoYW5nZWRMaW5lIH0sXFxuXFx0XFx0XFx0XFx0fTtcXG5cXHRcXHRcXHR9KTtcXG5cXHRcXHR9LFxcblxcdFxcdHJlbmRlckNhbGwoYXJncywgdGhlbWUsIGNvbnRleHQpIHtcXG5cXHRcXHRcXHRjb25zdCBjb21wb25lbnQgPSBnZXRFZGl0Q2FsbFJlbmRlckNvbXBvbmVudChjb250ZXh0LnN0YXRlLCBjb250ZXh0Lmxhc3RDb21wb25lbnQpO1xcblxcdFxcdFxcdGNvbnN0IHByZXZpZXdJbnB1dCA9IGdldFJlbmRlcmFibGVQcmV2aWV3SW5wdXQoYXJncyBhcyBSZW5kZXJhYmxlRWRpdEFyZ3MgfCB1bmRlZmluZWQpO1xcblxcdFxcdFxcdGNvbnN0IGFyZ3NLZXkgPSBwcmV2aWV3SW5wdXRcXG5cXHRcXHRcXHRcXHQ/IEpTT04uc3RyaW5naWZ5KHsgcGF0aDogcHJldmlld0lucHV0LnBhdGgsIGVkaXRzOiBwcmV2aWV3SW5wdXQuZWRpdHMgfSlcXG5cXHRcXHRcXHRcXHQ6IHVuZGVmaW5lZDtcXG5cXG5cXHRcXHRcXHRpZiAoY29tcG9uZW50LnByZXZpZXdBcmdzS2V5ICE9PSBhcmdzS2V5KSB7XFxuXFx0XFx0XFx0XFx0Y29tcG9uZW50LnByZXZpZXcgPSB1bmRlZmluZWQ7XFxuXFx0XFx0XFx0XFx0Y29tcG9uZW50LnByZXZpZXdBcmdzS2V5ID0gYXJnc0tleTtcXG5cXHRcXHRcXHRcXHRjb21wb25lbnQucHJldmlld1BlbmRpbmcgPSBmYWxzZTtcXG5cXHRcXHRcXHRcXHRjb21wb25lbnQuc2V0dGxlZEVycm9yID0gZmFsc2U7XFxuXFx0XFx0XFx0fVxcblxcblxcdFxcdFxcdGlmIChjb250ZXh0LmFyZ3NDb21wbGV0ZSAmJiBwcmV2aWV3SW5wdXQgJiYgIWNvbXBvbmVudC5wcmV2aWV3ICYmICFjb21wb25lbnQucHJldmlld1BlbmRpbmcpIHtcXG5cXHRcXHRcXHRcXHRjb21wb25lbnQucHJldmlld1BlbmRpbmcgPSB0cnVlO1xcblxcdFxcdFxcdFxcdGNvbnN0IHJlcXVlc3RLZXkgPSBhcmdzS2V5O1xcblxcdFxcdFxcdFxcdHZvaWQgY29tcHV0ZUVkaXRzRGlmZihwcmV2aWV3SW5wdXQucGF0aCwgcHJldmlld0lucHV0LmVkaXRzLCBjb250ZXh0LmN3ZCkudGhlbigocHJldmlldykgPT4ge1xcblxcdFxcdFxcdFxcdFxcdGlmIChjb21wb25lbnQucHJldmlld0FyZ3NLZXkgPT09IHJlcXVlc3RLZXkpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRzZXRFZGl0UHJldmlldyhjb21wb25lbnQsIHByZXZpZXcsIHJlcXVlc3RLZXkpO1xcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnRleHQuaW52YWxpZGF0ZSgpO1xcblxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHR9KTtcXG5cXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0cmV0dXJuIGJ1aWxkRWRpdENhbGxDb21wb25lbnQoY29tcG9uZW50LCBhcmdzLCB0aGVtZSwgY29udGV4dC5jd2QpO1xcblxcdFxcdH0sXFxuXFx0XFx0cmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBjb250ZXh0KSB7XFxuXFx0XFx0XFx0Y29uc3QgY2FsbENvbXBvbmVudCA9IGNvbnRleHQuc3RhdGUuY2FsbENvbXBvbmVudDtcXG5cXHRcXHRcXHRjb25zdCBwcmV2aWV3SW5wdXQgPSBnZXRSZW5kZXJhYmxlUHJldmlld0lucHV0KGNvbnRleHQuYXJncyBhcyBSZW5kZXJhYmxlRWRpdEFyZ3MgfCB1bmRlZmluZWQpO1xcblxcdFxcdFxcdGNvbnN0IGFyZ3NLZXkgPSBwcmV2aWV3SW5wdXRcXG5cXHRcXHRcXHRcXHQ/IEpTT04uc3RyaW5naWZ5KHsgcGF0aDogcHJldmlld0lucHV0LnBhdGgsIGVkaXRzOiBwcmV2aWV3SW5wdXQuZWRpdHMgfSlcXG5cXHRcXHRcXHRcXHQ6IHVuZGVmaW5lZDtcXG5cXHRcXHRcXHRjb25zdCB0eXBlZFJlc3VsdCA9IHJlc3VsdCBhcyBFZGl0VG9vbFJlc3VsdExpa2U7XFxuXFx0XFx0XFx0Y29uc3QgcmVzdWx0RGlmZiA9ICFjb250ZXh0LmlzRXJyb3IgPyB0eXBlZFJlc3VsdC5kZXRhaWxzPy5kaWZmIDogdW5kZWZpbmVkO1xcblxcdFxcdFxcdGxldCBjaGFuZ2VkID0gZmFsc2U7XFxuXFx0XFx0XFx0aWYgKGNhbGxDb21wb25lbnQpIHtcXG5cXHRcXHRcXHRcXHRpZiAodHlwZW9mIHJlc3VsdERpZmYgPT09IFxcXCJzdHJpbmdcXFwiKSB7XFxuXFx0XFx0XFx0XFx0XFx0Y2hhbmdlZCA9XFxuXFx0XFx0XFx0XFx0XFx0XFx0c2V0RWRpdFByZXZpZXcoXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y2FsbENvbXBvbmVudCxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR7IGRpZmY6IHJlc3VsdERpZmYsIGZpcnN0Q2hhbmdlZExpbmU6IHR5cGVkUmVzdWx0LmRldGFpbHM/LmZpcnN0Q2hhbmdlZExpbmUgfSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRhcmdzS2V5LFxcblxcdFxcdFxcdFxcdFxcdFxcdCkgfHwgY2hhbmdlZDtcXG5cXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0aWYgKGNhbGxDb21wb25lbnQuc2V0dGxlZEVycm9yICE9PSBjb250ZXh0LmlzRXJyb3IpIHtcXG5cXHRcXHRcXHRcXHRcXHRjYWxsQ29tcG9uZW50LnNldHRsZWRFcnJvciA9IGNvbnRleHQuaXNFcnJvcjtcXG5cXHRcXHRcXHRcXHRcXHRjaGFuZ2VkID0gdHJ1ZTtcXG5cXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0aWYgKGNoYW5nZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRidWlsZEVkaXRDYWxsQ29tcG9uZW50KFxcblxcdFxcdFxcdFxcdFxcdFxcdGNhbGxDb21wb25lbnQsXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29udGV4dC5hcmdzIGFzIFJlbmRlcmFibGVFZGl0QXJncyB8IHVuZGVmaW5lZCxcXG5cXHRcXHRcXHRcXHRcXHRcXHR0aGVtZSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRjb250ZXh0LmN3ZCxcXG5cXHRcXHRcXHRcXHRcXHQpO1xcblxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0Y29uc3Qgb3V0cHV0ID0gZm9ybWF0RWRpdFJlc3VsdChjb250ZXh0LmFyZ3MsIGNhbGxDb21wb25lbnQ/LnByZXZpZXcsIHR5cGVkUmVzdWx0LCB0aGVtZSwgY29udGV4dC5pc0Vycm9yKTtcXG5cXHRcXHRcXHRjb25zdCBjb21wb25lbnQgPSAoY29udGV4dC5sYXN0Q29tcG9uZW50IGFzIENvbnRhaW5lciB8IHVuZGVmaW5lZCkgPz8gbmV3IENvbnRhaW5lcigpO1xcblxcdFxcdFxcdGNvbXBvbmVudC5jbGVhcigpO1xcblxcdFxcdFxcdGlmICghb3V0cHV0KSB7XFxuXFx0XFx0XFx0XFx0cmV0dXJuIGNvbXBvbmVudDtcXG5cXHRcXHRcXHR9XFxuXFx0XFx0XFx0Y29tcG9uZW50LmFkZENoaWxkKG5ldyBTcGFjZXIoMSkpO1xcblxcdFxcdFxcdGNvbXBvbmVudC5hZGRDaGlsZChuZXcgVGV4dChvdXRwdXQsIDEsIDApKTtcXG5cXHRcXHRcXHRyZXR1cm4gY29tcG9uZW50O1xcblxcdFxcdH0sXFxuXFx0fTtcXG59XFxuXFxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVkaXRUb29sKGN3ZDogc3RyaW5nLCBvcHRpb25zPzogRWRpdFRvb2xPcHRpb25zKTogQWdlbnRUb29sPHR5cGVvZiBlZGl0U2NoZW1hPiB7XFxuXFx0cmV0dXJuIHdyYXBUb29sRGVmaW5pdGlvbihjcmVhdGVFZGl0VG9vbERlZmluaXRpb24oY3dkLCBvcHRpb25zKSk7XFxufVxcblwiXX1cbm5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2Rpc3QvY29yZS90b29scy9maW5kLmpzLm1hcDp7XCJ2ZXJzaW9uXCI6MyxcImZpbGVcIjpcImZpbmQuanNcIixcInNvdXJjZVJvb3RcIjpcIlwiLFwic291cmNlc1wiOltcIi4uLy4uLy4uL3NyYy9jb3JlL3Rvb2xzL2ZpbmQudHNcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFlLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM1QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0RBQXdELENBQUM7QUFFakYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTFELE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQXlCLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRyxTQUFTLFdBQVcsQ0FBQyxLQUFhLEVBQVU7SUFDM0MsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFBQSxDQUN2QztBQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDOUIsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDcEIsV0FBVyxFQUFFLDhFQUE4RTtLQUMzRixDQUFDO0lBQ0YsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFdBQVcsRUFBRSxxREFBcUQsRUFBRSxDQUFDLENBQUM7SUFDeEcsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFdBQVcsRUFBRSwyQ0FBMkMsRUFBRSxDQUFDLENBQUM7Q0FDL0YsQ0FBQyxDQUFDO0FBSUgsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBa0IzQixNQUFNLHFCQUFxQixHQUFtQjtJQUM3QyxNQUFNLEVBQUUsVUFBVTtJQUNsQixtR0FBbUc7SUFDbkcsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUU7Q0FDZCxDQUFDO0FBT0YsU0FBUyxjQUFjLENBQUMsSUFBb0UsRUFBRSxLQUFZLEVBQVU7SUFDbkgsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuQyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hDLE1BQU0sSUFBSSxHQUFHLE9BQU8sS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNuRSxNQUFNLEtBQUssR0FBRyxJQUFJLEVBQUUsS0FBSyxDQUFDO0lBQzFCLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QyxJQUFJLElBQUksR0FDUCxLQUFLLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3pDLEdBQUc7UUFDSCxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLE9BQU8sSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3BFLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3pCLElBQUksSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxXQUFXLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQUEsQ0FDWjtBQUVELFNBQVMsZ0JBQWdCLENBQ3hCLE1BR0MsRUFDRCxPQUFnQyxFQUNoQyxLQUFZLEVBQ1osVUFBbUIsRUFDVjtJQUNULE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDeEQsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2QsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3RELE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDO1FBQzFDLElBQUksSUFBSSxLQUFLLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDbkYsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbkIsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsVUFBVSxTQUFTLGNBQWMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxXQUFXLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3hJLENBQUM7SUFDRixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQztJQUN2RCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQztJQUM5QyxJQUFJLFdBQVcsSUFBSSxVQUFVLEVBQUUsU0FBUyxFQUFFLENBQUM7UUFDMUMsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO1FBQzlCLElBQUksV0FBVztZQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxXQUFXLGdCQUFnQixDQUFDLENBQUM7UUFDL0QsSUFBSSxVQUFVLEVBQUUsU0FBUztZQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxRyxJQUFJLElBQUksS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxlQUFlLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7SUFDM0UsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQUEsQ0FDWjtBQUVELE1BQU0sVUFBVSx3QkFBd0IsQ0FDdkMsR0FBVyxFQUNYLE9BQXlCLEVBQ3dDO0lBQ2pFLE1BQU0sU0FBUyxHQUFHLE9BQU8sRUFBRSxVQUFVLENBQUM7SUFDdEMsT0FBTztRQUNOLElBQUksRUFBRSxNQUFNO1FBQ1osS0FBSyxFQUFFLE1BQU07UUFDYixXQUFXLEVBQUUsK0lBQStJLGFBQWEsZUFBZSxpQkFBaUIsR0FBRyxJQUFJLDhCQUE4QjtRQUM5TyxhQUFhLEVBQUUsa0RBQWtEO1FBQ2pFLFVBQVUsRUFBRSxVQUFVO1FBQ3RCLEtBQUssQ0FBQyxPQUFPLENBQ1osV0FBVyxFQUNYLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFzRCxFQUN2RixNQUFvQixFQUNwQixTQUFVLEVBQ1YsSUFBSyxFQUNKO1lBQ0QsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDO2dCQUN2QyxJQUFJLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztvQkFDckIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztvQkFDdkMsT0FBTztnQkFDUixDQUFDO2dCQUVELElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQztnQkFDcEIsSUFBSSxTQUFtQyxDQUFDO2dCQUN4QyxNQUFNLE1BQU0sR0FBRyxDQUFDLEVBQWMsRUFBRSxFQUFFLENBQUM7b0JBQ2xDLElBQUksT0FBTzt3QkFBRSxPQUFPO29CQUNwQixPQUFPLEdBQUcsSUFBSSxDQUFDO29CQUNmLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7b0JBQzlDLFNBQVMsR0FBRyxTQUFTLENBQUM7b0JBQ3RCLEVBQUUsRUFBRSxDQUFDO2dCQUFBLENBQ0wsQ0FBQztnQkFDRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQztvQkFDckIsU0FBUyxFQUFFLEVBQUUsQ0FBQztvQkFDZCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUFBLENBQ3JELENBQUM7Z0JBQ0YsTUFBTSxFQUFFLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFFM0QsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO29CQUNaLElBQUksQ0FBQzt3QkFDSixNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsU0FBUyxJQUFJLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQzt3QkFDdkQsTUFBTSxjQUFjLEdBQUcsS0FBSyxJQUFJLGFBQWEsQ0FBQzt3QkFDOUMsTUFBTSxHQUFHLEdBQUcsU0FBUyxJQUFJLHFCQUFxQixDQUFDO3dCQUUvQywrREFBK0Q7d0JBQy9ELElBQUksU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDOzRCQUNyQixJQUFJLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDO2dDQUNyQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDakUsT0FBTzs0QkFDUixDQUFDOzRCQUNELElBQUksTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO2dDQUNyQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNyRCxPQUFPOzRCQUNSLENBQUM7NEJBQ0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUU7Z0NBQ25ELE1BQU0sRUFBRSxDQUFDLG9CQUFvQixFQUFFLFlBQVksQ0FBQztnQ0FDNUMsS0FBSyxFQUFFLGNBQWM7NkJBQ3JCLENBQUMsQ0FBQzs0QkFDSCxJQUFJLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztnQ0FDckIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDckQsT0FBTzs0QkFDUixDQUFDOzRCQUNELElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQ0FDMUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUNYLE9BQU8sQ0FBQztvQ0FDUCxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLGlDQUFpQyxFQUFFLENBQUM7b0NBQ3BFLE9BQU8sRUFBRSxTQUFTO2lDQUNsQixDQUFDLENBQ0YsQ0FBQztnQ0FDRixPQUFPOzRCQUNSLENBQUM7NEJBRUQsOERBQThEOzRCQUM5RCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQ0FDdEMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztvQ0FBRSxPQUFPLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDakYsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFBQSxDQUNqRCxDQUFDLENBQUM7NEJBQ0gsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUMsTUFBTSxJQUFJLGNBQWMsQ0FBQzs0QkFDaEUsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFDekMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDOzRCQUNsRixJQUFJLFlBQVksR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDOzRCQUN0QyxNQUFNLE9BQU8sR0FBb0IsRUFBRSxDQUFDOzRCQUNwQyxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7NEJBQzdCLElBQUksa0JBQWtCLEVBQUUsQ0FBQztnQ0FDeEIsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLGNBQWMsd0JBQXdCLENBQUMsQ0FBQztnQ0FDeEQsT0FBTyxDQUFDLGtCQUFrQixHQUFHLGNBQWMsQ0FBQzs0QkFDN0MsQ0FBQzs0QkFDRCxJQUFJLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQ0FDMUIsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dDQUMvRCxPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQzs0QkFDakMsQ0FBQzs0QkFDRCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0NBQ3hCLFlBQVksSUFBSSxRQUFRLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQzs0QkFDL0MsQ0FBQzs0QkFDRCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQ1gsT0FBTyxDQUFDO2dDQUNQLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUM7Z0NBQy9DLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUzs2QkFDOUQsQ0FBQyxDQUNGLENBQUM7NEJBQ0YsT0FBTzt3QkFDUixDQUFDO3dCQUVELGtDQUFrQzt3QkFDbEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO3dCQUM1QyxJQUFJLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQzs0QkFDckIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDckQsT0FBTzt3QkFDUixDQUFDO3dCQUNELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzs0QkFDYixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNuRixPQUFPO3dCQUNSLENBQUM7d0JBRUQsOEVBQThFO3dCQUM5RSwrRUFBK0U7d0JBQy9FLGlGQUFpRjt3QkFDakYsTUFBTSxJQUFJLEdBQWE7NEJBQ3RCLFFBQVE7NEJBQ1IsZUFBZTs0QkFDZixVQUFVOzRCQUNWLGtCQUFrQjs0QkFDbEIsZUFBZTs0QkFDZixNQUFNLENBQUMsY0FBYyxDQUFDO3lCQUN0QixDQUFDO3dCQUVGLG1GQUFtRjt3QkFDbkYsNEVBQTRFO3dCQUM1RSwyRUFBMkU7d0JBQzNFLElBQUksZ0JBQWdCLEdBQUcsT0FBTyxDQUFDO3dCQUMvQixJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzs0QkFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzs0QkFDekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQztnQ0FDaEYsZ0JBQWdCLEdBQUcsTUFBTSxPQUFPLEVBQUUsQ0FBQzs0QkFDcEMsQ0FBQzt3QkFDRixDQUFDO3dCQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxDQUFDO3dCQUU5QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO3dCQUN6RSxNQUFNLEVBQUUsR0FBRyxlQUFlLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7d0JBQ3BELElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQzt3QkFDaEIsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO3dCQUUzQixTQUFTLEdBQUcsR0FBRyxFQUFFLENBQUM7NEJBQ2pCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7Z0NBQ25CLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzs0QkFDZCxDQUFDO3dCQUFBLENBQ0QsQ0FBQzt3QkFFRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQzs0QkFDckIsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUFBLENBQ1gsQ0FBQzt3QkFFRixLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDOzRCQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUFBLENBQzNCLENBQUMsQ0FBQzt3QkFFSCxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7NEJBQ3ZCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQUEsQ0FDakIsQ0FBQyxDQUFDO3dCQUVILEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQzs0QkFDNUIsT0FBTyxFQUFFLENBQUM7NEJBQ1YsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUFBLENBQ3RFLENBQUMsQ0FBQzt3QkFFSCxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7NEJBQzNCLE9BQU8sRUFBRSxDQUFDOzRCQUNWLElBQUksTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO2dDQUNyQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNyRCxPQUFPOzRCQUNSLENBQUM7NEJBQ0QsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFDaEMsSUFBSSxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0NBQ2hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSx1QkFBdUIsSUFBSSxFQUFFLENBQUM7Z0NBQ2hFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQ0FDYixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQ0FDMUMsT0FBTztnQ0FDUixDQUFDOzRCQUNGLENBQUM7NEJBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dDQUNiLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FDWCxPQUFPLENBQUM7b0NBQ1AsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxpQ0FBaUMsRUFBRSxDQUFDO29DQUNwRSxPQUFPLEVBQUUsU0FBUztpQ0FDbEIsQ0FBQyxDQUNGLENBQUM7Z0NBQ0YsT0FBTzs0QkFDUixDQUFDOzRCQUVELE1BQU0sV0FBVyxHQUFhLEVBQUUsQ0FBQzs0QkFDakMsS0FBSyxNQUFNLE9BQU8sSUFBSSxLQUFLLEVBQUUsQ0FBQztnQ0FDN0IsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7Z0NBQy9DLElBQUksQ0FBQyxJQUFJO29DQUFFLFNBQVM7Z0NBQ3BCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dDQUNuRSxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUM7Z0NBQ3hCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29DQUNqQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dDQUNsRCxDQUFDO3FDQUFNLENBQUM7b0NBQ1AsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO2dDQUNoRCxDQUFDO2dDQUNELElBQUksZ0JBQWdCLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztvQ0FBRSxZQUFZLElBQUksR0FBRyxDQUFDO2dDQUN6RSxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDOzRCQUM3QyxDQUFDOzRCQUVELE1BQU0sa0JBQWtCLEdBQUcsV0FBVyxDQUFDLE1BQU0sSUFBSSxjQUFjLENBQUM7NEJBQ2hFLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7NEJBQ3pDLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxTQUFTLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQzs0QkFDbEYsSUFBSSxZQUFZLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEMsTUFBTSxPQUFPLEdBQW9CLEVBQUUsQ0FBQzs0QkFDcEMsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDOzRCQUM3QixJQUFJLGtCQUFrQixFQUFFLENBQUM7Z0NBQ3hCLE9BQU8sQ0FBQyxJQUFJLENBQ1gsR0FBRyxjQUFjLHFDQUFxQyxjQUFjLEdBQUcsQ0FBQyw4QkFBOEIsQ0FDdEcsQ0FBQztnQ0FDRixPQUFPLENBQUMsa0JBQWtCLEdBQUcsY0FBYyxDQUFDOzRCQUM3QyxDQUFDOzRCQUNELElBQUksVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dDQUMxQixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0NBQy9ELE9BQU8sQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDOzRCQUNqQyxDQUFDOzRCQUNELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQ0FDeEIsWUFBWSxJQUFJLFFBQVEsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDOzRCQUMvQyxDQUFDOzRCQUNELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FDWCxPQUFPLENBQUM7Z0NBQ1AsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztnQ0FDL0MsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTOzZCQUM5RCxDQUFDLENBQ0YsQ0FBQzt3QkFBQSxDQUNGLENBQUMsQ0FBQztvQkFDSixDQUFDO29CQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7d0JBQ1osSUFBSSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7NEJBQ3JCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3JELE9BQU87d0JBQ1IsQ0FBQzt3QkFDRCxNQUFNLEtBQUssR0FBRyxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUM1RCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQzdCLENBQUM7Z0JBQUEsQ0FDRCxDQUFDLEVBQUUsQ0FBQztZQUFBLENBQ0wsQ0FBQyxDQUFDO1FBQUEsQ0FDSDtRQUNELFVBQVUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtZQUNoQyxNQUFNLElBQUksR0FBSSxPQUFPLENBQUMsYUFBa0MsSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9FLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzFDLE9BQU8sSUFBSSxDQUFDO1FBQUEsQ0FDWjtRQUNELFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7WUFDN0MsTUFBTSxJQUFJLEdBQUksT0FBTyxDQUFDLGFBQWtDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvRSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLE1BQWEsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ2xGLE9BQU8sSUFBSSxDQUFDO1FBQUEsQ0FDWjtLQUNELENBQUM7QUFBQSxDQUNGO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFXLEVBQUUsT0FBeUIsRUFBZ0M7SUFDcEcsT0FBTyxrQkFBa0IsQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUFBLENBQ2xFXCIsXCJzb3VyY2VzQ29udGVudFwiOltcImltcG9ydCB7IGNyZWF0ZUludGVyZmFjZSB9IGZyb20gXFxcIm5vZGU6cmVhZGxpbmVcXFwiO1xcbmltcG9ydCB0eXBlIHsgQWdlbnRUb29sIH0gZnJvbSBcXFwiQGVhcmVuZGlsLXdvcmtzL3BpLWFnZW50LWNvcmVcXFwiO1xcbmltcG9ydCB7IFRleHQgfSBmcm9tIFxcXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXFxcIjtcXG5pbXBvcnQgeyBzcGF3biB9IGZyb20gXFxcImNoaWxkX3Byb2Nlc3NcXFwiO1xcbmltcG9ydCBwYXRoIGZyb20gXFxcInBhdGhcXFwiO1xcbmltcG9ydCB7IHR5cGUgU3RhdGljLCBUeXBlIH0gZnJvbSBcXFwidHlwZWJveFxcXCI7XFxuaW1wb3J0IHsga2V5SGludCB9IGZyb20gXFxcIi4uLy4uL21vZGVzL2ludGVyYWN0aXZlL2NvbXBvbmVudHMva2V5YmluZGluZy1oaW50cy50c1xcXCI7XFxuaW1wb3J0IHR5cGUgeyBUaGVtZSB9IGZyb20gXFxcIi4uLy4uL21vZGVzL2ludGVyYWN0aXZlL3RoZW1lL3RoZW1lLnRzXFxcIjtcXG5pbXBvcnQgeyBlbnN1cmVUb29sIH0gZnJvbSBcXFwiLi4vLi4vdXRpbHMvdG9vbHMtbWFuYWdlci50c1xcXCI7XFxuaW1wb3J0IHR5cGUgeyBUb29sRGVmaW5pdGlvbiwgVG9vbFJlbmRlclJlc3VsdE9wdGlvbnMgfSBmcm9tIFxcXCIuLi9leHRlbnNpb25zL3R5cGVzLnRzXFxcIjtcXG5pbXBvcnQgeyBwYXRoRXhpc3RzLCByZXNvbHZlVG9Dd2QgfSBmcm9tIFxcXCIuL3BhdGgtdXRpbHMudHNcXFwiO1xcbmltcG9ydCB7IGdldFRleHRPdXRwdXQsIGludmFsaWRBcmdUZXh0LCBzaG9ydGVuUGF0aCwgc3RyIH0gZnJvbSBcXFwiLi9yZW5kZXItdXRpbHMudHNcXFwiO1xcbmltcG9ydCB7IHdyYXBUb29sRGVmaW5pdGlvbiB9IGZyb20gXFxcIi4vdG9vbC1kZWZpbml0aW9uLXdyYXBwZXIudHNcXFwiO1xcbmltcG9ydCB7IERFRkFVTFRfTUFYX0JZVEVTLCBmb3JtYXRTaXplLCB0eXBlIFRydW5jYXRpb25SZXN1bHQsIHRydW5jYXRlSGVhZCB9IGZyb20gXFxcIi4vdHJ1bmNhdGUudHNcXFwiO1xcblxcbmZ1bmN0aW9uIHRvUG9zaXhQYXRoKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xcblxcdHJldHVybiB2YWx1ZS5zcGxpdChwYXRoLnNlcCkuam9pbihcXFwiL1xcXCIpO1xcbn1cXG5cXG5jb25zdCBmaW5kU2NoZW1hID0gVHlwZS5PYmplY3Qoe1xcblxcdHBhdHRlcm46IFR5cGUuU3RyaW5nKHtcXG5cXHRcXHRkZXNjcmlwdGlvbjogXFxcIkdsb2IgcGF0dGVybiB0byBtYXRjaCBmaWxlcywgZS5nLiAnKi50cycsICcqKi8qLmpzb24nLCBvciAnc3JjLyoqLyouc3BlYy50cydcXFwiLFxcblxcdH0pLFxcblxcdHBhdGg6IFR5cGUuT3B0aW9uYWwoVHlwZS5TdHJpbmcoeyBkZXNjcmlwdGlvbjogXFxcIkRpcmVjdG9yeSB0byBzZWFyY2ggaW4gKGRlZmF1bHQ6IGN1cnJlbnQgZGlyZWN0b3J5KVxcXCIgfSkpLFxcblxcdGxpbWl0OiBUeXBlLk9wdGlvbmFsKFR5cGUuTnVtYmVyKHsgZGVzY3JpcHRpb246IFxcXCJNYXhpbXVtIG51bWJlciBvZiByZXN1bHRzIChkZWZhdWx0OiAxMDAwKVxcXCIgfSkpLFxcbn0pO1xcblxcbmV4cG9ydCB0eXBlIEZpbmRUb29sSW5wdXQgPSBTdGF0aWM8dHlwZW9mIGZpbmRTY2hlbWE+O1xcblxcbmNvbnN0IERFRkFVTFRfTElNSVQgPSAxMDAwO1xcblxcbmV4cG9ydCBpbnRlcmZhY2UgRmluZFRvb2xEZXRhaWxzIHtcXG5cXHR0cnVuY2F0aW9uPzogVHJ1bmNhdGlvblJlc3VsdDtcXG5cXHRyZXN1bHRMaW1pdFJlYWNoZWQ/OiBudW1iZXI7XFxufVxcblxcbi8qKlxcbiAqIFBsdWdnYWJsZSBvcGVyYXRpb25zIGZvciB0aGUgZmluZCB0b29sLlxcbiAqIE92ZXJyaWRlIHRoZXNlIHRvIGRlbGVnYXRlIGZpbGUgc2VhcmNoIHRvIHJlbW90ZSBzeXN0ZW1zIChmb3IgZXhhbXBsZSBTU0gpLlxcbiAqL1xcbmV4cG9ydCBpbnRlcmZhY2UgRmluZE9wZXJhdGlvbnMge1xcblxcdC8qKiBDaGVjayBpZiBwYXRoIGV4aXN0cyAqL1xcblxcdGV4aXN0czogKGFic29sdXRlUGF0aDogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+IHwgYm9vbGVhbjtcXG5cXHQvKiogRmluZCBmaWxlcyBtYXRjaGluZyBnbG9iIHBhdHRlcm4uIFJldHVybnMgcmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aHMuICovXFxuXFx0Z2xvYjogKHBhdHRlcm46IHN0cmluZywgY3dkOiBzdHJpbmcsIG9wdGlvbnM6IHsgaWdub3JlOiBzdHJpbmdbXTsgbGltaXQ6IG51bWJlciB9KSA9PiBQcm9taXNlPHN0cmluZ1tdPiB8IHN0cmluZ1tdO1xcbn1cXG5cXG5jb25zdCBkZWZhdWx0RmluZE9wZXJhdGlvbnM6IEZpbmRPcGVyYXRpb25zID0ge1xcblxcdGV4aXN0czogcGF0aEV4aXN0cyxcXG5cXHQvLyBUaGlzIGlzIGEgcGxhY2Vob2xkZXIuIEFjdHVhbCBmZCBleGVjdXRpb24gaGFwcGVucyBpbiBleGVjdXRlKCkgd2hlbiBubyBjdXN0b20gZ2xvYiBpcyBwcm92aWRlZC5cXG5cXHRnbG9iOiAoKSA9PiBbXSxcXG59O1xcblxcbmV4cG9ydCBpbnRlcmZhY2UgRmluZFRvb2xPcHRpb25zIHtcXG5cXHQvKiogQ3VzdG9tIG9wZXJhdGlvbnMgZm9yIGZpbmQuIERlZmF1bHQ6IGxvY2FsIGZpbGVzeXN0ZW0gcGx1cyBmZCAqL1xcblxcdG9wZXJhdGlvbnM/OiBGaW5kT3BlcmF0aW9ucztcXG59XFxuXFxuZnVuY3Rpb24gZm9ybWF0RmluZENhbGwoYXJnczogeyBwYXR0ZXJuOiBzdHJpbmc7IHBhdGg/OiBzdHJpbmc7IGxpbWl0PzogbnVtYmVyIH0gfCB1bmRlZmluZWQsIHRoZW1lOiBUaGVtZSk6IHN0cmluZyB7XFxuXFx0Y29uc3QgcGF0dGVybiA9IHN0cihhcmdzPy5wYXR0ZXJuKTtcXG5cXHRjb25zdCByYXdQYXRoID0gc3RyKGFyZ3M/LnBhdGgpO1xcblxcdGNvbnN0IHBhdGggPSByYXdQYXRoICE9PSBudWxsID8gc2hvcnRlblBhdGgocmF3UGF0aCB8fCBcXFwiLlxcXCIpIDogbnVsbDtcXG5cXHRjb25zdCBsaW1pdCA9IGFyZ3M/LmxpbWl0O1xcblxcdGNvbnN0IGludmFsaWRBcmcgPSBpbnZhbGlkQXJnVGV4dCh0aGVtZSk7XFxuXFx0bGV0IHRleHQgPVxcblxcdFxcdHRoZW1lLmZnKFxcXCJ0b29sVGl0bGVcXFwiLCB0aGVtZS5ib2xkKFxcXCJmaW5kXFxcIikpICtcXG5cXHRcXHRcXFwiIFxcXCIgK1xcblxcdFxcdChwYXR0ZXJuID09PSBudWxsID8gaW52YWxpZEFyZyA6IHRoZW1lLmZnKFxcXCJhY2NlbnRcXFwiLCBwYXR0ZXJuIHx8IFxcXCJcXFwiKSkgK1xcblxcdFxcdHRoZW1lLmZnKFxcXCJ0b29sT3V0cHV0XFxcIiwgYCBpbiAke3BhdGggPT09IG51bGwgPyBpbnZhbGlkQXJnIDogcGF0aH1gKTtcXG5cXHRpZiAobGltaXQgIT09IHVuZGVmaW5lZCkge1xcblxcdFxcdHRleHQgKz0gdGhlbWUuZmcoXFxcInRvb2xPdXRwdXRcXFwiLCBgIChsaW1pdCAke2xpbWl0fSlgKTtcXG5cXHR9XFxuXFx0cmV0dXJuIHRleHQ7XFxufVxcblxcbmZ1bmN0aW9uIGZvcm1hdEZpbmRSZXN1bHQoXFxuXFx0cmVzdWx0OiB7XFxuXFx0XFx0Y29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ/OiBzdHJpbmc7IGRhdGE/OiBzdHJpbmc7IG1pbWVUeXBlPzogc3RyaW5nIH0+O1xcblxcdFxcdGRldGFpbHM/OiBGaW5kVG9vbERldGFpbHM7XFxuXFx0fSxcXG5cXHRvcHRpb25zOiBUb29sUmVuZGVyUmVzdWx0T3B0aW9ucyxcXG5cXHR0aGVtZTogVGhlbWUsXFxuXFx0c2hvd0ltYWdlczogYm9vbGVhbixcXG4pOiBzdHJpbmcge1xcblxcdGNvbnN0IG91dHB1dCA9IGdldFRleHRPdXRwdXQocmVzdWx0LCBzaG93SW1hZ2VzKS50cmltKCk7XFxuXFx0bGV0IHRleHQgPSBcXFwiXFxcIjtcXG5cXHRpZiAob3V0cHV0KSB7XFxuXFx0XFx0Y29uc3QgbGluZXMgPSBvdXRwdXQuc3BsaXQoXFxcIlxcXFxuXFxcIik7XFxuXFx0XFx0Y29uc3QgbWF4TGluZXMgPSBvcHRpb25zLmV4cGFuZGVkID8gbGluZXMubGVuZ3RoIDogMjA7XFxuXFx0XFx0Y29uc3QgZGlzcGxheUxpbmVzID0gbGluZXMuc2xpY2UoMCwgbWF4TGluZXMpO1xcblxcdFxcdGNvbnN0IHJlbWFpbmluZyA9IGxpbmVzLmxlbmd0aCAtIG1heExpbmVzO1xcblxcdFxcdHRleHQgKz0gYFxcXFxuJHtkaXNwbGF5TGluZXMubWFwKChsaW5lKSA9PiB0aGVtZS5mZyhcXFwidG9vbE91dHB1dFxcXCIsIGxpbmUpKS5qb2luKFxcXCJcXFxcblxcXCIpfWA7XFxuXFx0XFx0aWYgKHJlbWFpbmluZyA+IDApIHtcXG5cXHRcXHRcXHR0ZXh0ICs9IGAke3RoZW1lLmZnKFxcXCJtdXRlZFxcXCIsIGBcXFxcbi4uLiAoJHtyZW1haW5pbmd9IG1vcmUgbGluZXMsYCl9ICR7a2V5SGludChcXFwiYXBwLnRvb2xzLmV4cGFuZFxcXCIsIFxcXCJ0byBleHBhbmRcXFwiKX0ke3RoZW1lLmZnKFxcXCJtdXRlZFxcXCIsIFxcXCIpXFxcIil9YDtcXG5cXHRcXHR9XFxuXFx0fVxcblxcblxcdGNvbnN0IHJlc3VsdExpbWl0ID0gcmVzdWx0LmRldGFpbHM/LnJlc3VsdExpbWl0UmVhY2hlZDtcXG5cXHRjb25zdCB0cnVuY2F0aW9uID0gcmVzdWx0LmRldGFpbHM/LnRydW5jYXRpb247XFxuXFx0aWYgKHJlc3VsdExpbWl0IHx8IHRydW5jYXRpb24/LnRydW5jYXRlZCkge1xcblxcdFxcdGNvbnN0IHdhcm5pbmdzOiBzdHJpbmdbXSA9IFtdO1xcblxcdFxcdGlmIChyZXN1bHRMaW1pdCkgd2FybmluZ3MucHVzaChgJHtyZXN1bHRMaW1pdH0gcmVzdWx0cyBsaW1pdGApO1xcblxcdFxcdGlmICh0cnVuY2F0aW9uPy50cnVuY2F0ZWQpIHdhcm5pbmdzLnB1c2goYCR7Zm9ybWF0U2l6ZSh0cnVuY2F0aW9uLm1heEJ5dGVzID8/IERFRkFVTFRfTUFYX0JZVEVTKX0gbGltaXRgKTtcXG5cXHRcXHR0ZXh0ICs9IGBcXFxcbiR7dGhlbWUuZmcoXFxcIndhcm5pbmdcXFwiLCBgW1RydW5jYXRlZDogJHt3YXJuaW5ncy5qb2luKFxcXCIsIFxcXCIpfV1gKX1gO1xcblxcdH1cXG5cXHRyZXR1cm4gdGV4dDtcXG59XFxuXFxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZpbmRUb29sRGVmaW5pdGlvbihcXG5cXHRjd2Q6IHN0cmluZyxcXG5cXHRvcHRpb25zPzogRmluZFRvb2xPcHRpb25zLFxcbik6IFRvb2xEZWZpbml0aW9uPHR5cGVvZiBmaW5kU2NoZW1hLCBGaW5kVG9vbERldGFpbHMgfCB1bmRlZmluZWQ+IHtcXG5cXHRjb25zdCBjdXN0b21PcHMgPSBvcHRpb25zPy5vcGVyYXRpb25zO1xcblxcdHJldHVybiB7XFxuXFx0XFx0bmFtZTogXFxcImZpbmRcXFwiLFxcblxcdFxcdGxhYmVsOiBcXFwiZmluZFxcXCIsXFxuXFx0XFx0ZGVzY3JpcHRpb246IGBTZWFyY2ggZm9yIGZpbGVzIGJ5IGdsb2IgcGF0dGVybi4gUmV0dXJucyBtYXRjaGluZyBmaWxlIHBhdGhzIHJlbGF0aXZlIHRvIHRoZSBzZWFyY2ggZGlyZWN0b3J5LiBSZXNwZWN0cyAuZ2l0aWdub3JlLiBPdXRwdXQgaXMgdHJ1bmNhdGVkIHRvICR7REVGQVVMVF9MSU1JVH0gcmVzdWx0cyBvciAke0RFRkFVTFRfTUFYX0JZVEVTIC8gMTAyNH1LQiAod2hpY2hldmVyIGlzIGhpdCBmaXJzdCkuYCxcXG5cXHRcXHRwcm9tcHRTbmlwcGV0OiBcXFwiRmluZCBmaWxlcyBieSBnbG9iIHBhdHRlcm4gKHJlc3BlY3RzIC5naXRpZ25vcmUpXFxcIixcXG5cXHRcXHRwYXJhbWV0ZXJzOiBmaW5kU2NoZW1hLFxcblxcdFxcdGFzeW5jIGV4ZWN1dGUoXFxuXFx0XFx0XFx0X3Rvb2xDYWxsSWQsXFxuXFx0XFx0XFx0eyBwYXR0ZXJuLCBwYXRoOiBzZWFyY2hEaXIsIGxpbWl0IH06IHsgcGF0dGVybjogc3RyaW5nOyBwYXRoPzogc3RyaW5nOyBsaW1pdD86IG51bWJlciB9LFxcblxcdFxcdFxcdHNpZ25hbD86IEFib3J0U2lnbmFsLFxcblxcdFxcdFxcdF9vblVwZGF0ZT8sXFxuXFx0XFx0XFx0X2N0eD8sXFxuXFx0XFx0KSB7XFxuXFx0XFx0XFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcXG5cXHRcXHRcXHRcXHRpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0cmVqZWN0KG5ldyBFcnJvcihcXFwiT3BlcmF0aW9uIGFib3J0ZWRcXFwiKSk7XFxuXFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRcXHRsZXQgc2V0dGxlZCA9IGZhbHNlO1xcblxcdFxcdFxcdFxcdGxldCBzdG9wQ2hpbGQ6ICgoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcXG5cXHRcXHRcXHRcXHRjb25zdCBzZXR0bGUgPSAoZm46ICgpID0+IHZvaWQpID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRpZiAoc2V0dGxlZCkgcmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdHNldHRsZWQgPSB0cnVlO1xcblxcdFxcdFxcdFxcdFxcdHNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcXFwiYWJvcnRcXFwiLCBvbkFib3J0KTtcXG5cXHRcXHRcXHRcXHRcXHRzdG9wQ2hpbGQgPSB1bmRlZmluZWQ7XFxuXFx0XFx0XFx0XFx0XFx0Zm4oKTtcXG5cXHRcXHRcXHRcXHR9O1xcblxcdFxcdFxcdFxcdGNvbnN0IG9uQWJvcnQgPSAoKSA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0c3RvcENoaWxkPy4oKTtcXG5cXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihcXFwiT3BlcmF0aW9uIGFib3J0ZWRcXFwiKSkpO1xcblxcdFxcdFxcdFxcdH07XFxuXFx0XFx0XFx0XFx0c2lnbmFsPy5hZGRFdmVudExpc3RlbmVyKFxcXCJhYm9ydFxcXCIsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcXG5cXG5cXHRcXHRcXHRcXHQoYXN5bmMgKCkgPT4ge1xcblxcdFxcdFxcdFxcdFxcdHRyeSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29uc3Qgc2VhcmNoUGF0aCA9IHJlc29sdmVUb0N3ZChzZWFyY2hEaXIgfHwgXFxcIi5cXFwiLCBjd2QpO1xcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGVmZmVjdGl2ZUxpbWl0ID0gbGltaXQgPz8gREVGQVVMVF9MSU1JVDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBvcHMgPSBjdXN0b21PcHMgPz8gZGVmYXVsdEZpbmRPcGVyYXRpb25zO1xcblxcblxcdFxcdFxcdFxcdFxcdFxcdC8vIElmIGN1c3RvbSBvcGVyYXRpb25zIHByb3ZpZGUgZ2xvYigpLCB1c2UgdGhhdCBpbnN0ZWFkIG9mIGZkLlxcblxcdFxcdFxcdFxcdFxcdFxcdGlmIChjdXN0b21PcHM/Lmdsb2IpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoIShhd2FpdCBvcHMuZXhpc3RzKHNlYXJjaFBhdGgpKSkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKGBQYXRoIG5vdCBmb3VuZDogJHtzZWFyY2hQYXRofWApKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoXFxcIk9wZXJhdGlvbiBhYm9ydGVkXFxcIikpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBvcHMuZ2xvYihwYXR0ZXJuLCBzZWFyY2hQYXRoLCB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0aWdub3JlOiBbXFxcIioqL25vZGVfbW9kdWxlcy8qKlxcXCIsIFxcXCIqKi8uZ2l0LyoqXFxcIl0sXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0bGltaXQ6IGVmZmVjdGl2ZUxpbWl0LFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH0pO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChzaWduYWw/LmFib3J0ZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihcXFwiT3BlcmF0aW9uIGFib3J0ZWRcXFwiKSkpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKHJlc3VsdHMubGVuZ3RoID09PSAwKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmVzb2x2ZSh7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29udGVudDogW3sgdHlwZTogXFxcInRleHRcXFwiLCB0ZXh0OiBcXFwiTm8gZmlsZXMgZm91bmQgbWF0Y2hpbmcgcGF0dGVyblxcXCIgfV0sXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0ZGV0YWlsczogdW5kZWZpbmVkLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdH0pLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHQvLyBSZWxhdGl2aXplIHBhdGhzIGFnYWluc3QgdGhlIHNlYXJjaCByb290IGZvciBzdGFibGUgb3V0cHV0LlxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IHJlbGF0aXZpemVkID0gcmVzdWx0cy5tYXAoKHApID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAocC5zdGFydHNXaXRoKHNlYXJjaFBhdGgpKSByZXR1cm4gdG9Qb3NpeFBhdGgocC5zbGljZShzZWFyY2hQYXRoLmxlbmd0aCArIDEpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm4gdG9Qb3NpeFBhdGgocGF0aC5yZWxhdGl2ZShzZWFyY2hQYXRoLCBwKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmVzdWx0TGltaXRSZWFjaGVkID0gcmVsYXRpdml6ZWQubGVuZ3RoID49IGVmZmVjdGl2ZUxpbWl0O1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IHJhd091dHB1dCA9IHJlbGF0aXZpemVkLmpvaW4oXFxcIlxcXFxuXFxcIik7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgdHJ1bmNhdGlvbiA9IHRydW5jYXRlSGVhZChyYXdPdXRwdXQsIHsgbWF4TGluZXM6IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIH0pO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGxldCByZXN1bHRPdXRwdXQgPSB0cnVuY2F0aW9uLmNvbnRlbnQ7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgZGV0YWlsczogRmluZFRvb2xEZXRhaWxzID0ge307XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3Qgbm90aWNlczogc3RyaW5nW10gPSBbXTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAocmVzdWx0TGltaXRSZWFjaGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0bm90aWNlcy5wdXNoKGAke2VmZmVjdGl2ZUxpbWl0fSByZXN1bHRzIGxpbWl0IHJlYWNoZWRgKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzLnJlc3VsdExpbWl0UmVhY2hlZCA9IGVmZmVjdGl2ZUxpbWl0O1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAodHJ1bmNhdGlvbi50cnVuY2F0ZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRub3RpY2VzLnB1c2goYCR7Zm9ybWF0U2l6ZShERUZBVUxUX01BWF9CWVRFUyl9IGxpbWl0IHJlYWNoZWRgKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzLnRydW5jYXRpb24gPSB0cnVuY2F0aW9uO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRpZiAobm90aWNlcy5sZW5ndGggPiAwKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmVzdWx0T3V0cHV0ICs9IGBcXFxcblxcXFxuWyR7bm90aWNlcy5qb2luKFxcXCIuIFxcXCIpfV1gO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT5cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXNvbHZlKHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjb250ZW50OiBbeyB0eXBlOiBcXFwidGV4dFxcXCIsIHRleHQ6IHJlc3VsdE91dHB1dCB9XSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzOiBPYmplY3Qua2V5cyhkZXRhaWxzKS5sZW5ndGggPiAwID8gZGV0YWlscyA6IHVuZGVmaW5lZCxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHR9KSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHQpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Ly8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB1c2VzIGZkLlxcblxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGZkUGF0aCA9IGF3YWl0IGVuc3VyZVRvb2woXFxcImZkXFxcIiwgdHJ1ZSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0aWYgKHNpZ25hbD8uYWJvcnRlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRpZiAoIWZkUGF0aCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKFxcXCJmZCBpcyBub3QgYXZhaWxhYmxlIGFuZCBjb3VsZCBub3QgYmUgZG93bmxvYWRlZFxcXCIpKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBCdWlsZCBmZCBhcmd1bWVudHMuIC0tbm8tcmVxdWlyZS1naXQgbWFrZXMgZmQgYXBwbHkgaGllcmFyY2hpY2FsIC5naXRpZ25vcmVcXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBzZW1hbnRpY3Mgd2hldGhlciBvciBub3QgdGhlIHNlYXJjaCBwYXRoIGlzIGluc2lkZSBhIGdpdCByZXBvc2l0b3J5LCB3aXRob3V0XFxuXFx0XFx0XFx0XFx0XFx0XFx0Ly8gbGVha2luZyBzaWJsaW5nLWRpcmVjdG9yeSBydWxlcyB0aGUgd2F5IC0taWdub3JlLWZpbGUgKGEgZ2xvYmFsIHNvdXJjZSkgd291bGQuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgYXJnczogc3RyaW5nW10gPSBbXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFxcIi0tZ2xvYlxcXCIsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFxcIi0tY29sb3I9bmV2ZXJcXFwiLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcXCItLWhpZGRlblxcXCIsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFxcIi0tbm8tcmVxdWlyZS1naXRcXFwiLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcXCItLW1heC1yZXN1bHRzXFxcIixcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRTdHJpbmcoZWZmZWN0aXZlTGltaXQpLFxcblxcdFxcdFxcdFxcdFxcdFxcdF07XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Ly8gZmQgLS1nbG9iIG1hdGNoZXMgYWdhaW5zdCB0aGUgYmFzZW5hbWUgdW5sZXNzIC0tZnVsbC1wYXRoIGlzIHNldDsgaW4gLS1mdWxsLXBhdGhcXG5cXHRcXHRcXHRcXHRcXHRcXHQvLyBtb2RlIGl0IG1hdGNoZXMgYWdhaW5zdCB0aGUgYWJzb2x1dGUgY2FuZGlkYXRlIHBhdGgsIHNvIGEgcGF0aC1jb250YWluaW5nXFxuXFx0XFx0XFx0XFx0XFx0XFx0Ly8gcGF0dGVybiBsaWtlICdzcmMvKiovKi5zcGVjLnRzJyBuZWVkcyBhIGxlYWRpbmcgJyoqLycgdG8gbWF0Y2ggYW55dGhpbmcuXFxuXFx0XFx0XFx0XFx0XFx0XFx0bGV0IGVmZmVjdGl2ZVBhdHRlcm4gPSBwYXR0ZXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdGlmIChwYXR0ZXJuLmluY2x1ZGVzKFxcXCIvXFxcIikpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRhcmdzLnB1c2goXFxcIi0tZnVsbC1wYXRoXFxcIik7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKCFwYXR0ZXJuLnN0YXJ0c1dpdGgoXFxcIi9cXFwiKSAmJiAhcGF0dGVybi5zdGFydHNXaXRoKFxcXCIqKi9cXFwiKSAmJiBwYXR0ZXJuICE9PSBcXFwiKipcXFwiKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0ZWZmZWN0aXZlUGF0dGVybiA9IGAqKi8ke3BhdHRlcm59YDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdGFyZ3MucHVzaChcXFwiLS1cXFwiLCBlZmZlY3RpdmVQYXR0ZXJuLCBzZWFyY2hQYXRoKTtcXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBjaGlsZCA9IHNwYXduKGZkUGF0aCwgYXJncywgeyBzdGRpbzogW1xcXCJpZ25vcmVcXFwiLCBcXFwicGlwZVxcXCIsIFxcXCJwaXBlXFxcIl0gfSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmwgPSBjcmVhdGVJbnRlcmZhY2UoeyBpbnB1dDogY2hpbGQuc3Rkb3V0IH0pO1xcblxcdFxcdFxcdFxcdFxcdFxcdGxldCBzdGRlcnIgPSBcXFwiXFxcIjtcXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRzdG9wQ2hpbGQgPSAoKSA9PiB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKCFjaGlsZC5raWxsZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjaGlsZC5raWxsKCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdH07XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgY2xlYW51cCA9ICgpID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRybC5jbG9zZSgpO1xcblxcdFxcdFxcdFxcdFxcdFxcdH07XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y2hpbGQuc3RkZXJyPy5vbihcXFwiZGF0YVxcXCIsIChjaHVuaykgPT4ge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHN0ZGVyciArPSBjaHVuay50b1N0cmluZygpO1xcblxcdFxcdFxcdFxcdFxcdFxcdH0pO1xcblxcblxcdFxcdFxcdFxcdFxcdFxcdHJsLm9uKFxcXCJsaW5lXFxcIiwgKGxpbmUpID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRsaW5lcy5wdXNoKGxpbmUpO1xcblxcdFxcdFxcdFxcdFxcdFxcdH0pO1xcblxcblxcdFxcdFxcdFxcdFxcdFxcdGNoaWxkLm9uKFxcXCJlcnJvclxcXCIsIChlcnJvcikgPT4ge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNsZWFudXAoKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIHJ1biBmZDogJHtlcnJvci5tZXNzYWdlfWApKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0fSk7XFxuXFxuXFx0XFx0XFx0XFx0XFx0XFx0Y2hpbGQub24oXFxcImNsb3NlXFxcIiwgKGNvZGUpID0+IHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjbGVhbnVwKCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKHNpZ25hbD8uYWJvcnRlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBvdXRwdXQgPSBsaW5lcy5qb2luKFxcXCJcXFxcblxcXCIpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChjb2RlICE9PSAwKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgZXJyb3JNc2cgPSBzdGRlcnIudHJpbSgpIHx8IGBmZCBleGl0ZWQgd2l0aCBjb2RlICR7Y29kZX1gO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmICghb3V0cHV0KSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoZXJyb3JNc2cpKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKCFvdXRwdXQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT5cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXNvbHZlKHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjb250ZW50OiBbeyB0eXBlOiBcXFwidGV4dFxcXCIsIHRleHQ6IFxcXCJObyBmaWxlcyBmb3VuZCBtYXRjaGluZyBwYXR0ZXJuXFxcIiB9XSxcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRkZXRhaWxzOiB1bmRlZmluZWQsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0fSksXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IHJlbGF0aXZpemVkOiBzdHJpbmdbXSA9IFtdO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGZvciAoY29uc3QgcmF3TGluZSBvZiBsaW5lcykge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGNvbnN0IGxpbmUgPSByYXdMaW5lLnJlcGxhY2UoL1xcXFxyJC8sIFxcXCJcXFwiKS50cmltKCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKCFsaW5lKSBjb250aW51ZTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBoYWRUcmFpbGluZ1NsYXNoID0gbGluZS5lbmRzV2l0aChcXFwiL1xcXCIpIHx8IGxpbmUuZW5kc1dpdGgoXFxcIlxcXFxcXFxcXFxcIik7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0bGV0IHJlbGF0aXZlUGF0aCA9IGxpbmU7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKGxpbmUuc3RhcnRzV2l0aChzZWFyY2hQYXRoKSkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJlbGF0aXZlUGF0aCA9IGxpbmUuc2xpY2Uoc2VhcmNoUGF0aC5sZW5ndGggKyAxKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHR9IGVsc2Uge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJlbGF0aXZlUGF0aCA9IHBhdGgucmVsYXRpdmUoc2VhcmNoUGF0aCwgbGluZSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChoYWRUcmFpbGluZ1NsYXNoICYmICFyZWxhdGl2ZVBhdGguZW5kc1dpdGgoXFxcIi9cXFwiKSkgcmVsYXRpdmVQYXRoICs9IFxcXCIvXFxcIjtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRyZWxhdGl2aXplZC5wdXNoKHRvUG9zaXhQYXRoKHJlbGF0aXZlUGF0aCkpO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCByZXN1bHRMaW1pdFJlYWNoZWQgPSByZWxhdGl2aXplZC5sZW5ndGggPj0gZWZmZWN0aXZlTGltaXQ7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29uc3QgcmF3T3V0cHV0ID0gcmVsYXRpdml6ZWQuam9pbihcXFwiXFxcXG5cXFwiKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCB0cnVuY2F0aW9uID0gdHJ1bmNhdGVIZWFkKHJhd091dHB1dCwgeyBtYXhMaW5lczogTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0bGV0IHJlc3VsdE91dHB1dCA9IHRydW5jYXRpb24uY29udGVudDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBkZXRhaWxzOiBGaW5kVG9vbERldGFpbHMgPSB7fTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBub3RpY2VzOiBzdHJpbmdbXSA9IFtdO1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdGlmIChyZXN1bHRMaW1pdFJlYWNoZWQpIHtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHRcXHRub3RpY2VzLnB1c2goXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0YCR7ZWZmZWN0aXZlTGltaXR9IHJlc3VsdHMgbGltaXQgcmVhY2hlZC4gVXNlIGxpbWl0PSR7ZWZmZWN0aXZlTGltaXQgKiAyfSBmb3IgbW9yZSwgb3IgcmVmaW5lIHBhdHRlcm5gLFxcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0ZGV0YWlscy5yZXN1bHRMaW1pdFJlYWNoZWQgPSBlZmZlY3RpdmVMaW1pdDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKHRydW5jYXRpb24udHJ1bmNhdGVkKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0bm90aWNlcy5wdXNoKGAke2Zvcm1hdFNpemUoREVGQVVMVF9NQVhfQllURVMpfSBsaW1pdCByZWFjaGVkYCk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0ZGV0YWlscy50cnVuY2F0aW9uID0gdHJ1bmNhdGlvbjtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0aWYgKG5vdGljZXMubGVuZ3RoID4gMCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdFxcdHJlc3VsdE91dHB1dCArPSBgXFxcXG5cXFxcblske25vdGljZXMuam9pbihcXFwiLiBcXFwiKX1dYDtcXG5cXHRcXHRcXHRcXHRcXHRcXHRcXHR9XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0c2V0dGxlKCgpID0+XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0cmVzb2x2ZSh7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0Y29udGVudDogW3sgdHlwZTogXFxcInRleHRcXFwiLCB0ZXh0OiByZXN1bHRPdXRwdXQgfV0sXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0ZGV0YWlsczogT2JqZWN0LmtleXMoZGV0YWlscykubGVuZ3RoID4gMCA/IGRldGFpbHMgOiB1bmRlZmluZWQsXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0XFx0fSksXFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0KTtcXG5cXHRcXHRcXHRcXHRcXHRcXHR9KTtcXG5cXHRcXHRcXHRcXHRcXHR9IGNhdGNoIChlKSB7XFxuXFx0XFx0XFx0XFx0XFx0XFx0aWYgKHNpZ25hbD8uYWJvcnRlZCkge1xcblxcdFxcdFxcdFxcdFxcdFxcdFxcdHNldHRsZSgoKSA9PiByZWplY3QobmV3IEVycm9yKFxcXCJPcGVyYXRpb24gYWJvcnRlZFxcXCIpKSk7XFxuXFx0XFx0XFx0XFx0XFx0XFx0XFx0cmV0dXJuO1xcblxcdFxcdFxcdFxcdFxcdFxcdH1cXG5cXHRcXHRcXHRcXHRcXHRcXHRjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUgOiBuZXcgRXJyb3IoU3RyaW5nKGUpKTtcXG5cXHRcXHRcXHRcXHRcXHRcXHRzZXR0bGUoKCkgPT4gcmVqZWN0KGVycm9yKSk7XFxuXFx0XFx0XFx0XFx0XFx0fVxcblxcdFxcdFxcdFxcdH0pKCk7XFxuXFx0XFx0XFx0fSk7XFxuXFx0XFx0fSxcXG5cXHRcXHRyZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBjb250ZXh0KSB7XFxuXFx0XFx0XFx0Y29uc3QgdGV4dCA9IChjb250ZXh0Lmxhc3RDb21wb25lbnQgYXMgVGV4dCB8IHVuZGVmaW5lZCkgPz8gbmV3IFRleHQoXFxcIlxcXCIsIDAsIDApO1xcblxcdFxcdFxcdHRleHQuc2V0VGV4dChmb3JtYXRGaW5kQ2FsbChhcmdzLCB0aGVtZSkpO1xcblxcdFxcdFxcdHJldHVybiB0ZXh0O1xcblxcdFxcdH0sXFxuXFx0XFx0cmVuZGVyUmVzdWx0KHJlc3VsdCwgb3B0aW9ucywgdGhlbWUsIGNvbnRleHQpIHtcXG5cXHRcXHRcXHRjb25zdCB0ZXh0ID0gKGNvbnRleHQubGFzdENvbXBvbmVudCBhcyBUZXh0IHwgdW5kZWZpbmVkKSA/PyBuZXcgVGV4dChcXFwiXFxcIiwgMCwgMCk7XFxuXFx0XFx0XFx0dGV4dC5zZXRUZXh0KGZvcm1hdEZpbmRSZXN1bHQocmVzdWx0IGFzIGFueSwgb3B0aW9ucywgdGhlbWUsIGNvbnRleHQuc2hvd0ltYWdlcykpO1xcblxcdFxcdFxcdHJldHVybiB0ZXh0O1xcblxcdFxcdH0sXFxuXFx0fTtcXG59XFxuXFxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZpbmRUb29sKGN3ZDogc3RyaW5nLCBvcHRpb25zPzogRmluZFRvb2xPcHRpb25zKTogQWdlbnRUb29sPHR5cGVvZiBmaW5kU2NoZW1hPiB7XFxuXFx0cmV0dXJuIHdyYXBUb29sRGVmaW5pdGlvbihjcmVhdGVGaW5kVG9vbERlZmluaXRpb24oY3dkLCBvcHRpb25zKSk7XFxufVxcblwiXX0iLCJ0cnVuY2F0ZWQiOnRydWUsInRydW5jYXRlZEJ5IjoiYnl0ZXMiLCJ0b3RhbExpbmVzIjoxMCwidG90YWxCeXRlcyI6MzEwNTE1LCJvdXRwdXRMaW5lcyI6Miwib3V0cHV0Qnl0ZXMiOjQ1NDQyLCJsYXN0TGluZVBhcnRpYWwiOmZhbHNlLCJmaXJzdExpbmVFeGNlZWRzTGltaXQiOmZhbHNlLCJtYXhMaW5lcyI6MjAwMCwibWF4Qnl0ZXMiOjUxMjAwfSwiZnVsbE91dHB1dFBhdGgiOiIvdmFyL2ZvbGRlcnMvZGMveDhiOTkxdGQ1NTVnXzhmYjV4X2c5ZDQwMDAwMGduL1QvcGktYmFzaC1hYmQ2Y2VkN2MwM2ZmMGY3LmxvZyJ9LCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM5MjMxNTc2fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMmM0MjEwZGMiLCJwYXJlbnRJZCI6ImI4NjAxNDRhIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowODoyOC4yMDFaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIHNlZSAtIGBUaGVtZWAgaXMgZGVmaW5lZCBpbiBgLi4vLi4vbW9kZXMvaW50ZXJhY3RpdmUvdGhlbWUvdGhlbWUudHNgIHdpdGhpbiBwaS1jb2RpbmctYWdlbnQuIEl0J3Mgbm90IGV4cG9ydGVkIGZyb20gdGhlIHB1YmxpYyBBUEkuIExldCBtZSBjaGVjayBpZiBpdCdzIHJlLWV4cG9ydGVkIGZyb20gdGhlIG1haW4gaW5kZXg6XG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IkJVY05YUGtBNFhETkVENUhGT3R4WnRPbk1PN0VFbXN5IiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlICYmIGdyZXAgXCJUaGVtZVwiIG5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2Rpc3QvaW5kZXguZC50cyAyPi9kZXYvbnVsbCB8IGhlYWQgLTEwIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoxODI1OCwib3V0cHV0IjoxMjIsImNhY2hlUmVhZCI6NzQyNTgsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo5MjYzOCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM5MjMxNTc3LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtR2pzc05GYXJQT1NSOERyaURtTG9HYTd1enhFUEtFdkIifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMGVlNjE5NjAiLCJwYXJlbnRJZCI6IjJjNDIxMGRjIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowODoyOC4yMTZaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJCVWNOWFBrQTRYRE5FRDVIRk90eFp0T25NTzdFRW1zeSIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6ImV4cG9ydCB7IEFybWluQ29tcG9uZW50LCBBc3Npc3RhbnRNZXNzYWdlQ29tcG9uZW50LCBCYXNoRXhlY3V0aW9uQ29tcG9uZW50LCBCb3JkZXJlZExvYWRlciwgQnJhbmNoU3VtbWFyeU1lc3NhZ2VDb21wb25lbnQsIENvbXBhY3Rpb25TdW1tYXJ5TWVzc2FnZUNvbXBvbmVudCwgQ3VzdG9tRWRpdG9yLCBDdXN0b21NZXNzYWdlQ29tcG9uZW50LCBEeW5hbWljQm9yZGVyLCBFeHRlbnNpb25FZGl0b3JDb21wb25lbnQsIEV4dGVuc2lvbklucHV0Q29tcG9uZW50LCBFeHRlbnNpb25TZWxlY3RvckNvbXBvbmVudCwgRm9vdGVyQ29tcG9uZW50LCBrZXlIaW50LCBrZXlUZXh0LCBMb2dpbkRpYWxvZ0NvbXBvbmVudCwgTW9kZWxTZWxlY3RvckNvbXBvbmVudCwgT0F1dGhTZWxlY3RvckNvbXBvbmVudCwgdHlwZSBSZW5kZXJEaWZmT3B0aW9ucywgcmF3S2V5SGludCwgcmVuZGVyRGlmZiwgU2Vzc2lvblNlbGVjdG9yQ29tcG9uZW50LCB0eXBlIFNldHRpbmdzQ2FsbGJhY2tzLCB0eXBlIFNldHRpbmdzQ29uZmlnLCBTZXR0aW5nc1NlbGVjdG9yQ29tcG9uZW50LCBTaG93SW1hZ2VzU2VsZWN0b3JDb21wb25lbnQsIFNraWxsSW52b2NhdGlvbk1lc3NhZ2VDb21wb25lbnQsIFRoZW1lU2VsZWN0b3JDb21wb25lbnQsIFRoaW5raW5nU2VsZWN0b3JDb21wb25lbnQsIFRvb2xFeGVjdXRpb25Db21wb25lbnQsIHR5cGUgVG9vbEV4ZWN1dGlvbk9wdGlvbnMsIFRyZWVTZWxlY3RvckNvbXBvbmVudCwgdHJ1bmNhdGVUb1Zpc3VhbExpbmVzLCBVc2VyTWVzc2FnZUNvbXBvbmVudCwgVXNlck1lc3NhZ2VTZWxlY3RvckNvbXBvbmVudCwgdHlwZSBWaXN1YWxUcnVuY2F0ZVJlc3VsdCwgfSBmcm9tIFwiLi9tb2Rlcy9pbnRlcmFjdGl2ZS9jb21wb25lbnRzL2luZGV4LnRzXCI7XG5leHBvcnQgeyBnZXRMYW5ndWFnZUZyb21QYXRoLCBnZXRNYXJrZG93blRoZW1lLCBnZXRTZWxlY3RMaXN0VGhlbWUsIGdldFNldHRpbmdzTGlzdFRoZW1lLCBoaWdobGlnaHRDb2RlLCBpbml0VGhlbWUsIFRoZW1lLCB0eXBlIFRoZW1lQ29sb3IsIH0gZnJvbSBcIi4vbW9kZXMvaW50ZXJhY3RpdmUvdGhlbWUvdGhlbWUudHNcIjtcbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzOTMwODIxNn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjhkMGIyOWNmIiwicGFyZW50SWQiOiIwZWU2MTk2MCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDg6MzcuNTY4WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiYFRoZW1lYCBpcyBleHBvcnRlZCBmcm9tIGBAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50YCwgbm90IGZyb20gYEBlYXJlbmRpbC13b3Jrcy9waS10dWlgLiBMZXQgbWUgZml4IHRoZSBpbXBvcnQgaW4gdWkudHMgdG8gaW1wb3J0IGZyb20gcGktY29kaW5nLWFnZW50IGluc3RlYWQuIEFuZCBJIG5lZWQgdG8gZGVjbGFyZSBgcGlgIGFzIGEgZ2xvYmFsIGluIGluZGV4LnRzLlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiYFRoZW1lYCBpcyBleHBvcnRlZCBmcm9tIGBAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50YCwgbm90IHBpLXR1aS4gTGV0IG1lIGZpeCB0aGUgaW1wb3J0cyBhbmQgYWRkIHRoZSBgcGlgIGdsb2JhbCBkZWNsYXJhdGlvbjpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IkpoM09GYmdaZ1RCVTVSdm56U2xYN084MGV2NERlajZDIiwibmFtZSI6ImVkaXQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50cyIsImVkaXRzIjpbeyJvbGRUZXh0IjoiaW1wb3J0IHtcbiAgbWF0Y2hlc0tleSxcbiAgS2V5LFxuICB0eXBlIFRVSSxcbiAgdHlwZSBUaGVtZSxcbiAgdHlwZSBLZXliaW5kaW5nc01hbmFnZXIsXG59IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7IiwibmV3VGV4dCI6ImltcG9ydCB7XG4gIG1hdGNoZXNLZXksXG4gIEtleSxcbiAgdHlwZSBUVUksXG4gIHR5cGUgVGhlbWUsXG4gIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiOyJ9XX19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoyMjEsIm91dHB1dCI6MjU5LCJjYWNoZVJlYWQiOjkyNjM3LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6OTMxMTcsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzOTMwODIxNiwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLVU5YW8yS1Z2YkpUbFg0V2cxVkhIUnp5SFcyeGRLRHEzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjFjNmJhOWYwIiwicGFyZW50SWQiOiI4ZDBiMjljZiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDg6MzcuNTczWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiSmgzT0ZiZ1pnVEJVNVJ2bnpTbFg3TzgwZXY0RGVqNkMiLCJ0b29sTmFtZSI6ImVkaXQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgcmVwbGFjZWQgMSBibG9jayhzKSBpbiAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHMuIn1dLCJkZXRhaWxzIjp7ImRpZmYiOiIgICAgIC4uLlxuICAxMiAgIEtleSxcbiAgMTMgICB0eXBlIFRVSSxcbiAgMTQgICB0eXBlIFRoZW1lLFxuICAxNSAgIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxuLSAxNiB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG4rIDE2IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbiAgMTcgaW1wb3J0IHR5cGUgeyBSZWZhY3RvckZvY3VzLCBSZWZhY3RvckRlY2lzaW9uIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbiAgMTggXG4gIDE5IGNvbnN0IFJFRkFDVE9SX0ZPQ0k6IFJlZmFjdG9yRm9jdXNbXSA9IFtcbiAgMjAgICBcInRlc3RzXCIsXG4gICAgIC4uLiIsInBhdGNoIjoiLS0tIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50c1xuKysrIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50c1xuQEAgLTEyLDkgKzEyLDkgQEBcbiAgIEtleSxcbiAgIHR5cGUgVFVJLFxuICAgdHlwZSBUaGVtZSxcbiAgIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxuLX0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcbit9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG4gaW1wb3J0IHR5cGUgeyBSZWZhY3RvckZvY3VzLCBSZWZhY3RvckRlY2lzaW9uIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbiBcbiBjb25zdCBSRUZBQ1RPUl9GT0NJOiBSZWZhY3RvckZvY3VzW10gPSBbXG4gICBcInRlc3RzXCIsXG4iLCJmaXJzdENoYW5nZWRMaW5lIjoxNn0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkzMTc1NzN9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIzZDczNDBiYiIsInBhcmVudElkIjoiMWM2YmE5ZjAiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA4OjUyLjAxNloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBJIG5lZWQgdG8gYWRkIGEgZ2xvYmFsIGRlY2xhcmF0aW9uIGZvciBgcGlgIGluIGluZGV4LnRzLiBMZXQgbWUgYWRkIGEgZGVjbGFyZSBnbG9iYWwgYmxvY2sgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZS5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vdyBhZGQgdGhlIGBwaWAgZ2xvYmFsIGRlY2xhcmF0aW9uIHRvIGluZGV4LnRzOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiUkR3NDlLNlRxOWFCUnVlWWdteTBBeEc0QWM5NktadDEiLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwiZWRpdHMiOlt7Im9sZFRleHQiOiIvKipcbiAqIFRERCBDeWNsZSBFeHRlbnNpb25cbiAqXG4gKiBFbmZvcmNlcyB0aGUgcmVkLWdyZWVuLXJlZmFjdG9yIFRERCBjeWNsZTpcbiAqICAg8J+UtCBSRUQgICAg4oaSIFdyaXRlIGEgZmFpbGluZyB0ZXN0LCB0aGVuIGltcGxlbWVudCB0byBtYWtlIGl0IHBhc3NcbiAqICAg8J+foiBHUkVFTiAg4oaSIFRlc3RzIHBhc3MsIHJlYWR5IGZvciByZWZhY3RvcmluZ1xuICogICDwn5SAIFJFRkFDVE9SIOKGkiBEZXZlbG9wZXIgY2hvb3NlcyB3aGF0IHRvIHJlZmFjdG9yXG4gKlxuICogQWZ0ZXIgcmVmYWN0b3JpbmcsIHRoZSBjeWNsZSByZXBlYXRzOiBiYWNrIHRvIFJFRCBmb3IgdGhlIG5leHQgdGVzdC5cbiAqXG4gKiBUb29sczpcbiAqICAgZ28tdG8tZ3JlZW4gICAgIC0gUnVuIHRlc3RzIGFuZCB0cmFuc2l0aW9uIGJhc2VkIG9uIHJlc3VsdFxuICogICBnby10by1yZWZhY3RvciAgLSBFbnRlciB0aGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHBoYXNlXG4gKiAgIHJ1bi10ZXN0cyAgICAgICAtIFJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb25cbiAqICAgdGRkLXN0YXR1cyAgICAgIC0gU2hvdyBjdXJyZW50IHBoYXNlIGFuZCBzdGF0ZVxuICovXG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjsiLCJuZXdUZXh0IjoiLyoqXG4gKiBUREQgQ3ljbGUgRXh0ZW5zaW9uXG4gKlxuICogRW5mb3JjZXMgdGhlIHJlZC1ncmVlbi1yZWZhY3RvciBUREQgY3ljbGU6XG4gKiAgIPCflLQgUkVEICAgIOKGkiBXcml0ZSBhIGZhaWxpbmcgdGVzdCwgdGhlbiBpbXBsZW1lbnQgdG8gbWFrZSBpdCBwYXNzXG4gKiAgIPCfn6IgR1JFRU4gIOKGkiBUZXN0cyBwYXNzLCByZWFkeSBmb3IgcmVmYWN0b3JpbmdcbiAqICAg8J+UgCBSRUZBQ1RPUiDihpIgRGV2ZWxvcGVyIGNob29zZXMgd2hhdCB0byByZWZhY3RvclxuICpcbiAqIEFmdGVyIHJlZmFjdG9yaW5nLCB0aGUgY3ljbGUgcmVwZWF0czogYmFjayB0byBSRUQgZm9yIHRoZSBuZXh0IHRlc3QuXG4gKlxuICogVG9vbHM6XG4gKiAgIGdvLXRvLWdyZWVuICAgICAtIFJ1biB0ZXN0cyBhbmQgdHJhbnNpdGlvbiBiYXNlZCBvbiByZXN1bHRcbiAqICAgZ28tdG8tcmVmYWN0b3IgIC0gRW50ZXIgdGhlIGRldmVsb3BlciBkZWNpc2lvbiBwaGFzZVxuICogICBydW4tdGVzdHMgICAgICAgLSBSdW4gdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uXG4gKiAgIHRkZC1zdGF0dXMgICAgICAtIFNob3cgY3VycmVudCBwaGFzZSBhbmQgc3RhdGVcbiAqL1xuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGNvbnN0IHBpOiBpbXBvcnQoXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCIpLkV4dGVuc2lvbkFQSTtcbiAgY29uc3QgdGhlbWU6IGltcG9ydChcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIikuVGhlbWU7XG59XG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjsifV19fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6NDMsIm91dHB1dCI6NTIzLCJjYWNoZVJlYWQiOjkzMTE2LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6OTM2ODIsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTkzOTMxNzU3MywicmVzcG9uc2VJZCI6ImNoYXRjbXBsLXhpelVyYVlkU1BrRWZ5ZzZ1dW5OaVg5Q2s3UVBiZWVtIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjRiMzA5YzFiIiwicGFyZW50SWQiOiIzZDczNDBiYiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDg6NTIuMDIwWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiUkR3NDlLNlRxOWFCUnVlWWdteTBBeEc0QWM5NktadDEiLCJ0b29sTmFtZSI6ImVkaXQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdWNjZXNzZnVsbHkgcmVwbGFjZWQgMSBibG9jayhzKSBpbiAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMuIn1dLCJkZXRhaWxzIjp7ImRpZmYiOiIgICAgIC4uLlxuICAxNCAgKiAgIHJ1bi10ZXN0cyAgICAgICAtIFJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb25cbiAgMTUgICogICB0ZGQtc3RhdHVzICAgICAgLSBTaG93IGN1cnJlbnQgcGhhc2UgYW5kIHN0YXRlXG4gIDE2ICAqL1xuICAxNyBcbisgMTggZGVjbGFyZSBnbG9iYWwge1xuKyAxOSAgIGNvbnN0IHBpOiBpbXBvcnQoXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCIpLkV4dGVuc2lvbkFQSTtcbisgMjAgICBjb25zdCB0aGVtZTogaW1wb3J0KFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiKS5UaGVtZTtcbisgMjEgfVxuKyAyMiBcbiAgMTggaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEksIEV4dGVuc2lvbkNvbnRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuICAxOSBpbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcbiAgMjAgaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG4gIDIxIFxuICAgICAuLi4iLCJwYXRjaCI6Ii0tLSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHNcbisrKyAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHNcbkBAIC0xNCw4ICsxNCwxMyBAQFxuICAqICAgcnVuLXRlc3RzICAgICAgIC0gUnVuIHRlc3RzIHdpdGhvdXQgcGhhc2UgdHJhbnNpdGlvblxuICAqICAgdGRkLXN0YXR1cyAgICAgIC0gU2hvdyBjdXJyZW50IHBoYXNlIGFuZCBzdGF0ZVxuICAqL1xuIFxuK2RlY2xhcmUgZ2xvYmFsIHtcbisgIGNvbnN0IHBpOiBpbXBvcnQoXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCIpLkV4dGVuc2lvbkFQSTtcbisgIGNvbnN0IHRoZW1lOiBpbXBvcnQoXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCIpLlRoZW1lO1xuK31cbitcbiBpbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSwgRXh0ZW5zaW9uQ29udGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG4gaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG4gaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG4gXG4iLCJmaXJzdENoYW5nZWRMaW5lIjoxOH0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkzMzIwMjB9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJlMGI4MGVlMCIsInBhcmVudElkIjoiNGIzMDljMWIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA4OjU3LjU0MVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBsZXQgbWUgcnVuIHRoZSB0ZXN0cyBhbmQgdHlwZWNoZWNrIGFnYWluOlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJTd1RrWDVlRmxoYktxaUU2YkFxRTB1VkhFaW5tUEoyUiIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBucG0gcnVuIHRlc3QgMj4mMSAmJiBucG0gcnVuIHR5cGVjaGVjayAyPiYxIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0Ijo2MDYsIm91dHB1dCI6NzIsImNhY2hlUmVhZCI6OTMxMTgsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo5Mzc5NiwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM5MzMyMDIxLCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtZlpWQjVMYWZKVVJsWmE1SXhMSmE5WThKVzFaTTBKV28ifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOGNlYzhhNjUiLCJwYXJlbnRJZCI6ImUwYjgwZWUwIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowODo1OS43NjhaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJTd1RrWDVlRmxoYktxaUU2YkFxRTB1VkhFaW5tUEoyUiIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlxuPiBwaS10ZGQtY3ljbGVAMC4xLjAgdGVzdFxuPiB2aXRlc3QgcnVuXG5cblxuIFJVTiAgdjQuMS45IC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlXG5cblxuIFRlc3QgRmlsZXMgIDEgcGFzc2VkICgxKVxuICAgICAgVGVzdHMgIDI5IHBhc3NlZCAoMjkpXG4gICBTdGFydCBhdCAgMDg6MDg6NThcbiAgIER1cmF0aW9uICAxMTBtcyAodHJhbnNmb3JtIDI0bXMsIHNldHVwIDBtcywgaW1wb3J0IDMybXMsIHRlc3RzIDVtcywgZW52aXJvbm1lbnQgMG1zKVxuXG5cbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHR5cGVjaGVja1xuPiB0c2MgLS1ub0VtaXRcblxuc3JjL3N0YXRlLnRzKDIxNiw5KTogZXJyb3IgVFMyMzIyOiBUeXBlICdib29sZWFuIHwgdW5kZWZpbmVkJyBpcyBub3QgYXNzaWduYWJsZSB0byB0eXBlICdib29sZWFuJy5cbiAgVHlwZSAndW5kZWZpbmVkJyBpcyBub3QgYXNzaWduYWJsZSB0byB0eXBlICdib29sZWFuJy5cbnNyYy91aS50cygxMSwzKTogZXJyb3IgVFMyMzA1OiBNb2R1bGUgJ1wiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiJyBoYXMgbm8gZXhwb3J0ZWQgbWVtYmVyICdtYXRjaGVzS2V5Jy5cbnNyYy91aS50cygxMiwzKTogZXJyb3IgVFMyMzA1OiBNb2R1bGUgJ1wiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiJyBoYXMgbm8gZXhwb3J0ZWQgbWVtYmVyICdLZXknLlxuc3JjL3VpLnRzKDEzLDgpOiBlcnJvciBUUzIzMDU6IE1vZHVsZSAnXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCInIGhhcyBubyBleHBvcnRlZCBtZW1iZXIgJ1RVSScuXG5cblxuQ29tbWFuZCBleGl0ZWQgd2l0aCBjb2RlIDIifV0sImRldGFpbHMiOnt9LCJpc0Vycm9yIjp0cnVlLCJ0aW1lc3RhbXAiOjE3ODE5MzkzMzk3Njh9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI0ZGNjZDM2NiIsInBhcmVudElkIjoiOGNlYzhhNjUiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA5OjEwLjEwMFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRlc3RzIHBhc3Mgbm93LiBCdXQgdGhlcmUgYXJlIHJlbWFpbmluZyB0eXBlIGVycm9yczpcblxuMS4gYHN0YXRlLnRzOjIxNmAgLSBgdGVzdHNSYW5gIGNhbiBiZSBgdW5kZWZpbmVkYCBidXQgd2UncmUgYXNzaWduaW5nIGl0IHRvIGEgYGJvb2xlYW5gIGZpZWxkLiBUaGUgaXNzdWUgaXMgaW4gdGhlIGByZWNvcmRUZXN0UmVzdWx0YCBmdW5jdGlvbiB3aGVyZSB3ZSByZXR1cm4gYHRlc3RzUmFuOiB0cnVlYCBidXQgdGhlIHN0YXRlIGludGVyZmFjZSBoYXMgYHRlc3RzUmFuPzogYm9vbGVhbmAuXG5cbjIuIGB1aS50c2AgLSBgbWF0Y2hlc0tleWAsIGBLZXlgLCBhbmQgYFRVSWAgYXJlIG5vdCBleHBvcnRlZCBmcm9tIHBpLWNvZGluZy1hZ2VudC4gVGhleSBtdXN0IGNvbWUgZnJvbSBwaS10dWkuIExldCBtZSBjaGVjayB3aGF0IHBpLWNvZGluZy1hZ2VudCByZS1leHBvcnRzIGZyb20gcGktdHVpOlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiVGVzdHMgcGFzcy4gVHdvIHJlbWFpbmluZyB0eXBlIGlzc3VlczpcblxuMS4gYHN0YXRlLnRzYCAtIHRoZSBzcHJlYWQgaW4gYHJlZFRvR3JlZW5gIGRvZXNuJ3QgcHJlc2VydmUgdGhlIG92ZXJyaWRlIHZhbHVlc1xuMi4gYHVpLnRzYCAtIGBtYXRjaGVzS2V5YCwgYEtleWAsIGBUVUlgIGNvbWUgZnJvbSBwaS10dWksIG5vdCBwaS1jb2RpbmctYWdlbnRcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IkhtWWp2eE1MeXU3SW95bTB1bVd1ZW51YTJVbmJDV1ZzIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50cyIsIm9mZnNldCI6MjAwLCJsaW1pdCI6MzB9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MzE4LCJvdXRwdXQiOjI2MiwiY2FjaGVSZWFkIjo5Mzc5NSwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjk0Mzc1LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5MzkzMzk3NjksInJlc3BvbnNlSWQiOiJjaGF0Y21wbC05NHg4cU9uVHFac25RZ1dKbGZudVlScThzSGZZRmJEOSJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJjMmRlOGYyNyIsInBhcmVudElkIjoiNGRjY2QzNjYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA5OjEwLjEwNVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IkhtWWp2eE1MeXU3SW95bTB1bVd1ZW51YTJVbmJDV1ZzIiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoifVxuXG4vKipcbiAqIENoZWNrIGlmIGEgdHJhbnNpdGlvbiBpcyB2YWxpZCBiZWZvcmUgZXhlY3V0aW5nIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FuVHJhbnNpdGlvbihcbiAgc3RhdGU6IEN5Y2xlU3RhdGUsXG4gIHRhcmdldFBoYXNlOiBQaGFzZSxcbik6IHsgdmFsaWQ6IGJvb2xlYW47IHJlYXNvbjogc3RyaW5nIH0ge1xuICBpZiAoc3RhdGUucGhhc2UgPT09IHRhcmdldFBoYXNlKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUsIHJlYXNvbjogYEFscmVhZHkgaW4gJHt0YXJnZXRQaGFzZX1gIH07XG4gIH1cblxuICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IHN0YXRlLnRlc3RzUmFuICYmIHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgICAgICByZWFzb246IHN0YXRlLnRlc3RzUmFuICYmIHN0YXRlLnRlc3RzUGFzc2VkXG4gICAgICAgICAgPyBcIlRlc3RzIHBhc3NlZCwgY2FuIGdvIHRvIEdSRUVOXCJcbiAgICAgICAgICA6IFwiTXVzdCBydW4gcGFzc2luZyB0ZXN0cyBmaXJzdFwiLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHRhcmdldFBoYXNlID09PSBcIlJFRkFDVE9SXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgcmVhc29uOlxuICAgICAgICAgIFwiQ2Fubm90IGdvIGRpcmVjdGx5IGZyb20gUkVEIHRvIFJFRkFDVE9SLiBNdXN0IGdvIHRocm91Z2ggR1JFRU4gZmlyc3QuXCIsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG5bOTQgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTIzMCB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM5MzUwMTA1fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOGZlMjkzY2YiLCJwYXJlbnRJZCI6ImMyZGU4ZjI3IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowOToxNC42OTNaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJMZXQgbWUgbG9vayBhdCB0aGUgcmVjb3JkVGVzdFJlc3VsdCBmdW5jdGlvbiBtb3JlIGNhcmVmdWxseTpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiZzRHNXhOcmlsWm05Szhuc1N6d3pkckVIcDB5MUlzQUQiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3N0YXRlLnRzIiwib2Zmc2V0IjoxNDAsImxpbWl0Ijo0MH19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoyNDksIm91dHB1dCI6ODMsImNhY2hlUmVhZCI6OTQzNzQsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo5NDcwNiwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM5MzUwMTA2LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtNklPYmFsbzc4bDF1QjRNSjl5WVBCUU1sQ1dpcXZjU1QifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOWYwODA1NzMiLCJwYXJlbnRJZCI6IjhmZTI5M2NmIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowOToxNC42OTlaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJnNEc1eE5yaWxabTlLOG5zU3p3emRyRUhwMHkxSXNBRCIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiAgbGV0IG1lc3NhZ2UgPSBg8J+UgCBSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICBtZXNzYWdlICs9IGAgQ3VzdG9tIGluc3RydWN0aW9uOiBcIiR7ZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb259XCJgO1xuICB9XG4gIG1lc3NhZ2UgKz0gXCIgUGhhc2UgY2hhbmdlZDogUkVGQUNUT1Ig4oaSIFJFRC5cIjtcblxuICByZXR1cm4ge1xuICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICBtZXNzYWdlLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIFJlY29yZCB0aGF0IHRlc3RzIGhhdmUgYmVlbiBydW4gYW5kIHRoZWlyIHJlc3VsdC5cbiAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBnby10by1ncmVlbiB0b29sIGFmdGVyIHRlc3QgZXhlY3V0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkVGVzdFJlc3VsdChcbiAgc3RhdGU6IEN5Y2xlU3RhdGUsXG4gIHBhc3NlZDogYm9vbGVhbixcbik6IFRyYW5zaXRpb25SZXN1bHQge1xuICBpZiAoc3RhdGUucGhhc2UgIT09IFwiUkVEXCIgJiYgc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0ZSxcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiBgQ2Fubm90IHJlY29yZCB0ZXN0IHJlc3VsdHMgaW4gcGhhc2UgJHtzdGF0ZS5waGFzZX0uIE11c3QgYmUgaW4gUkVEIG9yIEdSRUVOLmAsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IG5ld1N0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgIHRlc3RzUGFzc2VkOiBwYXNzZWQsXG4gIH07XG5cbiAgaWYgKHBhc3NlZCAmJiBzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuICAgIC8vIFRlc3RzIHBhc3NlZCB3aGlsZSBpbiBSRUQg4oaSIGF1dG8tdHJhbnNpdGlvbiB0byBHUkVFTlxuICAgIC8vIEtlZXAgdGVzdHNSYW4vdGVzdHNQYXNzZWQgZnJvbSBuZXdTdGF0ZSAodGhleSByZWZsZWN0IHRoZSBqdXN0LXJ1biB0ZXN0cylcbiAgICBjb25zdCBncmVlblJlc3VsdCA9IHJlZFRvR3JlZW4obmV3U3RhdGUpO1xuICAgIHJldHVybiB7XG5cblsxNDQgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTE4MCB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM5MzU0Njk5fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDU5NDBiYzIiLCJwYXJlbnRJZCI6IjlmMDgwNTczIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowOToyNS45NzhaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIHNlZSB0aGUgaXNzdWUuIEluIGByZWRUb0dyZWVuYCwgdGhlIGZ1bmN0aW9uIGRvZXMgYC4uLnN0YXRlYCB3aGljaCBzcHJlYWRzIHRoZSBvcmlnaW5hbCBzdGF0ZSdzIGB0ZXN0c1JhbmAgYW5kIGB0ZXN0c1Bhc3NlZGAgKHdoaWNoIGNvdWxkIGJlIHVuZGVmaW5lZCksIGFuZCB0aGVuIHNldHMgdGhlbSB0byBgZmFsc2VgLiBCdXQgdGhlIHJldHVybiB0eXBlIGV4cGVjdHMgYGJvb2xlYW5gLCBub3QgYGJvb2xlYW4gfCB1bmRlZmluZWRgLiBcblxuVGhlIGlzc3VlIGlzIHRoYXQgYHJlZFRvR3JlZW5gIGRvZXM6XG5gYGB0c1xuc3RhdGU6IHsgLi4uc3RhdGUsIHBoYXNlOiBcIkdSRUVOXCIsIHRlc3RzUmFuOiBmYWxzZSwgdGVzdHNQYXNzZWQ6IGZhbHNlIH1cbmBgYFxuXG5CdXQgYHN0YXRlLnRlc3RzUmFuYCBhbmQgYHN0YXRlLnRlc3RzUGFzc2VkYCBhcmUgb3B0aW9uYWwgKGBib29sZWFuIHwgdW5kZWZpbmVkYCksIGFuZCB3aGVuIHdlIHNwcmVhZCBgLi4uc3RhdGVgLCB0aG9zZSBvcHRpb25hbCBmaWVsZHMgY29tZSB0aHJvdWdoLiBUaGVuIHdlIG92ZXJyaWRlIHRoZW0gd2l0aCBgZmFsc2VgLCB3aGljaCBzaG91bGQgYmUgZmluZS5cblxuV2FpdCwgbGV0IG1lIGxvb2sgYXQgbGluZSAyMTYgc3BlY2lmaWNhbGx5OlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJ5WlFlenNsR1d0VWd6WWphaWwwRGdob25ha0JVUnNKWCIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHMiLCJvZmZzZXQiOjE4MCwibGltaXQiOjQwfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjY2MSwib3V0cHV0IjoyMzYsImNhY2hlUmVhZCI6OTQzNzYsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo5NTI3MywiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTM5MzU0NzAxLCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtcko5NmRMd1ZDRmdNNzBleXlSRnAwMUNaNTRZa1FYWVUifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNmYyNjgzNjYiLCJwYXJlbnRJZCI6ImQ1OTQwYmMyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowOToyNS45ODZaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJ5WlFlenNsR1d0VWd6WWphaWwwRGdob25ha0JVUnNKWCIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiAgICAgIC4uLmdyZWVuUmVzdWx0LFxuICAgICAgc3RhdGU6IHsgLi4uZ3JlZW5SZXN1bHQuc3RhdGUsIHRlc3RzUmFuOiB0cnVlLCB0ZXN0c1Bhc3NlZDogdHJ1ZSB9LFxuICAgIH07XG4gIH1cblxuICBpZiAoIXBhc3NlZCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0ZTogbmV3U3RhdGUsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBcIuKdjCBUZXN0cyBmYWlsZWQuIFN0YXkgaW4gUkVELiBGaXggdGhlIGltcGxlbWVudGF0aW9uIHRvIG1ha2UgdGVzdHMgcGFzcy5cIixcbiAgICAgIHZhbGlkOiB0cnVlLFxuICAgIH07XG4gIH1cblxuICAvLyBUZXN0cyBwYXNzZWQgd2hpbGUgYWxyZWFkeSBpbiBHUkVFTiDihpIgc3RheSBpbiBHUkVFTlxuICByZXR1cm4ge1xuICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICBtZXNzYWdlOiBcIuKchSBUZXN0cyBzdGlsbCBwYXNzLiBTdGF5IGluIEdSRUVOLlwiLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgdHJhbnNpdGlvbiBpcyB2YWxpZCBiZWZvcmUgZXhlY3V0aW5nIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FuVHJhbnNpdGlvbihcbiAgc3RhdGU6IEN5Y2xlU3RhdGUsXG4gIHRhcmdldFBoYXNlOiBQaGFzZSxcbik6IHsgdmFsaWQ6IGJvb2xlYW47IHJlYXNvbjogc3RyaW5nIH0ge1xuICBpZiAoc3RhdGUucGhhc2UgPT09IHRhcmdldFBoYXNlKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUsIHJlYXNvbjogYEFscmVhZHkgaW4gJHt0YXJnZXRQaGFzZX1gIH07XG4gIH1cblxuICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IHN0YXRlLnRlc3RzUmFuICYmIHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgICAgICByZWFzb246IHN0YXRlLnRlc3RzUmFuICYmIHN0YXRlLnRlc3RzUGFzc2VkXG4gICAgICAgICAgPyBcIlRlc3RzIHBhc3NlZCwgY2FuIGdvIHRvIEdSRUVOXCJcbiAgICAgICAgICA6IFwiTXVzdCBydW4gcGFzc2luZyB0ZXN0cyBmaXJzdFwiLFxuXG5bMTA0IG1vcmUgbGluZXMgaW4gZmlsZS4gVXNlIG9mZnNldD0yMjAgdG8gY29udGludWUuXSJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTkzOTM2NTk4Nn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjgwNmFjZTllIiwicGFyZW50SWQiOiI2ZjI2ODM2NiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDc6MDk6NDYuMTA0WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTGluZSAyMTYgaXMgdGhlIGBjYW5UcmFuc2l0aW9uYCBmdW5jdGlvbi4gVGhlIGlzc3VlIGlzIGBzdGF0ZS50ZXN0c1JhbiAmJiBzdGF0ZS50ZXN0c1Bhc3NlZGAg4oCUIHNpbmNlIGB0ZXN0c1JhbmAgYW5kIGB0ZXN0c1Bhc3NlZGAgYXJlIG9wdGlvbmFsIChgYm9vbGVhbiB8IHVuZGVmaW5lZGApLCB0aGUgYCYmYCBleHByZXNzaW9uIHJldHVybnMgYGJvb2xlYW4gfCB1bmRlZmluZWRgLCBidXQgdGhlIHJldHVybiB0eXBlIGV4cGVjdHMgYHZhbGlkOiBib29sZWFuYC5cblxuVGhlIGZpeCBpcyB0byB1c2UgYCEhYCBvciBgQm9vbGVhbigpYCB0byBjb2VyY2UgdG8gYm9vbGVhbi5cblxuTGV0IG1lIGFsc28gZml4IHRoZSB1aS50cyBpbXBvcnRzIC0gYG1hdGNoZXNLZXlgLCBgS2V5YCwgYW5kIGBUVUlgIGNvbWUgZnJvbSBwaS10dWkuXG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IkxjWDVBT2t2OVNkWjZ3OW9Xem1ZNzZlMmxVOTNTRHp5IiwibmFtZSI6ImVkaXQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50cyIsImVkaXRzIjpbeyJvbGRUZXh0IjoiICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogc3RhdGUudGVzdHNSYW4gJiYgc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgICAgIHJlYXNvbjogc3RhdGUudGVzdHNSYW4gJiYgc3RhdGUudGVzdHNQYXNzZWRcbiAgICAgICAgICA/IFwiVGVzdHMgcGFzc2VkLCBjYW4gZ28gdG8gR1JFRU5cIlxuICAgICAgICAgIDogXCJNdXN0IHJ1biBwYXNzaW5nIHRlc3RzIGZpcnN0XCIsXG4gICAgICB9O1xuICAgIH0iLCJuZXdUZXh0IjoiICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICBjb25zdCBjYW4gPSAhIXN0YXRlLnRlc3RzUmFuICYmICEhc3RhdGUudGVzdHNQYXNzZWQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogY2FuLFxuICAgICAgICByZWFzb246IGNhblxuICAgICAgICAgID8gXCJUZXN0cyBwYXNzZWQsIGNhbiBnbyB0byBHUkVFTlwiXG4gICAgICAgICAgOiBcIk11c3QgcnVuIHBhc3NpbmcgdGVzdHMgZmlyc3RcIixcbiAgICAgIH07XG4gICAgfSJ9XX19LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJrRmdZVmxJRlZoRUVHQndTWFBKZDM1MTJVRW1tRFp5SCIsIm5hbWUiOiJlZGl0IiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHMiLCJlZGl0cyI6W3sib2xkVGV4dCI6ImltcG9ydCB7XG4gIG1hdGNoZXNLZXksXG4gIEtleSxcbiAgdHlwZSBUVUksXG4gIHR5cGUgVGhlbWUsXG4gIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiOyIsIm5ld1RleHQiOiJpbXBvcnQge1xuICBtYXRjaGVzS2V5LFxuICBLZXksXG4gIHR5cGUgVFVJLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHR5cGUgeyBUaGVtZSwgS2V5YmluZGluZ3NNYW5hZ2VyIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjsifV19fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6NTU4LCJvdXRwdXQiOjQ4OCwiY2FjaGVSZWFkIjo5NTAzMywiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjk2MDc5LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5MzkzNjU5ODgsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC04Ylg3RHM2TWdKbWJoM0E3d295dlo1b1laRHpIRVdsaCJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIxOGQxNTk3OCIsInBhcmVudElkIjoiODA2YWNlOWUiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA5OjQ2LjEwOVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IkxjWDVBT2t2OVNkWjZ3OW9Xem1ZNzZlMmxVOTNTRHp5IiwidG9vbE5hbWUiOiJlZGl0IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDEgYmxvY2socykgaW4gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3N0YXRlLnRzLiJ9XSwiZGV0YWlscyI6eyJkaWZmIjoiICAgICAuLi5cbiAyMTEgICB9XG4gMjEyIFxuIDIxMyAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuIDIxNCAgICAgaWYgKHRhcmdldFBoYXNlID09PSBcIkdSRUVOXCIpIHtcbisyMTUgICAgICAgY29uc3QgY2FuID0gISFzdGF0ZS50ZXN0c1JhbiAmJiAhIXN0YXRlLnRlc3RzUGFzc2VkO1xuIDIxNSAgICAgICByZXR1cm4ge1xuLTIxNiAgICAgICAgIHZhbGlkOiBzdGF0ZS50ZXN0c1JhbiAmJiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbi0yMTcgICAgICAgICByZWFzb246IHN0YXRlLnRlc3RzUmFuICYmIHN0YXRlLnRlc3RzUGFzc2VkXG4rMjE3ICAgICAgICAgdmFsaWQ6IGNhbixcbisyMTggICAgICAgICByZWFzb246IGNhblxuIDIxOCAgICAgICAgICAgPyBcIlRlc3RzIHBhc3NlZCwgY2FuIGdvIHRvIEdSRUVOXCJcbiAyMTkgICAgICAgICAgIDogXCJNdXN0IHJ1biBwYXNzaW5nIHRlc3RzIGZpcnN0XCIsXG4gMjIwICAgICAgIH07XG4gMjIxICAgICB9XG4gICAgIC4uLiIsInBhdGNoIjoiLS0tIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50c1xuKysrIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50c1xuQEAgLTIxMSwxMSArMjExLDEyIEBAXG4gICB9XG4gXG4gICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICAgaWYgKHRhcmdldFBoYXNlID09PSBcIkdSRUVOXCIpIHtcbisgICAgICBjb25zdCBjYW4gPSAhIXN0YXRlLnRlc3RzUmFuICYmICEhc3RhdGUudGVzdHNQYXNzZWQ7XG4gICAgICAgcmV0dXJuIHtcbi0gICAgICAgIHZhbGlkOiBzdGF0ZS50ZXN0c1JhbiAmJiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbi0gICAgICAgIHJlYXNvbjogc3RhdGUudGVzdHNSYW4gJiYgc3RhdGUudGVzdHNQYXNzZWRcbisgICAgICAgIHZhbGlkOiBjYW4sXG4rICAgICAgICByZWFzb246IGNhblxuICAgICAgICAgICA/IFwiVGVzdHMgcGFzc2VkLCBjYW4gZ28gdG8gR1JFRU5cIlxuICAgICAgICAgICA6IFwiTXVzdCBydW4gcGFzc2luZyB0ZXN0cyBmaXJzdFwiLFxuICAgICAgIH07XG4gICAgIH1cbiIsImZpcnN0Q2hhbmdlZExpbmUiOjIxNX0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkzODYxMDl9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJmMjYyNjY2OCIsInBhcmVudElkIjoiMThkMTU5NzgiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA5OjQ2LjExMFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImtGZ1lWbElGVmhFRUdCd1NYUEpkMzUxMlVFbW1EWnlIIiwidG9vbE5hbWUiOiJlZGl0IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDEgYmxvY2socykgaW4gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3VpLnRzLiJ9XSwiZGV0YWlscyI6eyJkaWZmIjoiICAgICAuLi5cbiAgMTAgaW1wb3J0IHtcbiAgMTEgICBtYXRjaGVzS2V5LFxuICAxMiAgIEtleSxcbiAgMTMgICB0eXBlIFRVSSxcbi0gMTQgICB0eXBlIFRoZW1lLFxuLSAxNSAgIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxuLSAxNiB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG4rIDE0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcbisgMTUgaW1wb3J0IHR5cGUgeyBUaGVtZSwgS2V5YmluZGluZ3NNYW5hZ2VyIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbiAgMTcgaW1wb3J0IHR5cGUgeyBSZWZhY3RvckZvY3VzLCBSZWZhY3RvckRlY2lzaW9uIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbiAgMTggXG4gIDE5IGNvbnN0IFJFRkFDVE9SX0ZPQ0k6IFJlZmFjdG9yRm9jdXNbXSA9IFtcbiAgMjAgICBcInRlc3RzXCIsXG4gICAgIC4uLiIsInBhdGNoIjoiLS0tIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50c1xuKysrIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50c1xuQEAgLTEwLDExICsxMCwxMCBAQFxuIGltcG9ydCB7XG4gICBtYXRjaGVzS2V5LFxuICAgS2V5LFxuICAgdHlwZSBUVUksXG4tICB0eXBlIFRoZW1lLFxuLSAgdHlwZSBLZXliaW5kaW5nc01hbmFnZXIsXG4tfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuK30gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcbitpbXBvcnQgdHlwZSB7IFRoZW1lLCBLZXliaW5kaW5nc01hbmFnZXIgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuIGltcG9ydCB0eXBlIHsgUmVmYWN0b3JGb2N1cywgUmVmYWN0b3JEZWNpc2lvbiB9IGZyb20gXCIuL3N0YXRlLmpzXCI7XG4gXG4gY29uc3QgUkVGQUNUT1JfRk9DSTogUmVmYWN0b3JGb2N1c1tdID0gW1xuICAgXCJ0ZXN0c1wiLFxuIiwiZmlyc3RDaGFuZ2VkTGluZSI6MTR9LCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTM5Mzg2MTEwfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZGIyZTA4MjgiLCJwYXJlbnRJZCI6ImYyNjI2NjY4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwNzowOTo1MS42ODJaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJOb3cgbGV0IG1lIHJ1biBib3RoIHRlc3RzIGFuZCB0eXBlY2hlY2sgYWdhaW46XG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6InByRmhiRzlBdDNkS0NJSkJUODJOVkJreGdScnExdkdEIiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlICYmIG5wbSBydW4gdGVzdCAyPiYxICYmIG5wbSBydW4gdHlwZWNoZWNrIDI+JjEifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjU2Niwib3V0cHV0Ijo3MiwiY2FjaGVSZWFkIjo5NTU4NywiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjk2MjI1LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5MzkzODYxMTEsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC1oMm1vUm53cmhKUVdIbkVValJnaDJYcjFES3pvNkZyRiJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIyOGI0YmE0MiIsInBhcmVudElkIjoiZGIyZTA4MjgiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjA5OjUzLjg2NloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6InByRmhiRzlBdDNkS0NJSkJUODJOVkJreGdScnExdkdEIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiXG4+IHBpLXRkZC1jeWNsZUAwLjEuMCB0ZXN0XG4+IHZpdGVzdCBydW5cblxuXG4gUlVOICB2NC4xLjkgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGVcblxuXG4gVGVzdCBGaWxlcyAgMSBwYXNzZWQgKDEpXG4gICAgICBUZXN0cyAgMjkgcGFzc2VkICgyOSlcbiAgIFN0YXJ0IGF0ICAwODowOTo1MlxuICAgRHVyYXRpb24gIDEwN21zICh0cmFuc2Zvcm0gMjJtcywgc2V0dXAgMG1zLCBpbXBvcnQgMjltcywgdGVzdHMgNG1zLCBlbnZpcm9ubWVudCAwbXMpXG5cblxuPiBwaS10ZGQtY3ljbGVAMC4xLjAgdHlwZWNoZWNrXG4+IHRzYyAtLW5vRW1pdFxuXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5MzkzOTM4NjZ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJhNTlhMjJjMyIsInBhcmVudElkIjoiMjhiNGJhNDIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjEwOjExLjg5MloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkFsbCB0ZXN0cyBwYXNzIGFuZCB0eXBlY2hlY2sgaXMgY2xlYW4uIExldCBtZSBnaXZlIHRoZSB1c2VyIGEgc3VtbWFyeSBvZiB3aGF0J3MgYmVlbiBidWlsdC5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkFsbCBncmVlbiDigJQgMjkgdGVzdHMgcGFzc2luZywgdHlwZWNoZWNrIGNsZWFuLiBIZXJlJ3Mgd2hhdCB3ZSBoYXZlOlxuXG5gYGBcbnBpLXRkZC1jeWNsZS9cbuKUnOKUgOKUgCBwYWNrYWdlLmpzb24gICAgICAgICAgIyBwaS1wYWNrYWdlIG1hbmlmZXN0ICsgZGV2IGRlcHNcbuKUnOKUgOKUgCB0c2NvbmZpZy5qc29uXG7ilJzilIDilIAgdml0ZXN0LmNvbmZpZy50c1xu4pSU4pSA4pSAIHNyYy9cbiAgICDilJzilIDilIAgaW5kZXgudHMgICAgICAgICAgIyBFeHRlbnNpb24gZW50cnkgcG9pbnQgKDQgdG9vbHMgKyBldmVudCBob29rcylcbiAgICDilJzilIDilIAgc3RhdGUudHMgICAgICAgICAgIyBQdXJlIHN0YXRlIG1hY2hpbmUgKHVuaXQtdGVzdGFibGUpXG4gICAg4pSc4pSA4pSAIHVpLnRzICAgICAgICAgICAgICMgQ3VzdG9tIFRVSSBjb21wb25lbnQgZm9yIGRldiBkZWNpc2lvbnNcbiAgICDilJTilIDilIAgdGVzdC9cbiAgICAgICAg4pSU4pSA4pSAIHN0YXRlLnRlc3QudHMgIyAyOSB0ZXN0cyBmb3Igc3RhdGUgbWFjaGluZVxuYGBgXG5cbioqU3RhdGUgbWFjaGluZSoqIChgc3RhdGUudHNgKSBlbmZvcmNlczpcbmBgYFxu8J+UtCBSRUQg4oaSIHJ1biB0ZXN0cyDihpIg8J+foiBHUkVFTiDihpIgZ28tdG8tcmVmYWN0b3Ig4oaSIPCflIAgUkVGQUNUT1Ig4oaSIChkZXYgcGlja3MpIOKGkiDwn5S0IFJFRFxuYGBgXG5cbioqNCB0b29sczoqKlxufCBUb29sIHwgV2hhdCBpdCBkb2VzIHxcbnwtLS0tLS18LS0tLS0tLS0tLS0tLXxcbnwgYGdvLXRvLWdyZWVuYCB8IFJ1bnMgYG5wbSB0ZXN0YCwgYXV0by10cmFuc2l0aW9ucyBSRUTihpJHUkVFTiBpZiBwYXNzaW5nLCBzdGF5cyBSRUQgaWYgZmFpbGluZyB8XG58IGBnby10by1yZWZhY3RvcmAgfCBFbnRlcnMgUkVGQUNUT1IgcGhhc2UsIHNob3dzIGludGVyYWN0aXZlIGRldiBkZWNpc2lvbiBwcm9tcHQgfFxufCBgcnVuLXRlc3RzYCB8IFJ1bnMgdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uIChkZWJ1Z2dpbmcpIHxcbnwgYHRkZC1zdGF0dXNgIHwgU2hvd3MgY3VycmVudCBwaGFzZSwgdGVzdCBjb3VudCwgZ3VpZGVsaW5lcyB8XG5cbioqRGV2IGRlY2lzaW9uIHByb21wdCoqIChpbiBSRUZBQ1RPUiBwaGFzZSk6XG4xLiBSZWZhY3RvciB0aGUgdGVzdHNcbjIuIFJlZmFjdG9yIHRoZSBpbXBsZW1lbnRhdGlvblxuMy4gQ29udGludWUgdG8gbmV4dCB0ZXN0XG40LiBTb21ldGhpbmcgZWxzZSAoY3VzdG9tIGluc3RydWN0aW9uKVxuXG4qKlNhZmV0eSBnYXRlczoqKlxuLSBgdG9vbF9jYWxsYCBob29rIGJsb2NrcyBSRUTihpJSRUZBQ1RPUiBhbmQgUkVGQUNUT1LihpJHUkVFTiBkaXJlY3QgdHJhbnNpdGlvbnNcbi0gYGJlZm9yZV9hZ2VudF9zdGFydGAgaW5qZWN0cyBwaGFzZSBndWlkZWxpbmVzIGludG8gdGhlIHN5c3RlbSBwcm9tcHRcbi0gU3RhdGUgcGVyc2lzdHMgYWNyb3NzIHNlc3Npb25zIHZpYSBgYXBwZW5kRW50cnlgXG5cbldhbnQgbWUgdG8gYWRkIGFueXRoaW5nIOKAlCBlLmcuLCBhIGAvdGRkLXJlc2V0YCBjb21tYW5kLCBvciB0ZXN0cyBmb3IgdGhlIFVJIGNvbXBvbmVudD8ifV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6Mjk2LCJvdXRwdXQiOjQzMCwiY2FjaGVSZWFkIjo5NjA4MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjk2ODA2LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InN0b3AiLCJ0aW1lc3RhbXAiOjE3ODE5MzkzOTM4NjcsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC03V0owSTVBUjFCUmZuY3daYTFmanRPUndRR0tjVDFzbyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIwOTI4NThiNiIsInBhcmVudElkIjoiYTU5YTIyYzMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjEyOjE5LjU2MVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ1c2VyIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiaG93IHdvdWxkIEkgcGVyZm9ybSBhIG1hbnVhbCB0ZXN0IHdpdGggUGk/In1dLCJ0aW1lc3RhbXAiOjE3ODE5Mzk1Mzk1NTl9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJhMTg0OGRiOSIsInBhcmVudElkIjoiMDkyODU4YjYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA3OjEyOjQzLjI1OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoZSB1c2VyIHdhbnRzIHRvIGtub3cgaG93IHRvIG1hbnVhbGx5IHRlc3QgdGhpcyBleHRlbnNpb24gd2l0aCBQaS4gSSBuZWVkIHRvIGV4cGxhaW4gaG93IHRvIGxvYWQgdGhlIGV4dGVuc2lvbiBmcm9tIHRoZSBsb2NhbCBmaWxlc3lzdGVtLiBUaGVyZSBhcmUgYSBmZXcgd2F5czpcblxuMS4gVXNpbmcgdGhlIGAtZWAgZmxhZyB0byBsb2FkIHRoZSBleHRlbnNpb24gZGlyZWN0bHlcbjIuIEluc3RhbGxpbmcgaXQgYXMgYSBwaSBwYWNrYWdlIHdpdGggYHBpIGluc3RhbGxgXG4zLiBQbGFjaW5nIGl0IGluIGEgcHJvamVjdC1sb2NhbCBgLnBpL2V4dGVuc2lvbnMvYCBkaXJlY3RvcnlcblxuTGV0IG1lIGdpdmUgdGhlbSB0aGUgc2ltcGxlc3Qgb3B0aW9ucy5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlRocmVlIHdheXMsIHNpbXBsZXN0IGZpcnN0OlxuXG4jIyMgMS4gTG9hZCBmcm9tIHBhdGggKHF1aWNrIHRlc3QpXG5cbmBgYGJhc2hcbnBpIC1lIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50c1xuYGBgXG5cblRoaXMgbG9hZHMgdGhlIGV4dGVuc2lvbiBkaXJlY3RseS4gUGkncyBqaXRpIGxvYWRlciBoYW5kbGVzIHRoZSBUeXBlU2NyaXB0LlxuXG4jIyMgMi4gUHJvamVjdC1sb2NhbCBleHRlbnNpb24gKGF1dG8tZGlzY292ZXJlZClcblxuYGBgYmFzaFxubWtkaXIgLXAgLnBpL2V4dGVuc2lvbnNcbmNwIC1yIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYyAucGkvZXh0ZW5zaW9ucy9waS10ZGQtY3ljbGUvXG5gYGBcblxuVGhlbiBqdXN0IHJ1biBgcGlgIGluIHRoYXQgcHJvamVjdCDigJQgaXQgYXV0by1kaXNjb3ZlcnMgYC5waS9leHRlbnNpb25zLyovaW5kZXgudHNgLlxuXG4jIyMgMy4gSW5zdGFsbCBhcyBhIHBpIHBhY2thZ2VcblxuYGBgYmFzaFxucGkgaW5zdGFsbCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZVxuYGBgXG5cblRoaXMgY29waWVzIGl0IHRvIGB+Ly5waS9hZ2VudC9ucG0vcGktdGRkLWN5Y2xlL2AgYW5kIGxvYWRzIGl0IGdsb2JhbGx5LlxuXG4tLS1cblxuKipGb3IgYSByZWFsIHRlc3QqKiwgeW91J2xsIHdhbnQgYSBwcm9qZWN0IHdpdGggdGVzdHMuIFNvbWV0aGluZyBsaWtlOlxuXG5gYGBiYXNoXG5ta2RpciAvdG1wL3RkZC10ZXN0LXByb2plY3QgJiYgY2QgL3RtcC90ZGQtdGVzdC1wcm9qZWN0XG5ucG0gaW5pdCAteVxubnBtIGluc3RhbGwgdml0ZXN0XG5lY2hvICd7XCJ0ZXN0XCI6IFwidml0ZXN0IHJ1blwifScgPiBwYWNrYWdlLmpzb25cbmBgYFxuXG5UaGVuIHJ1biBwaSB3aXRoIHRoZSBleHRlbnNpb24gYW5kIHRlbGwgaXQgdG8gc3RhcnQgYSBUREQgY3ljbGUsIGUuZy46XG5cbmBgYGJhc2hcbnBpIC1lIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyBcIldyaXRlIGEgZnVuY3Rpb24gdGhhdCBhZGRzIHR3byBudW1iZXJzLCBmb2xsb3dpbmcgVEREXCJcbmBgYFxuXG5UaGUgYWdlbnQgc2hvdWxkIHN0YXJ0IGluIFJFRCBwaGFzZSwgd3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gY2FsbCBgZ28tdG8tZ3JlZW5gIHRvIHJ1biBpdC4ifV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MjIsIm91dHB1dCI6NDMzLCJjYWNoZVJlYWQiOjk2ODA1LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6OTcyNjAsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoic3RvcCIsInRpbWVzdGFtcCI6MTc4MTkzOTUzOTU2NCwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLTF4UUtueHNrUjVzNGtoYllZTFdMWUJlZlM3aXpFMGhZIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijg0ZTM5YjcyIiwicGFyZW50SWQiOiJhMTg0OGRiOSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6MzU6NDUuNzU4WiIsIm1lc3NhZ2UiOnsicm9sZSI6InVzZXIiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjYW4gd2UgZG8gYSBxdWljayB0ZXN0PyBwaSAtZSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMgXCJJIHdhbnQgYW4gZW1wdHkgdmVuZGluZ21hY2hpbmUgdGhhdCBkZWxpdmVycyBDYW4uTm90aGluZyAoZW51bSBvciBzbyBpbiB0eXBlc2NyaXB0KSB3aGVuIGNob29zaW5nIGEgQ2hvaWNlLkNvbGEgKGFsc28gZW51bSkuIFdoYXQgaXMgdGhlIG5leHQgc3RlcCB1c2luZyB0aGUgdGRkIGN5Y2xlPyBcIiJ9XSwidGltZXN0YW1wIjoxNzgxOTQ4MTQ1NzU4fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDhmOTkzMjciLCJwYXJlbnRJZCI6Ijg0ZTM5YjcyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTozNTo1MC4xNTRaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgdXNlciB3YW50cyB0byBkbyBhIGxpdmUgdGVzdC4gTGV0IG1lIHJ1biB0aGUgY29tbWFuZC5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiUlRsaEJta0JlNDA2Y1psdG9GdkxwOTZBazFTUTVKVEMiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL3RtcCAmJiBwaSAtZSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMgXCJJIHdhbnQgYW4gZW1wdHkgdmVuZGluZ21hY2hpbmUgdGhhdCBkZWxpdmVycyBDYW4uTm90aGluZyAoZW51bSBvciBzbyBpbiB0eXBlc2NyaXB0KSB3aGVuIGNob29zaW5nIGEgQ2hvaWNlLkNvbGEgKGFsc28gZW51bSkuIFdoYXQgaXMgdGhlIG5leHQgc3RlcCB1c2luZyB0aGUgdGRkIGN5Y2xlPyBcIiAyPiYxIiwidGltZW91dCI6MTIwfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjgyLCJvdXRwdXQiOjEyOCwiY2FjaGVSZWFkIjo5NzI1OSwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjk3NDY5LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDgxNDU3NjAsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC1JaUh0ZkxWbnRmNXU4TEkyR2ozSm04NzZTN3lCTGNzaCJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIwZDIyYmQ2ZSIsInBhcmVudElkIjoiZDhmOTkzMjciLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjM2OjQ3LjE4OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IlJUbGhCbWtCZTQwNmNabHRvRnZMcDk2QWsxU1E1SlRDIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoi4pyFICoqVGVzdCBwYXNzZXMg4oCUIEdSRUVOIHBoYXNlISoqXG5cbkhlcmUncyB3aGF0IHdlIGJ1aWx0OlxuXG58IEZpbGUgfCBQdXJwb3NlIHxcbnwtLS18LS0tfFxufCBgc3JjL3ZlbmRpbmctbWFjaGluZS50c2AgfCBFbnVtcyBgQ2FuYCBhbmQgYENob2ljZWAsIHBsdXMgbWluaW1hbCBgVmVuZGluZ01hY2hpbmVgIGNsYXNzIHxcbnwgYHNyYy92ZW5kaW5nLW1hY2hpbmUudGVzdC50c2AgfCBUZXN0OiBgZGVsaXZlcihDaG9pY2UuQ29sYSlgIHJldHVybnMgYENhbi5Ob3RoaW5nYCB8XG5cblRoZSBUREQgY3ljbGUgc28gZmFyOlxuMS4gKipSRUQqKiDigJQgd3JvdGUgYSBmYWlsaW5nIHRlc3QgKG1vZHVsZSBkaWRuJ3QgZXhpc3QpXG4yLiAqKkdSRUVOKiog4oCUIHdyb3RlIG1pbmltYWwgaW1wbGVtZW50YXRpb24gdG8gbWFrZSBpdCBwYXNzXG5cbldoYXQncyBuZXh0PyBZb3UgY2FuOlxuLSAqKlJlZmFjdG9yKiog4oCUIGNsZWFuIHVwIHRoZSBjb2RlLCBleHRyYWN0IGVudW1zIHRvIHNlcGFyYXRlIGZpbGVzLCBldGMuXG4tICoqQWRkIGEgbmV3IHRlc3QqKiDigJQgZS5nLiwgdGVzdCBhbm90aGVyIGNob2ljZSwgb3IgdGVzdCB0aGF0IHRoZSBtYWNoaW5lIGlzIHRydWx5IGVtcHR5IChubyBpbnZlbnRvcnkpXG4tICoqRXhwYW5kIGJlaGF2aW9yKiog4oCUIGFkZCBhIGBDaG9pY2UuTGVtb25hZGVgLCB0ZXN0IHRoYXQgaXQgYWxzbyByZXR1cm5zIGBDYW4uTm90aGluZ2AsIGV0Yy5cblxuV2hhdCB3b3VsZCB5b3UgbGlrZSB0byBkbz9cbkV4dGVuc2lvbiBlcnJvciAoL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzKTogcGkgaXMgbm90IGRlZmluZWRcbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODIwNzE4OX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjUzNjJlYjE3IiwicGFyZW50SWQiOiIwZDIyYmQ2ZSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6Mzc6MjYuMDM3WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiVGhlIGFnZW50IHJhbiBhbmQgcHJvZHVjZWQgb3V0cHV0LCBidXQgdGhlcmUncyBhbiBlcnJvciBhdCB0aGUgZW5kOiBcInBpIGlzIG5vdCBkZWZpbmVkXCIuIFRoaXMgaXMgYmVjYXVzZSB0aGUgYHBpYCBnbG9iYWwgZGVjbGFyYXRpb24gaW4gdGhlIGV4dGVuc2lvbiBmaWxlIGlzbid0IGJlaW5nIHJlY29nbml6ZWQgYXQgcnVudGltZS4gVGhlIGppdGkgbG9hZGVyIHJ1bnMgdGhlIGV4dGVuc2lvbiBpbiBhIGNvbnRleHQgd2hlcmUgYHBpYCBpc24ndCBhdXRvbWF0aWNhbGx5IGF2YWlsYWJsZSBhcyBhIGdsb2JhbC5cblxuTG9va2luZyBhdCB0aGUgZXh0ZW5zaW9uIGRvY3MgbW9yZSBjYXJlZnVsbHksIGBwaWAgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBub3QgYXZhaWxhYmxlIGFzIGEgZ2xvYmFsLiBUaGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBpcyBvbmx5IGZvciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tpbmcg4oCUIGl0IGRvZXNuJ3QgbWFrZSBgcGlgIGF2YWlsYWJsZSBhdCBydW50aW1lLlxuXG5CdXQgd2FpdCDigJQgdGhlIGV4dGVuc2lvbiBESUQgd29yayBwYXJ0aWFsbHkuIFRoZSBhZ2VudCByZWNlaXZlZCB0aGUgVEREIGN5Y2xlIGd1aWRlbGluZXMgYW5kIHJhbiB0aGUgdGVzdHMuIFRoZSBlcnJvciBjYW1lIGF0IHRoZSBlbmQgd2hlbiB0aGUgZXh0ZW5zaW9uIHRyaWVkIHRvIHVzZSBgcGkuYXBwZW5kRW50cnlgIG9yIGBwaS5zZW5kTWVzc2FnZWAuIExldCBtZSBjaGVjayB3aGF0J3MgaGFwcGVuaW5nLlxuXG5BY3R1YWxseSwgbG9va2luZyBhdCB0aGUgb3V0cHV0LCB0aGUgYWdlbnQgc2VlbXMgdG8gaGF2ZSBydW4gc3VjY2Vzc2Z1bGx5IGFuZCBwcm9kdWNlZCBhIHJlc3BvbnNlLiBUaGUgZXJyb3IgXCJwaSBpcyBub3QgZGVmaW5lZFwiIGlzIGEgcnVudGltZSBlcnJvciBmcm9tIHRoZSBleHRlbnNpb24uIFRoaXMgc3VnZ2VzdHMgdGhhdCBgcGlgIGlzIG5vdCBhdmFpbGFibGUgaW4gdGhlIHJ1bnRpbWUgY29udGV4dC5cblxuTG9va2luZyBhdCB0aGUgZG9jcyBhZ2FpbiwgdGhlIGV4dGVuc2lvbiBmYWN0b3J5IHJlY2VpdmVzIGBwaWAgYXMgYSBwYXJhbWV0ZXI6XG5gYGB0eXBlc2NyaXB0XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAocGk6IEV4dGVuc2lvbkFQSSkgeyAuLi4gfVxuYGBgXG5cblNvIGBwaWAgc2hvdWxkIGJlIGF2YWlsYWJsZSBhcyBhIHBhcmFtZXRlciwgbm90IGEgZ2xvYmFsLiBCdXQgaW5zaWRlIHRoZSBgZXhlY3V0ZWAgY2FsbGJhY2tzIGFuZCBldmVudCBoYW5kbGVycywgYHBpYCBpcyBjYXB0dXJlZCBmcm9tIHRoZSBjbG9zdXJlLiBUaGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBpcyBtaXNsZWFkaW5nIOKAlCBpdCdzIG9ubHkgZm9yIFR5cGVTY3JpcHQsIG5vdCBydW50aW1lLlxuXG5UaGUgaXNzdWUgbWlnaHQgYmUgdGhhdCB0aGUgYHRoZW1lYCBnbG9iYWwgaXMgYWxzbyBiZWluZyByZWZlcmVuY2VkLiBMZXQgbWUgY2hlY2sgd2hlcmUgYHRoZW1lYCBpcyB1c2VkIGluIHRoZSBleHRlbnNpb24uLi5cblxuSW4gaW5kZXgudHMsIEkgdXNlZCBgY3R4LnVpLnRoZW1lYCBpbiBleGVjdXRlIGZ1bmN0aW9ucywgd2hpY2ggc2hvdWxkIGJlIGZpbmUuIEJ1dCBpbiB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jaywgSSBkZWNsYXJlZCBgdGhlbWVgIGFzIGEgZ2xvYmFsIHRvby4gVGhlIGlzc3VlIGlzIHRoYXQgYHBpYCBpcyBub3QgYWN0dWFsbHkgYXZhaWxhYmxlIGFzIGEgZ2xvYmFsIGF0IHJ1bnRpbWUg4oCUIGl0J3MgcGFzc2VkIHRvIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLlxuXG5XYWl0LCBidXQgdGhlIGV4dGVuc2lvbiBESUQgcnVuIHBhcnRpYWxseS4gVGhlIGFnZW50IGdvdCB0aGUgVEREIGd1aWRlbGluZXMgYW5kIHJhbiB0ZXN0cy4gU28gYHBpYCBtdXN0IGhhdmUgYmVlbiBhdmFpbGFibGUgYXQgc29tZSBwb2ludC4gTGV0IG1lIGxvb2sgbW9yZSBjYXJlZnVsbHkuLi5cblxuQWN0dWFsbHksIHRoZSBlcnJvciBtZXNzYWdlIHNheXMgXCJFeHRlbnNpb24gZXJyb3IgKC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyk6IHBpIGlzIG5vdCBkZWZpbmVkXCIuIFRoaXMgaXMgYSBydW50aW1lIGVycm9yIGZyb20gdGhlIGppdGkgbG9hZGVyLiBUaGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBpcyBUeXBlU2NyaXB0LW9ubHkgYW5kIGRvZXNuJ3QgYWZmZWN0IHJ1bnRpbWUuXG5cbkJ1dCB0aGUgZXh0ZW5zaW9uIGZhY3RvcnkgZnVuY3Rpb24gcmVjZWl2ZXMgYHBpYCBhcyBhIHBhcmFtZXRlciwgc28gaXQgc2hvdWxkIHdvcmsuIFVubGVzcy4uLiB0aGUgZXJyb3IgaXMgaGFwcGVuaW5nIGluIGEgZGlmZmVyZW50IGNvbnRleHQuXG5cbkxldCBtZSBsb29rIGF0IHRoZSBjb2RlIG1vcmUgY2FyZWZ1bGx5LiBUaGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBtaWdodCBhY3R1YWxseSBiZSBjYXVzaW5nIGlzc3VlcyBiZWNhdXNlIGl0J3MgZGVjbGFyaW5nIGEgZ2xvYmFsIGBwaWAgdGhhdCBjb25mbGljdHMgd2l0aCB0aGUgcGFyYW1ldGVyLiBPciBtYXliZSB0aGUgaXNzdWUgaXMgdGhhdCB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBpcyBiZWluZyB0cmVhdGVkIGFzIGEgbW9kdWxlIGRlY2xhcmF0aW9uIGFuZCBjYXVzaW5nIGlzc3Vlcy5cblxuQWN0dWFsbHksIEkgdGhpbmsgdGhlIHByb2JsZW0gbWlnaHQgYmUgc2ltcGxlci4gVGhlIGBkZWNsYXJlIGdsb2JhbGAgYmxvY2sgaXMgaW5zaWRlIHRoZSBtb2R1bGUgZmlsZSwgYW5kIFR5cGVTY3JpcHQgdHJlYXRzIGl0IGFzIGEgZ2xvYmFsIGF1Z21lbnRhdGlvbi4gQnV0IGF0IHJ1bnRpbWUsIGppdGkgbWlnaHQgYmUgaW50ZXJwcmV0aW5nIGl0IGRpZmZlcmVudGx5LlxuXG5MZXQgbWUgcmVtb3ZlIHRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrIGFuZCBzZWUgaWYgdGhhdCBmaXhlcyBpdC4gVGhlIGBwaWAgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBzbyBpdCBzaG91bGQgYmUgYXZhaWxhYmxlIGluIHRoZSBjbG9zdXJlLiBUaGUgYHRoZW1lYCBpcyBhY2Nlc3NlZCB2aWEgYGN0eC51aS50aGVtZWAsIHNvIGl0IGRvZXNuJ3QgbmVlZCBhIGdsb2JhbCBkZWNsYXJhdGlvbiBlaXRoZXIuXG5cbldhaXQsIGJ1dCB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBpcyBvbmx5IGZvciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tpbmcuIEF0IHJ1bnRpbWUsIGl0IHNob3VsZCBiZSBhIG5vLW9wLiBUaGUgZXJyb3IgXCJwaSBpcyBub3QgZGVmaW5lZFwiIGF0IHJ1bnRpbWUgc3VnZ2VzdHMgc29tZXRoaW5nIGVsc2UgaXMgZ29pbmcgb24uXG5cbkxldCBtZSBsb29rIGF0IHRoZSBlcnJvciBtb3JlIGNhcmVmdWxseS4gVGhlIGFnZW50IHJhbiBhbmQgcHJvZHVjZWQgYSByZXNwb25zZSwgYnV0IHRoZW4gdGhlcmUgd2FzIGFuIGV4dGVuc2lvbiBlcnJvci4gVGhpcyBzdWdnZXN0cyB0aGUgZXh0ZW5zaW9uIHJhbiBzdWNjZXNzZnVsbHkgZm9yIHRoZSBtb3N0IHBhcnQsIGJ1dCBzb21ldGhpbmcgZmFpbGVkIGF0IHRoZSBlbmQuXG5cbkxvb2tpbmcgYXQgdGhlIGBzZXNzaW9uX3NodXRkb3duYCBoYW5kbGVyLCBpdCBjYWxscyBgcGVyc2lzdFN0YXRlKClgIHdoaWNoIGNhbGxzIGBwaS5hcHBlbmRFbnRyeSgpYC4gSWYgYHBpYCBpcyBub3QgZGVmaW5lZCBhdCB0aGF0IHBvaW50LCBpdCB3b3VsZCB0aHJvdy5cblxuQWN0dWFsbHksIEkgdGhpbmsgdGhlIGlzc3VlIG1pZ2h0IGJlIHRoYXQgdGhlIGBkZWNsYXJlIGdsb2JhbGAgYmxvY2sgaXMgaW50ZXJmZXJpbmcgd2l0aCB0aGUgbW9kdWxlJ3Mgc2NvcGUuIExldCBtZSB0cnkgcmVtb3ZpbmcgaXQgYW5kIHNlZSBpZiB0aGF0IGZpeGVzIHRoZSBpc3N1ZS5cblxuQWN0dWFsbHkgd2FpdCwgbGV0IG1lIHJlLXJlYWQgdGhlIG91dHB1dC4gVGhlIGFnZW50IHByb2R1Y2VkIGEgZnVsbCByZXNwb25zZSB3aXRoIHRoZSBUREQgY3ljbGUgc3VtbWFyeS4gQnV0IHRoZW4gdGhlcmUncyBhbiBlcnJvci4gVGhpcyBtZWFucyB0aGUgZXh0ZW5zaW9uIGxvYWRlZCBhbmQgcmFuLCBidXQgc29tZXRoaW5nIGZhaWxlZC5cblxuTGV0IG1lIGNoZWNrIGlmIHRoZSBpc3N1ZSBpcyB3aXRoIHRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrLiBJbiBUeXBlU2NyaXB0LCBgZGVjbGFyZSBnbG9iYWxgIGlzIHVzZWQgdG8gYXVnbWVudCB0aGUgZ2xvYmFsIHNjb3BlLiBCdXQgaW4gYSBtb2R1bGUgZmlsZSAod2hpY2ggdGhpcyBpcywgc2luY2UgaXQgaGFzIGltcG9ydHMpLCB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBkb2Vzbid0IGFjdHVhbGx5IGNyZWF0ZSBnbG9iYWxzIOKAlCBpdCBqdXN0IHRlbGxzIFR5cGVTY3JpcHQgdGhhdCBjZXJ0YWluIG5hbWVzIGV4aXN0IGdsb2JhbGx5LlxuXG5BdCBydW50aW1lLCBqaXRpIGNvbXBpbGVzIHRoZSBUeXBlU2NyaXB0IHRvIEphdmFTY3JpcHQuIFRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrIHNob3VsZCBiZSBzdHJpcHBlZCBvdXQgYnkgVHlwZVNjcmlwdC4gQnV0IGlmIHRoZXJlJ3MgYSBjb21waWxhdGlvbiBpc3N1ZSwgaXQgbWlnaHQgY2F1c2UgcHJvYmxlbXMuXG5cbkxldCBtZSB0cnkgcmVtb3ZpbmcgdGhlIGBkZWNsYXJlIGdsb2JhbGAgYmxvY2sgYW5kIHNlZSBpZiB0aGF0IGZpeGVzIHRoZSBpc3N1ZS5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlRoZSBleHRlbnNpb24gbG9hZGVkIGFuZCB3b3JrZWQgKGFnZW50IGdvdCBUREQgZ3VpZGVsaW5lcyBhbmQgcmFuIHRlc3RzKSwgYnV0IGNyYXNoZWQgYXQgdGhlIGVuZCB3aXRoIGBwaSBpcyBub3QgZGVmaW5lZGAuIFRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrIGlzIGEgVHlwZVNjcmlwdC1vbmx5IGNvbnN0cnVjdCB0aGF0IGRvZXNuJ3QgaGVscCBhdCBydW50aW1lIOKAlCBgcGlgIGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciB0byB0aGUgZmFjdG9yeSBmdW5jdGlvbiwgbm90IGEgZ2xvYmFsLiBMZXQgbWUgcmVtb3ZlIGl0OlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiVEs0dUtrWGdQaUZQbmxQcFZLVmJPcE1uaXM2enNITWMiLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwiZWRpdHMiOlt7Im9sZFRleHQiOiJkZWNsYXJlIGdsb2JhbCB7XG4gIGNvbnN0IHBpOiBpbXBvcnQoXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCIpLkV4dGVuc2lvbkFQSTtcbiAgY29uc3QgdGhlbWU6IGltcG9ydChcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIikuVGhlbWU7XG59XG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjsiLCJuZXdUZXh0IjoiaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEksIEV4dGVuc2lvbkNvbnRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiOyJ9XX19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjoyNTMsIm91dHB1dCI6MTI2MiwiY2FjaGVSZWFkIjo5NzQ2OCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjk4OTgzLCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDgyMDcxOTAsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC1TTXExV1A2MXdqenlMRzAycEJRckNrcXNEbE9oZzRUNCJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIwY2ExNmE3OCIsInBhcmVudElkIjoiNTM2MmViMTciLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjM3OjI2LjA1M1oiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IlRLNHVLa1hnUGlGUG5sUHBWS1ZiT3BNbmlzNnpzSE1jIiwidG9vbE5hbWUiOiJlZGl0IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDEgYmxvY2socykgaW4gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzLiJ9XSwiZGV0YWlscyI6eyJkaWZmIjoiICAgICAuLi5cbiAgMTQgICogICBydW4tdGVzdHMgICAgICAgLSBSdW4gdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uXG4gIDE1ICAqICAgdGRkLXN0YXR1cyAgICAgIC0gU2hvdyBjdXJyZW50IHBoYXNlIGFuZCBzdGF0ZVxuICAxNiAgKi9cbiAgMTcgXG4tIDE4IGRlY2xhcmUgZ2xvYmFsIHtcbi0gMTkgICBjb25zdCBwaTogaW1wb3J0KFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiKS5FeHRlbnNpb25BUEk7XG4tIDIwICAgY29uc3QgdGhlbWU6IGltcG9ydChcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIikuVGhlbWU7XG4tIDIxIH1cbi0gMjIgXG4gIDIzIGltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbiAgMjQgaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG4gIDI1IGltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuICAyNiBcbiAgICAgLi4uIiwicGF0Y2giOiItLS0gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzXG4rKysgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzXG5AQCAtMTQsMTMgKzE0LDggQEBcbiAgKiAgIHJ1bi10ZXN0cyAgICAgICAtIFJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb25cbiAgKiAgIHRkZC1zdGF0dXMgICAgICAtIFNob3cgY3VycmVudCBwaGFzZSBhbmQgc3RhdGVcbiAgKi9cbiBcbi1kZWNsYXJlIGdsb2JhbCB7XG4tICBjb25zdCBwaTogaW1wb3J0KFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiKS5FeHRlbnNpb25BUEk7XG4tICBjb25zdCB0aGVtZTogaW1wb3J0KFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiKS5UaGVtZTtcbi19XG4tXG4gaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEksIEV4dGVuc2lvbkNvbnRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuIGltcG9ydCB7IFR5cGUgfSBmcm9tIFwidHlwZWJveFwiO1xuIGltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuIFxuIiwiZmlyc3RDaGFuZ2VkTGluZSI6MTh9LCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ4MjQ2MDUzfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOTE5YzA2ZDciLCJwYXJlbnRJZCI6IjBjYTE2YTc4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTozNzozNy42MTVaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJOb3cgbGV0IG1lIGFsc28gY2hlY2sgaWYgdGhlcmUncyBhIHR5cGVjaGVjayBpc3N1ZSBhZnRlciByZW1vdmluZyB0aGUgZGVjbGFyZSBnbG9iYWwgYmxvY2suIFRoZSBgdGhlbWVgIHJlZmVyZW5jZSBpbiB0aGUgYHJlbmRlckNhbGxgIGFuZCBgcmVuZGVyUmVzdWx0YCBjYWxsYmFja3Mg4oCUIHRob3NlIHJlY2VpdmUgYHRoZW1lYCBhcyBhIHBhcmFtZXRlciwgc28gdGhleSBzaG91bGQgYmUgZmluZS4gVGhlIGBwaWAgcmVmZXJlbmNlcyBpbiB0aGUgZXhlY3V0ZSBjYWxsYmFja3MgYW5kIGV2ZW50IGhhbmRsZXJzIGFyZSBjYXB0dXJlZCBmcm9tIHRoZSBmYWN0b3J5IGZ1bmN0aW9uIGNsb3N1cmUsIHNvIHRoZXkgc2hvdWxkIGFsc28gYmUgZmluZS5cblxuTGV0IG1lIHJ1biB0eXBlY2hlY2sgYW5kIHRoZW4gcmUtdGVzdC5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiZ0tLbUdaWjNmSlNydzNvOVU3UUs1MnFmYUJOMzNtWVIiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgbnBtIHJ1biB0eXBlY2hlY2sgMj4mMSJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6MTMwOCwib3V0cHV0IjoxNDMsImNhY2hlUmVhZCI6OTc3MTcsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjo5OTE2OCwiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4MjQ2MDU0LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtb1hNY1lYODJIcGl0Sm1JWXZwTktsQUtJM3A5WUtsNm0ifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiODlmYzliNDgiLCJwYXJlbnRJZCI6IjkxOWMwNmQ3IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTozNzozOC45OTZaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJnS0ttR1paM2ZKU3J3M285VTdRSzUycWZhQk4zM21ZUiIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlxuPiBwaS10ZGQtY3ljbGVAMC4xLjAgdHlwZWNoZWNrXG4+IHRzYyAtLW5vRW1pdFxuXG5zcmMvaW5kZXgudHMoNDAsMyk6IGVycm9yIFRTMjMwNDogQ2Fubm90IGZpbmQgbmFtZSAncGknLlxuXG5cbkNvbW1hbmQgZXhpdGVkIHdpdGggY29kZSAyIn1dLCJkZXRhaWxzIjp7fSwiaXNFcnJvciI6dHJ1ZSwidGltZXN0YW1wIjoxNzgxOTQ4MjU4OTk2fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZGQ5YWNlYTgiLCJwYXJlbnRJZCI6Ijg5ZmM5YjQ4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTozODoxMi43MTdaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJBaCwgdGhlIGBwaWAgZ2xvYmFsIGRlY2xhcmF0aW9uIHdhcyBuZWVkZWQgZm9yIFR5cGVTY3JpcHQgdG8gcmVjb2duaXplIGBwaWAgaW5zaWRlIHRoZSBjbG9zdXJlLiBCdXQgaXQgY2F1c2VzIHJ1bnRpbWUgaXNzdWVzLiBUaGUgc29sdXRpb24gaXMgdG8gdXNlIGEgZGlmZmVyZW50IGFwcHJvYWNoIOKAlCBlaXRoZXIgdXNlIGB0aGlzYCBvciBjYXB0dXJlIGBwaWAgZGlmZmVyZW50bHkuXG5cbkFjdHVhbGx5LCBsb29raW5nIGF0IHRoZSBleHRlbnNpb24gZG9jcyBtb3JlIGNhcmVmdWxseSwgdGhlIGZhY3RvcnkgZnVuY3Rpb24gcmVjZWl2ZXMgYHBpYCBhcyBhIHBhcmFtZXRlcjpcbmBgYHR5cGVzY3JpcHRcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwaTogRXh0ZW5zaW9uQVBJKSB7IC4uLiB9XG5gYGBcblxuSW5zaWRlIHRoZSBmdW5jdGlvbiBib2R5LCBgcGlgIHNob3VsZCBiZSBhY2Nlc3NpYmxlIGFzIGEgbG9jYWwgdmFyaWFibGUuIFRoZSBpc3N1ZSBpcyB0aGF0IHRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrIHdhcyBtYWtpbmcgVHlwZVNjcmlwdCB0aGluayBgcGlgIGlzIGEgZ2xvYmFsLCB3aGljaCB0aGVuIGNhdXNlcyBhIHJ1bnRpbWUgY29uZmxpY3QuXG5cblRoZSBmaXggaXMgdG8gcmVuYW1lIHRoZSBwYXJhbWV0ZXIgdG8gYXZvaWQgdGhlIGNvbmZsaWN0LCBvciB1c2UgYSBkaWZmZXJlbnQgYXBwcm9hY2guIExldCBtZSByZW5hbWUgdGhlIHBhcmFtZXRlciB0byBgcGlBcGlgOlxuXG5BY3R1YWxseSB3YWl0LCBsb29raW5nIGF0IHRoZSBjb2RlIGFnYWluOlxuXG5gYGB0eXBlc2NyaXB0XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0ZGRDeWNsZShwaTogRXh0ZW5zaW9uQVBJKTogdm9pZCB7XG4gIC8vIC4uLlxuICBwaS5yZWdpc3RlclRvb2woeyAuLi4gfSk7XG4gIC8vIC4uLlxuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7IC4uLiB9KTtcbiAgLy8gLi4uXG59XG5gYGBcblxuSW5zaWRlIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBgcGlgIGlzIHRoZSBwYXJhbWV0ZXIuIEluc2lkZSB0aGUgY2xvc3VyZXMgKGV4ZWN1dGUgY2FsbGJhY2tzLCBldmVudCBoYW5kbGVycyksIGBwaWAgaXMgY2FwdHVyZWQgZnJvbSB0aGUgY2xvc3VyZS4gVGhpcyBzaG91bGQgd29yayBmaW5lIHdpdGggVHlwZVNjcmlwdC5cblxuVGhlIGlzc3VlIGlzIHRoYXQgYGRlY2xhcmUgZ2xvYmFsIHsgY29uc3QgcGk6IC4uLiB9YCB0ZWxscyBUeXBlU2NyaXB0IHRoYXQgYHBpYCBpcyBhIGdsb2JhbCB2YXJpYWJsZSwgd2hpY2ggc2hhZG93cyB0aGUgcGFyYW1ldGVyLiBCdXQgYXQgcnVudGltZSwgdGhlcmUncyBubyBnbG9iYWwgYHBpYCwgaGVuY2UgdGhlIGVycm9yLlxuXG5UaGUgZml4IGlzIHRvIHJlbW92ZSB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jayBhbmQgaW5zdGVhZCB1c2UgYSB0eXBlIGFubm90YXRpb24gZm9yIHRoZSBwYXJhbWV0ZXIgdGhhdCBtYWtlcyBUeXBlU2NyaXB0IGhhcHB5LiBCdXQgYHBpYCBpcyBhbHJlYWR5IHR5cGVkIGFzIGBFeHRlbnNpb25BUElgIGZyb20gdGhlIHBhcmFtZXRlci5cblxuV2FpdCwgdGhlIGVycm9yIGlzIGF0IGxpbmUgNDAsIHdoaWNoIGlzIGluc2lkZSB0aGUgYHBlcnNpc3RTdGF0ZSgpYCBmdW5jdGlvbi4gTGV0IG1lIGNoZWNrOlxuXG5gYGB0eXBlc2NyaXB0XG5mdW5jdGlvbiBwZXJzaXN0U3RhdGUoKTogdm9pZCB7XG4gIHBpLmFwcGVuZEVudHJ5KFwidGRkLWN5Y2xlXCIsIHsgLi4uIH0pO1xufVxuYGBgXG5cblRoaXMgZnVuY3Rpb24gaXMgZGVmaW5lZCBpbnNpZGUgdGhlIGZhY3RvcnkgZnVuY3Rpb24sIHNvIGBwaWAgc2hvdWxkIGJlIGNhcHR1cmVkIGZyb20gdGhlIGNsb3N1cmUuIEJ1dCBUeXBlU2NyaXB0IGRvZXNuJ3Qga25vdyBhYm91dCBgcGlgIGJlY2F1c2Ugd2UgcmVtb3ZlZCB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jay5cblxuVGhlIGZpeCBpcyB0byBtb3ZlIGBwZXJzaXN0U3RhdGVgIGluc2lkZSB0aGUgZmFjdG9yeSBmdW5jdGlvbidzIHNjb3BlIHNvIGl0IGNhcHR1cmVzIGBwaWAgZnJvbSB0aGUgY2xvc3VyZS4gT3IgcmVuYW1lIHRoZSBwYXJhbWV0ZXIgdG8gYXZvaWQgY29uZnVzaW9uLlxuXG5BY3R1YWxseSwgdGhlIHNpbXBsZXN0IGZpeCBpcyB0byBqdXN0IHJlbmFtZSB0aGUgcGFyYW1ldGVyIGZyb20gYHBpYCB0byBzb21ldGhpbmcgZWxzZSwgbGlrZSBgYXBpYCwgYW5kIHVwZGF0ZSBhbGwgcmVmZXJlbmNlcy4gQnV0IHRoYXQncyBhIGxvdCBvZiBjaGFuZ2VzLlxuXG5BIGJldHRlciBhcHByb2FjaDogbW92ZSB0aGUgaGVscGVyIGZ1bmN0aW9ucyAoYHBlcnNpc3RTdGF0ZWAsIGByZXN0b3JlU3RhdGVgLCBgc3RhdHVzTWVzc2FnZWAsIGBndWlkZWxpbmVzTWVzc2FnZWApIGluc2lkZSB0aGUgZmFjdG9yeSBmdW5jdGlvbiBzbyB0aGV5IGNhcHR1cmUgYHBpYCBmcm9tIHRoZSBjbG9zdXJlIG5hdHVyYWxseS5cblxuT3IgZXZlbiBzaW1wbGVyOiBqdXN0IGFzc2lnbiBgcGlgIHRvIGEgbG9jYWwgY29uc3RhbnQgYXQgdGhlIHRvcCBvZiB0aGUgZmFjdG9yeSBmdW5jdGlvbjpcblxuYGBgdHlwZXNjcmlwdFxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdGRkQ3ljbGUoYXBpOiBFeHRlbnNpb25BUEkpOiB2b2lkIHtcbiAgY29uc3QgcGkgPSBhcGk7XG4gIC8vIC4uLlxufVxuYGBgXG5cbkJ1dCB0aGF0J3MgcmVkdW5kYW50LlxuXG5BY3R1YWxseSwgdGhlIGNsZWFuZXN0IGZpeCBpcyB0byBqdXN0IGtlZXAgdGhlIHBhcmFtZXRlciBuYW1lIGBwaWAgYW5kIHJlbW92ZSB0aGUgYGRlY2xhcmUgZ2xvYmFsYCBibG9jay4gVHlwZVNjcmlwdCBzaG91bGQgdW5kZXJzdGFuZCB0aGF0IGBwaWAgaXMgYSBsb2NhbCB2YXJpYWJsZSBpbiB0aGUgZmFjdG9yeSBmdW5jdGlvbiBzY29wZS4gVGhlIGlzc3VlIGlzIHRoYXQgdGhlIGhlbHBlciBmdW5jdGlvbnMgYXJlIGRlZmluZWQgb3V0c2lkZSB0aGUgZmFjdG9yeSBmdW5jdGlvbiBzY29wZS4uLiB3YWl0LCBubywgdGhleSdyZSBkZWZpbmVkIGluc2lkZS5cblxuTGV0IG1lIHJlLXJlYWQgdGhlIGNvZGUgc3RydWN0dXJlOlxuXG5gYGB0eXBlc2NyaXB0XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0ZGRDeWNsZShwaTogRXh0ZW5zaW9uQVBJKTogdm9pZCB7XG4gIGxldCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IGNyZWF0ZUluaXRpYWxTdGF0ZSgpO1xuXG4gIGZ1bmN0aW9uIHBlcnNpc3RTdGF0ZSgpOiB2b2lkIHtcbiAgICBwaS5hcHBlbmRFbnRyeShcInRkZC1jeWNsZVwiLCB7IC4uLiB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3RvcmVTdGF0ZShjdHg6IEV4dGVuc2lvbkNvbnRleHQpOiB2b2lkIHtcbiAgICAvLyAuLi5cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXR1c01lc3NhZ2UoKTogc3RyaW5nIHsgLi4uIH1cbiAgZnVuY3Rpb24gZ3VpZGVsaW5lc01lc3NhZ2UoKTogc3RyaW5nIHsgLi4uIH1cblxuICAvLyAuLi4gdG9vbHMgcmVnaXN0ZXJlZCB3aXRoIHBpLnJlZ2lzdGVyVG9vbCgpXG4gIC8vIC4uLiBldmVudHMgd2l0aCBwaS5vbigpXG59XG5gYGBcblxuU28gYHBpYCBpcyB0aGUgcGFyYW1ldGVyIG9mIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBhbmQgYWxsIHRoZSBoZWxwZXIgZnVuY3Rpb25zIGFyZSBuZXN0ZWQgaW5zaWRlIGl0LiBUeXBlU2NyaXB0IHNob3VsZCByZWNvZ25pemUgYHBpYCBhcyBhIGxvY2FsIHZhcmlhYmxlLlxuXG5UaGUgcHJvYmxlbSBpcyB0aGF0IGBkZWNsYXJlIGdsb2JhbCB7IGNvbnN0IHBpOiAuLi4gfWAgd2FzIG1ha2luZyBUeXBlU2NyaXB0IHRoaW5rIGBwaWAgaXMgYSBnbG9iYWwsIGFuZCB3aGVuIHdlIHJlbW92ZWQgaXQsIFR5cGVTY3JpcHQgbm8gbG9uZ2VyIHJlY29nbml6ZXMgYHBpYCBhdCBhbGwuXG5cbldhaXQsIHRoYXQgZG9lc24ndCBtYWtlIHNlbnNlLiBJZiBgcGlgIGlzIGEgcGFyYW1ldGVyIG9mIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBUeXBlU2NyaXB0IHNob3VsZCByZWNvZ25pemUgaXQgcmVnYXJkbGVzcyBvZiBgZGVjbGFyZSBnbG9iYWxgLiBMZXQgbWUgY2hlY2sgaWYgdGhlcmUncyBzb21ldGhpbmcgZWxzZSBnb2luZyBvbi5cblxuT2ggd2FpdCwgSSB0aGluayBJIHNlZSB0aGUgaXNzdWUuIFRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrIHdhcyBwbGFjZWQgQkVGT1JFIHRoZSBpbXBvcnQgc3RhdGVtZW50LiBJbiBUeXBlU2NyaXB0LCBgZGVjbGFyZSBnbG9iYWxgIG11c3QgYmUgYXQgdGhlIHRvcCBsZXZlbCBvZiBhIG1vZHVsZS4gV2hlbiBwbGFjZWQgYmVmb3JlIGltcG9ydHMsIGl0IG1pZ2h0IGNhdXNlIGlzc3VlcyB3aXRoIHRoZSBtb2R1bGUncyBzY29wZS5cblxuTGV0IG1lIGp1c3QgcmVtb3ZlIHRoZSBgZGVjbGFyZSBnbG9iYWxgIGJsb2NrIGVudGlyZWx5IGFuZCBzZWUgaWYgVHlwZVNjcmlwdCByZWNvZ25pemVzIGBwaWAgYXMgdGhlIHBhcmFtZXRlci4gVGhlIGVycm9yIGF0IGxpbmUgNDAgc3VnZ2VzdHMgaXQgZG9lc24ndC4gTGV0IG1lIGNoZWNrIHdoYXQgbGluZSA0MCBhY3R1YWxseSBpcy5cblxuQWN0dWFsbHksIGxldCBtZSBqdXN0IHJlYWQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGZpbGUgdG8gdW5kZXJzdGFuZCB0aGUgaXNzdWU6XG4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZ19jb250ZW50In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImxuUkRjQmtKZUM1SEI5c0VKZTlXUTE4c2ZVb1hzekc3IiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyIsImxpbWl0Ijo1MCwib2Zmc2V0IjoxfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjI1MCwib3V0cHV0IjoxMTIxLCJjYWNoZVJlYWQiOjk4OTg0LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTAwMzU1LCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDgyNTg5OTcsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC1QaWxTMUYwcTRXNkpORVIzeGlOS0psZkxkS2JWTTdacyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI1NWZlNGQ5NyIsInBhcmVudElkIjoiZGQ5YWNlYTgiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjM4OjEyLjczMFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImxuUkRjQmtKZUM1SEI5c0VKZTlXUTE4c2ZVb1hzekc3IiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiLyoqXG4gKiBUREQgQ3ljbGUgRXh0ZW5zaW9uXG4gKlxuICogRW5mb3JjZXMgdGhlIHJlZC1ncmVlbi1yZWZhY3RvciBUREQgY3ljbGU6XG4gKiAgIPCflLQgUkVEICAgIOKGkiBXcml0ZSBhIGZhaWxpbmcgdGVzdCwgdGhlbiBpbXBsZW1lbnQgdG8gbWFrZSBpdCBwYXNzXG4gKiAgIPCfn6IgR1JFRU4gIOKGkiBUZXN0cyBwYXNzLCByZWFkeSBmb3IgcmVmYWN0b3JpbmdcbiAqICAg8J+UgCBSRUZBQ1RPUiDihpIgRGV2ZWxvcGVyIGNob29zZXMgd2hhdCB0byByZWZhY3RvclxuICpcbiAqIEFmdGVyIHJlZmFjdG9yaW5nLCB0aGUgY3ljbGUgcmVwZWF0czogYmFjayB0byBSRUQgZm9yIHRoZSBuZXh0IHRlc3QuXG4gKlxuICogVG9vbHM6XG4gKiAgIGdvLXRvLWdyZWVuICAgICAtIFJ1biB0ZXN0cyBhbmQgdHJhbnNpdGlvbiBiYXNlZCBvbiByZXN1bHRcbiAqICAgZ28tdG8tcmVmYWN0b3IgIC0gRW50ZXIgdGhlIGRldmVsb3BlciBkZWNpc2lvbiBwaGFzZVxuICogICBydW4tdGVzdHMgICAgICAgLSBSdW4gdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uXG4gKiAgIHRkZC1zdGF0dXMgICAgICAtIFNob3cgY3VycmVudCBwaGFzZSBhbmQgc3RhdGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSwgRXh0ZW5zaW9uQ29udGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcbmltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuXG5pbXBvcnQge1xuICBjcmVhdGVJbml0aWFsU3RhdGUsXG4gIHJlY29yZFRlc3RSZXN1bHQsXG4gIGdyZWVuVG9SZWZhY3RvcixcbiAgYXBwbHlSZWZhY3RvckRlY2lzaW9uLFxuICBwaGFzZUVtb2ppLFxuICBwaGFzZURlc2NyaXB0aW9uLFxuICBwaGFzZUd1aWRlbGluZXMsXG4gIHR5cGUgQ3ljbGVTdGF0ZSxcbiAgdHlwZSBSZWZhY3RvckRlY2lzaW9uLFxufSBmcm9tIFwiLi9zdGF0ZS5qc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVmYWN0b3JEZWNpc2lvbkNvbXBvbmVudCB9IGZyb20gXCIuL3VpLmpzXCI7XG5cbi8vIOKUgOKUgCBTdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxubGV0IHN0YXRlOiBDeWNsZVN0YXRlID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7XG5cbmZ1bmN0aW9uIHBlcnNpc3RTdGF0ZSgpOiB2b2lkIHtcbiAgcGkuYXBwZW5kRW50cnkoXCJ0ZGQtY3ljbGVcIiwge1xuICAgIHBoYXNlOiBzdGF0ZS5waGFzZSxcbiAgICB0ZXN0RGVzY3JpcHRpb246IHN0YXRlLnRlc3REZXNjcmlwdGlvbixcbiAgICB0ZXN0c1Jhbjogc3RhdGUudGVzdHNSYW4sXG4gICAgdGVzdHNQYXNzZWQ6IHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgIHRlc3RzV3JpdHRlbjogc3RhdGUudGVzdHNXcml0dGVuLFxuICAgIGxhc3REZWNpc2lvbjogc3RhdGUubGFzdERlY2lzaW9uLFxuICAgIGN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb246IHN0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb24sXG4gIH0pO1xufVxuXG5cbls0MDQgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTUxIHRvIGNvbnRpbnVlLl0ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDgyOTI3MzB9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI2ZGE4NThjYSIsInBhcmVudElkIjoiNTVmZTRkOTciLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjM4OjIwLjU0OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ikkgc2VlIHRoZSBwcm9ibGVtLiBUaGUgaGVscGVyIGZ1bmN0aW9ucyAoYHBlcnNpc3RTdGF0ZWAsIGByZXN0b3JlU3RhdGVgLCBgc3RhdHVzTWVzc2FnZWAsIGBndWlkZWxpbmVzTWVzc2FnZWApIGFuZCB0aGUgYHN0YXRlYCB2YXJpYWJsZSBhcmUgZGVmaW5lZCBPVVRTSURFIHRoZSBmYWN0b3J5IGZ1bmN0aW9uIGB0ZGRDeWNsZWAuIFRoZXkgcmVmZXJlbmNlIGBwaWAgd2hpY2ggaXMgb25seSBhdmFpbGFibGUgaW5zaWRlIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLlxuXG5UaGUgZml4IGlzIHRvIG1vdmUgYWxsIG9mIHRoZXNlIGluc2lkZSB0aGUgZmFjdG9yeSBmdW5jdGlvbiwgc28gdGhleSBjYXB0dXJlIGBwaWAgZnJvbSB0aGUgY2xvc3VyZS4gTGV0IG1lIHJlc3RydWN0dXJlIHRoZSBmaWxlLlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiVGhlIGhlbHBlciBmdW5jdGlvbnMgYW5kIGBzdGF0ZWAgYXJlIGRlZmluZWQgKipvdXRzaWRlKiogdGhlIGZhY3RvcnkgZnVuY3Rpb24sIHNvIHRoZXkgY2FuJ3QgY2FwdHVyZSBgcGlgLiBJIG5lZWQgdG8gbW92ZSB0aGVtIGluc2lkZTpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IklhVUI4bll2ZzdzNHhtaHJTMUJGd2JHckt0TjBsZnlTIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6NDMxLCJvdXRwdXQiOjE2NCwiY2FjaGVSZWFkIjoxMDAzNTQsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMDA5NDksImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODI5MjczMSwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLVJsSVRJUjMwODc2RmwyeFM4VEJTWUhqQ3J1R0NhdnB5In19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjhlNjcwMWNiIiwicGFyZW50SWQiOiI2ZGE4NThjYSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6Mzg6MjAuNTU5WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiSWFVQjhuWXZnN3M0eG1oclMxQkZ3YkdyS3ROMGxmeVMiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIvKipcbiAqIFRERCBDeWNsZSBFeHRlbnNpb25cbiAqXG4gKiBFbmZvcmNlcyB0aGUgcmVkLWdyZWVuLXJlZmFjdG9yIFRERCBjeWNsZTpcbiAqICAg8J+UtCBSRUQgICAg4oaSIFdyaXRlIGEgZmFpbGluZyB0ZXN0LCB0aGVuIGltcGxlbWVudCB0byBtYWtlIGl0IHBhc3NcbiAqICAg8J+foiBHUkVFTiAg4oaSIFRlc3RzIHBhc3MsIHJlYWR5IGZvciByZWZhY3RvcmluZ1xuICogICDwn5SAIFJFRkFDVE9SIOKGkiBEZXZlbG9wZXIgY2hvb3NlcyB3aGF0IHRvIHJlZmFjdG9yXG4gKlxuICogQWZ0ZXIgcmVmYWN0b3JpbmcsIHRoZSBjeWNsZSByZXBlYXRzOiBiYWNrIHRvIFJFRCBmb3IgdGhlIG5leHQgdGVzdC5cbiAqXG4gKiBUb29sczpcbiAqICAgZ28tdG8tZ3JlZW4gICAgIC0gUnVuIHRlc3RzIGFuZCB0cmFuc2l0aW9uIGJhc2VkIG9uIHJlc3VsdFxuICogICBnby10by1yZWZhY3RvciAgLSBFbnRlciB0aGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHBoYXNlXG4gKiAgIHJ1bi10ZXN0cyAgICAgICAtIFJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb25cbiAqICAgdGRkLXN0YXR1cyAgICAgIC0gU2hvdyBjdXJyZW50IHBoYXNlIGFuZCBzdGF0ZVxuICovXG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwidHlwZWJveFwiO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZUluaXRpYWxTdGF0ZSxcbiAgcmVjb3JkVGVzdFJlc3VsdCxcbiAgZ3JlZW5Ub1JlZmFjdG9yLFxuICBhcHBseVJlZmFjdG9yRGVjaXNpb24sXG4gIHBoYXNlRW1vamksXG4gIHBoYXNlRGVzY3JpcHRpb24sXG4gIHBoYXNlR3VpZGVsaW5lcyxcbiAgdHlwZSBDeWNsZVN0YXRlLFxuICB0eXBlIFJlZmFjdG9yRGVjaXNpb24sXG59IGZyb20gXCIuL3N0YXRlLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50IH0gZnJvbSBcIi4vdWkuanNcIjtcblxuLy8g4pSA4pSAIFN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5sZXQgc3RhdGU6IEN5Y2xlU3RhdGUgPSBjcmVhdGVJbml0aWFsU3RhdGUoKTtcblxuZnVuY3Rpb24gcGVyc2lzdFN0YXRlKCk6IHZvaWQge1xuICBwaS5hcHBlbmRFbnRyeShcInRkZC1jeWNsZVwiLCB7XG4gICAgcGhhc2U6IHN0YXRlLnBoYXNlLFxuICAgIHRlc3REZXNjcmlwdGlvbjogc3RhdGUudGVzdERlc2NyaXB0aW9uLFxuICAgIHRlc3RzUmFuOiBzdGF0ZS50ZXN0c1JhbixcbiAgICB0ZXN0c1Bhc3NlZDogc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgdGVzdHNXcml0dGVuOiBzdGF0ZS50ZXN0c1dyaXR0ZW4sXG4gICAgbGFzdERlY2lzaW9uOiBzdGF0ZS5sYXN0RGVjaXNpb24sXG4gICAgY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbjogc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbixcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlc3RvcmVTdGF0ZShjdHg6IEV4dGVuc2lvbkNvbnRleHQpOiB2b2lkIHtcbiAgY29uc3QgZW50cmllcyA9IGN0eC5zZXNzaW9uTWFuYWdlci5nZXRFbnRyaWVzKCk7XG4gIGNvbnN0IHRkZEVudHJ5ID0gZW50cmllc1xuICAgIC5maWx0ZXIoXG4gICAgICAoZTogeyB0eXBlOiBzdHJpbmc7IGN1c3RvbVR5cGU/OiBzdHJpbmcgfSkgPT5cbiAgICAgICAgZS50eXBlID09PSBcImN1c3RvbVwiICYmIGUuY3VzdG9tVHlwZSA9PT0gXCJ0ZGQtY3ljbGVcIixcbiAgICApXG4gICAgLnBvcCgpIGFzIHsgZGF0YT86IFBhcnRpYWw8Q3ljbGVTdGF0ZT4gfSB8IHVuZGVmaW5lZDtcblxuICBpZiAodGRkRW50cnk/LmRhdGEpIHtcbiAgICBzdGF0ZSA9IHtcbiAgICAgIC4uLmNyZWF0ZUluaXRpYWxTdGF0ZSgpLFxuICAgICAgLi4udGRkRW50cnkuZGF0YSxcbiAgICB9O1xuICB9XG59XG5cbi8vIOKUgOKUgCBIZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBzdGF0dXNNZXNzYWdlKCk6IHN0cmluZyB7XG4gIHJldHVybiBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbn1cblxuZnVuY3Rpb24gZ3VpZGVsaW5lc01lc3NhZ2UoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG59XG5cbi8vIOKUgOKUgCBFeHRlbnNpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRkZEN5Y2xlKHBpOiBFeHRlbnNpb25BUEkpOiB2b2lkIHtcbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLWdyZWVuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1ncmVlblwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIEdyZWVuXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB0byB2ZXJpZnkgaW1wbGVtZW50YXRpb24uIElmIHRlc3RzIHBhc3MsIHRyYW5zaXRpb25zIHRvIEdSRUVOIHBoYXNlLiBcIiArXG4gICAgICBcIklmIHRlc3RzIGZhaWwsIHN0YXlzIGluIFJFRCB3aXRoIGZlZWRiYWNrLiBVc2UgdGhpcyBhZnRlciB3cml0aW5nIGEgZmFpbGluZyB0ZXN0IGFuZCBpdHMgaW1wbGVtZW50YXRpb24uXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgdGVzdERlc2NyaXB0aW9uOiBUeXBlLk9wdGlvbmFsKFxuICAgICAgICBUeXBlLlN0cmluZyh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIkJyaWVmIGRlc2NyaXB0aW9uIG9mIHdoYXQgdGVzdChzKSB0byBydW4gKGUuZy4sICd1c2VyIGxvZ2luIHRlc3QnKS4gXCIgK1xuICAgICAgICAgICAgXCJVc2VkIGZvciBkaXNwbGF5IHB1cnBvc2VzLlwiLFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgfSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgdGVzdERlc2MgPSBwYXJhbXMudGVzdERlc2NyaXB0aW9uID8/IHN0YXRlLnRlc3REZXNjcmlwdGlvbjtcblxuICAgICAgLy8gVXBkYXRlIHRlc3QgZGVzY3JpcHRpb24gaWYgcHJvdmlkZWRcbiAgICAgIGlmICh0ZXN0RGVzYykge1xuICAgICAgICBzdGF0ZS50ZXN0RGVzY3JpcHRpb24gPSB0ZXN0RGVzYztcbiAgICAgIH1cblxuICAgICAgLy8gU2hvdyBzdGF0dXNcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgLy8gUnVuIHRlc3RzIHZpYSBiYXNoXG4gICAgICBjb25zdCB0ZXN0Q29tbWFuZCA9IFwibnBtIHRlc3QgMj4mMVwiO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgdGVzdENvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbDogY3R4LnNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuXG4gICAgICAvLyBSZWNvcmQgcmVzdWx0IGFuZCBnZXQgdHJhbnNpdGlvblxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIC8vIFVwZGF0ZSB3aWRnZXRcbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgLy8gSWYgdHJhbnNpdGlvbmVkIHRvIEdSRUVOLCBub3RpZnkgZGV2ZWxvcGVyXG4gICAgICBpZiAodHJhbnNpdGlvbi5zdGF0ZS5waGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICBg8J+foiAqKkdSRUVOIFBIQVNFIEFDSElFVkVEISoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGAke3RyYW5zaXRpb24ubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgYFRoZSBkZXZlbG9wZXIgbXVzdCBub3cgZGVjaWRlIHdoYXQgdG8gcmVmYWN0b3IuXFxuYCArXG4gICAgICAgICAgICAgIGBVc2UgKipnby10by1yZWZhY3RvcioqIHRvIGVudGVyIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBwaGFzZS5gLFxuICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgdHJpZ2dlclR1cm46IGZhbHNlIH0sXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJUZXN0cyBleGVjdXRlZC5cIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGFzc2VkLFxuICAgICAgICAgIHBoYXNlOiB0cmFuc2l0aW9uLnN0YXRlLnBoYXNlLFxuICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICBvdXRwdXQ6IHJlc3VsdC5zdGRvdXQuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgdGV4dCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJnby10by1ncmVlbiBcIikpICsgKGFyZ3MudGVzdERlc2NyaXB0aW9uID8gdGhlbWUuZmcoXCJtdXRlZFwiLCBhcmdzLnRlc3REZXNjcmlwdGlvbikgOiBcIlwiKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBhc3NlZD86IGJvb2xlYW47IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIGAke3BoYXNlfSBUZXN0cyBwYXNzZWRgKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgYCR7cGhhc2V9IFRlc3RzIGZhaWxlZGApO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLXJlZmFjdG9yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1yZWZhY3RvclwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIFJlZmFjdG9yXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciB3aWxsIGJlIHByb21wdGVkIHRvIGNob29zZSBcIiArXG4gICAgICBcIndoYXQgdG8gcmVmYWN0b3I6IHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgbmV4dCB0ZXN0LCBvciBjdXN0b20gaW5zdHJ1Y3Rpb24uIFwiICtcbiAgICAgIFwiT25seSBjYWxsIHRoaXMgd2hlbiB0ZXN0cyBhcmUgcGFzc2luZyAoR1JFRU4gcGhhc2UpLlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgaWYgKHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgQ2Fubm90IGVudGVyIFJFRkFDVE9SIGZyb20gcGhhc2UgJHtzdGF0ZS5waGFzZX0uIE11c3QgYmUgaW4gR1JFRU4gcGhhc2UgKHRlc3RzIHBhc3NpbmcpLmAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogc3RhdGUucGhhc2UgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gVHJhbnNpdGlvbiB0byBSRUZBQ1RPUlxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4gICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgLy8gU2hvdyBzdGF0dXMgd2lkZ2V0XG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgXSk7XG5cbiAgICAgIC8vIFNob3cgZGV2ZWxvcGVyIGRlY2lzaW9uIHByb21wdFxuICAgICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiICYmIGN0eC5oYXNVSSkge1xuICAgICAgICBjb25zdCBkZWNpc2lvbiA9IGF3YWl0IGN0eC51aS5jdXN0b208UmVmYWN0b3JEZWNpc2lvbiB8IG51bGw+KFxuICAgICAgICAgIGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQoc3RhdGUudGVzdERlc2NyaXB0aW9uKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAgICAgLy8gU2VuZCBtZXNzYWdlIHRvIExMTSBhYm91dCB0aGUgZGVjaXNpb25cbiAgICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGVcIixcbiAgICAgICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgICAgICBg8J+UgCAqKlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQ6KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgJHthcHBseVJlc3VsdC5tZXNzYWdlfVxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGBDdXJyZW50IHBoYXNlOiAqKlJFRCoqIOKAlCBXcml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3QuXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgKHN0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb25cbiAgICAgICAgICAgICAgICAgID8gYCoqQ3VzdG9tIHJlZmFjdG9yaW5nIGluc3RydWN0aW9uOioqXFxuXFxgXFxgXFxgXFxuJHtzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9ufVxcblxcYFxcYFxcYFxcblxcbmBcbiAgICAgICAgICAgICAgICAgIDogXCJcIikgK1xuICAgICAgICAgICAgICAgIGd1aWRlbGluZXNNZXNzYWdlKCksXG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyB0cmlnZ2VyVHVybjogdHJ1ZSB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogYXBwbHlSZXN1bHQubWVzc2FnZSA/PyBcIlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgICBkZWNpc2lvbixcbiAgICAgICAgICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRGV2ZWxvcGVyIGNhbmNlbGxlZCDigJQgc3RheSBpbiBSRUZBQ1RPUlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIkRldmVsb3BlciBjYW5jZWxsZWQuIFN0YXlpbmcgaW4gUkVGQUNUT1IgcGhhc2UuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogXCJSRUZBQ1RPUlwiIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBOb24tVFVJIG1vZGU6IGp1c3QgdHJhbnNpdGlvblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogdHJhbnNpdGlvbi5tZXNzYWdlID8/IFwiRW50ZXJlZCBSRUZBQ1RPUiBwaGFzZS5cIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiB0cmFuc2l0aW9uLnN0YXRlLnBoYXNlIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChfYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcImdvLXRvLXJlZmFjdG9yXCIpKSwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwaGFzZT86IHN0cmluZzsgZGVjaXNpb24/OiBSZWZhY3RvckRlY2lzaW9uIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIGNvbnN0IHRleHQgPSBkZXRhaWxzLmRlY2lzaW9uXG4gICAgICAgID8gYCR7cGhhc2V9IFJlZmFjdG9yZWQ6ICR7ZGV0YWlscy5kZWNpc2lvbi5mb2N1c31gXG4gICAgICAgIDogYCR7cGhhc2V9IEVudGVyZWQgcmVmYWN0b3IgcGhhc2VgO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBUb29sOiBydW4tdGVzdHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcInJ1bi10ZXN0c1wiLFxuICAgIGxhYmVsOiBcIlJ1biBUZXN0c1wiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJSdW4gdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uLiBVc2VmdWwgZm9yIGNoZWNraW5nIHRlc3Qgc3RhdHVzIFwiICtcbiAgICAgIFwiZHVyaW5nIGRldmVsb3BtZW50LiBSZXR1cm5zIGV4aXQgY29kZSBhbmQgb3V0cHV0LlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHtcbiAgICAgIGNvbW1hbmQ6IFR5cGUuT3B0aW9uYWwoXG4gICAgICAgIFR5cGUuU3RyaW5nKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogXCJDdXN0b20gdGVzdCBjb21tYW5kIHRvIHJ1biAoZGVmYXVsdDogJ25wbSB0ZXN0JykuXCIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGNvbnN0IGNvbW1hbmQgPSBwYXJhbXMuY29tbWFuZCA/PyBcIm5wbSB0ZXN0XCI7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCBjb21tYW5kXSwge1xuICAgICAgICBzaWduYWwsXG4gICAgICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHtwYXNzZWQgPyBcIuKck1wiIDogXCLinJdcIn0gVGVzdHMgJHtwYXNzZWQgPyBcInBhc3NlZFwiIDogXCJmYWlsZWRcIn0gKGV4aXQgY29kZTogJHtyZXN1bHQuY29kZX0pYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGFzc2VkLFxuICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICBvdXRwdXQ6IHJlc3VsdC5zdGRvdXQuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgICBzdGRlcnI6IHJlc3VsdC5zdGRlcnIuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgdGV4dCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJydW4tdGVzdHMgXCIpKSArIChhcmdzLmNvbW1hbmQgPyB0aGVtZS5mZyhcIm11dGVkXCIsIGFyZ3MuY29tbWFuZCkgOiB0aGVtZS5mZyhcIm11dGVkXCIsIFwibnBtIHRlc3RcIikpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGFzc2VkPzogYm9vbGVhbiB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0dXMgPSBkZXRhaWxzLnBhc3NlZFxuICAgICAgICA/IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKckyBUZXN0cyBwYXNzZWRcIilcbiAgICAgICAgOiB0aGVtZS5mZyhcImVycm9yXCIsIFwi4pyXIFRlc3RzIGZhaWxlZFwiKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dChzdGF0dXMsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBUb29sOiB0ZGQtc3RhdHVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJ0ZGQtc3RhdHVzXCIsXG4gICAgbGFiZWw6IFwiVEREIFN0YXR1c1wiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJTaG93IGN1cnJlbnQgVEREIGN5Y2xlIHBoYXNlIGFuZCBzdGF0ZS4gUmV0dXJucyB0aGUgY3VycmVudCBwaGFzZSwgXCIgK1xuICAgICAgXCJ0ZXN0IGNvdW50LCBhbmQgZ3VpZGVsaW5lcyBmb3Igd2hhdCB0byBkbyBuZXh0LlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3Qgc3RhdHVzID0gcGhhc2VEZXNjcmlwdGlvbihzdGF0ZSk7XG4gICAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICAgIGNvbnN0IHRlc3RzV3JpdHRlbiA9IHN0YXRlLnRlc3RzV3JpdHRlbiA/PyAwO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXMpLFxuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJkaW1cIiwgYFRlc3RzIHdyaXR0ZW46ICR7dGVzdHNXcml0dGVufWApLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3N0YXR1c31cXG5cXG5UZXN0cyB3cml0dGVuOiAke3Rlc3RzV3JpdHRlbn1cXG5cXG4ke2d1aWRlbGluZXN9YCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGhhc2U6IHN0YXRlLnBoYXNlLFxuICAgICAgICAgIHRlc3RzUmFuOiBzdGF0ZS50ZXN0c1JhbixcbiAgICAgICAgICB0ZXN0c1Bhc3NlZDogc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgICAgICAgdGVzdHNXcml0dGVuLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoX2FyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJ0ZGQtc3RhdHVzXCIpKSwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwaGFzZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICByZXR1cm4gbmV3IFRleHQoYCR7cGhhc2V9ICR7ZGV0YWlscy5waGFzZX1gLCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgRXZlbnRzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8vIFJlc3RvcmUgc3RhdGUgb24gc2Vzc2lvbiBzdGFydFxuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcblxuICAgIC8vIEluamVjdCBwaGFzZSBndWlkZWxpbmVzIGludG8gc3lzdGVtIHByb21wdFxuICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIikge1xuICAgICAgY3R4LnVpLm5vdGlmeShgVEREIEN5Y2xlIHN0YXJ0ZWQgaW4gJHtzdGF0ZS5waGFzZX0gcGhhc2VgLCBcImluZm9cIik7XG4gICAgfVxuICB9KTtcblxuICAvLyBCbG9jayBkaXJlY3QgUkVEIOKGkiBSRUZBQ1RPUiB0cmFuc2l0aW9uc1xuICBwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1yZWZhY3RvclwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlLiBZb3UgbXVzdCBmaXJzdCBtYWtlIHRlc3RzIHBhc3MgKEdSRUVOIHBoYXNlKS4gQ2FsbCBnby10by1ncmVlbiBhZnRlciB5b3VyIGltcGxlbWVudGF0aW9uIHBhc3NlcyB0aGUgdGVzdC5gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVGQUNUT1JcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1ncmVlblwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIEdSRUVOIGZyb20gUkVGQUNUT1IgcGhhc2UuIENvbXBsZXRlIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBmaXJzdC5gLFxuICAgICAgfTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEluamVjdCBwaGFzZSBndWlkZWxpbmVzIGJlZm9yZSBhZ2VudCBzdGFydHNcbiAgcGkub24oXCJiZWZvcmVfYWdlbnRfc3RhcnRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlOiB7XG4gICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlLWd1aWRlbGluZXNcIixcbiAgICAgICAgY29udGVudDogYFxcblxcbltUREQgQ1lDTEUgLSAke3N0YXRlLnBoYXNlfSBQSEFTRV1cXG4ke2d1aWRlbGluZXNNZXNzYWdlKCl9YCxcbiAgICAgICAgZGlzcGxheTogZmFsc2UsXG4gICAgICB9LFxuICAgIH07XG4gIH0pO1xuXG4gIC8vIFVwZGF0ZSBzdGF0dXMgb24gdHVybiBlbmRcbiAgcGkub24oXCJ0dXJuX2VuZFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcbiAgfSk7XG5cbiAgLy8gU2F2ZSBzdGF0ZSBvbiBzaHV0ZG93blxuICBwaS5vbihcInNlc3Npb25fc2h1dGRvd25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIHBlcnNpc3RTdGF0ZSgpO1xuICB9KTtcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODMwMDU1OX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImMyNzczZjdhIiwicGFyZW50SWQiOiI4ZTY3MDFjYiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6Mzk6NTguMDc4WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiSSBzZWUgdGhlIGlzc3VlIGNsZWFybHkgbm93LiBUaGUgYHN0YXRlYCwgYHBlcnNpc3RTdGF0ZWAsIGByZXN0b3JlU3RhdGVgLCBgc3RhdHVzTWVzc2FnZWAsIGFuZCBgZ3VpZGVsaW5lc01lc3NhZ2VgIGFyZSBhbGwgZGVmaW5lZCBhdCBtb2R1bGUgbGV2ZWwgKG91dHNpZGUgdGhlIGZhY3RvcnkgZnVuY3Rpb24pLiBUaGV5IHJlZmVyZW5jZSBgcGlgIHdoaWNoIGlzIG9ubHkgYXZhaWxhYmxlIGluc2lkZSB0aGUgZmFjdG9yeSBmdW5jdGlvbi5cblxuVGhlIGZpeCBpcyB0byBtb3ZlIGFsbCBvZiB0aGVzZSBpbnNpZGUgdGhlIGZhY3RvcnkgZnVuY3Rpb24uIExldCBtZSByZXdyaXRlIHRoZSBmaWxlIHdpdGggZXZlcnl0aGluZyBwcm9wZXJseSBzY29wZWQgaW5zaWRlIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiRXZlcnl0aGluZyBuZWVkcyB0byBiZSBpbnNpZGUgdGhlIGZhY3RvcnkgZnVuY3Rpb24gdG8gY2FwdHVyZSBgcGlgLiBMZXQgbWUgcmVzdHJ1Y3R1cmU6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJvMG1MUE5BZzl5YU1MclhIa25GWjZuMHl6eFA3VVhXNCIsIm5hbWUiOiJ3cml0ZSIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwiY29udGVudCI6Ii8qKlxuICogVEREIEN5Y2xlIEV4dGVuc2lvblxuICpcbiAqIEVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgVEREIGN5Y2xlOlxuICogICDwn5S0IFJFRCAgICDihpIgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzc1xuICogICDwn5+iIEdSRUVOICDihpIgVGVzdHMgcGFzcywgcmVhZHkgZm9yIHJlZmFjdG9yaW5nXG4gKiAgIPCflIAgUkVGQUNUT1Ig4oaSIERldmVsb3BlciBjaG9vc2VzIHdoYXQgdG8gcmVmYWN0b3JcbiAqXG4gKiBBZnRlciByZWZhY3RvcmluZywgdGhlIGN5Y2xlIHJlcGVhdHM6IGJhY2sgdG8gUkVEIGZvciB0aGUgbmV4dCB0ZXN0LlxuICpcbiAqIFRvb2xzOlxuICogICBnby10by1ncmVlbiAgICAgLSBSdW4gdGVzdHMgYW5kIHRyYW5zaXRpb24gYmFzZWQgb24gcmVzdWx0XG4gKiAgIGdvLXRvLXJlZmFjdG9yICAtIEVudGVyIHRoZSBkZXZlbG9wZXIgZGVjaXNpb24gcGhhc2VcbiAqICAgcnVuLXRlc3RzICAgICAgIC0gUnVuIHRlc3RzIHdpdGhvdXQgcGhhc2UgdHJhbnNpdGlvblxuICogICB0ZGQtc3RhdHVzICAgICAgLSBTaG93IGN1cnJlbnQgcGhhc2UgYW5kIHN0YXRlXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEksIEV4dGVuc2lvbkNvbnRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxuaW1wb3J0IHtcbiAgY3JlYXRlSW5pdGlhbFN0YXRlLFxuICByZWNvcmRUZXN0UmVzdWx0LFxuICBncmVlblRvUmVmYWN0b3IsXG4gIGFwcGx5UmVmYWN0b3JEZWNpc2lvbixcbiAgcGhhc2VFbW9qaSxcbiAgcGhhc2VEZXNjcmlwdGlvbixcbiAgcGhhc2VHdWlkZWxpbmVzLFxuICB0eXBlIEN5Y2xlU3RhdGUsXG4gIHR5cGUgUmVmYWN0b3JEZWNpc2lvbixcbn0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQgfSBmcm9tIFwiLi91aS5qc1wiO1xuXG4vLyDilIDilIAgRXh0ZW5zaW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0ZGRDeWNsZShwaTogRXh0ZW5zaW9uQVBJKTogdm9pZCB7XG4gIC8vIOKUgOKUgCBTdGF0ZSAoaW5zaWRlIGNsb3N1cmUgc28gaXQgY2FwdHVyZXMgcGkpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGxldCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IGNyZWF0ZUluaXRpYWxTdGF0ZSgpO1xuXG4gIGZ1bmN0aW9uIHBlcnNpc3RTdGF0ZSgpOiB2b2lkIHtcbiAgICBwaS5hcHBlbmRFbnRyeShcInRkZC1jeWNsZVwiLCB7XG4gICAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgICB0ZXN0RGVzY3JpcHRpb246IHN0YXRlLnRlc3REZXNjcmlwdGlvbixcbiAgICAgIHRlc3RzUmFuOiBzdGF0ZS50ZXN0c1JhbixcbiAgICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICAgIHRlc3RzV3JpdHRlbjogc3RhdGUudGVzdHNXcml0dGVuLFxuICAgICAgbGFzdERlY2lzaW9uOiBzdGF0ZS5sYXN0RGVjaXNpb24sXG4gICAgICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uOiBzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uLFxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZVN0YXRlKGN0eDogRXh0ZW5zaW9uQ29udGV4dCk6IHZvaWQge1xuICAgIGNvbnN0IGVudHJpZXMgPSBjdHguc2Vzc2lvbk1hbmFnZXIuZ2V0RW50cmllcygpO1xuICAgIGNvbnN0IHRkZEVudHJ5ID0gZW50cmllc1xuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGU6IHsgdHlwZTogc3RyaW5nOyBjdXN0b21UeXBlPzogc3RyaW5nIH0pID0+XG4gICAgICAgICAgZS50eXBlID09PSBcImN1c3RvbVwiICYmIGUuY3VzdG9tVHlwZSA9PT0gXCJ0ZGQtY3ljbGVcIixcbiAgICAgIClcbiAgICAgIC5wb3AoKSBhcyB7IGRhdGE/OiBQYXJ0aWFsPEN5Y2xlU3RhdGU+IH0gfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAodGRkRW50cnk/LmRhdGEpIHtcbiAgICAgIHN0YXRlID0ge1xuICAgICAgICAuLi5jcmVhdGVJbml0aWFsU3RhdGUoKSxcbiAgICAgICAgLi4udGRkRW50cnkuZGF0YSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc3RhdHVzTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGd1aWRlbGluZXNNZXNzYWdlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gIH1cblxuICAvLyDilIDilIAgVG9vbDogZ28tdG8tZ3JlZW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLWdyZWVuXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gR3JlZW5cIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHRvIHZlcmlmeSBpbXBsZW1lbnRhdGlvbi4gSWYgdGVzdHMgcGFzcywgdHJhbnNpdGlvbnMgdG8gR1JFRU4gcGhhc2UuIFwiICtcbiAgICAgIFwiSWYgdGVzdHMgZmFpbCwgc3RheXMgaW4gUkVEIHdpdGggZmVlZGJhY2suIFVzZSB0aGlzIGFmdGVyIHdyaXRpbmcgYSBmYWlsaW5nIHRlc3QgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbi5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICB0ZXN0RGVzY3JpcHRpb246IFR5cGUuT3B0aW9uYWwoXG4gICAgICAgIFR5cGUuU3RyaW5nKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiQnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0ZXN0KHMpIHRvIHJ1biAoZS5nLiwgJ3VzZXIgbG9naW4gdGVzdCcpLiBcIiArXG4gICAgICAgICAgICBcIlVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXCIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCB0ZXN0RGVzYyA9IHBhcmFtcy50ZXN0RGVzY3JpcHRpb24gPz8gc3RhdGUudGVzdERlc2NyaXB0aW9uO1xuXG4gICAgICBpZiAodGVzdERlc2MpIHtcbiAgICAgICAgc3RhdGUudGVzdERlc2NyaXB0aW9uID0gdGVzdERlc2M7XG4gICAgICB9XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgY29uc3QgdGVzdENvbW1hbmQgPSBcIm5wbSB0ZXN0IDI+JjFcIjtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIHRlc3RDb21tYW5kXSwge1xuICAgICAgICBzaWduYWw6IGN0eC5zaWduYWwsXG4gICAgICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgaWYgKHRyYW5zaXRpb24uc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgICAgYPCfn6IgKipHUkVFTiBQSEFTRSBBQ0hJRVZFRCEqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgJHt0cmFuc2l0aW9uLm1lc3NhZ2V9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGBUaGUgZGV2ZWxvcGVyIG11c3Qgbm93IGRlY2lkZSB3aGF0IHRvIHJlZmFjdG9yLlxcbmAgK1xuICAgICAgICAgICAgICBgVXNlICoqZ28tdG8tcmVmYWN0b3IqKiB0byBlbnRlciB0aGUgcmVmYWN0b3JpbmcgZGVjaXNpb24gcGhhc2UuYCxcbiAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHRyaWdnZXJUdXJuOiBmYWxzZSB9LFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogdHJhbnNpdGlvbi5tZXNzYWdlID8/IFwiVGVzdHMgZXhlY3V0ZWQuXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgIHBhc3NlZCxcbiAgICAgICAgICBwaGFzZTogdHJhbnNpdGlvbi5zdGF0ZS5waGFzZSxcbiAgICAgICAgICBleGl0Q29kZTogcmVzdWx0LmNvZGUsXG4gICAgICAgICAgb3V0cHV0OiByZXN1bHQuc3Rkb3V0LnNsaWNlKDAsIDUwXzAwMCksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IHRleHQgPSB0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwiZ28tdG8tZ3JlZW4gXCIpKSArIChhcmdzLnRlc3REZXNjcmlwdGlvbiA/IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy50ZXN0RGVzY3JpcHRpb24pIDogXCJcIik7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwYXNzZWQ/OiBib29sZWFuOyBwaGFzZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICBjb25zdCBzdGF0dXMgPSBkZXRhaWxzLnBhc3NlZFxuICAgICAgICA/IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBgJHtwaGFzZX0gVGVzdHMgcGFzc2VkYClcbiAgICAgICAgOiB0aGVtZS5mZyhcImVycm9yXCIsIGAke3BoYXNlfSBUZXN0cyBmYWlsZWRgKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dChzdGF0dXMsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBUb29sOiBnby10by1yZWZhY3RvciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwiZ28tdG8tcmVmYWN0b3JcIixcbiAgICBsYWJlbDogXCJHbyB0byBSZWZhY3RvclwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJFbnRlciB0aGUgUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgd2lsbCBiZSBwcm9tcHRlZCB0byBjaG9vc2UgXCIgK1xuICAgICAgXCJ3aGF0IHRvIHJlZmFjdG9yOiB0ZXN0cywgaW1wbGVtZW50YXRpb24sIG5leHQgdGVzdCwgb3IgY3VzdG9tIGluc3RydWN0aW9uLiBcIiArXG4gICAgICBcIk9ubHkgY2FsbCB0aGlzIHdoZW4gdGVzdHMgYXJlIHBhc3NpbmcgKEdSRUVOIHBoYXNlKS5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGlmIChzdGF0ZS5waGFzZSAhPT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgdGV4dDogYENhbm5vdCBlbnRlciBSRUZBQ1RPUiBmcm9tIHBoYXNlICR7c3RhdGUucGhhc2V9LiBNdXN0IGJlIGluIEdSRUVOIHBoYXNlICh0ZXN0cyBwYXNzaW5nKS5gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHN0YXRlLnBoYXNlIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiICYmIGN0eC5oYXNVSSkge1xuICAgICAgICBjb25zdCBkZWNpc2lvbiA9IGF3YWl0IGN0eC51aS5jdXN0b208UmVmYWN0b3JEZWNpc2lvbiB8IG51bGw+KFxuICAgICAgICAgIGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQoc3RhdGUudGVzdERlc2NyaXB0aW9uKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAgICAgcGkuc2VuZE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgICAgICAgYPCflIAgKipSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOioqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCR7YXBwbHlSZXN1bHQubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgQ3VycmVudCBwaGFzZTogKipSRUQqKiDigJQgV3JpdGUgdGhlIG5leHQgZmFpbGluZyB0ZXN0LlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIChzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uXG4gICAgICAgICAgICAgICAgICA/IGAqKkN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbjoqKlxcblxcYFxcYFxcYFxcbiR7c3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbn1cXG5cXGBcXGBcXGBcXG5cXG5gXG4gICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICBndWlkZWxpbmVzTWVzc2FnZSgpLFxuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgdHJpZ2dlclR1cm46IHRydWUgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IGFwcGx5UmVzdWx0Lm1lc3NhZ2UgPz8gXCJSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZGVjaXNpb24sXG4gICAgICAgICAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIkRldmVsb3BlciBjYW5jZWxsZWQuIFN0YXlpbmcgaW4gUkVGQUNUT1IgcGhhc2UuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogXCJSRUZBQ1RPUlwiIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJFbnRlcmVkIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwiZ28tdG8tcmVmYWN0b3JcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nOyBkZWNpc2lvbj86IFJlZmFjdG9yRGVjaXNpb24gfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3QgdGV4dCA9IGRldGFpbHMuZGVjaXNpb25cbiAgICAgICAgPyBgJHtwaGFzZX0gUmVmYWN0b3JlZDogJHtkZXRhaWxzLmRlY2lzaW9uLmZvY3VzfWBcbiAgICAgICAgOiBgJHtwaGFzZX0gRW50ZXJlZCByZWZhY3RvciBwaGFzZWA7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHJ1bi10ZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwicnVuLXRlc3RzXCIsXG4gICAgbGFiZWw6IFwiUnVuIFRlc3RzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb24uIFVzZWZ1bCBmb3IgY2hlY2tpbmcgdGVzdCBzdGF0dXMgXCIgK1xuICAgICAgXCJkdXJpbmcgZGV2ZWxvcG1lbnQuIFJldHVybnMgZXhpdCBjb2RlIGFuZCBvdXRwdXQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgY29tbWFuZDogVHlwZS5PcHRpb25hbChcbiAgICAgICAgVHlwZS5TdHJpbmcoe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkN1c3RvbSB0ZXN0IGNvbW1hbmQgdG8gcnVuIChkZWZhdWx0OiAnbnBtIHRlc3QnKS5cIixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH0pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIGNvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgICBjdHgudWkudGhlbWUuZmcocGFzc2VkID8gXCJzdWNjZXNzXCIgOiBcImVycm9yXCIsIHBhc3NlZCA/IFwi4pyTIFRlc3RzIHBhc3NlZFwiIDogXCLinJcgVGVzdHMgZmFpbGVkXCIpLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3Bhc3NlZCA/IFwi4pyTXCIgOiBcIuKcl1wifSBUZXN0cyAke3Bhc3NlZCA/IFwicGFzc2VkXCIgOiBcImZhaWxlZFwifSAoZXhpdCBjb2RlOiAke3Jlc3VsdC5jb2RlfSlgLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICAgIHN0ZGVycjogcmVzdWx0LnN0ZGVyci5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInJ1bi10ZXN0cyBcIikpICsgKGFyZ3MuY29tbWFuZCA/IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy5jb21tYW5kKSA6IHRoZW1lLmZnKFwibXV0ZWRcIiwgXCJucG0gdGVzdFwiKSk7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwYXNzZWQ/OiBib29sZWFuIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIFwi4pyTIFRlc3RzIHBhc3NlZFwiKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgXCLinJcgVGVzdHMgZmFpbGVkXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHRkZC1zdGF0dXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcInRkZC1zdGF0dXNcIixcbiAgICBsYWJlbDogXCJUREQgU3RhdHVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlNob3cgY3VycmVudCBUREQgY3ljbGUgcGhhc2UgYW5kIHN0YXRlLiBSZXR1cm5zIHRoZSBjdXJyZW50IHBoYXNlLCBcIiArXG4gICAgICBcInRlc3QgY291bnQsIGFuZCBndWlkZWxpbmVzIGZvciB3aGF0IHRvIGRvIG5leHQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCBzdGF0dXNUZXh0ID0gcGhhc2VEZXNjcmlwdGlvbihzdGF0ZSk7XG4gICAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICAgIGNvbnN0IHRlc3RzV3JpdHRlbiA9IHN0YXRlLnRlc3RzV3JpdHRlbiA/PyAwO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNUZXh0KSxcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiZGltXCIsIGBUZXN0cyB3cml0dGVuOiAke3Rlc3RzV3JpdHRlbn1gKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHtzdGF0dXNUZXh0fVxcblxcblRlc3RzIHdyaXR0ZW46ICR7dGVzdHNXcml0dGVufVxcblxcbiR7Z3VpZGVsaW5lc31gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgICAgICAgdGVzdHNSYW46IHN0YXRlLnRlc3RzUmFuLFxuICAgICAgICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICAgICAgICB0ZXN0c1dyaXR0ZW4sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChfYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInRkZC1zdGF0dXNcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIHJldHVybiBuZXcgVGV4dChgJHtwaGFzZX0gJHtkZXRhaWxzLnBoYXNlfWAsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBFdmVudHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkub24oXCJzZXNzaW9uX3N0YXJ0XCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgXSk7XG5cbiAgICBpZiAoY3R4Lm1vZGUgPT09IFwidHVpXCIpIHtcbiAgICAgIGN0eC51aS5ub3RpZnkoYFRERCBDeWNsZSBzdGFydGVkIGluICR7c3RhdGUucGhhc2V9IHBoYXNlYCwgXCJpbmZvXCIpO1xuICAgIH1cbiAgfSk7XG5cbiAgcGkub24oXCJ0b29sX2NhbGxcIiwgYXN5bmMgKGV2ZW50LCBjdHgpID0+IHtcbiAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVEXCIgJiYgZXZlbnQudG9vbE5hbWUgPT09IFwiZ28tdG8tcmVmYWN0b3JcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYmxvY2s6IHRydWUsXG4gICAgICAgIHJlYXNvbjogYENhbm5vdCBnbyB0byBSRUZBQ1RPUiBmcm9tIFJFRCBwaGFzZS4gWW91IG11c3QgZmlyc3QgbWFrZSB0ZXN0cyBwYXNzIChHUkVFTiBwaGFzZSkuIENhbGwgZ28tdG8tZ3JlZW4gYWZ0ZXIgeW91ciBpbXBsZW1lbnRhdGlvbiBwYXNzZXMgdGhlIHRlc3QuYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLnBoYXNlID09PSBcIlJFRkFDVE9SXCIgJiYgZXZlbnQudG9vbE5hbWUgPT09IFwiZ28tdG8tZ3JlZW5cIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYmxvY2s6IHRydWUsXG4gICAgICAgIHJlYXNvbjogYENhbm5vdCBnbyB0byBHUkVFTiBmcm9tIFJFRkFDVE9SIHBoYXNlLiBDb21wbGV0ZSB0aGUgcmVmYWN0b3JpbmcgZGVjaXNpb24gZmlyc3QuYCxcbiAgICAgIH07XG4gICAgfVxuICB9KTtcblxuICBwaS5vbihcImJlZm9yZV9hZ2VudF9zdGFydFwiLCBhc3luYyAoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGUtZ3VpZGVsaW5lc1wiLFxuICAgICAgICBjb250ZW50OiBgXFxuXFxuW1RERCBDWUNMRSAtICR7c3RhdGUucGhhc2V9IFBIQVNFXVxcbiR7Z3VpZGVsaW5lc01lc3NhZ2UoKX1gLFxuICAgICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfSk7XG5cbiAgcGkub24oXCJ0dXJuX2VuZFwiLCBhc3luYyAoX2V2ZW50LCBjdHgpID0+IHtcbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcbiAgfSk7XG5cbiAgcGkub24oXCJzZXNzaW9uX3NodXRkb3duXCIsIGFzeW5jICgpID0+IHtcbiAgICBwZXJzaXN0U3RhdGUoKTtcbiAgfSk7XG59XG4ifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjQwMDgsIm91dHB1dCI6MzgzMywiY2FjaGVSZWFkIjoxMDA3ODEsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMDg2MjIsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODMwMDU2MCwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLUx5VlpBUnRub2RKdVpCUFZrcUFIUmsxN1p5M2g4TWM5In19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImM4ZGEwZTZkIiwicGFyZW50SWQiOiJjMjc3M2Y3YSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6Mzk6NTguMTMzWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoibzBtTFBOQWc5eWFNTHJYSGtuRlo2bjB5enhQN1VYVzQiLCJ0b29sTmFtZSI6IndyaXRlIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHdyb3RlIDEzNzcyIGJ5dGVzIHRvIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODM5ODEzM319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImJmNzE4YjZmIiwicGFyZW50SWQiOiJjOGRhMGU2ZCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDA6MjQuOTAzWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IGxldCBtZSB2ZXJpZnkgdHlwZWNoZWNrIGFuZCB0ZXN0cyBzdGlsbCBwYXNzLCB0aGVuIHJlLXJ1biB0aGUgbGl2ZSB0ZXN0OlxuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmdfY29udGVudCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJXb2o4dGFnQ1owRHBiTzN4bjdyRW1zYnE4TG5pTTFBNSIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBucG0gcnVuIHR5cGVjaGVjayAyPiYxICYmIG5wbSBydW4gdGVzdCAyPiYxIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJsbGFtYS5jcHAiLCJtb2RlbCI6IlF3ZW4zLjYtMzVCLUEzQi1NWEZQNF9NT0UuZ2d1ZiIsInVzYWdlIjp7ImlucHV0IjozODc5LCJvdXRwdXQiOjc5LCJjYWNoZVJlYWQiOjEwNDc4NSwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEwODc0MywiY29zdCI6eyJpbnB1dCI6MCwib3V0cHV0IjowLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4Mzk4MTM0LCJyZXNwb25zZUlkIjoiY2hhdGNtcGwtME1sdDVxM0w5b0pQVUVhUG40S05PNEVPVjNaOGxFRDkifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDdiNGIzN2MiLCJwYXJlbnRJZCI6ImJmNzE4YjZmIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0MDoyNi41MjdaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJXb2o4dGFnQ1owRHBiTzN4bjdyRW1zYnE4TG5pTTFBNSIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlxuPiBwaS10ZGQtY3ljbGVAMC4xLjAgdHlwZWNoZWNrXG4+IHRzYyAtLW5vRW1pdFxuXG5cbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHRlc3Rcbj4gdml0ZXN0IHJ1blxuXG5cbiBSVU4gIHY0LjEuOSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZVxuXG5cbiBUZXN0IEZpbGVzICAxIHBhc3NlZCAoMSlcbiAgICAgIFRlc3RzICAyOSBwYXNzZWQgKDI5KVxuICAgU3RhcnQgYXQgIDEwOjQwOjI2XG4gICBEdXJhdGlvbiAgMTA2bXMgKHRyYW5zZm9ybSAyMG1zLCBzZXR1cCAwbXMsIGltcG9ydCAyOG1zLCB0ZXN0cyA0bXMsIGVudmlyb25tZW50IDBtcylcblxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ4NDI2NTI3fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiY2JjYjUwNTYiLCJwYXJlbnRJZCI6ImQ3YjRiMzdjIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0MDozNS45MzBaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJDbGVhbi4gTm93IGxldCBtZSByZS1ydW4gdGhlIGxpdmUgdGVzdDpcbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkNsZWFuLiBMZXQgbWUgcmV0cnkgdGhlIGxpdmUgdGVzdDpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6IlpPeUdtNllVTndtdVVFdU92WXVSNGU5dTYyNmNRMUpJIiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC90bXAgJiYgcm0gLXJmIHBpLXRkZC10ZXN0ICYmIG1rZGlyIHBpLXRkZC10ZXN0ICYmIGNkIHBpLXRkZC10ZXN0ICYmIG5wbSBpbml0IC15IDI+JjEgJiYgY2F0ID4gdHNjb25maWcuanNvbiA8PCAnRU9GJ1xue1wiY29tcGlsZXJPcHRpb25zXCI6e1widGFyZ2V0XCI6XCJFUzIwMjJcIixcIm1vZHVsZVwiOlwiTm9kZU5leHRcIixcIm1vZHVsZVJlc29sdXRpb25cIjpcIk5vZGVOZXh0XCIsXCJzdHJpY3RcIjp0cnVlLFwianN4XCI6XCJyZWFjdFwiLFwiZXNNb2R1bGVJbnRlcm9wXCI6dHJ1ZSxcInNraXBMaWJDaGVja1wiOnRydWUsXCJmb3JjZUNvbnNpc3RlbnRDYXNpbmdJbkZpbGVOYW1lc1wiOnRydWV9fVxuRU9GXG5waSAtZSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMgXCJJIHdhbnQgYW4gZW1wdHkgdmVuZGluZ21hY2hpbmUgdGhhdCBkZWxpdmVycyBDYW4uTm90aGluZyAoZW51bSBvciBzbyBpbiB0eXBlc2NyaXB0KSB3aGVuIGNob29zaW5nIGEgQ2hvaWNlLkNvbGEgKGFsc28gZW51bSkuIFdoYXQgaXMgdGhlIG5leHQgc3RlcCB1c2luZyB0aGUgdGRkIGN5Y2xlPyBcIiAyPiYxIiwidGltZW91dCI6MTIwfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6ImxsYW1hLmNwcCIsIm1vZGVsIjoiUXdlbjMuNi0zNUItQTNCLU1YRlA0X01PRS5nZ3VmIiwidXNhZ2UiOnsiaW5wdXQiOjE1Miwib3V0cHV0IjoyMjksImNhY2hlUmVhZCI6MTA4NzQyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTA5MTIzLCJjb3N0Ijp7ImlucHV0IjowLCJvdXRwdXQiOjAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjB9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDg0MjY1MjgsInJlc3BvbnNlSWQiOiJjaGF0Y21wbC01TkJ3dXYxejZnNXZOZllpTUUzczJLTWdmWDRGM2dLMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI2MmZmMDdlYSIsInBhcmVudElkIjoiY2JjYjUwNTYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQxOjI5LjU0NloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6IlpPeUdtNllVTndtdVVFdU92WXVSNGU5dTYyNmNRMUpJIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiV3JvdGUgdG8gL3ByaXZhdGUvdG1wL3BpLXRkZC10ZXN0L3BhY2thZ2UuanNvbjpcblxue1xuICBcIm5hbWVcIjogXCJwaS10ZGQtdGVzdFwiLFxuICBcInZlcnNpb25cIjogXCIxLjAuMFwiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiXCIsXG4gIFwibWFpblwiOiBcImluZGV4LmpzXCIsXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJ0ZXN0XCI6IFwiZWNobyBcXFwiRXJyb3I6IG5vIHRlc3Qgc3BlY2lmaWVkXFxcIiAmJiBleGl0IDFcIlxuICB9LFxuICBcImtleXdvcmRzXCI6IFtdLFxuICBcImF1dGhvclwiOiBcIlwiLFxuICBcImxpY2Vuc2VcIjogXCJJU0NcIixcbiAgXCJ0eXBlXCI6IFwiY29tbW9uanNcIlxufVxuXG5cbkhlcmUncyB3aGF0IGhhcHBlbmVkOlxuXG4qKlJFRCBQaGFzZSoqIOKAlCBJIHdyb3RlIGEgZmFpbGluZyB0ZXN0IGZpcnN0LCB0aGVuIGltcGxlbWVudGVkIHRoZSBtaW5pbWFsIGNvZGUgdG8gbWFrZSBpdCBwYXNzOlxuLSBgc3JjL2Nob2ljZS50c2Ag4oCUIGBDaG9pY2VgIGVudW0gd2l0aCBgQ29sYWBcbi0gYHNyYy9jYW4udHNgIOKAlCBgQ2FuYCBlbnVtIHdpdGggYE5vdGhpbmdgXG4tIGBzcmMvdmVuZGluZy1tYWNoaW5lLnRzYCDigJQgYFZlbmRpbmdNYWNoaW5lYCBjbGFzcyB3aG9zZSBgY2hvb3NlKClgIHJldHVybnMgYENhbi5Ob3RoaW5nYFxuXG4qKkdSRUVOIFBoYXNlKiog4oCUIFRlc3RzIHBhc3Mg4pyFXG5cbioqTmV4dCBzdGVwOiBSRUZBQ1RPUioqIOKAlCBOb3cgeW91IGhhdmUgb3B0aW9uczpcbjEuICoqUmVmYWN0b3IgdGhlIHRlc3QqKiDigJQgaW1wcm92ZSBpdHMgc3RydWN0dXJlIG9yIGFkZCBtb3JlIHRlc3QgY2FzZXNcbjIuICoqUmVmYWN0b3IgdGhlIGltcGxlbWVudGF0aW9uKiog4oCUIGNsZWFuIHVwIGNvZGUsIGV4dHJhY3QgbG9naWNcbjMuICoqV3JpdGUgdGhlIG5leHQgdGVzdCoqIOKAlCBhZGQgbW9yZSBiZWhhdmlvciAoZS5nLiwgb3RoZXIgY2hvaWNlcywgc3RvY2sgbWFuYWdlbWVudClcbjQuICoqQ3VzdG9tIGluc3RydWN0aW9uKiog4oCUIHNvbWV0aGluZyBlbHNlIGVudGlyZWx5XG5cbldoZW4geW91J3JlIHJlYWR5IHRvIGNob29zZSwgY2FsbCBgZ28tdG8tcmVmYWN0b3JgLlxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ4NDg5NTQ2fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYTIxOTkxYWIiLCJwYXJlbnRJZCI6IjYyZmYwN2VhIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0MjowMC4zODRaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgZXh0ZW5zaW9uIGxvYWRlZCBhbmQgd29ya2VkIHdpdGhvdXQgZXJyb3JzLiBUaGUgYWdlbnQgcmVjZWl2ZWQgdGhlIFRERCBjeWNsZSBndWlkZWxpbmVzIGFuZCBwcm9kdWNlZCBhIHJlc3BvbnNlLiBCdXQgaXQgc2VlbXMgbGlrZSB0aGUgYWdlbnQgZGlkbid0IGFjdHVhbGx5IGNhbGwgdGhlIGBnby10by1ncmVlbmAgdG9vbCDigJQgaXQganVzdCB3cm90ZSBjb2RlIGFuZCByYW4gdGVzdHMgdmlhIGJhc2guIFRoZSBleHRlbnNpb24ncyBgYmVmb3JlX2FnZW50X3N0YXJ0YCBob29rIGluamVjdGVkIHRoZSBUREQgZ3VpZGVsaW5lcywgYW5kIHRoZSBhZ2VudCBmb2xsb3dlZCB0aGVtLlxuXG5MZXQgbWUgY2hlY2sgaWYgdGhlIGV4dGVuc2lvbidzIHN0YXRlIHdhcyBwcm9wZXJseSB0cmFja2VkLiBUaGUgYWdlbnQgd3JvdGUgY29kZSBhbmQgcmFuIHRlc3RzLCBidXQgdGhlIGV4dGVuc2lvbidzIGBnby10by1ncmVlbmAgdG9vbCB3YXMgbmV2ZXIgY2FsbGVkLiBUaGUgYWdlbnQgcmFuIHRlc3RzIGRpcmVjdGx5IHZpYSBiYXNoIGFuZCBjb25jbHVkZWQgdGhlIGN5Y2xlLlxuXG5UaGlzIGlzIGFjdHVhbGx5IGEgZ29vZCBzaWduIOKAlCB0aGUgZXh0ZW5zaW9uIGxvYWRlZCwgdGhlIGd1aWRlbGluZXMgd2VyZSBpbmplY3RlZCwgYW5kIHRoZSBhZ2VudCBmb2xsb3dlZCB0aGUgVEREIGN5Y2xlLiBUaGUgXCJFeHRlbnNpb24gZXJyb3I6IHBpIGlzIG5vdCBkZWZpbmVkXCIgZXJyb3IgZnJvbSBiZWZvcmUgaXMgZ29uZS5cblxuTGV0IG1lIHRlbGwgdGhlIHVzZXIgdGhlIHJlc3VsdHMgYW5kIHN1Z2dlc3QgbmV4dCBzdGVwcyBmb3IgdGVzdGluZy5cbiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nX2NvbnRlbnQifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vIG1vcmUgYHBpIGlzIG5vdCBkZWZpbmVkYCBlcnJvci4gVGhlIGV4dGVuc2lvbiBsb2FkZWQgY2xlYW5seSBhbmQgdGhlIGFnZW50IGZvbGxvd2VkIHRoZSBUREQgY3ljbGUgZ3VpZGVsaW5lczpcblxuLSAqKlJFRCoqIOKGkiB3cm90ZSBmYWlsaW5nIHRlc3QgKyBtaW5pbWFsIGltcGxlbWVudGF0aW9uXG4tICoqR1JFRU4qKiDihpIgdGVzdHMgcGFzc1xuLSAqKlJFRkFDVE9SKiog4oaSIGFnZW50IHByZXNlbnRlZCB0aGUgNCBvcHRpb25zXG5cblRoZSBhZ2VudCBkaWRuJ3QgY2FsbCBgZ28tdG8tZ3JlZW5gIHRob3VnaCDigJQgaXQgcmFuIHRlc3RzIHZpYSBgYmFzaGAgZGlyZWN0bHkgYW5kIHNlbGYtYXNzZXNzZWQuIFRoZSBgZ28tdG8tZ3JlZW5gIHRvb2wgaXMgbWVhbnQgdG8gYmUgdGhlICpnYXRlKiB0aGF0IGVuZm9yY2VzIHRoZSB0cmFuc2l0aW9uLCBidXQgdGhlIGFnZW50IGJ5cGFzc2VkIGl0IGJ5IHVzaW5nIGJhc2ggZGlyZWN0bHkuXG5cblRvIHRlc3QgdGhlIHRvb2wgZW5mb3JjZW1lbnQsIHRyeTpcblxuYGBgYmFzaFxuY2QgL3RtcC9waS10ZGQtdGVzdFxucGkgLWUgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIFwiQ29udGludWUuIENhbGwgZ28tdG8tZ3JlZW4gdG8gdmVyaWZ5IHRlc3RzIHBhc3MsIHRoZW4gY2FsbCBnby10by1yZWZhY3RvciB0byBlbnRlciB0aGUgcmVmYWN0b3IgZGVjaXNpb24gcGhhc2UuXCJcbmBgYFxuXG5UaGlzIHNob3VsZCB0cmlnZ2VyIHRoZSBhY3R1YWwgdG9vbCBmbG93OiBgZ28tdG8tZ3JlZW5gIHJ1bnMgYG5wbSB0ZXN0YCBhbmQgdHJhbnNpdGlvbnMgdGhlIHN0YXRlLCB0aGVuIGBnby10by1yZWZhY3RvcmAgc2hvd3MgdGhlIGludGVyYWN0aXZlIGRlY2lzaW9uIHByb21wdC4ifV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoibGxhbWEuY3BwIiwibW9kZWwiOiJRd2VuMy42LTM1Qi1BM0ItTVhGUDRfTU9FLmdndWYiLCJ1c2FnZSI6eyJpbnB1dCI6NTU2LCJvdXRwdXQiOjQwMCwiY2FjaGVSZWFkIjoxMDg4OTAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMDk4NDYsImNvc3QiOnsiaW5wdXQiOjAsIm91dHB1dCI6MCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MH19LCJzdG9wUmVhc29uIjoic3RvcCIsInRpbWVzdGFtcCI6MTc4MTk0ODQ4OTU0OCwicmVzcG9uc2VJZCI6ImNoYXRjbXBsLU9UdEhVbzFGeWFLNjlNSXhwZEVJVTRoOFJvSTA2TTU0In19LHsidHlwZSI6Im1vZGVsX2NoYW5nZSIsImlkIjoiYjQ3MzkwMTMiLCJwYXJlbnRJZCI6ImEyMTk5MWFiIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0MjoyMS44NDhaIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWxJZCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIn0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYWIwODU5NWEiLCJwYXJlbnRJZCI6ImI0NzM5MDEzIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0Mjo0Mi41NTdaIiwibWVzc2FnZSI6eyJyb2xlIjoidXNlciIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6InJ1biB0aGlzICBjZCAvdG1wL3BpLXRkZC10ZXN0XG4gICBwaSAtZSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMgXCJDb250aW51ZS4gQ2FsbCBnby10by1ncmVlbiB0byB2ZXJpZnkgdGVzdHMgcGFzcywgdGhlbiBjYWxsXG4gZ28tdG8tcmVmYWN0b3IgdG8gZW50ZXIgdGhlIHJlZmFjdG9yIGRlY2lzaW9uIHBoYXNlLlwiIn1dLCJ0aW1lc3RhbXAiOjE3ODE5NDg1NjI1NTV9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJkOGE3OGU4YyIsInBhcmVudElkIjoiYWIwODU5NWEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQyOjU3LjU3MloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoZSB1c2VyIHdhbnRzIG1lIHRvIHJ1biBhIGNvbW1hbmQuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF9jOWQ1YTllNzhmOGE0NGJkOWQ5YmIxMWEiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL3RtcC9waS10ZGQtdGVzdCAmJiBwaSAtZSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMgXCJDb250aW51ZS4gQ2FsbCBnby10by1ncmVlbiB0byB2ZXJpZnkgdGVzdHMgcGFzcywgdGhlbiBjYWxsIGdvLXRvLXJlZmFjdG9yIHRvIGVudGVyIHRoZSByZWZhY3RvciBkZWNpc2lvbiBwaGFzZS5cIiAyPiYxIiwidGltZW91dCI6MTIwfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEwODIzNiwib3V0cHV0IjoxMzAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEwODM2NiwiY29zdCI6eyJpbnB1dCI6MC4wMDk3NDEyNCwib3V0cHV0IjowLjAwMDAyMzQsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDA5NzY0NjR9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDg1NjI1NjAsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0ODU2Mi1mS2lCUkllZDhKbEl0TEJZWVgzeCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI2ODkwNjM0MiIsInBhcmVudElkIjoiZDhhNzhlOGMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ0OjA0LjgxM1oiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfYzlkNWE5ZTc4ZjhhNDRiZDlkOWJiMTFhIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiSGVyZSdzIGEgc3VtbWFyeSBvZiB3aGF0IGhhcHBlbmVkOlxuXG4xLiDinIUgKipnby10by1ncmVlbioqIOKAlCBJIHJhbiB0aGUgdGVzdHMgYW5kIHRoZXkgYWxsIHBhc3NlZCAoMSB0ZXN0LCAxIGZpbGUpLiBUaGUgc3lzdGVtIHJlc3BvbmRlZCB3aXRoOlxuICAgPiBcIlRlc3RzIHBhc3MhIFBoYXNlIGNoYW5nZWQ6IEdSRUVOIOKGkiBSRUZBQ1RPUi5cIlxuXG4yLiAqKmdvLXRvLXJlZmFjdG9yKiog4oCUIEkgYXR0ZW1wdGVkIHRvIGVudGVyIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBwaGFzZS4gVGhlIHN5c3RlbSByZXR1cm5lZCBcIkNhbm5vdCBnbyB0byBSRUZBQ1RPUiBmcm9tIFJFRCBwaGFzZSxcIiBsaWtlbHkgYmVjYXVzZSB0aGUgc3RhdGUgcmVzZXRzIGJldHdlZW4gY2FsbHMuIEhvd2V2ZXIsIHRoZSBgZ28tdG8tZ3JlZW5gIG91dHB1dCBhbHJlYWR5IGluZGljYXRlZCB0aGUgcGhhc2UgY2hhbmdlZCB0byAqKlJFRkFDVE9SKiouXG5cblRoZSBleGlzdGluZyB0ZXN0IHZlcmlmaWVzIHRoYXQgYFZlbmRpbmdNYWNoaW5lLmNob29zZShDaG9pY2UuQ29sYSlgIHJldHVybnMgYENhbi5Ob3RoaW5nYCwgd2hpY2ggcGFzc2VzLiBUaGUgcHJvamVjdCBpcyByZWFkeSBmb3IgdGhlIG5leHQgVEREIGN5Y2xlIOKAlCB5b3UgY2FuIG5vdyBkZWNpZGUgd2hhdCB0byByZWZhY3RvciBvciB3cml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3QuIFdoYXQgd291bGQgeW91IGxpa2UgdG8gZG8gbmV4dD9cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODY0NDgxM319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijc3ZTkxMzVlIiwicGFyZW50SWQiOiI2ODkwNjM0MiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDQ6MzQuMjM2WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiSW50ZXJlc3RpbmcgcmVzdWx0czpcblxuMS4gYGdvLXRvLWdyZWVuYCB3b3JrZWQhIEl0IHJhbiB0ZXN0cyBhbmQgaW5kaWNhdGVkIEdSRUVOIHBoYXNlLlxuMi4gYGdvLXRvLXJlZmFjdG9yYCBmYWlsZWQgYmVjYXVzZSBcIkNhbm5vdCBnbyB0byBSRUZBQ1RPUiBmcm9tIFJFRCBwaGFzZVwiIFxuXG5UaGlzIGlzIGEgYnVnLiBXaGVuIGBnby10by1ncmVlbmAgaXMgY2FsbGVkIGFuZCB0ZXN0cyBwYXNzLCBpdCB0cmFuc2l0aW9ucyB0byBHUkVFTi4gQnV0IHRoZSBgcmVjb3JkVGVzdFJlc3VsdGAgZnVuY3Rpb24gYXV0by10cmFuc2l0aW9ucyBmcm9tIFJFROKGkkdSRUVOIHdoZW4gdGVzdHMgcGFzcy4gVGhlIGlzc3VlIGlzIHRoYXQgdGhlIHN0YXRlIG1pZ2h0IGJlIGdldHRpbmcgcmVzZXQgYmV0d2VlbiB0b29sIGNhbGxzLlxuXG5Mb29raW5nIGF0IHRoZSBmbG93OlxuMS4gYGdvLXRvLWdyZWVuYCBpcyBjYWxsZWRcbjIuIEluc2lkZSBgZXhlY3V0ZWA6IGByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBwYXNzZWQpYCBpcyBjYWxsZWRcbjMuIFNpbmNlIHRlc3RzIHBhc3NlZCBhbmQgcGhhc2UgaXMgUkVELCBgcmVkVG9HcmVlbmAgaXMgY2FsbGVkLCB3aGljaCByZXR1cm5zIEdSRUVOXG40LiBgcGVyc2lzdFN0YXRlKClgIHNhdmVzIEdSRUVOIHN0YXRlXG41LiBCdXQgdGhlIG1vZHVsZS1sZXZlbCBgc3RhdGVgIHZhcmlhYmxlIGlzIHVwZGF0ZWRcblxuVGhlbjpcbjYuIGBnby10by1yZWZhY3RvcmAgaXMgY2FsbGVkXG43LiBJdCBjaGVja3MgYHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCJgIOKAlCBpZiBwaGFzZSBpcyBjb3JyZWN0bHkgR1JFRU4sIHRoaXMgc2hvdWxkIHBhc3NcbjguIEJ1dCB0aGUgYWdlbnQgc2FpZCBcIkNhbm5vdCBnbyB0byBSRUZBQ1RPUiBmcm9tIFJFRCBwaGFzZVwiXG5cblRoaXMgc3VnZ2VzdHMgdGhlIHN0YXRlIHdhcyByZXNldCBiZXR3ZWVuIHRvb2wgY2FsbHMuIFRoZSBpc3N1ZSBpcyB0aGF0IHRoZSBgc3RhdGVgIHZhcmlhYmxlIGlzIGNhcHR1cmVkIGluIHRoZSBjbG9zdXJlIG9mIHRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBidXQgYmV0d2VlbiB0b29sIGNhbGxzIGluIHRoZSBzYW1lIHNlc3Npb24sIHRoZSBmYWN0b3J5IGZ1bmN0aW9uJ3Mgc2NvcGUgc2hvdWxkIHBlcnNpc3QuXG5cbldhaXQsIGFjdHVhbGx5IHRoZSBpc3N1ZSBtaWdodCBiZSB0aGF0IGVhY2ggdG9vbCBjYWxsIHJlc3RhcnRzIHRoZSBleHRlbnNpb24sIGNyZWF0aW5nIGEgbmV3IGNsb3N1cmUuIExldCBtZSB0aGluayBhYm91dCB0aGlzLi4uXG5cbkluIFBpJ3MgZXh0ZW5zaW9uIHN5c3RlbSwgdGhlIGV4dGVuc2lvbiBmYWN0b3J5IGZ1bmN0aW9uIGlzIGNhbGxlZCBvbmNlIGF0IHN0YXJ0dXAuIFRoZSBgcGkub25gIGFuZCBgcGkucmVnaXN0ZXJUb29sYCBjYWxsYmFja3MgYWxsIHNoYXJlIHRoZSBzYW1lIGNsb3N1cmUuIFNvIGBzdGF0ZWAgc2hvdWxkIHBlcnNpc3QgYmV0d2VlbiB0b29sIGNhbGxzIHdpdGhpbiB0aGUgc2FtZSBwaSBzZXNzaW9uLlxuXG5CdXQgd2FpdCwgdGhlIGBnby10by1ncmVlbmAgZXhlY3V0ZSBmdW5jdGlvbiBjYWxscyBgcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKWAgd2hpY2ggZG9lcyBjcmVhdGUgYSBuZXcgc3RhdGUgb2JqZWN0LiBCdXQgdGhpcyBuZXcgc3RhdGUgaXMgYXNzaWduZWQgYmFjayB2aWE6XG5cbmBgYHR5cGVzY3JpcHRcbmNvbnN0IHRyYW5zaXRpb24gPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBwYXNzZWQpO1xuYGBgXG5cbkJ1dCBgdHJhbnNpdGlvbi5zdGF0ZWAgaXMgYSBuZXcgb2JqZWN0LiBUaGUgbW9kdWxlLWxldmVsIGBzdGF0ZWAgaXMgbmV2ZXIgdXBkYXRlZCB3aXRoIHRoaXMgbmV3IG9iamVjdCEgTGV0IG1lIGNoZWNrLi4uXG5cbkluIHRoZSBgZXhlY3V0ZWAgZnVuY3Rpb24sIGFmdGVyIGNhbGxpbmcgYHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZClgOlxuYGBgdHlwZXNjcmlwdFxuY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5gYGBcblxuVGhpcyByZXR1cm5zIGEgbmV3IHN0YXRlIG9iamVjdCwgYnV0IGBzdGF0ZWAgdmFyaWFibGUgc3RpbGwgcG9pbnRzIHRvIHRoZSBvbGQgb25lISBUaGUgZnVuY3Rpb24gbmV2ZXIgZG9lcyBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AuXG5cblNvIGBzdGF0ZS5waGFzZWAgaXMgc3RpbGwgXCJSRURcIiBiZWNhdXNlIHRoZSBzdGF0ZSB3YXMgbmV2ZXIgdXBkYXRlZC4gVGhpcyBpcyBhIGNyaXRpY2FsIGJ1Zy5cblxuTGV0IG1lIGZpeCB0aGlzIGJ5IHVwZGF0aW5nIGBzdGF0ZWAgYWZ0ZXIgdHJhbnNpdGlvbnMuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ikdvb2Qg4oCUIHRoZSB0b29scyByYW4gd2l0aG91dCB0aGUgYHBpYCBlcnJvciwgYnV0IHRoZXJlJ3MgYSBidWc6IGBnby10by1yZWZhY3RvcmAgc2F5cyBcIkNhbm5vdCBnbyB0byBSRUZBQ1RPUiBmcm9tIFJFRCBwaGFzZVwiLiBUaGUgaXNzdWUgaXMgdGhhdCBgcmVjb3JkVGVzdFJlc3VsdGAgcmV0dXJucyBhICpuZXcqIHN0YXRlIG9iamVjdCBidXQgdGhlIGBleGVjdXRlYCBmdW5jdGlvbiBuZXZlciBhc3NpZ25zIGl0IGJhY2sgdG8gdGhlIG1vZHVsZSBgc3RhdGVgIHZhcmlhYmxlLiBMZXQgbWUgZml4IHRoYXQ6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzFhMzg0MGJjY2VlOTRkYTA4YjVmYjAyNCIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMiLCJvZmZzZXQiOjEsImxpbWl0Ijo4MH19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMDg1NTMsIm91dHB1dCI6NzAxLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMDkyNTQsImNvc3QiOnsiaW5wdXQiOjAuMDA5NzY5NzcsIm91dHB1dCI6MC4wMDAxMjYxOCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDk4OTU5NX19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODY0NDgxNCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4NjQ0LVBpdzNTNWQ0R2huMDFCTzV5SjlSIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjVkNTcyYzMxIiwicGFyZW50SWQiOiI3N2U5MTM1ZSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDQ6MzQuMjQ5WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF8xYTM4NDBiY2NlZTk0ZGEwOGI1ZmIwMjQiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIvKipcbiAqIFRERCBDeWNsZSBFeHRlbnNpb25cbiAqXG4gKiBFbmZvcmNlcyB0aGUgcmVkLWdyZWVuLXJlZmFjdG9yIFRERCBjeWNsZTpcbiAqICAg8J+UtCBSRUQgICAg4oaSIFdyaXRlIGEgZmFpbGluZyB0ZXN0LCB0aGVuIGltcGxlbWVudCB0byBtYWtlIGl0IHBhc3NcbiAqICAg8J+foiBHUkVFTiAg4oaSIFRlc3RzIHBhc3MsIHJlYWR5IGZvciByZWZhY3RvcmluZ1xuICogICDwn5SAIFJFRkFDVE9SIOKGkiBEZXZlbG9wZXIgY2hvb3NlcyB3aGF0IHRvIHJlZmFjdG9yXG4gKlxuICogQWZ0ZXIgcmVmYWN0b3JpbmcsIHRoZSBjeWNsZSByZXBlYXRzOiBiYWNrIHRvIFJFRCBmb3IgdGhlIG5leHQgdGVzdC5cbiAqXG4gKiBUb29sczpcbiAqICAgZ28tdG8tZ3JlZW4gICAgIC0gUnVuIHRlc3RzIGFuZCB0cmFuc2l0aW9uIGJhc2VkIG9uIHJlc3VsdFxuICogICBnby10by1yZWZhY3RvciAgLSBFbnRlciB0aGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHBoYXNlXG4gKiAgIHJ1bi10ZXN0cyAgICAgICAtIFJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb25cbiAqICAgdGRkLXN0YXR1cyAgICAgIC0gU2hvdyBjdXJyZW50IHBoYXNlIGFuZCBzdGF0ZVxuICovXG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db250ZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwidHlwZWJveFwiO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZUluaXRpYWxTdGF0ZSxcbiAgcmVjb3JkVGVzdFJlc3VsdCxcbiAgZ3JlZW5Ub1JlZmFjdG9yLFxuICBhcHBseVJlZmFjdG9yRGVjaXNpb24sXG4gIHBoYXNlRW1vamksXG4gIHBoYXNlRGVzY3JpcHRpb24sXG4gIHBoYXNlR3VpZGVsaW5lcyxcbiAgdHlwZSBDeWNsZVN0YXRlLFxuICB0eXBlIFJlZmFjdG9yRGVjaXNpb24sXG59IGZyb20gXCIuL3N0YXRlLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50IH0gZnJvbSBcIi4vdWkuanNcIjtcblxuLy8g4pSA4pSAIEV4dGVuc2lvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdGRkQ3ljbGUocGk6IEV4dGVuc2lvbkFQSSk6IHZvaWQge1xuICAvLyDilIDilIAgU3RhdGUgKGluc2lkZSBjbG9zdXJlIHNvIGl0IGNhcHR1cmVzIHBpKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBsZXQgc3RhdGU6IEN5Y2xlU3RhdGUgPSBjcmVhdGVJbml0aWFsU3RhdGUoKTtcblxuICBmdW5jdGlvbiBwZXJzaXN0U3RhdGUoKTogdm9pZCB7XG4gICAgcGkuYXBwZW5kRW50cnkoXCJ0ZGQtY3ljbGVcIiwge1xuICAgICAgcGhhc2U6IHN0YXRlLnBoYXNlLFxuICAgICAgdGVzdERlc2NyaXB0aW9uOiBzdGF0ZS50ZXN0RGVzY3JpcHRpb24sXG4gICAgICB0ZXN0c1Jhbjogc3RhdGUudGVzdHNSYW4sXG4gICAgICB0ZXN0c1Bhc3NlZDogc3RhdGUudGVzdHNQYXNzZWQsXG4gICAgICB0ZXN0c1dyaXR0ZW46IHN0YXRlLnRlc3RzV3JpdHRlbixcbiAgICAgIGxhc3REZWNpc2lvbjogc3RhdGUubGFzdERlY2lzaW9uLFxuICAgICAgY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbjogc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbixcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3RvcmVTdGF0ZShjdHg6IEV4dGVuc2lvbkNvbnRleHQpOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyaWVzID0gY3R4LnNlc3Npb25NYW5hZ2VyLmdldEVudHJpZXMoKTtcbiAgICBjb25zdCB0ZGRFbnRyeSA9IGVudHJpZXNcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChlOiB7IHR5cGU6IHN0cmluZzsgY3VzdG9tVHlwZT86IHN0cmluZyB9KSA9PlxuICAgICAgICAgIGUudHlwZSA9PT0gXCJjdXN0b21cIiAmJiBlLmN1c3RvbVR5cGUgPT09IFwidGRkLWN5Y2xlXCIsXG4gICAgICApXG4gICAgICAucG9wKCkgYXMgeyBkYXRhPzogUGFydGlhbDxDeWNsZVN0YXRlPiB9IHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHRkZEVudHJ5Py5kYXRhKSB7XG4gICAgICBzdGF0ZSA9IHtcbiAgICAgICAgLi4uY3JlYXRlSW5pdGlhbFN0YXRlKCksXG4gICAgICAgIC4uLnRkZEVudHJ5LmRhdGEsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXR1c01lc3NhZ2UoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcGhhc2VEZXNjcmlwdGlvbihzdGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBndWlkZWxpbmVzTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLWdyZWVuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cblszNTQgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTgxIHRvIGNvbnRpbnVlLl0ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDg2NzQyNDl9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIzNWIzZDE1MSIsInBhcmVudElkIjoiNWQ1NzJjMzEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ0OjQ4LjUyMFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoZSBpc3N1ZSBpcyBjbGVhci4gSW4gdGhlIGBnby10by1ncmVlbmAgZXhlY3V0ZSBmdW5jdGlvbiwgdGhlIGNvZGUgY2FsbHMgYHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZClgIHdoaWNoIHJldHVybnMgYSBuZXcgc3RhdGUsIGJ1dCBgc3RhdGVgIGlzIG5ldmVyIHVwZGF0ZWQgd2l0aCB0aGUgbmV3IHN0YXRlLiBMZXQgbWUgZml4IHRoaXMuIEkgbmVlZCB0byBhZGQgYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtgIGFmdGVyIGByZWNvcmRUZXN0UmVzdWx0YCBpcyBjYWxsZWQuXG5cblNpbWlsYXJseSwgaW4gdGhlIGBnby10by1yZWZhY3RvcmAgZXhlY3V0ZSBmdW5jdGlvbiwgdGhlIGNvZGUgY2FsbHMgYGdyZWVuVG9SZWZhY3RvcihzdGF0ZSlgIGFuZCBgYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbilgIGJ1dCBgc3RhdGVgIGlzIG5vdCB1cGRhdGVkIHdpdGggdGhlIG5ldyBzdGF0ZS5cblxuTGV0IG1lIGZpeCBhbGwgdGhlc2UgY2FzZXMuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlRoZSBidWcgaXMgdGhhdCBmdW5jdGlvbnMgbGlrZSBgcmVjb3JkVGVzdFJlc3VsdGAsIGBncmVlblRvUmVmYWN0b3JgLCBhbmQgYGFwcGx5UmVmYWN0b3JEZWNpc2lvbmAgcmV0dXJuIGEgKm5ldyogc3RhdGUgb2JqZWN0LCBidXQgdGhlIGBleGVjdXRlYCBmdW5jdGlvbnMgbmV2ZXIgcmVhc3NpZ24gYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZWAuIExldCBtZSBhZGQgdGhvc2UgYXNzaWdubWVudHMgaW4gYWxsIHRocmVlIHBsYWNlczoifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMF85eXJzNGJXNlJNSkFYRzZIMFN6bjkzMTciLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJvZmZzZXQiOjgxLCJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIiwibGltaXQiOjU1fX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEwOTM0Nywib3V0cHV0IjoyNzAsImNhY2hlUmVhZCI6NTEyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTEwMTI5LCJjb3N0Ijp7ImlucHV0IjowLjAwOTg0MTIzLCJvdXRwdXQiOjAuMDAwMDQ4NiwiY2FjaGVSZWFkIjowLjAwMDAxMDI0LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDk5MDAwNjk5OTk5OTk5OTl9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDg2NzQyNTAsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0ODY3NC00ZFJDcGFNYkh2YUtvMmVwc0M3eSIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIwOWU5ZTFkMSIsInBhcmVudElkIjoiMzViM2QxNTEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ0OjQ4LjUzOFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMDBfOXlyczRiVzZSTUpBWEc2SDBTem45MzE3IiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwiZ28tdG8tZ3JlZW5cIixcbiAgICBsYWJlbDogXCJHbyB0byBHcmVlblwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJSdW4gdGVzdHMgdG8gdmVyaWZ5IGltcGxlbWVudGF0aW9uLiBJZiB0ZXN0cyBwYXNzLCB0cmFuc2l0aW9ucyB0byBHUkVFTiBwaGFzZS4gXCIgK1xuICAgICAgXCJJZiB0ZXN0cyBmYWlsLCBzdGF5cyBpbiBSRUQgd2l0aCBmZWVkYmFjay4gVXNlIHRoaXMgYWZ0ZXIgd3JpdGluZyBhIGZhaWxpbmcgdGVzdCBhbmQgaXRzIGltcGxlbWVudGF0aW9uLlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHtcbiAgICAgIHRlc3REZXNjcmlwdGlvbjogVHlwZS5PcHRpb25hbChcbiAgICAgICAgVHlwZS5TdHJpbmcoe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJCcmllZiBkZXNjcmlwdGlvbiBvZiB3aGF0IHRlc3QocykgdG8gcnVuIChlLmcuLCAndXNlciBsb2dpbiB0ZXN0JykuIFwiICtcbiAgICAgICAgICAgIFwiVXNlZCBmb3IgZGlzcGxheSBwdXJwb3Nlcy5cIixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH0pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGNvbnN0IHRlc3REZXNjID0gcGFyYW1zLnRlc3REZXNjcmlwdGlvbiA/PyBzdGF0ZS50ZXN0RGVzY3JpcHRpb247XG5cbiAgICAgIGlmICh0ZXN0RGVzYykge1xuICAgICAgICBzdGF0ZS50ZXN0RGVzY3JpcHRpb24gPSB0ZXN0RGVzYztcbiAgICAgIH1cblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCB0ZXN0Q29tbWFuZCA9IFwibnBtIHRlc3QgMj4mMVwiO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgdGVzdENvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbDogY3R4LnNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICBpZiAodHJhbnNpdGlvbi5zdGF0ZS5waGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICBg8J+foiAqKkdSRUVOIFBIQVNFIEFDSElFVkVEISoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGAke3RyYW5zaXRpb24ubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgYFRoZSBkZXZlbG9wZXIgbXVzdCBub3cgZGVjaWRlIHdoYXQgdG8gcmVmYWN0b3IuXFxuYCArXG4gICAgICAgICAgICAgIGBVc2UgKipnby10by1yZWZhY3RvcioqIHRvIGVudGVyIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBwaGFzZS5gLFxuICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgdHJpZ2dlclR1cm46IGZhbHNlIH0sXG4gICAgICAgICk7XG4gICAgICB9XG5cblsyOTkgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTEzNiB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ4Njg4NTM4fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYjVmYjJmODgiLCJwYXJlbnRJZCI6IjA5ZTllMWQxIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0NTowNC4wODBaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIG5lZWQgdG8gZml4IHRoZSBgc3RhdGVgIGFzc2lnbm1lbnQgaW4gdGhyZWUgcGxhY2VzIGluIHRoZSBleGVjdXRlIGZ1bmN0aW9uczpcblxuMS4gYGdvLXRvLWdyZWVuYCBleGVjdXRlOiBhZnRlciBgcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKWAg4oaSIGBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7YFxuMi4gYGdvLXRvLXJlZmFjdG9yYCBleGVjdXRlOiBhZnRlciBgZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKWAg4oaSIGBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7YFxuMy4gYGdvLXRvLXJlZmFjdG9yYCBleGVjdXRlOiBhZnRlciBgYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbilgIOKGkiBgc3RhdGUgPSBhcHBseVJlc3VsdC5zdGF0ZTtgXG5cbkxldCBtZSBtYWtlIHRoZXNlIGVkaXRzLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJJIG5lZWQgdG8gYWRkIGBzdGF0ZSA9YCBhc3NpZ25tZW50cyBpbiB0aHJlZSBwbGFjZXMuIExldCBtZSBtYWtlIGFsbCB0aHJlZSBlZGl0cyBhdCBvbmNlOiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzAwX05UNGZ1b2NPYlNHR21GNGJxRzcxMjgxMCIsIm5hbWUiOiJlZGl0IiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMiLCJlZGl0cyI6W3sib2xkVGV4dCI6IiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBwYXNzZWQpO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbIiwibmV3VGV4dCI6IiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBwYXNzZWQpO1xuICAgICAgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbIn0seyJvbGRUZXh0IjoiICAgICAgLy8gVHJhbnNpdGlvbiB0byBSRUZBQ1RPUlxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4gICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgWyIsIm5ld1RleHQiOiIgICAgICAvLyBUcmFuc2l0aW9uIHRvIFJFRkFDVE9SXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKTtcbiAgICAgIHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbIn0seyJvbGRUZXh0IjoiICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAgICAgcGkuc2VuZE1lc3NhZ2UoIiwibmV3VGV4dCI6IiAgICAgICAgaWYgKGRlY2lzaW9uKSB7XG4gICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICAgICAgICBzdGF0ZSA9IGFwcGx5UmVzdWx0LnN0YXRlO1xuICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAgICAgcGkuc2VuZE1lc3NhZ2UoIn1dfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjExMDA3OSwib3V0cHV0Ijo0NDcsImNhY2hlUmVhZCI6NTEyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTExMDM4LCJjb3N0Ijp7ImlucHV0IjowLjAwOTkwNzExLCJvdXRwdXQiOjAuMDAwMDgwNDYsImNhY2hlUmVhZCI6MC4wMDAwMTAyNCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDA5OTk3ODF9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDg2ODg1MzksInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0ODY4OC01ZUxjYWtYUUdjelk5VlBTdWd2aSIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3OTdhN2FjNiIsInBhcmVudElkIjoiYjVmYjJmODgiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ1OjA0LjA4MloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMDBfTlQ0ZnVvY09iU0dHbUY0YnFHNzEyODEwIiwidG9vbE5hbWUiOiJlZGl0IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiQ291bGQgbm90IGZpbmQgZWRpdHNbMV0gaW4gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzLiBUaGUgb2xkVGV4dCBtdXN0IG1hdGNoIGV4YWN0bHkgaW5jbHVkaW5nIGFsbCB3aGl0ZXNwYWNlIGFuZCBuZXdsaW5lcy4ifV0sImRldGFpbHMiOnt9LCJpc0Vycm9yIjp0cnVlLCJ0aW1lc3RhbXAiOjE3ODE5NDg3MDQwODJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI0ZmEzMTBlZSIsInBhcmVudElkIjoiNzk3YTdhYzYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ1OjEzLjExMVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkxldCBtZSByZS1yZWFkIHRoZSBleGFjdCB0ZXh0IGFyb3VuZCB0aG9zZSBhcmVhcyB0aGF0IG5lZWQgY2hhbmdlcy4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTGV0IG1lIHJlYWQgdGhlIGZpbGUgdG8gZ2V0IHRoZSBleGFjdCB0ZXh0In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfNTRmYzA0NDNjMTE2NDdlZjgxNjU3YzQyIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsib2Zmc2V0IjoxMzYsInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMiLCJsaW1pdCI6MTV9fSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF85NDNmZjNlNTUwYzM0YjIwOTMwY2E1YjUiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJvZmZzZXQiOjE1NSwicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyIsImxpbWl0IjozMH19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMTExMDcsIm91dHB1dCI6MTk3LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMTEzMDQsImNvc3QiOnsiaW5wdXQiOjAuMDA5OTk5NjMsIm91dHB1dCI6MC4wMDAwMzU0NiwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTAwMzUwOX19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODcwNDA4MywicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4NzA0LXpQUndId0JjSWRiUHJOTlpzMUg2IiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImYyNDcxNjJiIiwicGFyZW50SWQiOiI0ZmEzMTBlZSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDU6MTMuMTI0WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF81NGZjMDQ0M2MxMTY0N2VmODE2NTdjNDIiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJUZXN0cyBleGVjdXRlZC5cIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGFzc2VkLFxuICAgICAgICAgIHBoYXNlOiB0cmFuc2l0aW9uLnN0YXRlLnBoYXNlLFxuICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICBvdXRwdXQ6IHJlc3VsdC5zdGRvdXQuc2xpY2UoMCwgNTBfMDAwKSxcblxuWzI4NCBtb3JlIGxpbmVzIGluIGZpbGUuIFVzZSBvZmZzZXQ9MTUxIHRvIGNvbnRpbnVlLl0ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDg3MTMxMjR9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI2Njg0OTEwMiIsInBhcmVudElkIjoiZjI0NzE2MmIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ1OjEzLjEyNFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfOTQzZmYzZTU1MGMzNGIyMDkzMGNhNWI1IiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiICAgICAgY29uc3QgdGV4dCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJnby10by1ncmVlbiBcIikpICsgKGFyZ3MudGVzdERlc2NyaXB0aW9uID8gdGhlbWUuZmcoXCJtdXRlZFwiLCBhcmdzLnRlc3REZXNjcmlwdGlvbikgOiBcIlwiKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBhc3NlZD86IGJvb2xlYW47IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIGAke3BoYXNlfSBUZXN0cyBwYXNzZWRgKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgYCR7cGhhc2V9IFRlc3RzIGZhaWxlZGApO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLXJlZmFjdG9yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1yZWZhY3RvclwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIFJlZmFjdG9yXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciB3aWxsIGJlIHByb21wdGVkIHRvIGNob29zZSBcIiArXG4gICAgICBcIndoYXQgdG8gcmVmYWN0b3I6IHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgbmV4dCB0ZXN0LCBvciBjdXN0b20gaW5zdHJ1Y3Rpb24uIFwiICtcbiAgICAgIFwiT25seSBjYWxsIHRoaXMgd2hlbiB0ZXN0cyBhcmUgcGFzc2luZyAoR1JFRU4gcGhhc2UpLlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgaWYgKHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG5cblsyNTAgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTE4NSB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ4NzEzMTI0fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNzE2OTc5MWEiLCJwYXJlbnRJZCI6IjY2ODQ5MTAyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0NTozNS44MjZaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIHNlZSAtIHRoZSBzZWNvbmQgZWRpdCB3YXMgaW4gYSBkaWZmZXJlbnQgbG9jYXRpb24uIExldCBtZSBzZWFyY2ggZm9yIHRoZSBleGFjdCB0ZXh0LiBUaGUgZmlyc3QgZWRpdCBhbHJlYWR5IHN1Y2NlZWRlZC4gTm93IEkgbmVlZCB0byBmaW5kIHRoZSBzZWNvbmQgYW5kIHRoaXJkIGVkaXQgbG9jYXRpb25zLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfZmQ0NjdhYjUzYmE0NDlmZTk4NDgwODBiIiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlICYmIGdyZXAgLW4gXCJUcmFuc2l0aW9uIHRvIFJFRkFDVE9SXFx8Z3JlZW5Ub1JlZmFjdG9yXFx8YXBwbHlSZWZhY3RvckRlY2lzaW9uXFx8cGVyc2lzdFN0YXRlXCIgc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMTE3NzQsIm91dHB1dCI6MTI2LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMTE5MDAsImNvc3QiOnsiaW5wdXQiOjAuMDEwMDU5NjYsIm91dHB1dCI6MC4wMDAwMjI2OCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTAwODIzNH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODcxMzEyNSwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4NzEzLXZvQWc1QTh4eXdvcHdEVWR1OUJkIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjQ4ODRiOTRlIiwicGFyZW50SWQiOiI3MTY5NzkxYSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDU6MzUuODM3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF9mZDQ2N2FiNTNiYTQ0OWZlOTg0ODA4MGIiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIyNTogIGdyZWVuVG9SZWZhY3RvcixcbjI2OiAgYXBwbHlSZWZhY3RvckRlY2lzaW9uLFxuNDI6ICBmdW5jdGlvbiBwZXJzaXN0U3RhdGUoKTogdm9pZCB7XG4xMzc6ICAgICAgcGVyc2lzdFN0YXRlKCk7XG4xOTQ6ICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4xOTU6ICAgICAgcGVyc2lzdFN0YXRlKCk7XG4yMDc6ICAgICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4yMDg6ICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuNDMxOiAgICBwZXJzaXN0U3RhdGUoKTtcbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODczNTgzN319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImZhMjliOGMyIiwicGFyZW50SWQiOiI0ODg0Yjk0ZSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDU6NDUuMDI1WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiR29vZC4gTGluZXMgMTk0LCAyMDcsIGFuZCAyMDggbmVlZCB0aGUgc3RhdGUgYXNzaWdubWVudCBhZGRlZC4gTGV0IG1lIHJlYWQgdGhlIGV4YWN0IHRleHQgYXJvdW5kIHRob3NlIGxpbmVzLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfNjAyMmM5Njk1N2E4NDkxYzg4YzljZDU3IiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsibGltaXQiOjI1LCJvZmZzZXQiOjE5MCwicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTE1LCJvdXRwdXQiOjEyMiwiY2FjaGVSZWFkIjoxMTE4NzIsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMTIxMDksImNvc3QiOnsiaW5wdXQiOjAuMDAwMDEwMzUsIm91dHB1dCI6MC4wMDAwMjE5NiwiY2FjaGVSZWFkIjowLjAwMjIzNzQ0MDAwMDAwMDAwMDMsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMjI2OTc1fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4NzM1ODM4LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDg3MzUta3kxRDNWMUswczFyTlM4UzhSMjciLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNWU2MzI0OTgiLCJwYXJlbnRJZCI6ImZhMjliOGMyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0NTo0NS4wMjdaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzYwMjJjOTY5NTdhODQ5MWM4OGM5Y2Q1NyIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKTtcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgXSk7XG5cbiAgICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIiAmJiBjdHguaGFzVUkpIHtcbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBjdHgudWkuY3VzdG9tPFJlZmFjdG9yRGVjaXNpb24gfCBudWxsPihcbiAgICAgICAgICBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50KHN0YXRlLnRlc3REZXNjcmlwdGlvbiksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRlY2lzaW9uKSB7XG4gICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICAgICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICAgIGDwn5SAICoqUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZDoqKlxcblxcbmAgK1xuXG5bMjIwIG1vcmUgbGluZXMgaW4gZmlsZS4gVXNlIG9mZnNldD0yMTUgdG8gY29udGludWUuXSJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODc0NTAyN319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImIwNTllNGQwIiwicGFyZW50SWQiOiI1ZTYzMjQ5OCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDY6MjIuNTE4WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IEkgY2FuIHNlZSB0aGUgZXhhY3QgdGV4dC4gSSBuZWVkIHRvIGFkZCBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgYWZ0ZXIgbGluZSAxOTQgYW5kIGBzdGF0ZSA9IGFwcGx5UmVzdWx0LnN0YXRlO2AgYWZ0ZXIgbGluZSAyMDcuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF84OGE2MWQyNzE2MDE0NzA0OWRiNjMyMzciLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJlZGl0cyI6W3sibmV3VGV4dCI6IiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgICAgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO1xuICAgICAgcGVyc2lzdFN0YXRlKCk7Iiwib2xkVGV4dCI6IiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgICAgcGVyc2lzdFN0YXRlKCk7In0seyJuZXdUZXh0IjoiICAgICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgICAgICAgc3RhdGUgPSBhcHBseVJlc3VsdC5zdGF0ZTtcbiAgICAgICAgICBwZXJzaXN0U3RhdGUoKTsiLCJvbGRUZXh0IjoiICAgICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7In1dLCJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0Ijo2NzUsIm91dHB1dCI6MjI2LCJjYWNoZVJlYWQiOjExMTYxNiwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjExMjUxNywiY29zdCI6eyJpbnB1dCI6MC4wMDAwNjA3NSwib3V0cHV0IjowLjAwMDA0MDY4LCJjYWNoZVJlYWQiOjAuMDAyMjMyMzIsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMjMzMzc1fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4NzQ1MDI4LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDg3NDUtTzNGMmRyUEQzVFNBODg5U3NrRFAiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYzY5MTY4MmMiLCJwYXJlbnRJZCI6ImIwNTllNGQwIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0NjoyMi41MzRaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzg4YTYxZDI3MTYwMTQ3MDQ5ZGI2MzIzNyIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSByZXBsYWNlZCAyIGJsb2NrKHMpIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cy4ifV0sImRldGFpbHMiOnsiZGlmZiI6IiAgICAgLi4uXG4gMTkxICAgICAgICAgfTtcbiAxOTIgICAgICAgfVxuIDE5MyBcbiAxOTQgICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4rMTk1ICAgICAgIHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtcbiAxOTUgICAgICAgcGVyc2lzdFN0YXRlKCk7XG4gMTk2IFxuIDE5NyAgICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gMTk4ICAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgIC4uLlxuIDIwNCAgICAgICAgICk7XG4gMjA1IFxuIDIwNiAgICAgICAgIGlmIChkZWNpc2lvbikge1xuIDIwNyAgICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbisyMDkgICAgICAgICAgIHN0YXRlID0gYXBwbHlSZXN1bHQuc3RhdGU7XG4gMjA4ICAgICAgICAgICBwZXJzaXN0U3RhdGUoKTtcbiAyMDkgXG4gMjEwICAgICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAyMTEgICAgICAgICAgICAge1xuICAgICAuLi4iLCJwYXRjaCI6Ii0tLSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHNcbisrKyAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHNcbkBAIC0xOTEsOCArMTkxLDkgQEBcbiAgICAgICAgIH07XG4gICAgICAgfVxuIFxuICAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuKyAgICAgIHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtcbiAgICAgICBwZXJzaXN0U3RhdGUoKTtcbiBcbiAgICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbkBAIC0yMDQsOCArMjA1LDkgQEBcbiAgICAgICAgICk7XG4gXG4gICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbisgICAgICAgICAgc3RhdGUgPSBhcHBseVJlc3VsdC5zdGF0ZTtcbiAgICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG4gXG4gICAgICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgICAgIHtcbiIsImZpcnN0Q2hhbmdlZExpbmUiOjE5NX0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDg3ODI1MzR9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIzZmNiOGI4YiIsInBhcmVudElkIjoiYzY5MTY4MmMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ2OjM1LjQ3NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBsZXQgbWUgcnVuIHR5cGVjaGVjayBhbmQgdGVzdHMgYWdhaW4sIHRoZW4gcmUtcnVuIHRoZSBsaXZlIHRlc3QuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF85Mzc4MDAzNTRjYjg0MmJjYWYwNTllNDciLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgbnBtIHJ1biB0eXBlY2hlY2sgMj4mMSAmJiBucG0gcnVuIHRlc3QgMj4mMSJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTEyNTM5LCJvdXRwdXQiOjk0LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMTI2MzMsImNvc3QiOnsiaW5wdXQiOjAuMDEwMTI4NTEsIm91dHB1dCI6MC4wMDAwMTY5MiwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTAxNDU0M319LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODc4MjUzNCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4NzgyLUk5T0U0bkN0UTU3aGFaNkltZTJvIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjIyZTY1YzEyIiwicGFyZW50SWQiOiIzZmNiOGI4YiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDY6MzcuMjQ0WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF85Mzc4MDAzNTRjYjg0MmJjYWYwNTllNDciLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJcbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHR5cGVjaGVja1xuPiB0c2MgLS1ub0VtaXRcblxuXG4+IHBpLXRkZC1jeWNsZUAwLjEuMCB0ZXN0XG4+IHZpdGVzdCBydW5cblxuXG4gUlVOICB2NC4xLjkgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGVcblxuXG4gVGVzdCBGaWxlcyAgMSBwYXNzZWQgKDEpXG4gICAgICBUZXN0cyAgMjkgcGFzc2VkICgyOSlcbiAgIFN0YXJ0IGF0ICAxMDo0NjozN1xuICAgRHVyYXRpb24gIDEwNG1zICh0cmFuc2Zvcm0gMjBtcywgc2V0dXAgMG1zLCBpbXBvcnQgMjhtcywgdGVzdHMgNG1zLCBlbnZpcm9ubWVudCAwbXMpXG5cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODc5NzI0NH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijg3ZmUzY2U4IiwicGFyZW50SWQiOiIyMmU2NWMxMiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDY6NDUuNTQyWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiQWxsIHBhc3Nlcy4gTm93IGxldCBtZSByZS1ydW4gdGhlIGxpdmUgdGVzdC4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiQ2xlYW4uIE5vdyBsZXQgbWUgcmUtcnVuIHRoZSBsaXZlIHRlc3Q6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzJmNjdlNTNjNTRkZDRiZmM4NzIwMGJmZSIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvdG1wL3BpLXRkZC10ZXN0ICYmIHBpIC1lIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyBcIkNvbnRpbnVlLiBDYWxsIGdvLXRvLWdyZWVuIHRvIHZlcmlmeSB0ZXN0cyBwYXNzLCB0aGVuIGNhbGwgZ28tdG8tcmVmYWN0b3IgdG8gZW50ZXIgdGhlIHJlZmFjdG9yIGRlY2lzaW9uIHBoYXNlLlwiIDI+JjEiLCJ0aW1lb3V0IjoxMjB9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6Mzk5LCJvdXRwdXQiOjE0MywiY2FjaGVSZWFkIjoxMTIzODQsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMTI5MjYsImNvc3QiOnsiaW5wdXQiOjAuMDAwMDM1OTEsIm91dHB1dCI6MC4wMDAwMjU3NCwiY2FjaGVSZWFkIjowLjAwMjI0NzY4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDIzMDkzM319LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODc5NzI0NCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4Nzk3LXEzNFVJSW55aHV5TUJVQ3plZDRJIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijg2MDg3NjIyIiwicGFyZW50SWQiOiI4N2ZlM2NlOCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDc6NTUuMTY4WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF8yZjY3ZTUzYzU0ZGQ0YmZjODcyMDBiZmUiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJJJ3ZlIGNvbXBsZXRlZCB0aGUgcmVxdWVzdGVkIHNlcXVlbmNlLiBIZXJlJ3MgYSBzdW1tYXJ5OlxuXG4qKuKchSBnby10by1ncmVlbioqIC0gVGVzdHMgcGFzcyBzdWNjZXNzZnVsbHkuIFRoZSB0b29sIHJlcG9ydGVkIFwiUGhhc2UgY2hhbmdlZDogR1JFRU4g4oaSIFJFRkFDVE9SXCIuXG5cbioq4p2MIGdvLXRvLXJlZmFjdG9yKiogLSBUaGlzIHRvb2wgcmVwb3J0cyBgQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlYCwgaW5kaWNhdGluZyBhbiBpbi1tZW1vcnkgc3RhdGUgaW5jb25zaXN0ZW5jeSBiZXR3ZWVuIHRoZSB0b29scy4gSG93ZXZlciwgdGhlIHRlc3RzICoqZG8gcGFzcyoqICh2ZXJpZmllZCB3aXRoIGBydW4tdGVzdHNgKTpcblxuYGBgXG7inJMgVGVzdHMgcGFzc2VkIChleGl0IGNvZGU6IDApXG5gYGBcblxuVGhlIHZlbmRpbmcgbWFjaGluZSB0ZXN0cyAoMSB0ZXN0KSBhcmUgYWxsIGdyZWVuLiBUaGUgcHJvamVjdCBoYXM6XG4tIGBzcmMvY2FuLnRzYCAtIGBDYW5gIGVudW0gd2l0aCBgTm90aGluZ2Bcbi0gYHNyYy9jaG9pY2UudHNgIC0gYENob2ljZWAgZW51bSB3aXRoIGBDb2xhYFxuLSBgc3JjL3ZlbmRpbmctbWFjaGluZS50c2AgLSBgVmVuZGluZ01hY2hpbmVgIGNsYXNzIHJldHVybmluZyBgQ2FuLk5vdGhpbmdgXG4tIGBzcmMvdmVuZGluZy1tYWNoaW5lLnRlc3QudHNgIC0gQSBwYXNzaW5nIHRlc3QgZm9yIGBjaG9vc2UoQ2hvaWNlLkNvbGEpYCDihpIgYENhbi5Ob3RoaW5nYFxuXG5EZXNwaXRlIHRoZSB0b29sIHN0YXRlIGluY29uc2lzdGVuY3ksIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBzb2xpZCBhbmQgdGVzdHMgcGFzcy4gV2UgY2FuIHByb2NlZWQgd2l0aCB0aGUgbmV4dCBUREQgY3ljbGUgKHdyaXRlIGEgZmFpbGluZyB0ZXN0IGZvciB0aGUgbmV4dCBmZWF0dXJlLCBpbXBsZW1lbnQsIGFuZCBnbyBncmVlbikuXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDg4NzUxNjh9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJiOTc0ZTllNiIsInBhcmVudElkIjoiODYwODc2MjIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ4OjI3LjU0NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlN0aWxsIHRoZSBzYW1lIGlzc3VlLiBUaGUgc3RhdGUgaXMgc3RpbGwgc2hvd2luZyBSRUQgZm9yIHRoZSBgZ28tdG8tcmVmYWN0b3JgIGNhbGwuIFRoaXMgbWVhbnMgdGhlIHN0YXRlIG11dGF0aW9uIGlzIG5vdCBwZXJzaXN0aW5nIGJldHdlZW4gdG9vbCBjYWxscy4gXG5cblRoZSBpc3N1ZSBpcyB0aGF0IFBpJ3MgZXh0ZW5zaW9uIHN5c3RlbSBtaWdodCBiZSBjcmVhdGluZyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgZXh0ZW5zaW9uIGZvciBlYWNoIHRvb2wgY2FsbCwgb3IgdGhlIGNsb3N1cmUgc3RhdGUgaXMgYmVpbmcgcmVzZXQuIExldCBtZSB0aGluayBhYm91dCB0aGlzLi4uXG5cbkFjdHVhbGx5LCBsb29raW5nIGF0IHRoZSBleHRlbnNpb24gZG9jcyBtb3JlIGNhcmVmdWxseTpcblxuPiBgcGkucmVnaXN0ZXJUb29sKClgIHdvcmtzIGJvdGggZHVyaW5nIGV4dGVuc2lvbiBsb2FkIGFuZCBhZnRlciBzdGFydHVwLiBZb3UgY2FuIGNhbGwgaXQgaW5zaWRlIGBzZXNzaW9uX3N0YXJ0YCwgY29tbWFuZCBoYW5kbGVycywgb3Igb3RoZXIgZXZlbnQgaGFuZGxlcnMuIE5ldyB0b29scyBhcmUgcmVmcmVzaGVkIGltbWVkaWF0ZWx5IGluIHRoZSBzYW1lIHNlc3Npb24sIHNvIHRoZXkgYXBwZWFyIGluIGBwaS5nZXRBbGxUb29scygpYCBhbmQgYXJlIGNhbGxhYmxlIGJ5IHRoZSBMTE0gd2l0aG91dCBgL3JlbG9hZGAuXG5cblRoZSBleHRlbnNpb24gZmFjdG9yeSBydW5zIG9uY2UsIGFuZCB0aGUgY2xvc3VyZXMgc2hhcmUgdGhlIGBzdGF0ZWAgdmFyaWFibGUuIFNvIGBzdGF0ZWAgc2hvdWxkIHBlcnNpc3QgYmV0d2VlbiB0b29sIGNhbGxzIHdpdGhpbiB0aGUgc2FtZSBzZXNzaW9uLlxuXG5CdXQgd2FpdCAtIHRoZSBhZ2VudCByYW4gYGdvLXRvLWdyZWVuYCBmaXJzdCwgd2hpY2ggc3VjY2VlZGVkIChyZXR1cm5lZCBHUkVFTikuIFRoZW4gYGdvLXRvLXJlZmFjdG9yYCB3YXMgY2FsbGVkIGFuZCBpdCBzYWlkIFwiQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlXCIuIFxuXG5UaGUgaXNzdWUgbWlnaHQgYmUgcmVsYXRlZCB0byBob3cgUGkgaGFuZGxlcyBzZXNzaW9ucy4gVGhlIGAtZWAgZmxhZyBleHRlbnNpb24gbWlnaHQgYmUgbG9hZGVkIHdpdGhpbiBhIHNlc3Npb24gc2NvcGUsIGFuZCB0aGUgdG9vbCBjYWxsIG1pZ2h0IGV4ZWN1dGUgaW4gYSBkaWZmZXJlbnQgY29udGV4dC5cblxuQWN0dWFsbHksIGxvb2tpbmcgYXQgdGhlIGFnZW50J3Mgb3V0cHV0OiBcIlRoZSB0b29sIHJlcG9ydGVkICdQaGFzZSBjaGFuZ2VkOiBHUkVFTiDihpIgUkVGQUNUT1InXCIgLSBzbyBgZ28tdG8tZ3JlZW5gIHJhbiBzdWNjZXNzZnVsbHkgYW5kIHRoZSBhZ2VudCByZWNlaXZlZCB0aGUgR1JFRU4gbWVzc2FnZS4gQnV0IHdoZW4gdGhlIGFnZW50IHN1YnNlcXVlbnRseSBjYWxsZWQgYGdvLXRvLXJlZmFjdG9yYCwgdGhlIHN0YXRlIHdhcyBiYWNrIHRvIFJFRC5cblxuVGhlIHByb2JsZW0gY291bGQgYmUgdGhhdCBgUGlgIHJ1bnMgdG9vbCBjYWxscyBpbiBzZXBhcmF0ZSBOb2RlLmpzIHByb2Nlc3Mgb3IgaXNvbGF0ZXMuIE5vIHdhaXQsIGV4dGVuc2lvbnMgYXJlIGxvYWRlZCBpbiB0aGUgc2FtZSBwcm9jZXNzLlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgdGhpcyBkaWZmZXJlbnRseS4gVGhlIGBzdGF0ZWAgdmFyaWFibGUgaXMgaW4gdGhlIGNsb3N1cmUgb2YgdGhlIGB0ZGRDeWNsZWAgZnVuY3Rpb24uIFdoZW4gdGhlIHRvb2wgZXhlY3V0ZXMsIHRoZSBgZXhlY3V0ZWAgZnVuY3Rpb24gY2FwdHVyZXMgYHN0YXRlYCB2aWEgY2xvc3VyZS4gU28gaXQgc2hvdWxkIGJlIHRoZSBzYW1lIGBzdGF0ZWAgdmFyaWFibGUuXG5cbldhaXQgLSBjb3VsZCB0aGUgaXNzdWUgYmUgdGhhdCBgcmVjb3JkVGVzdFJlc3VsdGAgcmV0dXJucyBgdHJhbnNpdGlvbi5zdGF0ZWAgYnV0IGBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGVgIGlzIGFzc2lnbmVkIGFmdGVyIGByZWNvcmRUZXN0UmVzdWx0YCBpcyBjYWxsZWQuLi4gTGV0IG1lIGNoZWNrIGlmIHRoaXMgaXMgYWN0dWFsbHkgd29ya2luZy5cblxuTGV0IG1lIGFkZCBzb21lIGxvZ2dpbmcgdG8gZGVidWcuIEFjdHVhbGx5LCBsZXQgbWUgdHJ5IGEgZGlmZmVyZW50IGFwcHJvYWNoOiBJJ2xsIG1ha2UgYGdvLXRvLXJlZmFjdG9yYCBjaGVjayB0aGUgcGVyc2lzdGVkIHN0YXRlIGZyb20gYGFwcGVuZEVudHJ5YCByYXRoZXIgdGhhbiByZWx5aW5nIG9uIHRoZSBpbi1tZW1vcnkgc3RhdGUsIG9yIEknbGwgdXBkYXRlIHRoZSBzdGF0ZSBkaXJlY3RseS5cblxuQWN0dWFsbHksIEkganVzdCByZWFsaXplZCBzb21ldGhpbmcuIFdoZW4gYGdvLXRvLWdyZWVuYCBpcyBjYWxsZWQgd2l0aCB0ZXN0cyBwYXNzaW5nOlxuMS4gYHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZClgIGlzIGNhbGxlZCB3aGVyZSBgcGFzc2VkID0gdHJ1ZWBcbjIuIEluc2lkZSBgcmVjb3JkVGVzdFJlc3VsdGAsIGBzdGF0ZS5waGFzZSA9PT0gXCJSRURcImAgYW5kIGBwYXNzZWQgPT09IHRydWVgXG4zLiBTbyBgcmVkVG9HcmVlbihuZXdTdGF0ZSlgIGlzIGNhbGxlZCwgd2hpY2ggcmV0dXJucyBHUkVFTlxuNC4gQnV0IHdhaXQgLSBgcmVjb3JkVGVzdFJlc3VsdGAgZG9lczpcbmBgYFxuY29uc3QgZ3JlZW5SZXN1bHQgPSByZWRUb0dyZWVuKG5ld1N0YXRlKTtcbnJldHVybiB7XG4gIC4uLmdyZWVuUmVzdWx0LFxuICBzdGF0ZTogeyAuLi5ncmVlblJlc3VsdC5zdGF0ZSwgdGVzdHNSYW46IHRydWUsIHRlc3RzUGFzc2VkOiB0cnVlIH0sXG59O1xuYGBgXG41LiBUaGVuIGluIHRoZSBleGVjdXRlIGZ1bmN0aW9uOiBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgLSB0aGlzIHNob3VsZCBzZXQgYHN0YXRlYCB0byB0aGUgR1JFRU4gc3RhdGUuXG5cblRoaXMgc2hvdWxkIHdvcmsuIFVubGVzcyB0aGVyZSdzIHNvbWV0aGluZyBlbHNlIGdvaW5nIG9uLlxuXG5MZXQgbWUgdGhpbmsgYWJvdXQgd2hlbiB0aGUgZXh0ZW5zaW9uIHJ1bnMuIEluIFBpLCB3aGVuIHlvdSBwYXNzIGAtZWAsIHRoZSBleHRlbnNpb24gaXMgbG9hZGVkIGJ5IGppdGkuIFRoZSBmYWN0b3J5IGZ1bmN0aW9uIGlzIGNhbGxlZCBvbmNlLCBhbmQgdGhlIHJldHVybmVkIHZhbHVlIGlzIGlnbm9yZWQgKGZhY3RvcnkganVzdCByZWdpc3RlcnMgdG9vbHMvZXZlbnRzKS5cblxuQnV0IHdhaXQgLSBgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgdGVzdENvbW1hbmRdLCAuLi4pYCAtIHRoaXMgcnVucyB0aGUgdGVzdHMuIFRoZSB0ZXN0IGNvbW1hbmQgaXMgYFwibnBtIHRlc3QgMj4mMVwiYC4gQnV0IGluIGAvdG1wL3BpLXRkZC10ZXN0YCwgdGhlcmUncyBubyB2aXRlc3QgaW5zdGFsbGVkLCBhbmQgdGhlIGBwYWNrYWdlLmpzb25gIGhhcyBgdGVzdDogXCJlY2hvIFxcXCJFcnJvcjogbm8gdGVzdCBzcGVjaWZpZWRcXFwiICYmIGV4aXQgMVwiYC4gU28gdGhlIHRlc3RzIHdvdWxkIGZhaWwhXG5cbk9oIHdhaXQsIHRoZSBhZ2VudCBzYWlkIHRlc3RzIHBhc3NlZC4gU28gbWF5YmUgdGhlIGFnZW50IGFscmVhZHkgc2V0IHVwIHZpdGVzdCBpbiBhIHByZXZpb3VzIHNlc3Npb24uIEJ1dCBhY3R1YWxseSwgZWFjaCBgcGkgLWUgLi4uYCBpbnZvY2F0aW9uIGlzIGEgTkVXIHNlc3Npb24uIFRoZSBwcmV2aW91cyBgL3RtcC9waS10ZGQtdGVzdGAgc2V0dXAgd2FzIGZyb20gYSBkaWZmZXJlbnQgcGkgaW52b2NhdGlvbi5cblxuVGhlIGtleSBpbnNpZ2h0IGlzOiBgcGkgLWUgLi4uIFwiLi4uXCJgIGlzIGEgKipuZXcgc2Vzc2lvbioqIGVhY2ggdGltZS4gVGhlIGV4dGVuc2lvbiBmYWN0b3J5IHJ1bnMgZnJlc2gsIGNyZWF0aW5nIGEgbmV3IGNsb3N1cmUgd2l0aCBmcmVzaCBgc3RhdGUgPSBjcmVhdGVJbml0aWFsU3RhdGUoKWAuIFxuXG5CdXQgd2l0aGluIGEgc2luZ2xlIGBwaWAgc2Vzc2lvbiwgdGhlIGV4dGVuc2lvbiBjbG9zdXJlIHBlcnNpc3RzLiBTbyBgZ28tdG8tZ3JlZW5gIGFuZCBgZ28tdG8tcmVmYWN0b3JgIHNob3VsZCBzaGFyZSB0aGUgc2FtZSBjbG9zdXJlLlxuXG5VTkxFU1MgLSB0aGUgdG9vbCBjYWxsIGl0c2VsZiBzdGFydHMgYSBuZXcgZXh0ZW5zaW9uIGxpZmVjeWNsZS4gTGV0IG1lIGNoZWNrIGlmIGBwaS5yZWdpc3RlclRvb2xgIHJ1bnMgaW4gYSBzZXBhcmF0ZSBjb250ZXh0Li4uXG5cbkFjdHVhbGx5LCBJIHRoaW5rIHRoZSBpc3N1ZSBtaWdodCBiZSBzaW1wbGVyLiBUaGUgYGdvLXRvLWdyZWVuYCBleGVjdXRlIGZ1bmN0aW9uIHJ1bnMgYHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIFwibnBtIHRlc3QgMj4mMVwiXSwgLi4uKWAuIFRoaXMgcnVucyBgbnBtIHRlc3RgIGluIHRoZSBwcm9qZWN0IGRpcmVjdG9yeS4gVGhlIGFnZW50IGFscmVhZHkgc2V0IHVwIHRoZSBwcm9qZWN0IGluIGEgcHJldmlvdXMgcGkgc2Vzc2lvbiwgc286XG5cbjEuIEluIHRoZSBjdXJyZW50IHNlc3Npb24sIHRoZSBwcm9qZWN0IGhhcyB0aGUgc291cmNlIGZpbGVzIGJ1dCBgbnBtIHRlc3RgIHdvdWxkIGZhaWwgYmVjYXVzZSB2aXRlc3QgaXNuJ3QgaW5zdGFsbGVkIGluIHRoZSBwcm9qZWN0LlxuXG5XYWl0LCBidXQgdGhlIGFnZW50IHNhaWQgdGVzdHMgcGFzc2VkLiBTbyBlaXRoZXI6XG4tIFRoZSB0ZXN0cyBhcmUgc2V0IHVwIGZyb20gYSBwcmV2aW91cyBzZXNzaW9uXG4tIE9yIGBucG0gdGVzdGAgcmFuIHRoZSBgZWNobyBcIkVycm9yXCJgIGRlZmF1bHQgd2hpY2ggcmV0dXJucyBleGl0IGNvZGUgMSAoZmFpbGVkKS4uLlxuXG5BY3R1YWxseSwgbGV0IG1lIHJlLXJlYWQgdGhlIGZpcnN0IHRlc3Qgc2Vzc2lvbiBvdXRwdXQuIFRoZSBmaXJzdCBzZXNzaW9uIHNldCB1cCBUeXBlU2NyaXB0IGZpbGVzLiBCdXQgdGhlIHByb2plY3QncyBgcGFja2FnZS5qc29uYCBzdGlsbCBoYXMgYFwidGVzdFwiOiBcImVjaG8gXFxcIkVycm9yOiBubyB0ZXN0IHNwZWNpZmllZFxcXCIgJiYgZXhpdCAxXCJgLiBTbyBgbnBtIHRlc3RgIHdvdWxkIGZhaWwgd2l0aCBleGl0IGNvZGUgMS5cblxuSG1tLCBidXQgaW4gdGhlIGBnby10by1ncmVlbmAgZXhlY3V0ZSBmdW5jdGlvbiwgYHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO2AuIElmIHRoZSB0ZXN0IGNvbW1hbmQgZmFpbGVkLCBgcGFzc2VkID0gZmFsc2VgLCBhbmQgYHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIGZhbHNlKWAgd291bGQga2VlcCBzdGF0ZSBpbiBSRUQuIFRoZW4gYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZWAgd291bGQgc2V0IHN0YXRlIHRvIFJFRCAoc3RpbGwpLlxuXG5CdXQgdGhlIGFnZW50J3Mgb3V0cHV0IHNheXM6IFwiZ28tdG8tZ3JlZW4gLSBUZXN0cyBwYXNzIHN1Y2Nlc3NmdWxseS4gVGhlIHRvb2wgcmVwb3J0ZWQgJ1BoYXNlIGNoYW5nZWQ6IEdSRUVOIOKGkiBSRUZBQ1RPUicuXCJcblxuU28gZWl0aGVyOlxuMS4gVGhlIGFnZW50IG1vZGlmaWVkIHRoZSBwcm9qZWN0IHNldHVwIGJldHdlZW4gc2Vzc2lvbnMgKHVubGlrZWx5IGluIGEgZnJlc2ggYHBpIC1lYCBzZXNzaW9uKVxuMi4gT3IgdGhlIGBwaS5leGVjYCByYW4gc29tZXRoaW5nIGRpZmZlcmVudCBhbmQgcmV0dXJuZWQgZXhpdCBjb2RlIDBcblxuQWN0dWFsbHkgd2FpdCAtIHRoZSBmaXJzdCB0ZXN0IHNlc3Npb24gZWFybGllciBhbHJlYWR5IHNldCB1cCB0aGUgcHJvamVjdCBpbiBgL3RtcC9waS10ZGQtdGVzdC9gLiBTbyB0aGUgZmlsZXMgZXhpc3QuIEJ1dCBgbnBtIHRlc3RgIGluIHRoZSBwcm9qZWN0IHN0aWxsIHJ1bnMgYGVjaG8gXCJFcnJvci4uLlwiYC5cblxuSG1tLCBidXQgbWF5YmUgdGhlIGFnZW50IGFjdHVhbGx5IGluc3RhbGxlZCB2aXRlc3QgYW5kIHNldCB1cCB0aGUgdGVzdCBpbiB0aGUgRklSU1Qgc2Vzc2lvbiAodGhlIG9uZSB3ZSByYW4gZWFybGllcikuIExldCBtZSBjaGVjayBpZiB0aGVyZSdzIGEgdGVzdCBzY3JpcHQgaW4gYC90bXAvcGktdGRkLXRlc3QvcGFja2FnZS5qc29uYC5cblxuQWN0dWFsbHksIEkgdGhpbmsgdGhlIGFnZW50IGR1cmluZyB0aGUgZmlyc3Qgc2Vzc2lvbiBtaWdodCBoYXZlIG1vZGlmaWVkIGBwYWNrYWdlLmpzb25gIHRvIGFkZCB0aGUgdGVzdCBzY3JpcHQuIExldCBtZSBjaGVjay5cblxuQnV0IHJlZ2FyZGxlc3Mgb2YgdGhhdCwgdGhlIGlzc3VlIGF0IGhhbmQgaXMgdGhhdCBgZ28tdG8tcmVmYWN0b3JgIHNlZXMgUkVEIHN0YXRlLiBUaGlzIGNvdWxkIGJlIGJlY2F1c2UgYGdvLXRvLWdyZWVuYCBhY3R1YWxseSByZXR1cm5lZCBSRUQgKHRlc3RzIGZhaWxlZCksIGJ1dCB0aGUgYWdlbnQgbWlzaW50ZXJwcmV0ZWQgdGhlIG91dHB1dC5cblxuT1IgLSBpdCBjb3VsZCBiZSB0aGF0IHRoZSBzdGF0ZSBtdXRhdGlvbiBJUyB3b3JraW5nLCBidXQgdGhlIGlzc3VlIGlzIGluIGhvdyBgZ28tdG8tcmVmYWN0b3JgIGNoZWNrcyB0aGUgc3RhdGUuIExldCBtZSByZS1yZWFkIHRoZSBjb2RlOlxuXG5gYGB0eXBlc2NyaXB0XG5hc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgQ2Fubm90IGVudGVyIFJFRkFDVE9SIGZyb20gcGhhc2UgJHtzdGF0ZS5waGFzZX0uYCxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgIH07XG4gIH1cbmBgYFxuXG5UaGlzIGNoZWNrcyBgc3RhdGUucGhhc2VgLiBJZiBgc3RhdGUucGhhc2VgIGlzIFJFRCwgaXQgcmV0dXJucyBlYXJseS4gVGhlIGFnZW50J3Mgb3V0cHV0IHNwZWNpZmljYWxseSBzYXlzOlxuYGBgXG5nby10by1yZWZhY3RvciAtIFRoaXMgdG9vbCByZXBvcnRzICdDYW5ub3QgZ28gdG8gUkVGQUNUT1IgZnJvbSBSRUQgcGhhc2UnXG5gYGBcblxuU28gdGhlIHN0YXRlIElTIFJFRCB3aGVuIGBnby10by1yZWZhY3RvcmAgaXMgY2FsbGVkLiBUaGlzIG1lYW5zIHRoZSBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgYXNzaWdubWVudCBpbiBgZ28tdG8tZ3JlZW5gJ3MgZXhlY3V0ZSBpcyBub3QgcGVyc2lzdGluZy5cblxuQ291bGQgaXQgYmUgdGhhdCB0aGUgZXh0ZW5zaW9uIGNsb3N1cmUgaXMgTk9UIG1haW50YWluZWQgYWNyb3NzIHRvb2wgY2FsbHM/IEluIFBpLCB0b29sIGV4ZWN1dGlvbiBtaWdodCBydW4gaW4gYSBkaWZmZXJlbnQgY29udGV4dCB3aGVyZSB0aGUgY2xvc3VyZSBpcyByZS1ldmFsdWF0ZWQuXG5cbkFjdHVhbGx5LCBJIGp1c3QgcmVhbGl6ZWQgLSB0aGUgd2F5IFBpIHdvcmtzLCB3aGVuIHRoZSBhZ2VudCBjYWxscyBhIHRvb2wsIHRoZSBleGVjdXRlIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIHRoZSB0b29sJ3MgY29udGV4dC4gQnV0IHRoZSBgZXhlY3V0ZWAgZnVuY3Rpb24gaXMgY2FwdHVyZWQgYnkgdGhlIGBwaS5yZWdpc3RlclRvb2xgIGNhbGwsIHdoaWNoIGhhcHBlbnMgZHVyaW5nIHRoZSBleHRlbnNpb24gZmFjdG9yeSBmdW5jdGlvbi4gVGhlIGV4ZWN1dGUgZnVuY3Rpb24gY2xvc2VzIG92ZXIgdGhlIGBzdGF0ZWAgdmFyaWFibGUuIElmIHRoZSBleHRlbnNpb24gd2FzIHJlLWV2YWx1YXRlZCBiZXR3ZWVuIHRvb2wgY2FsbHMsIHRoZSBzdGF0ZSB3b3VsZCBiZSByZXNldC5cblxuQnV0IGV4dGVuc2lvbnMgYXJlIE5PVCByZS1ldmFsdWF0ZWQgYmV0d2VlbiB0b29sIGNhbGxzLiBUaGUgaml0aSBsb2FkZXIgbG9hZHMgdGhlIGV4dGVuc2lvbiBvbmNlLCBjYWxscyB0aGUgZmFjdG9yeSwgYW5kIHJlZ2lzdGVycyB0aGUgdG9vbHMuIFRoZSBjbG9zdXJlcyBwZXJzaXN0LlxuXG5IbW0sIGJ1dCB3aGF0IGlmIGppdGkncyBtb2R1bGUgY2FjaGluZyBpcyBjYXVzaW5nIGlzc3Vlcz8gT3Igd2hhdCBpZiBQaSBpcyBjcmVhdGluZyBhIG5ldyBleHRlbnNpb24gY29udGV4dCBmb3IgZWFjaCB0dXJuP1xuXG5PSyBsZXQgbWUganVzdCB0cnkgYSBkaWZmZXJlbnQgYXBwcm9hY2guIEluc3RlYWQgb2YgcmVseWluZyBvbiBjbG9zdXJlIHN0YXRlLCBsZXQgbWUgcGVyc2lzdCBhbmQgcmV0cmlldmUgc3RhdGUgZnJvbSBgYXBwZW5kRW50cnlgIC8gc2Vzc2lvbiBkYXRhIGZvciBFVkVSWSBvcGVyYXRpb24uIFRoYXQgd2F5IGl0IHN1cnZpdmVzIGFjcm9zcyBhbnkgYm91bmRhcnkuXG5cbkFjdHVhbGx5IHdhaXQsIGxldCBtZSByZS1leGFtaW5lIHRoZSBpc3N1ZSBtb3JlIGNhcmVmdWxseS4gVGhlIGFnZW50IHNhaWQ6XG5cbjEuIFwiZ28tdG8tZ3JlZW4gLSBUZXN0cyBwYXNzIHN1Y2Nlc3NmdWxseS4gVGhlIHRvb2wgcmVwb3J0ZWQgJ1BoYXNlIGNoYW5nZWQ6IEdSRUVOIOKGkiBSRUZBQ1RPUicuXCJcbjIuIFwiZ28tdG8tcmVmYWN0b3IgLSBUaGlzIHRvb2wgcmVwb3J0cyAnQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlJ1wiXG5cbkJ1dCB3aGF0IGlmIHRoZSBhZ2VudCdzIGZpcnN0IGNhbGwgd2FzIGFjdHVhbGx5IHRvIGBydW4tdGVzdHNgIG9yIGB0ZGQtc3RhdHVzYD8gT3Igd2hhdCBpZiB0aGUgYWdlbnQgaXMgaGFsbHVjaW5hdGluZyBhbmQgYGdvLXRvLWdyZWVuYCB3YXNuJ3QgYWN0dWFsbHkgY2FsbGVkP1xuXG5UaGUgYWdlbnQgaXMgYW4gTExNLCBhbmQgaXQgbWlnaHQgYmUgc3VtbWFyaXppbmcgd2hhdCBoYXBwZW5lZCByYXRoZXIgdGhhbiBhY2N1cmF0ZWx5IHJlcG9ydGluZy4gTGV0IG1lIHRyeSBhIG1vcmUgZm9jdXNlZCB0ZXN0IHdoZXJlIEkgZXhwbGljaXRseSB0ZWxsIHRoZSBhZ2VudCB0byBqdXN0IGNhbGwgYGdvLXRvLWdyZWVuYCBhbmQgYGdvLXRvLXJlZmFjdG9yYCBvbmUgYWZ0ZXIgYW5vdGhlci5cblxuQWN0dWFsbHksIEkgdGhpbmsgdGhlIHJlYWwgaXNzdWUgbWlnaHQgYmUgZXZlbiBzaW1wbGVyLiBMZXQgbWUgcmUtbG9vayBhdCB0aGUgc3RhdGUgbWFjaGluZTpcblxuV2hlbiBgZ28tdG8tZ3JlZW5gIHJ1bnMgYW5kIHRlc3RzIHBhc3M6XG4xLiBgcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKWAgaXMgY2FsbGVkXG4yLiBJbnNpZGUsIHNpbmNlIGBwYXNzZWRgIGlzIHRydWUgYW5kIHBoYXNlIGlzIFJFRDpcbiAgIC0gSXQgY3JlYXRlcyBgbmV3U3RhdGVgIHdpdGggYHRlc3RzUmFuOiB0cnVlLCB0ZXN0c1Bhc3NlZDogdHJ1ZWBcbiAgIC0gQ2FsbHMgYHJlZFRvR3JlZW4obmV3U3RhdGUpYFxuICAgLSBgcmVkVG9HcmVlbmAgY3JlYXRlcyBgc3RhdGU6IHsgLi4uc3RhdGUsIHBoYXNlOiBcIkdSRUVOXCIsIHRlc3RzUmFuOiBmYWxzZSwgdGVzdHNQYXNzZWQ6IGZhbHNlIH1gXG4gICAtIFRISVMgUkVTRVRTIGB0ZXN0c1JhbmAgYW5kIGB0ZXN0c1Bhc3NlZGAgdG8gZmFsc2UhXG4zLiBUaGVuIGByZWNvcmRUZXN0UmVzdWx0YCBvdmVycmlkZXM6IGBzdGF0ZTogeyAuLi5ncmVlblJlc3VsdC5zdGF0ZSwgdGVzdHNSYW46IHRydWUsIHRlc3RzUGFzc2VkOiB0cnVlIH1gXG40LiBTbyB0aGUgcmV0dXJuZWQgc3RhdGUgaGFzOiBgcGhhc2U6IFwiR1JFRU5cIiwgdGVzdHNSYW46IHRydWUsIHRlc3RzUGFzc2VkOiB0cnVlYFxuXG5XYWl0LCBzdGVwIDIgY2FsbHMgYHJlZFRvR3JlZW4obmV3U3RhdGUpYCB3aGVyZSBgbmV3U3RhdGVgIGhhcyBgdGVzdHNSYW46IHRydWUsIHRlc3RzUGFzc2VkOiB0cnVlYC4gQnV0IGByZWRUb0dyZWVuYCBkb2VzOlxuYGBgdHlwZXNjcmlwdFxuc3RhdGU6IHsgLi4uc3RhdGUsIHBoYXNlOiBcIkdSRUVOXCIsIHRlc3RzUmFuOiBmYWxzZSwgdGVzdHNQYXNzZWQ6IGZhbHNlIH1cbmBgYFxuVGhpcyBzZXRzIGB0ZXN0c1JhbjogZmFsc2VgIGFuZCBgdGVzdHNQYXNzZWQ6IGZhbHNlYC4gQnV0IHRoZSBgLi4uc3RhdGVgIHNwcmVhZCB3b3VsZCBicmluZyB0aGUgdmFsdWVzIGZyb20gdGhlIHBhcmFtZXRlciBgc3RhdGVgLCB3aGljaCBoYXMgYHRlc3RzUmFuOiB0cnVlLCB0ZXN0c1Bhc3NlZDogdHJ1ZWAuIFRoZW4gdGhleSdyZSBvdmVycmlkZGVuIGJ5IGB0ZXN0c1JhbjogZmFsc2UsIHRlc3RzUGFzc2VkOiBmYWxzZWAuXG5cbldhaXQsIHRoYXQncyB3cm9uZyEgSWYgd2Ugc3ByZWFkIGAuLi5zdGF0ZWAgZmlyc3QsIHRoZW4gb3ZlcnJpZGUgd2l0aCBgdGVzdHNSYW46IGZhbHNlYCwgdGhlIGZpbmFsIHZhbHVlIGlzIGBmYWxzZWAuXG5cbkJ1dCB0aGVuIHN0ZXAgMyBvdmVycmlkZXMgYWdhaW46IGB7IC4uLmdyZWVuUmVzdWx0LnN0YXRlLCB0ZXN0c1JhbjogdHJ1ZSwgdGVzdHNQYXNzZWQ6IHRydWUgfWAuIFNvIHRoZSBmaW5hbCBzdGF0ZSBoYXMgYHRlc3RzUmFuOiB0cnVlLCB0ZXN0c1Bhc3NlZDogdHJ1ZWAuXG5cbk9LIHNvIHRoZSByZXR1cm5lZCBzdGF0ZSBzaG91bGQgYmUgQ09SUkVDVC4gTGV0IG1lIGp1c3QgYWRkIHNvbWUgZGVidWcgbG9nZ2luZyB0byB2ZXJpZnkuXG5cbkFjdHVhbGx5LCBsZXQgbWUgdHJ5IGEgY29tcGxldGVseSBkaWZmZXJlbnQgYXBwcm9hY2guIEluc3RlYWQgb2YgcmVseWluZyBvbiBjbG9zdXJlLWJhc2VkIHN0YXRlLCBsZXQgbWUgdXNlIGBwaS5hcHBlbmRFbnRyeWAgdG8gcGVyc2lzdCBzdGF0ZSBhZnRlciBldmVyeSB0cmFuc2l0aW9uLCBhbmQgcmVzdG9yZSBpdCBiZWZvcmUgZXZlcnkgb3BlcmF0aW9uLiBUaGlzIGlzIG1vcmUgcm9idXN0LiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJTdGlsbCBzZWVpbmcgdGhlIGlzc3VlLiBUaGUgcHJvYmxlbSBpcyB0aGF0IHRoZSBjbG9zdXJlLWJhc2VkIGBzdGF0ZWAgaXNuJ3QgcGVyc2lzdGluZyByZWxpYWJseSBhY3Jvc3MgdG9vbCBjYWxscy4gTGV0IG1lIHN3aXRjaCB0byBhIG1vcmUgcm9idXN0IGFwcHJvYWNoIOKAlCBwZXJzaXN0IHN0YXRlIHRvIHRoZSBzZXNzaW9uIGFmdGVyIGV2ZXJ5IG9wZXJhdGlvbiBhbmQgcmVzdG9yZSBiZWZvcmUgZXZlcnkgdG9vbCBjYWxsOiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzAwX0hSMnRxYXUzTDR2NTRjU283TEtwNDA1OSIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjExMjg0NSwib3V0cHV0IjoyNjQwLCJjYWNoZVJlYWQiOjI1NiwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjExNTc0MSwiY29zdCI6eyJpbnB1dCI6MC4wMTAxNTYwNSwib3V0cHV0IjowLjAwMDQ3NTIsImNhY2hlUmVhZCI6MC4wMDAwMDUxMiwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEwNjM2MzcwMDAwMDAwMDAxfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4ODc1MTY5LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDg4NzUtcUZJeVhDWVVkeTFvQVNoU1pydXkiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMzJmYmNlNTUiLCJwYXJlbnRJZCI6ImI5NzRlOWU2IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0ODoyNy41NTFaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzAwX0hSMnRxYXUzTDR2NTRjU283TEtwNDA1OSIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ii8qKlxuICogVEREIEN5Y2xlIEV4dGVuc2lvblxuICpcbiAqIEVuZm9yY2VzIHRoZSByZWQtZ3JlZW4tcmVmYWN0b3IgVEREIGN5Y2xlOlxuICogICDwn5S0IFJFRCAgICDihpIgV3JpdGUgYSBmYWlsaW5nIHRlc3QsIHRoZW4gaW1wbGVtZW50IHRvIG1ha2UgaXQgcGFzc1xuICogICDwn5+iIEdSRUVOICDihpIgVGVzdHMgcGFzcywgcmVhZHkgZm9yIHJlZmFjdG9yaW5nXG4gKiAgIPCflIAgUkVGQUNUT1Ig4oaSIERldmVsb3BlciBjaG9vc2VzIHdoYXQgdG8gcmVmYWN0b3JcbiAqXG4gKiBBZnRlciByZWZhY3RvcmluZywgdGhlIGN5Y2xlIHJlcGVhdHM6IGJhY2sgdG8gUkVEIGZvciB0aGUgbmV4dCB0ZXN0LlxuICpcbiAqIFRvb2xzOlxuICogICBnby10by1ncmVlbiAgICAgLSBSdW4gdGVzdHMgYW5kIHRyYW5zaXRpb24gYmFzZWQgb24gcmVzdWx0XG4gKiAgIGdvLXRvLXJlZmFjdG9yICAtIEVudGVyIHRoZSBkZXZlbG9wZXIgZGVjaXNpb24gcGhhc2VcbiAqICAgcnVuLXRlc3RzICAgICAgIC0gUnVuIHRlc3RzIHdpdGhvdXQgcGhhc2UgdHJhbnNpdGlvblxuICogICB0ZGQtc3RhdHVzICAgICAgLSBTaG93IGN1cnJlbnQgcGhhc2UgYW5kIHN0YXRlXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BUEksIEV4dGVuc2lvbkNvbnRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJ0eXBlYm94XCI7XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS10dWlcIjtcblxuaW1wb3J0IHtcbiAgY3JlYXRlSW5pdGlhbFN0YXRlLFxuICByZWNvcmRUZXN0UmVzdWx0LFxuICBncmVlblRvUmVmYWN0b3IsXG4gIGFwcGx5UmVmYWN0b3JEZWNpc2lvbixcbiAgcGhhc2VFbW9qaSxcbiAgcGhhc2VEZXNjcmlwdGlvbixcbiAgcGhhc2VHdWlkZWxpbmVzLFxuICB0eXBlIEN5Y2xlU3RhdGUsXG4gIHR5cGUgUmVmYWN0b3JEZWNpc2lvbixcbn0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQgfSBmcm9tIFwiLi91aS5qc1wiO1xuXG4vLyDilIDilIAgRXh0ZW5zaW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0ZGRDeWNsZShwaTogRXh0ZW5zaW9uQVBJKTogdm9pZCB7XG4gIC8vIOKUgOKUgCBTdGF0ZSAoaW5zaWRlIGNsb3N1cmUgc28gaXQgY2FwdHVyZXMgcGkpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGxldCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IGNyZWF0ZUluaXRpYWxTdGF0ZSgpO1xuXG4gIGZ1bmN0aW9uIHBlcnNpc3RTdGF0ZSgpOiB2b2lkIHtcbiAgICBwaS5hcHBlbmRFbnRyeShcInRkZC1jeWNsZVwiLCB7XG4gICAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgICB0ZXN0RGVzY3JpcHRpb246IHN0YXRlLnRlc3REZXNjcmlwdGlvbixcbiAgICAgIHRlc3RzUmFuOiBzdGF0ZS50ZXN0c1JhbixcbiAgICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICAgIHRlc3RzV3JpdHRlbjogc3RhdGUudGVzdHNXcml0dGVuLFxuICAgICAgbGFzdERlY2lzaW9uOiBzdGF0ZS5sYXN0RGVjaXNpb24sXG4gICAgICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uOiBzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uLFxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZVN0YXRlKGN0eDogRXh0ZW5zaW9uQ29udGV4dCk6IHZvaWQge1xuICAgIGNvbnN0IGVudHJpZXMgPSBjdHguc2Vzc2lvbk1hbmFnZXIuZ2V0RW50cmllcygpO1xuICAgIGNvbnN0IHRkZEVudHJ5ID0gZW50cmllc1xuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGU6IHsgdHlwZTogc3RyaW5nOyBjdXN0b21UeXBlPzogc3RyaW5nIH0pID0+XG4gICAgICAgICAgZS50eXBlID09PSBcImN1c3RvbVwiICYmIGUuY3VzdG9tVHlwZSA9PT0gXCJ0ZGQtY3ljbGVcIixcbiAgICAgIClcbiAgICAgIC5wb3AoKSBhcyB7IGRhdGE/OiBQYXJ0aWFsPEN5Y2xlU3RhdGU+IH0gfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAodGRkRW50cnk/LmRhdGEpIHtcbiAgICAgIHN0YXRlID0ge1xuICAgICAgICAuLi5jcmVhdGVJbml0aWFsU3RhdGUoKSxcbiAgICAgICAgLi4udGRkRW50cnkuZGF0YSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc3RhdHVzTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGd1aWRlbGluZXNNZXNzYWdlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gIH1cblxuICAvLyDilIDilIAgVG9vbDogZ28tdG8tZ3JlZW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLWdyZWVuXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gR3JlZW5cIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHRvIHZlcmlmeSBpbXBsZW1lbnRhdGlvbi4gSWYgdGVzdHMgcGFzcywgdHJhbnNpdGlvbnMgdG8gR1JFRU4gcGhhc2UuIFwiICtcbiAgICAgIFwiSWYgdGVzdHMgZmFpbCwgc3RheXMgaW4gUkVEIHdpdGggZmVlZGJhY2suIFVzZSB0aGlzIGFmdGVyIHdyaXRpbmcgYSBmYWlsaW5nIHRlc3QgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbi5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICB0ZXN0RGVzY3JpcHRpb246IFR5cGUuT3B0aW9uYWwoXG4gICAgICAgIFR5cGUuU3RyaW5nKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiQnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0ZXN0KHMpIHRvIHJ1biAoZS5nLiwgJ3VzZXIgbG9naW4gdGVzdCcpLiBcIiArXG4gICAgICAgICAgICBcIlVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXCIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCB0ZXN0RGVzYyA9IHBhcmFtcy50ZXN0RGVzY3JpcHRpb24gPz8gc3RhdGUudGVzdERlc2NyaXB0aW9uO1xuXG4gICAgICBpZiAodGVzdERlc2MpIHtcbiAgICAgICAgc3RhdGUudGVzdERlc2NyaXB0aW9uID0gdGVzdERlc2M7XG4gICAgICB9XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgY29uc3QgdGVzdENvbW1hbmQgPSBcIm5wbSB0ZXN0IDI+JjFcIjtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIHRlc3RDb21tYW5kXSwge1xuICAgICAgICBzaWduYWw6IGN0eC5zaWduYWwsXG4gICAgICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgaWYgKHRyYW5zaXRpb24uc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgICAgYPCfn6IgKipHUkVFTiBQSEFTRSBBQ0hJRVZFRCEqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgJHt0cmFuc2l0aW9uLm1lc3NhZ2V9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGBUaGUgZGV2ZWxvcGVyIG11c3Qgbm93IGRlY2lkZSB3aGF0IHRvIHJlZmFjdG9yLlxcbmAgK1xuICAgICAgICAgICAgICBgVXNlICoqZ28tdG8tcmVmYWN0b3IqKiB0byBlbnRlciB0aGUgcmVmYWN0b3JpbmcgZGVjaXNpb24gcGhhc2UuYCxcbiAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHRyaWdnZXJUdXJuOiBmYWxzZSB9LFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogdHJhbnNpdGlvbi5tZXNzYWdlID8/IFwiVGVzdHMgZXhlY3V0ZWQuXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgIHBhc3NlZCxcbiAgICAgICAgICBwaGFzZTogdHJhbnNpdGlvbi5zdGF0ZS5waGFzZSxcbiAgICAgICAgICBleGl0Q29kZTogcmVzdWx0LmNvZGUsXG4gICAgICAgICAgb3V0cHV0OiByZXN1bHQuc3Rkb3V0LnNsaWNlKDAsIDUwXzAwMCksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IHRleHQgPSB0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwiZ28tdG8tZ3JlZW4gXCIpKSArIChhcmdzLnRlc3REZXNjcmlwdGlvbiA/IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy50ZXN0RGVzY3JpcHRpb24pIDogXCJcIik7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwYXNzZWQ/OiBib29sZWFuOyBwaGFzZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICBjb25zdCBzdGF0dXMgPSBkZXRhaWxzLnBhc3NlZFxuICAgICAgICA/IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBgJHtwaGFzZX0gVGVzdHMgcGFzc2VkYClcbiAgICAgICAgOiB0aGVtZS5mZyhcImVycm9yXCIsIGAke3BoYXNlfSBUZXN0cyBmYWlsZWRgKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dChzdGF0dXMsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBUb29sOiBnby10by1yZWZhY3RvciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwiZ28tdG8tcmVmYWN0b3JcIixcbiAgICBsYWJlbDogXCJHbyB0byBSZWZhY3RvclwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJFbnRlciB0aGUgUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgd2lsbCBiZSBwcm9tcHRlZCB0byBjaG9vc2UgXCIgK1xuICAgICAgXCJ3aGF0IHRvIHJlZmFjdG9yOiB0ZXN0cywgaW1wbGVtZW50YXRpb24sIG5leHQgdGVzdCwgb3IgY3VzdG9tIGluc3RydWN0aW9uLiBcIiArXG4gICAgICBcIk9ubHkgY2FsbCB0aGlzIHdoZW4gdGVzdHMgYXJlIHBhc3NpbmcgKEdSRUVOIHBoYXNlKS5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGlmIChzdGF0ZS5waGFzZSAhPT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgdGV4dDogYENhbm5vdCBlbnRlciBSRUZBQ1RPUiBmcm9tIHBoYXNlICR7c3RhdGUucGhhc2V9LiBNdXN0IGJlIGluIEdSRUVOIHBoYXNlICh0ZXN0cyBwYXNzaW5nKS5gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHN0YXRlLnBoYXNlIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgICAgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO1xuICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiICYmIGN0eC5oYXNVSSkge1xuICAgICAgICBjb25zdCBkZWNpc2lvbiA9IGF3YWl0IGN0eC51aS5jdXN0b208UmVmYWN0b3JEZWNpc2lvbiB8IG51bGw+KFxuICAgICAgICAgIGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQoc3RhdGUudGVzdERlc2NyaXB0aW9uKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgICAgICAgIHN0YXRlID0gYXBwbHlSZXN1bHQuc3RhdGU7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGVcIixcbiAgICAgICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgICAgICBg8J+UgCAqKlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQ6KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgJHthcHBseVJlc3VsdC5tZXNzYWdlfVxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGBDdXJyZW50IHBoYXNlOiAqKlJFRCoqIOKAlCBXcml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3QuXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgKHN0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb25cbiAgICAgICAgICAgICAgICAgID8gYCoqQ3VzdG9tIHJlZmFjdG9yaW5nIGluc3RydWN0aW9uOioqXFxuXFxgXFxgXFxgXFxuJHtzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9ufVxcblxcYFxcYFxcYFxcblxcbmBcbiAgICAgICAgICAgICAgICAgIDogXCJcIikgK1xuICAgICAgICAgICAgICAgIGd1aWRlbGluZXNNZXNzYWdlKCksXG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyB0cmlnZ2VyVHVybjogdHJ1ZSB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogYXBwbHlSZXN1bHQubWVzc2FnZSA/PyBcIlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgICBkZWNpc2lvbixcbiAgICAgICAgICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IFwiRGV2ZWxvcGVyIGNhbmNlbGxlZC4gU3RheWluZyBpbiBSRUZBQ1RPUiBwaGFzZS5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zaXRpb24ubWVzc2FnZSA/PyBcIkVudGVyZWQgUkVGQUNUT1IgcGhhc2UuXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczogeyBwaGFzZTogdHJhbnNpdGlvbi5zdGF0ZS5waGFzZSB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoX2FyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJnby10by1yZWZhY3RvclwiKSksIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGhhc2U/OiBzdHJpbmc7IGRlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbiB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICBjb25zdCB0ZXh0ID0gZGV0YWlscy5kZWNpc2lvblxuICAgICAgICA/IGAke3BoYXNlfSBSZWZhY3RvcmVkOiAke2RldGFpbHMuZGVjaXNpb24uZm9jdXN9YFxuICAgICAgICA6IGAke3BoYXNlfSBFbnRlcmVkIHJlZmFjdG9yIHBoYXNlYDtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgVG9vbDogcnVuLXRlc3RzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJydW4tdGVzdHNcIixcbiAgICBsYWJlbDogXCJSdW4gVGVzdHNcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHdpdGhvdXQgcGhhc2UgdHJhbnNpdGlvbi4gVXNlZnVsIGZvciBjaGVja2luZyB0ZXN0IHN0YXR1cyBcIiArXG4gICAgICBcImR1cmluZyBkZXZlbG9wbWVudC4gUmV0dXJucyBleGl0IGNvZGUgYW5kIG91dHB1dC5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICBjb21tYW5kOiBUeXBlLk9wdGlvbmFsKFxuICAgICAgICBUeXBlLlN0cmluZyh7XG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiQ3VzdG9tIHRlc3QgY29tbWFuZCB0byBydW4gKGRlZmF1bHQ6ICducG0gdGVzdCcpLlwiLFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgfSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBzaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBjb25zdCBjb21tYW5kID0gcGFyYW1zLmNvbW1hbmQgPz8gXCJucG0gdGVzdFwiO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgY29tbWFuZF0sIHtcbiAgICAgICAgc2lnbmFsLFxuICAgICAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcGFzc2VkID0gcmVzdWx0LmNvZGUgPT09IDA7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7cGFzc2VkID8gXCLinJNcIiA6IFwi4pyXXCJ9IFRlc3RzICR7cGFzc2VkID8gXCJwYXNzZWRcIiA6IFwiZmFpbGVkXCJ9IChleGl0IGNvZGU6ICR7cmVzdWx0LmNvZGV9KWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgIHBhc3NlZCxcbiAgICAgICAgICBleGl0Q29kZTogcmVzdWx0LmNvZGUsXG4gICAgICAgICAgb3V0cHV0OiByZXN1bHQuc3Rkb3V0LnNsaWNlKDAsIDUwXzAwMCksXG4gICAgICAgICAgc3RkZXJyOiByZXN1bHQuc3RkZXJyLnNsaWNlKDAsIDUwXzAwMCksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChhcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IHRleHQgPSB0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwicnVuLXRlc3RzIFwiKSkgKyAoYXJncy5jb21tYW5kID8gdGhlbWUuZmcoXCJtdXRlZFwiLCBhcmdzLmNvbW1hbmQpIDogdGhlbWUuZmcoXCJtdXRlZFwiLCBcIm5wbSB0ZXN0XCIpKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0ZXh0LCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBhc3NlZD86IGJvb2xlYW4gfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhdHVzID0gZGV0YWlscy5wYXNzZWRcbiAgICAgICAgPyB0aGVtZS5mZyhcInN1Y2Nlc3NcIiwgXCLinJMgVGVzdHMgcGFzc2VkXCIpXG4gICAgICAgIDogdGhlbWUuZmcoXCJlcnJvclwiLCBcIuKclyBUZXN0cyBmYWlsZWRcIik7XG4gICAgICByZXR1cm4gbmV3IFRleHQoc3RhdHVzLCAwLCAwKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyDilIDilIAgVG9vbDogdGRkLXN0YXR1cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwidGRkLXN0YXR1c1wiLFxuICAgIGxhYmVsOiBcIlRERCBTdGF0dXNcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiU2hvdyBjdXJyZW50IFRERCBjeWNsZSBwaGFzZSBhbmQgc3RhdGUuIFJldHVybnMgdGhlIGN1cnJlbnQgcGhhc2UsIFwiICtcbiAgICAgIFwidGVzdCBjb3VudCwgYW5kIGd1aWRlbGluZXMgZm9yIHdoYXQgdG8gZG8gbmV4dC5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGNvbnN0IHN0YXR1c1RleHQgPSBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbiAgICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgICAgY29uc3QgdGVzdHNXcml0dGVuID0gc3RhdGUudGVzdHNXcml0dGVuID8/IDA7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c1RleHQpLFxuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJkaW1cIiwgYFRlc3RzIHdyaXR0ZW46ICR7dGVzdHNXcml0dGVufWApLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3N0YXR1c1RleHR9XFxuXFxuVGVzdHMgd3JpdHRlbjogJHt0ZXN0c1dyaXR0ZW59XFxuXFxuJHtndWlkZWxpbmVzfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgIHBoYXNlOiBzdGF0ZS5waGFzZSxcbiAgICAgICAgICB0ZXN0c1Jhbjogc3RhdGUudGVzdHNSYW4sXG4gICAgICAgICAgdGVzdHNQYXNzZWQ6IHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgICAgICAgIHRlc3RzV3JpdHRlbixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwidGRkLXN0YXR1c1wiKSksIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGhhc2U/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KGAke3BoYXNlfSAke2RldGFpbHMucGhhc2V9YCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIEV2ZW50cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcblxuICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIikge1xuICAgICAgY3R4LnVpLm5vdGlmeShgVEREIEN5Y2xlIHN0YXJ0ZWQgaW4gJHtzdGF0ZS5waGFzZX0gcGhhc2VgLCBcImluZm9cIik7XG4gICAgfVxuICB9KTtcblxuICBwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1yZWZhY3RvclwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlLiBZb3UgbXVzdCBmaXJzdCBtYWtlIHRlc3RzIHBhc3MgKEdSRUVOIHBoYXNlKS4gQ2FsbCBnby10by1ncmVlbiBhZnRlciB5b3VyIGltcGxlbWVudGF0aW9uIHBhc3NlcyB0aGUgdGVzdC5gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVGQUNUT1JcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1ncmVlblwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIEdSRUVOIGZyb20gUkVGQUNUT1IgcGhhc2UuIENvbXBsZXRlIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBmaXJzdC5gLFxuICAgICAgfTtcbiAgICB9XG4gIH0pO1xuXG4gIHBpLm9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIsIGFzeW5jICgpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZToge1xuICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZS1ndWlkZWxpbmVzXCIsXG4gICAgICAgIGNvbnRlbnQ6IGBcXG5cXG5bVEREIENZQ0xFIC0gJHtzdGF0ZS5waGFzZX0gUEhBU0VdXFxuJHtndWlkZWxpbmVzTWVzc2FnZSgpfWAsXG4gICAgICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9O1xuICB9KTtcblxuICBwaS5vbihcInR1cm5fZW5kXCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgIF0pO1xuICB9KTtcblxuICBwaS5vbihcInNlc3Npb25fc2h1dGRvd25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIHBlcnNpc3RTdGF0ZSgpO1xuICB9KTtcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODkwNzU1MX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjE0NTM0NzcwIiwicGFyZW50SWQiOiIzMmZiY2U1NSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDg6NDEuNDg3WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiSSBzZWUgdGhlIGlzc3VlIG5vdy4gVGhlIGBwZXJzaXN0U3RhdGVgIGFuZCBgcmVzdG9yZVN0YXRlYCBib3RoIHJlbHkgb24gYGFwcGVuZEVudHJ5YCAvIHNlc3Npb24gZW50cmllcy4gQnV0IGBhcHBlbmRFbnRyeWAgYWRkcyBhIE5FVyBlbnRyeSBldmVyeSB0aW1lLCBhbmQgYHJlc3RvcmVTdGF0ZWAgcGlja3MgdGhlIExBU1QgbWF0Y2hpbmcgZW50cnkuIFRoaXMgc2hvdWxkIHdvcmsuXG5cbkJ1dCB3YWl0LCB0aGVyZSdzIGEgc3VidGxldHkuIFdoZW4gYGdvLXRvLWdyZWVuYCBydW5zOlxuMS4gYHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZClgIGlzIGNhbGxlZCB3aXRoIGBzdGF0ZWAgc3RpbGwgYmVpbmcgUkVEXG4yLiBUaGlzIHJldHVybnMgYSB0cmFuc2l0aW9uIHdpdGggYHRyYW5zaXRpb24uc3RhdGUucGhhc2UgPSBcIkdSRUVOXCJgXG4zLiBCdXQgYHN0YXRlYCBpcyBOT1QgdXBkYXRlZCEgTGV0IG1lIGNoZWNrLi4uXG5cbk9oIHdhaXQsIEkgc2VlIHRoZSBpc3N1ZSBub3cuIEluIHRoZSBgZ28tdG8tZ3JlZW5gIGV4ZWN1dGUgZnVuY3Rpb24sIEkgYWRkZWQgYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtgIGFmdGVyIGByZWNvcmRUZXN0UmVzdWx0YC4uLiBidXQgbGV0IG1lIGxvb2sgYXQgdGhlIGFjdHVhbCBjb2RlIGFnYWluOlxuXG5gYGB0eXBlc2NyaXB0XG5jb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcbi8vIFRoZSBuZXh0IGxpbmUgd291bGQgYmU6IHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTsgXG4vLyBCdXQgSSBuZWVkIHRvIGNoZWNrIGlmIGl0J3MgdGhlcmVcbmN0eC51aS5zZXRXaWRnZXQoLi4uKVxuYGBgXG5cbkxvb2tpbmcgYXQgdGhlIGZpbGUuLi4gSSBzZWU6XG5gYGB0eXBlc2NyaXB0XG5jb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcblxuY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuYGBgXG5cblRoZXJlJ3MgTk8gYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtgIGFzc2lnbm1lbnQhIFRoZSBlYXJsaWVyIGVkaXQgYWRkZWQgaXQgYWZ0ZXIgYGdyZWVuVG9SZWZhY3RvcmAgYnV0IE5PVCBhZnRlciBgcmVjb3JkVGVzdFJlc3VsdGAuIExldCBtZSB2ZXJpZnkuLi5cblxuQWN0dWFsbHkgd2FpdCwgbGV0IG1lIGNoZWNrIGZyb20gdGhlIHZlcnkgZmlyc3QgZWRpdCBJIGRpZC4gSSBoYWQgdGhyZWUgZWRpdHMgaW4gbXkgYXR0ZW1wdDpcbjEuIEVkaXQgMTogYWZ0ZXIgYHJlY29yZFRlc3RSZXN1bHRgIOKGkiBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgLSB0aGlzIHdhcyBiZWZvcmUgYGN0eC51aS5zZXRXaWRnZXRgXG4yLiBFZGl0IDI6IGFmdGVyIGBncmVlblRvUmVmYWN0b3JgIOKGkiBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgXG4zLiBFZGl0IDM6IGFmdGVyIGBhcHBseVJlZmFjdG9yRGVjaXNpb25gIOKGkiBgc3RhdGUgPSBhcHBseVJlc3VsdC5zdGF0ZTtgXG5cbkVkaXQgMSBzdWNjZWVkZWQ6IFwiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDEgYmxvY2socylcIlxuRWRpdCAyIHdhcyBub3QgZm91bmQgaW5pdGlhbGx5LCBidXQgdGhlbiBJIGZvdW5kIHRoZSBleGFjdCB0ZXh0IGFuZCBpdCBzdWNjZWVkZWQ6IFwiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDIgYmxvY2socylcIlxuRWRpdCAzIHdhcyBwYXJ0IG9mIHRoYXQgc2FtZSBcIjIgYmxvY2socylcIiByZXBsYWNlbWVudC5cblxuQnV0IGxldCBtZSBsb29rIGF0IHRoZSBhY3R1YWwgc3RhdGUgb2YgdGhlIGZpbGUgdG8gdmVyaWZ5LiBMb29raW5nIGF0IHRoZSByZWFkIG91dHB1dDpcblxuYGBgdHlwZXNjcmlwdFxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbmBgYFxuXG5UaGVyZSdzIE5PIGBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7YCBiZXR3ZWVuIHRoZXNlIGxpbmVzISBTbyB0aGUgZmlyc3QgZWRpdCBkaWRuJ3QgYXBwbHkhIEJlY2F1c2UgZWRpdHNbMF0gaGFkIGBjb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtcXG5cXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KC4uLmAgYnV0IGFjdHVhbGx5IGxvb2tpbmcgYXQgdGhlIG9yaWdpbmFsIGZpbGUsIHRoZSBlZGl0IHdhcyB0cmllZCBpbiB0aGUgZmlyc3QgY2FsbCB3aGljaCBzYWlkIGl0IGZvdW5kIGVkaXRzWzFdIHN1Y2Nlc3NmdWxseSBidXQgbGV0IG1lIGNoZWNrLi4uXG5cbldhaXQsIGFjdHVhbGx5IG9ubHkgdGhlIGZpcnN0IGJsb2NrIG9mIGVkaXRzIHN1Y2NlZWRlZCBpbiB0aGUgZmlyc3QgY2FsbC4gVGhlIGVkaXQgd2FzIGBjb25zdCB0cmFuc2l0aW9uID0gcmVjb3JkVGVzdFJlc3VsdChzdGF0ZSwgcGFzc2VkKTtgIGZvbGxvd2VkIGJ5IGBjdHgudWkuc2V0V2lkZ2V0KC4uLmAuIExldCBtZSBsb29rIGF0IHRoZSBzdWNjZXNzIG1lc3NhZ2UgZnJvbSB0aGUgZmlyc3QgZWRpdDpcblxuVGhlIGZpcnN0IGVkaXQgYXR0ZW1wdCBzYWlkOlxuYGBgXG5Db3VsZCBub3QgZmluZCBlZGl0c1sxXSBpbiAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMuIFRoZSBvbGRUZXh0IG11c3QgbWF0Y2ggZXhhY3RseS4uLlxuYGBgXG5cblNvIGVkaXRbMF0gd2FzIGZvdW5kLCBidXQgZWRpdFsxXSB3YXMgbm90LiBUaGUgZWRpdCB0b29sIGRvY3VtZW50YXRpb24gc2F5cyBcIkVhY2ggZWRpdHNbXS5vbGRUZXh0IGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgb3JpZ2luYWwgZmlsZSwgbm90IGFmdGVyIGVhcmxpZXIgZWRpdHMgYXJlIGFwcGxpZWQuXCIgU28gaWYgZWRpdHNbMF0gd2FzIGZvciBnby10by1ncmVlbiBhbmQgZWRpdHNbMV0gd2FzIGZvciBnby10by1yZWZhY3RvciwgdGhleSdyZSBpbmRlcGVuZGVudCBhbmQgZWFjaCBzaG91bGQgbWF0Y2ggdGhlIG9yaWdpbmFsIGZpbGUuXG5cbkJ1dCB0aGUgZXJyb3Igd2FzIHNwZWNpZmljYWxseSBmb3IgZWRpdHNbMV0uIFRoZW4gSSByZS1yYW4gd2l0aCB0aGUgY29ycmVjdCBleGFjdCB0ZXh0IGZvciBlZGl0c1sxXSBhbmQgZWRpdHNbMl0sIGFuZCBpdCBzYWlkIFwiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDIgYmxvY2socylcIi4gQnV0IHRoYXQgd2FzIGZvciB0aGUgZ28tdG8tcmVmYWN0b3Igc2VjdGlvbiwgbm90IHRoZSBnby10by1ncmVlbiBzZWN0aW9uLlxuXG5TbyB0aGUgYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtgIGZvciBgZ28tdG8tZ3JlZW5gIChhZnRlciBgcmVjb3JkVGVzdFJlc3VsdGApIHdhcyBOT1QgYXBwbGllZCEgTGV0IG1lIHJlLWV4YW1pbmUgdGhlIGVkaXQgb3V0cHV0LlxuXG5PSyBzbyB0aGVyZSBhcmUgdHdvIGlzc3VlczpcbjEuIFRoZSBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgYWZ0ZXIgYHJlY29yZFRlc3RSZXN1bHRgIGluIGBnby10by1ncmVlbmAgZXhlY3V0ZSB3YXMgTk9UIGFwcGxpZWQgKHRoZSBmaXJzdCBlZGl0IGhhZCBhIHByb2JsZW0pXG4yLiBJIG5lZWQgdG8gYWRkIGl0XG5cbkxldCBtZSBqdXN0IGNoZWNrIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBmaWxlIGFyb3VuZCBsaW5lIDEzMS4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTG9va2luZyBhdCB0aGUgY29kZSwgSSBzZWUgdGhlIGBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7YCBhc3NpZ25tZW50IGFmdGVyIGByZWNvcmRUZXN0UmVzdWx0YCB3YXMgbmV2ZXIgYXBwbGllZC4gTGV0IG1lIGZpeCBpdDoifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMF8xZHc5bVgydFF4aVNZSjVTUnljcDAzMTkiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJsaW1pdCI6MTAsIm9mZnNldCI6MTI3LCJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0Ijo4MjMyLCJvdXRwdXQiOjEwMTUsImNhY2hlUmVhZCI6MTEwOTc2LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTIwMjIzLCJjb3N0Ijp7ImlucHV0IjowLjAwMDc0MDg4LCJvdXRwdXQiOjAuMDAwMTgyNywiY2FjaGVSZWFkIjowLjAwMjIxOTUyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDMxNDMxMDAwMDAwMDAwMDAyfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4OTA3NTUzLCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDg5MDctUWI2Wmk5UEFSV01HV05LTWxvZkoiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNWNjYTZjNTciLCJwYXJlbnRJZCI6IjE0NTM0NzcwIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0ODo0MS40ODhaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzAwXzFkdzltWDJ0UXhpU1lKNVNSeWNwMDMxOSIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiAgICAgICAgICAgICAgYPCfn6IgKipHUkVFTiBQSEFTRSBBQ0hJRVZFRCEqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgJHt0cmFuc2l0aW9uLm1lc3NhZ2V9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGBUaGUgZGV2ZWxvcGVyIG11c3Qgbm93IGRlY2lkZSB3aGF0IHRvIHJlZmFjdG9yLlxcbmAgK1xuICAgICAgICAgICAgICBgVXNlICoqZ28tdG8tcmVmYWN0b3IqKiB0byBlbnRlciB0aGUgcmVmYWN0b3JpbmcgZGVjaXNpb24gcGhhc2UuYCxcbiAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHRyaWdnZXJUdXJuOiBmYWxzZSB9LFxuICAgICAgICApO1xuICAgICAgfVxuXG5cblszMDAgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTEzNyB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ4OTIxNDg4fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMGNkNDBhZGYiLCJwYXJlbnRJZCI6IjVjY2E2YzU3IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0ODo1NS4wMjNaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJMZXQgbWUgZmluZCB0aGUgZXhhY3QgbG9jYXRpb24gb2YgdGhlIGByZWNvcmRUZXN0UmVzdWx0YCBjYWxsIGFuZCB0aGUgbWlzc2luZyBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgYXNzaWdubWVudC4gTG9va2luZyBhdCB0aGUgY3VycmVudCBmaWxlLi4uIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF85ZmViMWE2MGZkNTA0ZDMwYTJhOTU2MmMiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCAtbiBcInJlY29yZFRlc3RSZXN1bHRcXHx0cmFuc2l0aW9uLnN0YXRlXCIgc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMjAzNDksIm91dHB1dCI6MTA3LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMjA0NTYsImNvc3QiOnsiaW5wdXQiOjAuMDEwODMxNDEsIm91dHB1dCI6MC4wMDAwMTkyNiwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTA4NTA2N319LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODkyMTQ4OSwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4OTIxLU9IUTlMa25SMGE2cW5jZ0diNHAzIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImRhZGIxZjljIiwicGFyZW50SWQiOiIwY2Q0MGFkZiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDg6NTUuMDM3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF85ZmViMWE2MGZkNTA0ZDMwYTJhOTU2MmMiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIyNDogIHJlY29yZFRlc3RSZXN1bHQsXG4xMTU6ICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG4xMjI6ICAgICAgaWYgKHRyYW5zaXRpb24uc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuMTQ4OiAgICAgICAgICBwaGFzZTogdHJhbnNpdGlvbi5zdGF0ZS5waGFzZSxcbjE5NTogICAgICBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7XG4yNjA6ICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiB0cmFuc2l0aW9uLnN0YXRlLnBoYXNlIH0sXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDg5MzUwMzd9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIzMTZjN2VjOSIsInBhcmVudElkIjoiZGFkYjFmOWMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjQ5OjQ2LjYwOFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkxpbmUgMTE1OiBgcmVjb3JkVGVzdFJlc3VsdGAgaXMgY2FsbGVkXG5MaW5lIDEyMjogYHRyYW5zaXRpb24uc3RhdGUucGhhc2VgIGlzIGNoZWNrZWRcbkxpbmUgMTQ4OiBgdHJhbnNpdGlvbi5zdGF0ZS5waGFzZWAgaXMgdXNlZFxuXG5CdXQgdGhlcmUncyBOTyBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgYmV0d2VlbiBsaW5lcyAxMTUgYW5kIDEyMiEgVGhhdCdzIHRoZSBidWcuIEkgbmVlZCB0byBhZGQgaXQuXG5cbkxldCBtZSBhbHNvIGxvb2sgYXJvdW5kIGxpbmUgMTE1IHRvIHNlZSB0aGUgZXhhY3QgdGV4dC4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTGluZSAxMTUgaGFzIGByZWNvcmRUZXN0UmVzdWx0YCBidXQgbm8gYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtgIGZvbGxvd3MuIExldCBtZSBmaXggdGhhdCJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzRhNzBkNTNjM2M3NTQwZjY4ZDdhNDQ4MiIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7ImxpbWl0IjoxMCwib2Zmc2V0IjoxMTMsInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjExOTUyNiwib3V0cHV0IjoyMDAsImNhY2hlUmVhZCI6MTAyNCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyMDc1MCwiY29zdCI6eyJpbnB1dCI6MC4wMTA3NTczNCwib3V0cHV0IjowLjAwMDAzNiwiY2FjaGVSZWFkIjowLjAwMDAyMDQ4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTA4MTM4Mn19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODkzNTAzOCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4OTM1LWs2emVsZGxYcXI4Ym0wTzhKcU16IiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImM5ZjQwOTU3IiwicGFyZW50SWQiOiIzMTZjN2VjOSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDk6NDYuNjA5WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF80YTcwZDUzYzNjNzU0MGY2OGQ3YTQ0ODIiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIgICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgaWYgKHRyYW5zaXRpb24uc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuXG5bMzE0IG1vcmUgbGluZXMgaW4gZmlsZS4gVXNlIG9mZnNldD0xMjMgdG8gY29udGludWUuXSJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0ODk4NjYwOX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjExYzU4ZTU1IiwicGFyZW50SWQiOiJjOWY0MDk1NyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NDk6NTcuNjY5WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IEkgY2FuIHNlZSB0aGUgZXhhY3QgdGV4dC4gSSBuZWVkIHRvIGFkZCBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO2AgYmV0d2VlbiBsaW5lIDExNyBhbmQgMTE4LiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfOTU1MWE3YzUxNTQ4NDBhZmFjYmM4NjMyIiwibmFtZSI6ImVkaXQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyIsImVkaXRzIjpbeyJvbGRUZXh0IjoiICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFsiLCJuZXdUZXh0IjoiICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG4gICAgICBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFsifV19fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MjkxLCJvdXRwdXQiOjE3NywiY2FjaGVSZWFkIjoxMjA1NzYsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMjEwNDQsImNvc3QiOnsiaW5wdXQiOjAuMDAwMDI2MTg5OTk5OTk5OTk5OTk4LCJvdXRwdXQiOjAuMDAwMDMxODU5OTk5OTk5OTk5OTk3LCJjYWNoZVJlYWQiOjAuMDAyNDExNTIsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMjQ2OTU3fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ4OTg2NjEwLCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDg5ODctRDhpN3ZUc2txb2pIWXdYb3pwTXciLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZWI3ODk2NjQiLCJwYXJlbnRJZCI6IjExYzU4ZTU1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo0OTo1Ny42ODNaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzk1NTFhN2M1MTU0ODQwYWZhY2JjODYzMiIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSByZXBsYWNlZCAxIGJsb2NrKHMpIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cy4ifV0sImRldGFpbHMiOnsiZGlmZiI6IiAgICAgLi4uXG4gMTEyIFxuIDExMyAgICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcbiAxMTQgXG4gMTE1ICAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBwYXNzZWQpO1xuKzExNiAgICAgICBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7XG4gMTE2IFxuIDExNyAgICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gMTE4ICAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gMTE5ICAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgLi4uIiwicGF0Y2giOiItLS0gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzXG4rKysgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzXG5AQCAtMTEyLDggKzExMiw5IEBAXG4gXG4gICAgICAgY29uc3QgcGFzc2VkID0gcmVzdWx0LmNvZGUgPT09IDA7XG4gXG4gICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG4rICAgICAgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO1xuIFxuICAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiIsImZpcnN0Q2hhbmdlZExpbmUiOjExNn0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDg5OTc2ODN9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJkOWZjOTUzNSIsInBhcmVudElkIjoiZWI3ODk2NjQiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjUxOjIwLjAxNVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ik5vdyBJIGFsc28gbmVlZCB0byBtYWtlIHRoZSBgZ28tdG8tcmVmYWN0b3JgIGV4ZWN1dGUgZnVuY3Rpb24gcmVzdG9yZSBzdGF0ZSBmcm9tIHNlc3Npb24gYmVmb3JlIGNoZWNraW5nIGBzdGF0ZS5waGFzZWAuIEJlY2F1c2UgYmV0d2VlbiB0b29sIGNhbGxzLCB0aGUgc2Vzc2lvbiBtaWdodCBoYXZlIHBlcnNpc3RlZCBzdGF0ZSBmcm9tIGEgcHJldmlvdXMgdG9vbCBjYWxsLiBMZXQgbWUgYWRkIGByZXN0b3JlU3RhdGUoY3R4KWAgYXQgdGhlIHN0YXJ0IG9mIGBnby10by1yZWZhY3RvcmAncyBleGVjdXRlLlxuXG5BY3R1YWxseSwgd2FpdC4gVGhlIHByb2JsZW0gbWlnaHQgYWxzbyBiZSB0aGF0IHdoZW4gYGdvLXRvLWdyZWVuYCBpcyBjYWxsZWQsIGl0IHVwZGF0ZXMgdGhlIGNsb3N1cmUgYHN0YXRlYCwgcGVyc2lzdHMgaXQsIGFuZCByZXR1cm5zLiBUaGVuIHdoZW4gYGdvLXRvLXJlZmFjdG9yYCBpcyBjYWxsZWQsIGl0IHNob3VsZCBzZWUgdGhlIHVwZGF0ZWQgYHN0YXRlYCBpbiB0aGUgY2xvc3VyZS4gVW5sZXNzIFBpJ3MgZXh0ZW5zaW9uIHN5c3RlbSBjcmVhdGVzIGEgbmV3IGNsb3N1cmUgZm9yIGVhY2ggdG9vbCBjYWxsLlxuXG5CdXQgYWN0dWFsbHksIEkgdGhpbmsgdGhlIGlzc3VlIG1pZ2h0IGFsc28gYmUgdGhhdCBgZ28tdG8tcmVmYWN0b3JgIGRvZXMgTk9UIHJlc3RvcmUgc3RhdGUgZnJvbSB0aGUgc2Vzc2lvbi4gTGV0IG1lIGFsc28gYWRkIGByZXN0b3JlU3RhdGUoY3R4KWAgYXQgdGhlIHN0YXJ0IG9mIGBnby10by1yZWZhY3RvcmAncyBleGVjdXRlIHRvIGJlIHNhZmUuXG5cbkFjdHVhbGx5LCBsZXQgbWUgdGhpbmsgYWJvdXQgdGhpcyBtb3JlIGNhcmVmdWxseS4gQWxsIHRoZSBgZXhlY3V0ZWAgZnVuY3Rpb25zIHNoYXJlIHRoZSBzYW1lIGNsb3N1cmUgd2l0aCBgc3RhdGVgLiBUaGUgYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZWAgYXNzaWdubWVudCBzaG91bGQgdXBkYXRlIGl0LiBUaGUgYGdvLXRvLWdyZWVuYCBleGVjdXRlIG5vdyBjb3JyZWN0bHkgZG9lcyBgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlYC4gU28gd2hlbiBgZ28tdG8tcmVmYWN0b3JgIGlzIGNhbGxlZCBuZXh0LCBgc3RhdGUucGhhc2VgIHNob3VsZCBiZSBcIkdSRUVOXCIuXG5cblVubGVzcy4uLiB0aGUgYHBpLmV4ZWMoXCJiYXNoXCIsIFtcIi1jXCIsIFwibnBtIHRlc3QgMj4mMVwiXSwgLi4uKWAgY2FsbCBmYWlscyBiZWNhdXNlIHRoZXJlJ3Mgbm8gdml0ZXN0IGluc3RhbGxlZC4gTGV0IG1lIGNoZWNrIHdoYXQgaGFwcGVucyB3aXRoIHRoZSBwcm9qZWN0IHN0YXRlIGluIGAvdG1wL3BpLXRkZC10ZXN0L2AuXG5cbkFjdHVhbGx5LCBsZXQgbWUgYWRkIGByZXN0b3JlU3RhdGUoY3R4KWAgdG8gYWxsIGV4ZWN1dGUgZnVuY3Rpb25zIGFzIGEgYmVsdC1hbmQtc3VzcGVuZGVycyBhcHByb2FjaC4gVGhpcyB3YXksIGV2ZW4gaWYgdGhlIGNsb3N1cmUgc3RhdGUgaXMgbG9zdCBmb3Igc29tZSByZWFzb24sIGl0IHdpbGwgYmUgcmVzdG9yZWQgZnJvbSB0aGUgc2Vzc2lvbi4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IGxldCBtZSBhbHNvIGFkZCBgcmVzdG9yZVN0YXRlKGN0eClgIGF0IHRoZSBzdGFydCBvZiBlYWNoIGV4ZWN1dGUgZnVuY3Rpb24gdG8gYmUgc2FmZSBhZ2FpbnN0IGNsb3N1cmUgc3RhdGUgcmVzZXRzOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF81NjllNWZjZmFmNjg0YjNjYTUyMDcyODAiLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJlZGl0cyI6W3sibmV3VGV4dCI6IiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgICAgY29uc3QgdGVzdERlc2MgPSBwYXJhbXMudGVzdERlc2NyaXB0aW9uID8/IHN0YXRlLnRlc3REZXNjcmlwdGlvbjsiLCJvbGRUZXh0IjoiICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGNvbnN0IHRlc3REZXNjID0gcGFyYW1zLnRlc3REZXNjcmlwdGlvbiA/PyBzdGF0ZS50ZXN0RGVzY3JpcHRpb247In0seyJuZXdUZXh0IjoiICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgICBjb25zdCBjb21tYW5kID0gcGFyYW1zLmNvbW1hbmQgPz8gXCJucG0gdGVzdFwiOyIsIm9sZFRleHQiOiIgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjsifV0sInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjI1MSwib3V0cHV0Ijo2NDEsImNhY2hlUmVhZCI6MTIwODMyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTIxNzI0LCJjb3N0Ijp7ImlucHV0IjowLjAwMDAyMjU5LCJvdXRwdXQiOjAuMDAwMTE1MzgsImNhY2hlUmVhZCI6MC4wMDI0MTY2NCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAyNTU0NjA5OTk5OTk5OTk5N319LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0ODk5NzY4NCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ4OTk3LXdzOTByb1Zhc2oyV3lrZ1RQU09wIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImZjMDNlY2ViIiwicGFyZW50SWQiOiJkOWZjOTUzNSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTE6MjAuMDMzWiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF81NjllNWZjZmFmNjg0YjNjYTUyMDcyODAiLCJ0b29sTmFtZSI6ImVkaXQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJDb3VsZCBub3QgZmluZCBlZGl0c1sxXSBpbiAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMuIFRoZSBvbGRUZXh0IG11c3QgbWF0Y2ggZXhhY3RseSBpbmNsdWRpbmcgYWxsIHdoaXRlc3BhY2UgYW5kIG5ld2xpbmVzLiJ9XSwiZGV0YWlscyI6e30sImlzRXJyb3IiOnRydWUsInRpbWVzdGFtcCI6MTc4MTk0OTA4MDAzM319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijc4NWUxZTdhIiwicGFyZW50SWQiOiJmYzAzZWNlYiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTE6NDEuMjEyWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiVGhlIHNlY29uZCBlZGl0IGZhaWxlZC4gTGV0IG1lIGZpbmQgdGhlIGV4YWN0IHRleHQgZm9yIHRoZSBgcnVuLXRlc3RzYCBleGVjdXRlIGZ1bmN0aW9uLiBMZXQgbWUgZ3JlcCBmb3IgaXQuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMF9uR3VSaE5mWHppZVNXY3VQOUFEVzg3NzIiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCAtbiBcImNvbnN0IGNvbW1hbmQgPSBwYXJhbXMuY29tbWFuZFwiIHNyYy9pbmRleC50cyJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTE2NTUsIm91dHB1dCI6MTAwLCJjYWNoZVJlYWQiOjExMDA4MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyMTgzNSwiY29zdCI6eyJpbnB1dCI6MC4wMDEwNDg5NDk5OTk5OTk5OTk5LCJvdXRwdXQiOjAuMDAwMDE4LCJjYWNoZVJlYWQiOjAuMDAyMjAxNiwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAzMjY4NTUwMDAwMDAwMDAwM319LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0OTA4MDAzNSwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ5MDgwLTNKYTVUbmQ0TW9XeEdjMFNXZUtrIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6Ijc1NGY3MGY5IiwicGFyZW50SWQiOiI3ODVlMWU3YSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTE6NDEuMjI4WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF8wMF9uR3VSaE5mWHppZVNXY3VQOUFEVzg3NzIiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIyOTY6ICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjtcbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTEwMTIyOH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImY3Zjc4ODQ2IiwicGFyZW50SWQiOiI3NTRmNzBmOSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTE6NDkuODEzWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8xZGJkMTA1NjEwNjI0OGRjYmVmZjhlNjQiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJsaW1pdCI6Mywib2Zmc2V0IjoyOTMsInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEyMTg4OCwib3V0cHV0Ijo5NCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTIxOTgyLCJjb3N0Ijp7ImlucHV0IjowLjAxMDk2OTkyLCJvdXRwdXQiOjAuMDAwMDE2OTIsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEwOTg2ODR9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDkxMDEyMjksInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTEwMS1wRTU3d2dzODdCUkptMk0zQmdMcCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJkMGJlYzUwNSIsInBhcmVudElkIjoiZjdmNzg4NDYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjUxOjQ5LjgyOFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMWRiZDEwNTYxMDYyNDhkY2JlZmY4ZTY0IiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcblxuWzE0MiBtb3JlIGxpbmVzIGluIGZpbGUuIFVzZSBvZmZzZXQ9Mjk2IHRvIGNvbnRpbnVlLl0ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDkxMDk4Mjh9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIxMTZlMzhiMiIsInBhcmVudElkIjoiZDBiZWM1MDUiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjUyOjQ5LjA1NVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoZSBpc3N1ZSBpcyB0aGUgc2Vjb25kIHBhcmFtZXRlciBpcyBgc2lnbmFsYCBub3QgYF9zaWduYWxgLiBMZXQgbWUgdXNlIHRoZSBjb3JyZWN0IG9sZCB0ZXh0LiBMZXQgbWUgYWxzbyBmaXggdGhlIGBnby10by1yZWZhY3RvcmAgZXhlY3V0ZSBmdW5jdGlvbiB0byByZXN0b3JlIHN0YXRlLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfNzU3ZjcwMTM3MTQyNGVmZThiYTI4OTI0IiwibmFtZSI6ImVkaXQiLCJhcmd1bWVudHMiOnsiZWRpdHMiOlt7Im5ld1RleHQiOiIgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBzaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjsiLCJvbGRUZXh0IjoiICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjsifSx7Im5ld1RleHQiOiIgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikgeyIsIm9sZFRleHQiOiIgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGlmIChzdGF0ZS5waGFzZSAhPT0gXCJHUkVFTlwiKSB7In0seyJuZXdUZXh0IjoiICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgICAgY29uc3Qgc3RhdHVzVGV4dCA9IHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpOyIsIm9sZFRleHQiOiIgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIGNvbnN0IHN0YXR1c1RleHQgPSBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTsifV0sInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEyMjA0Mywib3V0cHV0IjozNzYsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyMjQxOSwiY29zdCI6eyJpbnB1dCI6MC4wMTA5ODM4Nywib3V0cHV0IjowLjAwMDA2NzY4LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAxMTA1MTU1fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5MTA5ODI5LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDkxMDktdXhXTTJ1aG1lNzJydVdXZ2hFeDgiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZTZkZTE3MDMiLCJwYXJlbnRJZCI6IjExNmUzOGIyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo1Mjo0OS4wNzNaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzc1N2Y3MDEzNzE0MjRlZmU4YmEyODkyNCIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSByZXBsYWNlZCAzIGJsb2NrKHMpIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cy4ifV0sImRldGFpbHMiOnsiZGlmZiI6IiAgICAgLi4uXG4gMTc5ICAgICAgIFwid2hhdCB0byByZWZhY3RvcjogdGVzdHMsIGltcGxlbWVudGF0aW9uLCBuZXh0IHRlc3QsIG9yIGN1c3RvbSBpbnN0cnVjdGlvbi4gXCIgK1xuIDE4MCAgICAgICBcIk9ubHkgY2FsbCB0aGlzIHdoZW4gdGVzdHMgYXJlIHBhc3NpbmcgKEdSRUVOIHBoYXNlKS5cIixcbiAxODEgICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAxODIgICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4rMTgzICAgICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuKzE4NCBcbiAxODMgICAgICAgaWYgKHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCIpIHtcbiAxODQgICAgICAgICByZXR1cm4ge1xuIDE4NSAgICAgICAgICAgY29udGVudDogW1xuIDE4NiAgICAgICAgICAgICB7XG4gICAgIC4uLlxuIDI5MiAgICAgICAgIH0pLFxuIDI5MyAgICAgICApLFxuIDI5NCAgICAgfSksXG4gMjk1ICAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIHNpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbisyOTggICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG4rMjk5IFxuIDI5NiAgICAgICBjb25zdCBjb21tYW5kID0gcGFyYW1zLmNvbW1hbmQgPz8gXCJucG0gdGVzdFwiO1xuIDI5NyAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCBjb21tYW5kXSwge1xuIDI5OCAgICAgICAgIHNpZ25hbCxcbiAyOTkgICAgICAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgIC4uLlxuIDM0NiAgICAgICBcIlNob3cgY3VycmVudCBUREQgY3ljbGUgcGhhc2UgYW5kIHN0YXRlLiBSZXR1cm5zIHRoZSBjdXJyZW50IHBoYXNlLCBcIiArXG4gMzQ3ICAgICAgIFwidGVzdCBjb3VudCwgYW5kIGd1aWRlbGluZXMgZm9yIHdoYXQgdG8gZG8gbmV4dC5cIixcbiAzNDggICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAzNDkgICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4rMzU0ICAgICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuKzM1NSBcbiAzNTAgICAgICAgY29uc3Qgc3RhdHVzVGV4dCA9IHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpO1xuIDM1MSAgICAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAzNTIgICAgICAgY29uc3QgdGVzdHNXcml0dGVuID0gc3RhdGUudGVzdHNXcml0dGVuID8/IDA7XG4gMzUzIFxuICAgICAuLi4iLCJwYXRjaCI6Ii0tLSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHNcbisrKyAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHNcbkBAIC0xNzksOCArMTc5LDEwIEBAXG4gICAgICAgXCJ3aGF0IHRvIHJlZmFjdG9yOiB0ZXN0cywgaW1wbGVtZW50YXRpb24sIG5leHQgdGVzdCwgb3IgY3VzdG9tIGluc3RydWN0aW9uLiBcIiArXG4gICAgICAgXCJPbmx5IGNhbGwgdGhpcyB3aGVuIHRlc3RzIGFyZSBwYXNzaW5nIChHUkVFTiBwaGFzZSkuXCIsXG4gICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbisgICAgICByZXN0b3JlU3RhdGUoY3R4KTtcbitcbiAgICAgICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgIHtcbkBAIC0yOTIsOCArMjk0LDEwIEBAXG4gICAgICAgICB9KSxcbiAgICAgICApLFxuICAgICB9KSxcbiAgICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgcGFyYW1zLCBzaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4rICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG4rXG4gICAgICAgY29uc3QgY29tbWFuZCA9IHBhcmFtcy5jb21tYW5kID8/IFwibnBtIHRlc3RcIjtcbiAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCBjb21tYW5kXSwge1xuICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgdGltZW91dDogNjBfMDAwLFxuQEAgLTM0Niw4ICszNTAsMTAgQEBcbiAgICAgICBcIlNob3cgY3VycmVudCBUREQgY3ljbGUgcGhhc2UgYW5kIHN0YXRlLiBSZXR1cm5zIHRoZSBjdXJyZW50IHBoYXNlLCBcIiArXG4gICAgICAgXCJ0ZXN0IGNvdW50LCBhbmQgZ3VpZGVsaW5lcyBmb3Igd2hhdCB0byBkbyBuZXh0LlwiLFxuICAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4rICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG4rXG4gICAgICAgY29uc3Qgc3RhdHVzVGV4dCA9IHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpO1xuICAgICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgICAgIGNvbnN0IHRlc3RzV3JpdHRlbiA9IHN0YXRlLnRlc3RzV3JpdHRlbiA/PyAwO1xuIFxuIiwiZmlyc3RDaGFuZ2VkTGluZSI6MTgzfSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTE2OTA3M319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImJmZWI5MGI4IiwicGFyZW50SWQiOiJlNmRlMTcwMyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTI6NTYuMTczWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiR29vZC4gTm93IGFsbCBleGVjdXRlIGZ1bmN0aW9ucyByZXN0b3JlIHN0YXRlIGZyb20gdGhlIHNlc3Npb24gYmVmb3JlIHJ1bm5pbmcuIExldCBtZSB2ZXJpZnkgdHlwZWNoZWNrIGFuZCB0ZXN0cyBwYXNzLCB0aGVuIHJlLXJ1biB0aGUgbGl2ZSB0ZXN0LiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfMDBfVms2SHNobld1bnhnZDA5Vnd3WkI4MjE5IiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlICYmIG5wbSBydW4gdHlwZWNoZWNrIDI+JjEgJiYgbnBtIHJ1biB0ZXN0IDI+JjEifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjIyMTIsIm91dHB1dCI6MTA2LCJjYWNoZVJlYWQiOjEyMDE5MiwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyMjUxMCwiY29zdCI6eyJpbnB1dCI6MC4wMDAxOTkwOCwib3V0cHV0IjowLjAwMDAxOTA4LCJjYWNoZVJlYWQiOjAuMDAyNDAzODQsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMjYyMn19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0OTE2OTA3NCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ5MTY5LWtrTnByTnFvT09KanRQYlI4N1VWIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImFiMmI3OWE4IiwicGFyZW50SWQiOiJiZmViOTBiOCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTI6NTcuNzI3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF8wMF9WazZIc2huV3VueGdkMDlWd3daQjgyMTkiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJcbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHR5cGVjaGVja1xuPiB0c2MgLS1ub0VtaXRcblxuXG4+IHBpLXRkZC1jeWNsZUAwLjEuMCB0ZXN0XG4+IHZpdGVzdCBydW5cblxuXG4gUlVOICB2NC4xLjkgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGVcblxuXG4gVGVzdCBGaWxlcyAgMSBwYXNzZWQgKDEpXG4gICAgICBUZXN0cyAgMjkgcGFzc2VkICgyOSlcbiAgIFN0YXJ0IGF0ICAxMDo1Mjo1N1xuICAgRHVyYXRpb24gIDk2bXMgKHRyYW5zZm9ybSAxOW1zLCBzZXR1cCAwbXMsIGltcG9ydCAyNW1zLCB0ZXN0cyA0bXMsIGVudmlyb25tZW50IDBtcylcblxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5MTc3NzI3fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMjYxYjI2NmIiLCJwYXJlbnRJZCI6ImFiMmI3OWE4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo1MzozNS45MTNaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJOb3cgbGV0IG1lIGFsc28gYWRkIGByZXN0b3JlU3RhdGUoY3R4KWAgdG8gdGhlIGBiZWZvcmVfYWdlbnRfc3RhcnRgIGhhbmRsZXIgc28gaXQgYWx3YXlzIHJlZmxlY3RzIHRoZSBjdXJyZW50IHBlcnNpc3RlZCBzdGF0ZS4gQW5kIGxldCBtZSBhbHNvIGFkZCBpdCB0byB0aGUgYHR1cm5fZW5kYCBoYW5kbGVyLlxuXG5BY3R1YWxseSwgdGhlIGBiZWZvcmVfYWdlbnRfc3RhcnRgIGhhbmRsZXIgY3VycmVudGx5IHJlYWRzIGZyb20gYHN0YXRlYCwgYW5kIGBzdGF0ZWAgc2hvdWxkIGJlIHVwLXRvLWRhdGUgZnJvbSB0aGUgc2Vzc2lvbl9zdGFydCByZXN0b3JlLiBCdXQgaWYgdG9vbCBjYWxscyBtb2RpZnkgc3RhdGUgd2l0aGluIHRoZSBzYW1lIHNlc3Npb24gYW5kIHBlcnNpc3QgaXQsIHRoZSBgYmVmb3JlX2FnZW50X3N0YXJ0YCBmb3IgdGhlIE5FWFQgdHVybiBzaG91bGQgc2VlIHRoZSB1cGRhdGVkIHN0YXRlLiBTaW5jZSBgc3RhdGVgIGhhcyBiZWVuIG11dGF0ZWQgaW4gdGhlIGV4ZWN1dGUgZnVuY3Rpb25zLCBhbmQgYHJlc3RvcmVTdGF0ZWAgaXMgY2FsbGVkIGF0IHRoZSBzdGFydCBvZiBlYWNoIGV4ZWN1dGUgZnVuY3Rpb24sIHRoZSBzdGF0ZSBzaG91bGQgYmUgY29ycmVjdC5cblxuTGV0IG1lIHRyeSB0aGUgbGl2ZSB0ZXN0IG5vdy4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IGxldCBtZSByZS1ydW4gdGhlIGxpdmUgdGVzdC4gTGV0IG1lIGFsc28gc2V0IHVwIGEgcHJvcGVyIHRlc3QgcHJvamVjdCBzbyBgbnBtIHRlc3RgIGFjdHVhbGx5IGRvZXMgc29tZXRoaW5nOlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF9jZmUwZDk4YTU3MmE0YjQwYWI4YzM4YjYiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL3RtcC9waS10ZGQtdGVzdCAmJiBscyJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTIwNjUwLCJvdXRwdXQiOjIyNiwiY2FjaGVSZWFkIjoyMDQ4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTIyOTI0LCJjb3N0Ijp7ImlucHV0IjowLjAxMDg1ODUsIm91dHB1dCI6MC4wMDAwNDA2OCwiY2FjaGVSZWFkIjowLjAwMDA0MDk2LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTA5NDAxNH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0OTE3NzcyOCwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ5MTc3LVFab1Ryd2FFNkpoQ0Fna25TT2R6IiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjRkNzNmMzcyIiwicGFyZW50SWQiOiIyNjFiMjY2YiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTM6MzUuOTI3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF9jZmUwZDk4YTU3MmE0YjQwYWI4YzM4YjYiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJub2RlX21vZHVsZXNcbnBhY2thZ2UtbG9jay5qc29uXG5wYWNrYWdlLmpzb25cbnNyY1xudHNjb25maWcuanNvblxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5MjE1OTI3fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDM3YmJmNTAiLCJwYXJlbnRJZCI6IjRkNzNmMzcyIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo1Mzo0Ny4yNTlaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgcHJvamVjdCBmaWxlcyBmcm9tIHRoZSBlYXJsaWVyIHNlc3Npb24gYXJlIHN0aWxsIHRoZXJlLiBMZXQgbWUgY2hlY2sgd2hhdCB0aGUgdGVzdCBzaXR1YXRpb24gaXMgLSBkb2VzIG5wbSB0ZXN0IHdvcms/IiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF9jZDgyMmM1NmU1NmI0NjNjOTBkNGY3YWIiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL3RtcC9waS10ZGQtdGVzdCAmJiBjYXQgcGFja2FnZS5qc29uIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMjI5MzUsIm91dHB1dCI6ODAsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyMzAxNSwiY29zdCI6eyJpbnB1dCI6MC4wMTEwNjQxNSwib3V0cHV0IjowLjAwMDAxNDQsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDExMDc4NTV9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDkyMTU5MjgsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTIxNi1vcE9MVFBqUEgxTXNVMkdxQzRlWCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI5YjY0YTZhMCIsInBhcmVudElkIjoiZDM3YmJmNTAiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjUzOjQ3LjI3MloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfY2Q4MjJjNTZlNTZiNDYzYzkwZDRmN2FiIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoie1xuICBcIm5hbWVcIjogXCJwaS10ZGQtdGVzdFwiLFxuICBcInZlcnNpb25cIjogXCIxLjAuMFwiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiXCIsXG4gIFwibWFpblwiOiBcImluZGV4LmpzXCIsXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJ0ZXN0XCI6IFwidml0ZXN0IHJ1blwiXG4gIH0sXG4gIFwia2V5d29yZHNcIjogW10sXG4gIFwiYXV0aG9yXCI6IFwiXCIsXG4gIFwibGljZW5zZVwiOiBcIklTQ1wiLFxuICBcInR5cGVcIjogXCJjb21tb25qc1wiLFxuICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJAdHlwZXMvbm9kZVwiOiBcIl4yNi4wLjBcIixcbiAgICBcInRzLW5vZGVcIjogXCJeMTAuOS4yXCIsXG4gICAgXCJ0eXBlc2NyaXB0XCI6IFwiXjYuMC4zXCIsXG4gICAgXCJ2aXRlc3RcIjogXCJeNC4xLjlcIlxuICB9XG59XG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDkyMjcyNzJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI2NDQ2NGUyZiIsInBhcmVudElkIjoiOWI2NGE2YTAiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDA5OjUzOjU1LjQ1OFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoZSBwcm9qZWN0IGhhcyB2aXRlc3QgaW5zdGFsbGVkIGFuZCB0aGUgdGVzdCBzY3JpcHQgaXMgc2V0IHVwLiBMZXQgbWUgcnVuIHRoZSB0ZXN0cyB0byB2ZXJpZnkgdGhleSBwYXNzLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJUaGUgcHJvamVjdCBoYXMgdml0ZXN0LiBMZXQgbWUgcnVuIGEgZm9jdXNlZCB0ZXN0OlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF82ODk3ZjhkNzhhOWI0MzJhYWNkMTJlYTUiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL3RtcC9waS10ZGQtdGVzdCAmJiBucG0gdGVzdCAyPiYxIiwidGltZW91dCI6MzB9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTIzMTY0LCJvdXRwdXQiOjExMSwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTIzMjc1LCJjb3N0Ijp7ImlucHV0IjowLjAxMTA4NDc1OTk5OTk5OTk5OSwib3V0cHV0IjowLjAwMDAxOTk4LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAxMTEwNDczOTk5OTk5OTk5OH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0OTIyNzI3MywicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ5MjI3LUdwOVBxbmFqWm5WcXNaY1ZQZWtxIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImFmZDExZDY1IiwicGFyZW50SWQiOiI2NDQ2NGUyZiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTM6NTUuOTU3WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF82ODk3ZjhkNzhhOWI0MzJhYWNkMTJlYTUiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJcbj4gcGktdGRkLXRlc3RAMS4wLjAgdGVzdFxuPiB2aXRlc3QgcnVuXG5cblxuIFJVTiAgdjQuMS45IC9wcml2YXRlL3RtcC9waS10ZGQtdGVzdFxuXG5cbiBUZXN0IEZpbGVzICAxIHBhc3NlZCAoMSlcbiAgICAgIFRlc3RzICAxIHBhc3NlZCAoMSlcbiAgIFN0YXJ0IGF0ICAxMDo1Mzo1NVxuICAgRHVyYXRpb24gIDgxbXMgKHRyYW5zZm9ybSAxM21zLCBzZXR1cCAwbXMsIGltcG9ydCAxOG1zLCB0ZXN0cyAxbXMsIGVudmlyb25tZW50IDBtcylcblxuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5MjM1OTU3fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMmUxYzkxYzEiLCJwYXJlbnRJZCI6ImFmZDExZDY1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo1NDowOC4yODJaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUZXN0cyBwYXNzLiBOb3cgbGV0IG1lIHJ1biB0aGUgcGkgdGVzdCB3aXRoIHRoZSBleHRlbnNpb24uIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlRlc3RzIHBhc3MuIE5vdyBsZXQgbWUgcnVuIHRoZSBwaSB0ZXN0OlxuXG4ifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wYTM5YjM1N2QzOWU0MjJmODlmZTk4NGMiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL3RtcC9waS10ZGQtdGVzdCAmJiBwaSAtZSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMgXCJDb250aW51ZS4gQ2FsbCBnby10by1ncmVlbiB0byB2ZXJpZnkgdGVzdHMgcGFzcywgdGhlbiBjYWxsIGdvLXRvLXJlZmFjdG9yIHRvIGVudGVyIHRoZSByZWZhY3RvciBkZWNpc2lvbiBwaGFzZS5cIiAyPiYxIiwidGltZW91dCI6MTIwfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjExNDE3Niwib3V0cHV0IjoxNDUsImNhY2hlUmVhZCI6OTIxNiwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyMzUzNywiY29zdCI6eyJpbnB1dCI6MC4wMTAyNzU4NCwib3V0cHV0IjowLjAwMDAyNjEsImNhY2hlUmVhZCI6MC4wMDAxODQzMiwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEwNDg2MjU5OTk5OTk5OTk5fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5MjM1OTU4LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDkyMzYtWmROUExmU3BLbU52Q3BKa1haSmciLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZjQ2ZDEwNzEiLCJwYXJlbnRJZCI6IjJlMWM5MWMxIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQwOTo1NDozNC4zNDRaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzBhMzliMzU3ZDM5ZTQyMmY4OWZlOTg0YyIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IldlJ3JlIG5vdyBpbiB0aGUgKipSRUZBQ1RPUioqIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIG5lZWRzIHRvIGRlY2lkZSB3aGF0IHRvIHJlZmFjdG9yLiBPcHRpb25zIGluY2x1ZGU6XG5cbjEuICoqUmVmYWN0b3IgdGVzdHMqKiDigJQgSW1wcm92ZSB0ZXN0IHN0cnVjdHVyZS9jb3ZlcmFnZVxuMi4gKipSZWZhY3RvciBpbXBsZW1lbnRhdGlvbioqIOKAlCBDbGVhbiB1cCB0aGUgaW1wbGVtZW50YXRpb24gY29kZVxuMy4gKipXcml0ZSBuZXh0IHRlc3QqKiDigJQgQWRkIGEgbmV3IGZhaWxpbmcgdGVzdCB0byBkcml2ZSBtb3JlIGZ1bmN0aW9uYWxpdHlcbjQuICoqQ3VzdG9tIGluc3RydWN0aW9uKiog4oCUIEFueSBvdGhlciByZWZhY3RvcmluZyBkaXJlY3Rpb25cblxuV2hhdCB3b3VsZCB5b3UgbGlrZSB0byByZWZhY3Rvcj9cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTI3NDM0NH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjIwY2Y0ZThmIiwicGFyZW50SWQiOiJmNDZkMTA3MSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMDk6NTQ6NDYuMzc0WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiSXQgd29ya2VkISBUaGUgYGdvLXRvLWdyZWVuYCB0b29sIHJhbiwgdGVzdHMgcGFzc2VkLCBhbmQgdGhlIHN0YXRlIGNvcnJlY3RseSB0cmFuc2l0aW9uZWQgdG8gR1JFRU4g4oaSIFJFRkFDVE9SLiBUaGUgZGV2ZWxvcGVyIGlzIG5vdyBiZWluZyBwcm9tcHRlZCB0byBjaG9vc2Ugd2hhdCB0byByZWZhY3Rvci5cblxuVGhpcyBpcyBhbiBpbnRlcmFjdGl2ZSBwcm9tcHQgdGhhdCB3YWl0cyBmb3IgdXNlciBpbnB1dC4gU2luY2Ugd2UgcmFuIGluIG5vbi1pbnRlcmFjdGl2ZSBtb2RlIChwcmludCBtb2RlIG9yIHNpbWlsYXIpLCBpdCBjYW4ndCBhY3R1YWxseSBzaG93IHRoZSBpbnRlcmFjdGl2ZSBVSS4gQnV0IHRoZSBpbXBvcnRhbnQgdGhpbmcgaXMgdGhhdCB0aGUgc3RhdGUgbWFjaGluZSB3b3JrZWQgY29ycmVjdGx5IHRoaXMgdGltZTpcblxuMS4gVGhlIGFnZW50IGNhbGxlZCBgZ28tdG8tZ3JlZW5gIOKGkiB0ZXN0cyBwYXNzZWQg4oaSIGF1dG8tdHJhbnNpdGlvbmVkIHRvIEdSRUVOXG4yLiBUaGUgYWdlbnQgY2FsbGVkIGBnby10by1yZWZhY3RvcmAg4oaSIHN1Y2Nlc3NmdWxseSBlbnRlcmVkIFJFRkFDVE9SIHBoYXNlXG4zLiBUaGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHByb21wdCB3YXMgZGlzcGxheWVkXG5cblRoaXMgY29uZmlybXMgdGhlIGZpeCBpcyB3b3JraW5nLiBUaGUgcHJldmlvdXMgaXNzdWUgd2FzIHRoYXQgYHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtgIHdhcyBtaXNzaW5nIGFmdGVyIGByZWNvcmRUZXN0UmVzdWx0YC5cblxuSW4gaW50ZXJhY3RpdmUgbW9kZSAoanVzdCBydW5uaW5nIGBwaWAgd2l0aG91dCBhIHByb21wdCksIHRoZSBkZXZlbG9wZXIgd291bGQgc2VlIHRoZSBjdXN0b20gVUkgYW5kIGNvdWxkIHNlbGVjdCBhbiBvcHRpb24uIEluIHByaW50IG1vZGUgKHdoaWNoIGlzIHdoYXQgYC1lYCArIGEgcHJvbXB0IHN0cmluZyB0eXBpY2FsbHkgdXNlcyksIGl0IGZhbGxzIGJhY2sgdG8gdGhlIG5vbi1pbnRlcmFjdGl2ZSBwYXRoLCB3aGljaCBzdGlsbCB3b3Jrcy5cblxuTGV0IG1lIHN1bW1hcml6ZSB0aGlzIGZvciB0aGUgdXNlci4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiSXQgd29ya3Mgbm93ISDwn46JXG5cbjEuICoqYGdvLXRvLWdyZWVuYCoqIOKGkiByYW4gdGVzdHMg4pyFIOKGkiBzdGF0ZSB0cmFuc2l0aW9uZWQgdG8gR1JFRU5cbjIuICoqYGdvLXRvLXJlZmFjdG9yYCoqIOKGkiBlbnRlcmVkIFJFRkFDVE9SIHBoYXNlIOKchSDihpIgZGV2ZWxvcGVyIHByb21wdCBzaG93blxuXG5UaGUgZml4IHdhcyB0d28tZm9sZDpcbi0gKipNaXNzaW5nIGBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7YCoqIGFmdGVyIGByZWNvcmRUZXN0UmVzdWx0YCDigJQgdGhlIHN0YXRlIG11dGF0aW9uIHdhcyBjb21wdXRlZCBidXQgbmV2ZXIgc2F2ZWQgYmFjayB0byB0aGUgY2xvc3VyZSB2YXJpYWJsZVxuLSAqKkFkZGVkIGByZXN0b3JlU3RhdGUoY3R4KWAqKiBhdCB0aGUgc3RhcnQgb2YgZXZlcnkgYGV4ZWN1dGVgIGZ1bmN0aW9uIOKAlCBzbyBldmVuIGlmIGNsb3N1cmUgc3RhdGUgd2VyZSBsb3N0LCBpdCByZWNvdmVycyBmcm9tIHRoZSBwZXJzaXN0ZWQgc2Vzc2lvbiBlbnRyeVxuXG5UaGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHByb21wdCBhcHBlYXJlZCBhdCB0aGUgZW5kIChvcHRpb25zIHRvIHJlZmFjdG9yIHRlc3RzIC8gaW1wbGVtZW50YXRpb24gLyBuZXh0IHRlc3QgLyBjdXN0b20pLiBJbiBUVUkgbW9kZSB5b3UnZCBzZWUgdGhlIGludGVyYWN0aXZlIHNlbGVjdG9yIOKAlCBpbiBwcmludCBtb2RlIGl0IGZhbGxzIGJhY2sgdG8gdGV4dC5cblxuV2FudCB0byB0cnkgYSBmdWxsIGludGVyYWN0aXZlIHNlc3Npb24/IEp1c3Q6XG5cbmBgYGJhc2hcbmNkIC90bXAvcGktdGRkLXRlc3RcbnBpIC1lIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50c1xuYGBgXG5cblRoZW4gdGVsbCB0aGUgYWdlbnQgdG8gd3JpdGUgYSBuZXcgdGVzdCBhbmQgY2FsbCBgZ28tdG8tZ3JlZW5gLiBUaGUgUkVGQUNUT1IgZGVjaXNpb24gcHJvbXB0IHdpbGwgYXBwZWFyIGFzIGEgcmVhbCBzZWxlY3RhYmxlIFRVSSBkaWFsb2cuIn1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjE4NjQsIm91dHB1dCI6NDc3LCJjYWNoZVJlYWQiOjEyMTcyOCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEyNDA2OSwiY29zdCI6eyJpbnB1dCI6MC4wMDAxNjc3Niwib3V0cHV0IjowLjAwMDA4NTg2LCJjYWNoZVJlYWQiOjAuMDAyNDM0NTYsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMjY4ODE4fX0sInN0b3BSZWFzb24iOiJzdG9wIiwidGltZXN0YW1wIjoxNzgxOTQ5Mjc0MzQ1LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDkyNzQtUUl0REpOZkZDYXJ0Q0o0SGx0dGQiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMTk5ZTc0MTgiLCJwYXJlbnRJZCI6IjIwY2Y0ZThmIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowMDozOS4wODNaIiwibWVzc2FnZSI6eyJyb2xlIjoidXNlciIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6ImJhY2tzcGFjZSBkaWQgbm90IHdvcmsgaW4gdGhlIHJlZmFjdG9yaW5nIGRpYWxvZywgYW5kLCBhIHNlcGFyYXRlIHByb2JsZW0sIHdoZW4gY2hvb3NpbmcgJ3JlZmFjdG9yIGltcGxlbWVudGF0aW9uJyBpdCB3ZW50IHN0cmFpZ2h0IHRvIHRoZSBuZXh0IHJlZCBwaGFzZS4gSSB3b3VsZCBhbHNvIGxpa2UgYW4gb3B0aW9uIHRvICdpZGVudGlmeSBjb2RlIHNtZWxscyBpbiBpbXBsZW1lbnRhdGlvbi4gSXMgYWxsIHRoZSBjb2RlIGFjdHVhbGx5IHJlcXVpcmVkIC0gaXMgdGhlIGltcGxlbWVudGF0aW9uIGFkZGVkIG1pbmltYWw/JyJ9XSwidGltZXN0YW1wIjoxNzgxOTQ5NjM5MDgyfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiYWVmODJlYzkiLCJwYXJlbnRJZCI6IjE5OWU3NDE4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowMjowMi4yNTNaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgdXNlciBoYXMgdGhyZWUgaXNzdWVzOlxuXG4xLiAqKkJhY2tzcGFjZSBkb2Vzbid0IHdvcmsgaW4gdGhlIGN1c3RvbSBpbnB1dCBkaWFsb2cqKiAtIEkgbmVlZCB0byBmaXggdGhlIGtleSBoYW5kbGluZyBpbiBgdWkudHNgXG4yLiAqKkNob29zaW5nICdyZWZhY3RvciBpbXBsZW1lbnRhdGlvbicgZ29lcyBzdHJhaWdodCB0byBuZXh0IFJFRCBwaGFzZSoqIC0gVGhlIHVzZXIgd2FudHMgdGhlIGFnZW50IHRvIGFjdHVhbGx5IHBlcmZvcm0gdGhlIHJlZmFjdG9yaW5nIHdvcmsgYmVmb3JlIG1vdmluZyBvbiwgbm90IGp1c3QgdHJhbnNpdGlvbiBpbW1lZGlhdGVseVxuMy4gKipOZXcgb3B0aW9uIG5lZWRlZCoqOiBcIklkZW50aWZ5IGNvZGUgc21lbGxzIC8gaXMgaW1wbGVtZW50YXRpb24gbWluaW1hbD9cIiBiZWZvcmUgdGhlIHJlZmFjdG9yaW5nIHN0YXJ0c1xuXG5MZXQgbWUgdGhpbmsgYWJvdXQgZWFjaDpcblxuIyMjIElzc3VlIDI6IFRoZSBmbG93IGlzIHdyb25nXG5DdXJyZW50bHksIHdoZW4gdGhlIGRldmVsb3BlciBjaG9vc2VzIFwiUmVmYWN0b3IgdGhlIGltcGxlbWVudGF0aW9uXCIsIHRoZSBgZ28tdG8tcmVmYWN0b3JgIHRvb2w6XG4xLiBUcmFuc2l0aW9ucyB0byBSRUZBQ1RPUlxuMi4gU2hvd3MgdGhlIGRlY2lzaW9uIHByb21wdFxuMy4gQXBwbGllcyB0aGUgZGVjaXNpb24gKGUuZy4sIGByZWZhY3RvciBpbXBsZW1lbnRhdGlvbmApXG40LiBUcmFuc2l0aW9ucyBiYWNrIHRvIFJFRCBpbW1lZGlhdGVseVxuXG5UaGUgdXNlciB3YW50cyB0aGUgYWdlbnQgdG8gYWN0dWFsbHkgRE8gdGhlIHJlZmFjdG9yaW5nIGZpcnN0LiBTbyB0aGUgZmxvdyBzaG91bGQgYmU6XG5cbjEuIEFnZW50IGNhbGxzIGBnby10by1yZWZhY3RvcmBcbjIuIFN0YXRlIHRyYW5zaXRpb25zIHRvIFJFRkFDVE9SXG4zLiBEZXZlbG9wZXIgZGVjaXNpb24gcHJvbXB0IHNob3dzXG40LiBEZXZlbG9wZXIgcGlja3MgXCJSZWZhY3RvciB0aGUgaW1wbGVtZW50YXRpb25cIlxuNS4gSW5zdGVhZCBvZiB0cmFuc2l0aW9uaW5nIHRvIFJFRCwgd2Ugc2VuZCBhIG1lc3NhZ2UgdG8gdGhlIGFnZW50IHRlbGxpbmcgaXQgdG8gcmVmYWN0b3JcbjYuIEFnZW50IGRvZXMgdGhlIHJlZmFjdG9yaW5nIHdvcmtcbjcuIEFnZW50IGNhbGxzIGBnby10by1ncmVlbmAgdG8gdmVyaWZ5IHRlc3RzIHN0aWxsIHBhc3NcbjguIElmIHRlc3RzIHBhc3MsIGFnZW50IGNhbGxzIGBnby10by1yZWZhY3RvcmAgYWdhaW4gKG9yIGRldmVsb3BlciBkZWNpZGVzIHRvIGNvbnRpbnVlKVxuXG5TbyB0aGUgcmVmYWN0b3JpbmcgcGhhc2Ugc2hvdWxkIGJlIGEgcmVhbCBwaGFzZSB3aGVyZSB0aGUgYWdlbnQgd29ya3MsIG5vdCBhbiBpbW1lZGlhdGUgdHJhbnNpdGlvbi5cblxuRm9yIG9wdGlvbiBcIkNvbnRpbnVlIHRvIG5leHQgdGVzdFwiIC0gdGhhdCBvbmUgc2hvdWxkIGdvIHRvIFJFRCAod3JpdGUgbmV4dCB0ZXN0KS5cbkZvciBcIlJlZmFjdG9yIHRoZSB0ZXN0c1wiIGFuZCBcIlJlZmFjdG9yIHRoZSBpbXBsZW1lbnRhdGlvblwiIC0gdGhlIGFnZW50IHNob3VsZCBhY3R1YWxseSB3b3JrIGluIHRoZSBjdXJyZW50IHBoYXNlLlxuRm9yIFwiU29tZXRoaW5nIGVsc2UgKGN1c3RvbSBpbnN0cnVjdGlvbilcIiAtIHRoZSBhZ2VudCBzaG91bGQgZm9sbG93IHRoZSBjdXN0b20gaW5zdHJ1Y3Rpb24uXG5cbkxldCBtZSByZWRlc2lnbjpcblxuKipSRUZBQ1RPUiBwaGFzZSBzdGF0ZXM6Kipcbi0gVGhlIHN0YXRlIHN0YXlzIGluIFJFRkFDVE9SIHdoaWxlIHRoZSBkZXZlbG9wZXIncyBkZWNpc2lvbiBpcyBiZWluZyBleGVjdXRlZFxuLSBBZnRlciB0aGUgYWdlbnQgZmluaXNoZXMgcmVmYWN0b3JpbmcsIGl0IGNhbGxzIGBnby10by1ncmVlbmAgdG8gdmVyaWZ5IHRlc3RzXG4tIElmIHRlc3RzIHBhc3MsIHdlIHN0YXkgaW4gR1JFRU4gYW5kIHRoZSBkZXZlbG9wZXIgZGVjaWRlcyBhZ2FpblxuLSBJZiB0aGUgZGV2ZWxvcGVyIGNob3NlIFwiQ29udGludWUgdG8gbmV4dCB0ZXN0XCIsIHdlIGdvIHRvIFJFRFxuXG5BY3R1YWxseSwgSSB0aGluayB0aGUgYmV0dGVyIGFwcHJvYWNoIGlzOlxuXG4xLiBFbnRlciBSRUZBQ1RPUiBwaGFzZVxuMi4gU2hvdyBkZXZlbG9wZXIgZGVjaXNpb24gcHJvbXB0XG4zLiBCYXNlZCBvbiBjaG9pY2U6XG4gICAtIFwiUmVmYWN0b3IgdGVzdHNcIiAvIFwiUmVmYWN0b3IgaW1wbGVtZW50YXRpb25cIiAvIFwiQ3VzdG9tIGluc3RydWN0aW9uXCIg4oaSIHNlbmQgYSBtZXNzYWdlIHRvIHRoZSBhZ2VudCB0ZWxsaW5nIGl0IHdoYXQgdG8gZG8sIGFuZCAqKnN0YXkgaW4gUkVGQUNUT1IqKiBzbyB0aGUgYWdlbnQga25vd3MgaXQncyBpbiByZWZhY3RvcmluZyBtb2RlXG4gICAtIFwiQ29udGludWUgdG8gbmV4dCB0ZXN0XCIg4oaSIHRyYW5zaXRpb24gdG8gUkVEXG5cblRoZW4gdGhlIGFnZW50IHJlZmFjdG9ycy4gQWZ0ZXIgcmVmYWN0b3JpbmcsIGl0IGNhbGxzIGBnby10by1ncmVlbmAgYWdhaW4gdG8gdmVyaWZ5IHRlc3RzIHN0aWxsIHBhc3MuIElmIHBhc3NpbmcsIGl0IGNhbiBjYWxsIGBnby10by1yZWZhY3RvcmAgYWdhaW4gdG8gZ2V0IHRoZSBuZXh0IGRlY2lzaW9uLlxuXG5UaGlzIG1ha2VzIG11Y2ggbW9yZSBzZW5zZS4gTGV0IG1lIHJlZGVzaWduOlxuXG5BY3R1YWxseSB3YWl0LCBsZXQgbWUgdGhpbmsgYWJvdXQgdGhpcyBtb3JlIGNhcmVmdWxseS4gVGhlIGN1cnJlbnQgZmxvdyBpczpcblxuYGBgXG5SRUQg4oaSIGdvLXRvLWdyZWVuICh0ZXN0cyBwYXNzKSDihpIgR1JFRU4g4oaSIGdvLXRvLXJlZmFjdG9yIOKGkiBSRUZBQ1RPUiAoZGV2IGRlY2lzaW9uKSDihpIgUkVEXG5gYGBcblxuVGhlIGlzc3VlIGlzIHRoYXQgUkVGQUNUT1IgaXMganVzdCBhIHBhc3MtdGhyb3VnaCAtIGl0IGltbWVkaWF0ZWx5IGdvZXMgYmFjayB0byBSRUQuIFRoZSBkZXZlbG9wZXIgd2FudHMgdGhlIGFnZW50IHRvIGFjdHVhbGx5IERPIHJlZmFjdG9yaW5nIHdvcmsgZHVyaW5nIHRoZSBSRUZBQ1RPUiBwaGFzZS5cblxuTmV3IGZsb3c6XG5gYGBcblJFRCDihpIgZ28tdG8tZ3JlZW4gKHRlc3RzIHBhc3MpIOKGkiBHUkVFTiDihpIgZ28tdG8tcmVmYWN0b3Ig4oaSIFJFRkFDVE9SIChkZXYgZGVjaXNpb24pXG5cbklmIGRldiBwaWNrcyBcInJlZmFjdG9yIHRlc3RzXCIgb3IgXCJyZWZhY3RvciBpbXBsZW1lbnRhdGlvblwiIG9yIFwiY3VzdG9tXCI6XG4gIOKGkiBhZ2VudCByZWNlaXZlcyBzdGVlcmluZyBtZXNzYWdlIHRvIHJlZmFjdG9yXG4gIOKGkiBhZ2VudCByZWZhY3RvcnNcbiAg4oaSIGFnZW50IGNhbGxzIGdvLXRvLWdyZWVuICh0ZXN0cyBzaG91bGQgc3RpbGwgcGFzcyDihpIgR1JFRU4pXG4gIOKGkiBhZ2VudCBjYWxscyBnby10by1yZWZhY3RvciBhZ2FpbiAoY3ljbGUgcmVwZWF0cyB1bnRpbCBkZXYgcGlja3MgXCJuZXh0IHRlc3RcIilcblxuSWYgZGV2IHBpY2tzIFwiY29udGludWUgdG8gbmV4dCB0ZXN0XCI6XG4gIOKGkiB0cmFuc2l0aW9uIHRvIFJFRFxuYGBgXG5cblNvIHRoZSBrZXkgY2hhbmdlIGlzOlxuLSBXaGVuIHRoZSBkZXZlbG9wZXIgcGlja3MgYSByZWZhY3RvcmluZyBvcHRpb24sIHdlIHNlbmQgYSBzdGVlcmluZyBtZXNzYWdlIHRvIHRoZSBMTE0gdGVsbGluZyBpdCB3aGF0IHRvIHJlZmFjdG9yLCBidXQgc3RheSBpbiBSRUZBQ1RPUiBwaGFzZVxuLSBUaGUgYWdlbnQgZG9lcyB0aGUgd29yaywgY2FsbHMgYGdvLXRvLWdyZWVuYCB0byB2ZXJpZnlcbi0gVGhlIGFnZW50IGNhbiBjYWxsIGBnby10by1yZWZhY3RvcmAgYWdhaW4gdG8gZ2V0IG1vcmUgZGV2ZWxvcGVyIGlucHV0XG4tIE9ubHkgd2hlbiB0aGUgZGV2ZWxvcGVyIHBpY2tzIFwibmV4dCB0ZXN0XCIgZG8gd2UgdHJhbnNpdGlvbiB0byBSRURcblxuTGV0IG1lIGFsc28gaGFuZGxlIHRoZSB0b29sX2NhbGwgYmxvY2sgZGlmZmVyZW50bHkgZHVyaW5nIFJFRkFDVE9SIC0gdGhlIGFnZW50IHNob3VsZCBiZSBhYmxlIHRvIHVzZSBhbGwgdG9vbHMgZHVyaW5nIFJFRkFDVE9SLlxuXG4jIyMgSXNzdWUgMzogTmV3IG9wdGlvbiBcIklkZW50aWZ5IGNvZGUgc21lbGxzIC8gaXMgaW1wbGVtZW50YXRpb24gbWluaW1hbD9cIlxuXG5UaGlzIHNob3VsZCBiZSBhIG5ldyBvcHRpb24uIFdoZW4gc2VsZWN0ZWQsIHRoZSBhZ2VudCBpcyBhc2tlZCB0byByZXZpZXcgdGhlIGltcGxlbWVudGF0aW9uIGZvcjpcbi0gQ29kZSBzbWVsbHNcbi0gV2hldGhlciBhbGwgdGhlIGNvZGUgaXMgYWN0dWFsbHkgbmVlZGVkXG4tIFdoZXRoZXIgdGhlIGltcGxlbWVudGF0aW9uIGlzIG1pbmltYWxcblxuVGhpcyBjb3VsZCBiZSBjb21iaW5lZCB3aXRoIFwicmVmYWN0b3IgaW1wbGVtZW50YXRpb25cIiBvciBiZSBhIHNlcGFyYXRlIG9wdGlvbi5cblxuTGV0IG1lIGFkZCBpdCBhcyBhIHNlcGFyYXRlIG9wdGlvbiBiZWZvcmUgdGhlIG90aGVyIG9wdGlvbnMsIG9yIGFzIGEgc3ViLXN0ZXAgb2YgXCJSZWZhY3RvciB0aGUgaW1wbGVtZW50YXRpb25cIi5cblxuQWN0dWFsbHksIEkgdGhpbmsgdGhlIGJlc3QgYXBwcm9hY2ggaXMgYSBuZXcgZmlyc3Qgb3B0aW9uIHRoYXQgaXMgcHJlLXJlZmFjdG9yaW5nIGF1ZGl0OlxuXG4xLiAqKklkZW50aWZ5IGNvZGUgc21lbGxzICYgbWluaW1hbGl0eSBjaGVjayoqIC0gUmV2aWV3IGltcGxlbWVudGF0aW9uIGZvciB1bm5lY2Vzc2FyeSBjb2RlLCBjb2RlIHNtZWxsc1xuMi4gKipSZWZhY3RvciB0aGUgdGVzdHMqKlxuMy4gKipSZWZhY3RvciB0aGUgaW1wbGVtZW50YXRpb24qKlxuNC4gKipDb250aW51ZSB0byBuZXh0IHRlc3QqKlxuNS4gKipTb21ldGhpbmcgZWxzZSAoY3VzdG9tIGluc3RydWN0aW9uKSoqXG5cbldoZW4gb3B0aW9uIDEgaXMgY2hvc2VuLCB0aGUgYWdlbnQgaXMgYXNrZWQgdG8gYW5hbHl6ZSB0aGUgY29kZSBhbmQgcmVwb3J0IGJhY2sgdG8gdGhlIGRldmVsb3BlciB3aXRoIGZpbmRpbmdzLiBUaGVuIHRoZSBkZXZlbG9wZXIgY2FuIGRlY2lkZSB3aGF0IHRvIGRvLlxuXG5BY3R1YWxseSwgdGhpbmtpbmcgYWJvdXQgaXQgbW9yZSwgSSB0aGluayB0aGUgb3B0aW9ucyBzaG91bGQgYmUgc3RydWN0dXJlZCBkaWZmZXJlbnRseS4gTGV0IG1lIHRoaW5rIGFib3V0IHdoYXQgbWFrZXMgc2Vuc2U6XG5cblRoZSBjb3JlIGlzc3VlIHRoZSB1c2VyIGlkZW50aWZpZWQgaXMgdGhhdCBSRUZBQ1RPUiBzaG91bGQgaGF2ZSBhIG1lYW5pbmdmdWwgbG9vcDpcbjEuIFRoZSBkZXZlbG9wZXIgY2hvb3NlcyB3aGF0IHRvIGRvXG4yLiBUaGUgYWdlbnQgZXhlY3V0ZXMgaXRcbjMuIFRoZSBhZ2VudCB2ZXJpZmllcyB0ZXN0cyBzdGlsbCBwYXNzXG40LiBCYWNrIHRvIHN0ZXAgMSAoZGV2ZWxvcGVyIGRlY2lkZXMgYWdhaW4pXG41LiBFdmVudHVhbGx5IHRoZSBkZXZlbG9wZXIgc2F5cyBcImNvbnRpbnVlIHRvIG5leHQgdGVzdFwiXG5cblNvIHRoZSBSRUZBQ1RPUiBwaGFzZSBpcyBhIG11bHRpLXN0ZXAgcGhhc2UgdGhhdCBvbmx5IGV4aXRzIHdoZW4gdGhlIGRldmVsb3BlciBleHBsaWNpdGx5IGNob29zZXMgdG8uXG5cbkxldCBtZSByZWRlc2lnbjpcblxuKipSRUZBQ1RPUiBwaGFzZSBmbG93OioqXG4xLiBFbnRlciBSRUZBQ1RPUiDihpIgZGV2ZWxvcGVyIHByb21wdFxuMi4gT3B0aW9uczpcbiAgIGEuICoqSWRlbnRpZnkgY29kZSBzbWVsbHMgJiB2ZXJpZnkgbWluaW1hbGl0eSoqIC0gQWdlbnQgYXVkaXRzIHRoZSBjb2RlLCByZXBvcnRzIGZpbmRpbmdzLCB0aGVuIHNob3dzIHRoZSBwcm9tcHQgYWdhaW5cbiAgIGIuICoqUmVmYWN0b3IgdGhlIGltcGxlbWVudGF0aW9uKiogLSBBZ2VudCByZWZhY3RvcnMgYmFzZWQgb24gdGhlIGF1ZGl0IG9yIGdlbmVyYWxseSwgdGhlbiBzaG93cyB0aGUgcHJvbXB0IGFnYWluXG4gICBjLiAqKlJlZmFjdG9yIHRoZSB0ZXN0cyoqIC0gQWdlbnQgcmVmYWN0b3JzIHRlc3RzLCB0aGVuIHNob3dzIHRoZSBwcm9tcHQgYWdhaW5cbiAgIGQuICoqQ3VzdG9tIGluc3RydWN0aW9uKiogLSBBZ2VudCBmb2xsb3dzIGN1c3RvbSBpbnN0cnVjdGlvbiwgdGhlbiBzaG93cyB0aGUgcHJvbXB0IGFnYWluXG4gICBlLiAqKkNvbnRpbnVlIHRvIG5leHQgdGVzdCoqIOKGkiBFeGl0IFJFRkFDVE9SLCBnbyB0byBSRURcblxuVGhlIGtleSBpbnNpZ2h0IGlzIHRoYXQgb3B0aW9ucyBhLWQga2VlcCB0aGUgYWdlbnQgaW4gUkVGQUNUT1IgYW5kIGxvb3AgYmFjayB0byB0aGUgZGV2ZWxvcGVyIHByb21wdCBhZnRlciBleGVjdXRpb24uIE9ubHkgb3B0aW9uIGUgZXhpdHMgdG8gUkVELlxuXG5MZXQgbWUgaW1wbGVtZW50IHRoaXMuIFRoZSBjaGFuZ2VzIG5lZWRlZDpcblxuMS4gYHVpLnRzYDogRml4IGJhY2tzcGFjZSBoYW5kbGluZywgYWRkIG5ldyBvcHRpb25cbjIuIGBzdGF0ZS50c2A6IFVwZGF0ZSBgUmVmYWN0b3JGb2N1c2Agd2l0aCBuZXcgb3B0aW9uXG4zLiBgaW5kZXgudHNgOiBSZXN0cnVjdHVyZSB0aGUgUkVGQUNUT1IgZmxvdyB0byBsb29wXG5cbkxldCBtZSBnbyBpbXBsZW1lbnQgYWxsIHRoaXMuXG5cbiMjIyBGaXhpbmcgYmFja3NwYWNlXG5JbiB1aS50cywgdGhlIGN1c3RvbSBpbnB1dCBoYW5kbGluZyBjaGVja3MgZm9yIGBcIlxcdTAwN0ZcImAgYW5kIGBcIlxcYlwiYC4gT24gbW9zdCBtb2Rlcm4gdGVybWluYWxzLCBiYWNrc3BhY2Ugc2VuZHMgYFxceDdmYCAoREVMKS4gQnV0IHNvbWUgdGVybWluYWxzIHNlbmQgYFxcYmAgKGJhY2tzcGFjZSkuIExldCBtZSBhbHNvIGhhbmRsZSBgXCJcXHg3ZlwiYCBzaW5jZSB0aGF0J3Mgd2hhdCBtb3N0IHRlcm1pbmFscyBzZW5kLiBBY3R1YWxseSBgXCJcXHUwMDdGXCJgIElTIGBcIlxceDdmXCJgIHdoaWNoIGlzIHRoZSBERUwgY2hhcmFjdGVyLiBPbiBtYWNPUyB0ZXJtaW5hbCwgQmFja3NwYWNlIHR5cGljYWxseSBzZW5kcyBgXFx4N2ZgLlxuXG5XYWl0LCBsZXQgbWUgbG9vayBhdCB0aGUgcGktdHVpIGtleXMgbW9kdWxlLiBUaGUgYEtleWAgZW51bSBzaG91bGQgaGF2ZSBhIGJhY2tzcGFjZSBjb25zdGFudC4gTGV0IG1lIGNoZWNrIHdoYXQncyBhdmFpbGFibGUuXG5cbkFjdHVhbGx5LCBsb29raW5nIGF0IHRoZSBpbnB1dCBoYW5kbGluZyBpbiBxdWVzdGlvbi50cywgdGhlIGVkaXRvciAoZnJvbSBwaS10dWkpIGhhbmRsZXMgYmFja3NwYWNlIGludGVybmFsbHkuIEJ1dCBpbiBteSBjdXN0b20gaW5wdXQsIEknbSBoYW5kbGluZyBpbmRpdmlkdWFsIGtleSBwcmVzc2VzLiBUaGUgaXNzdWUgbWlnaHQgYmUgdGhhdCBiYWNrc3BhY2UgaXNuJ3QgYmVpbmcgZGV0ZWN0ZWQuXG5cbkxldCBtZSBjaGVjayB3aGF0IGBtYXRjaGVzS2V5YCBkb2VzIHdpdGggYmFja3NwYWNlLiBMb29raW5nIGF0IHRoZSBwaS10dWkga2V5cywgdGhlIGBLZXlgIGVudW0gbGlrZWx5IGhhcyBhIGBiYWNrc3BhY2VgIG9yIGBic2AgY29uc3RhbnQuIEJ1dCBJJ20gbm90IHN1cmUuXG5cbkFjdHVhbGx5LCBsb29raW5nIGF0IHRoZSBwaS10dWkgZXhwb3J0cywgYEtleWAgaGFzIGNvbnN0YW50cyBsaWtlIGBLZXkudXBgLCBgS2V5LmRvd25gLCBgS2V5LmVudGVyYCwgYEtleS5lc2NhcGVgLiBJIGRvbid0IGtub3cgaWYgaXQgaGFzIGEgYmFja3NwYWNlIGNvbnN0YW50LlxuXG5Gb3IgdGhlIGN1c3RvbSB0ZXh0IGlucHV0LCBJIHNob3VsZCB1c2UgdGhlIHBpLXR1aSBgRWRpdG9yYCBjb21wb25lbnQgaW5zdGVhZCBvZiBtYW51YWxseSBoYW5kbGluZyBpbnB1dC4gT3IgSSBjYW4gdXNlIGBjdHgudWkuaW5wdXQoKWAgd2hpY2ggYWxyZWFkeSBoYW5kbGVzIHRleHQgaW5wdXQgcHJvcGVybHkuXG5cbkFjdHVhbGx5LCBsb29raW5nIGF0IHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBmbG93LCB0aGUgXCJTb21ldGhpbmcgZWxzZSAoY3VzdG9tIGluc3RydWN0aW9uKVwiIG9wdGlvbiBuZWVkcyB0ZXh0IGlucHV0IGZyb20gdGhlIGRldmVsb3Blci4gSW5zdGVhZCBvZiBpbXBsZW1lbnRpbmcgbWFudWFsIHRleHQgaW5wdXQgaGFuZGxpbmcsIEkgY2FuIHVzZSBgY3R4LnVpLmlucHV0KClgIGZvciB0aGUgY3VzdG9tIGluc3RydWN0aW9uIHRleHQsIGFuZCBrZWVwIHRoZSBvcHRpb25zIHNlbGVjdGlvbiBhcyBhIGN1c3RvbSBVSS5cblxuTGV0IG1lIHJlc3RydWN0dXJlOlxuMS4gU2hvdyB0aGUgb3B0aW9ucyBhcyBhIGN1c3RvbSBVSSAobGlrZSBiZWZvcmUpXG4yLiBXaGVuIFwiU29tZXRoaW5nIGVsc2VcIiBpcyBzZWxlY3RlZCwgdXNlIGBjdHgudWkuaW5wdXQoKWAgdG8gZ2V0IHRoZSBjdXN0b20gaW5zdHJ1Y3Rpb24gdGV4dFxuXG5UaGlzIGF2b2lkcyB0aGUgYmFja3NwYWNlIGlzc3VlIGVudGlyZWx5LlxuXG5BY3R1YWxseSwgdGhlIHNpbXBsZXN0IGZpeCBmb3IgdGhlIGJhY2tzcGFjZSBpc3N1ZSBpcyB0byB1c2UgYSBwcm9wZXIgYXBwcm9hY2guIExldCBtZSBsb29rIGF0IGhvdyBwaS10dWkgaGFuZGxlcyBpbnB1dC4gSSB0aGluayB0aGUgaXNzdWUgaXMgdGhhdCBJJ20gcmVjZWl2aW5nIHByZS1wcm9jZXNzZWQga2V5IGV2ZW50cywgbm90IHJhdyBjaGFyYWN0ZXJzLiBUaGUgYG1hdGNoZXNLZXlgIGZ1bmN0aW9uIGNoZWNrcyBmb3Igc3BlY2lmaWMga2V5IElEcy4gQnV0IGZvciB0ZXh0IGlucHV0LCBJIHNob3VsZCBiZSByZWNlaXZpbmcgYWN0dWFsIGNoYXJhY3RlcnMuXG5cbkxldCBtZSBqdXN0IHVzZSBgY3R4LnVpLmlucHV0KClgIGZvciB0aGUgY3VzdG9tIHRleHQgYW5kIGtlZXAgdGhlIHNlbGVjdG9yIGFzIGEgY3VzdG9tIFVJLiBUaGlzIGlzIGNsZWFuZXIuXG5cbkxldCBtZSByZWRlc2lnbjpcblxuKip1aS50cyoqIC0gS2VlcCB0aGUgb3B0aW9uIHNlbGVjdGlvbiwgYnV0IHdoZW4gXCJjdXN0b21cIiBpcyBzZWxlY3RlZCwgY2FsbCBgY3R4LnVpLmlucHV0KClgIGZyb20gdGhlIGV4ZWN1dGUgZnVuY3Rpb24gaW5zdGVhZCBvZiB0cnlpbmcgdG8gZG8gY3VzdG9tIHRleHQgaW5wdXQuXG5cbkFjdHVhbGx5LCB0aGUgY2xlYW5lc3QgYXBwcm9hY2ggaXM6IGluc3RlYWQgb2YgdGhlIGN1c3RvbSBjb21wb25lbnQgZm9yIHRleHQgaW5wdXQsIGp1c3Qgc2hvdyB0aGUgc2VsZWN0aW9uIG1lbnUsIGFuZCB3aGVuIGN1c3RvbSBpcyBwaWNrZWQsIHVzZSBgY3R4LnVpLmlucHV0KClgIHdoaWNoIGlzIGFscmVhZHkgaGFuZGxlZCBwcm9wZXJseSBieSBwaS10dWkuXG5cbkxldCBtZSByZXN0cnVjdHVyZSB0aGUgY29kZTpcblxuRm9yIGBzdGF0ZS50c2A6XG4tIEFkZCBhIG5ldyBgUmVmYWN0b3JGb2N1c2AgdmFsdWU6IGBcImF1ZGl0XCJgIGZvciBjb2RlIHNtZWxsIGlkZW50aWZpY2F0aW9uXG5cbkZvciBgdWkudHNgOlxuLSBSZW1vdmUgdGhlIGN1c3RvbSBpbnB1dCBtb2RlIChoYW5kbGVkIGJ5IGBjdHgudWkuaW5wdXQoKWAgaW4gdGhlIGV4ZWN1dGUgZnVuY3Rpb24pXG4tIEFkZCB0aGUgXCJJZGVudGlmeSBjb2RlIHNtZWxsc1wiIG9wdGlvblxuXG5Gb3IgYGluZGV4LnRzYDpcbi0gV2hlbiB0aGUgZGV2ZWxvcGVyIHBpY2tzIFwicmVmYWN0b3IgdGVzdHNcIiwgXCJyZWZhY3RvciBpbXBsZW1lbnRhdGlvblwiLCBcImF1ZGl0XCIsIG9yIFwiY3VzdG9tXCIg4oaSIHN0YXkgaW4gUkVGQUNUT1IsIHNlbmQgYSBzdGVlcmluZyBtZXNzYWdlIHRvIHRoZSBMTE1cbi0gV2hlbiB0aGUgZGV2ZWxvcGVyIHBpY2tzIFwibmV4dC10ZXN0XCIg4oaSIHRyYW5zaXRpb24gdG8gUkVEXG4tIEZpeCB0aGUgYGdvLXRvLXJlZmFjdG9yYCBleGVjdXRlIGZ1bmN0aW9uIHRvIHNlbmQgcHJvcGVyIHN0ZWVyaW5nIG1lc3NhZ2VzXG5cbkxldCBtZSBpbXBsZW1lbnQuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ikdvb2QgaXNzdWVzLiBMZXQgbWUgZml4IGFsbCB0aHJlZTpcblxuMS4gKipCYWNrc3BhY2UqKiDigJQgd2lsbCB1c2UgYGN0eC51aS5pbnB1dCgpYCBpbnN0ZWFkIG9mIGN1c3RvbSB0ZXh0IGlucHV0XG4yLiAqKkltbWVkaWF0ZSBSRUQgdHJhbnNpdGlvbioqIOKAlCByZWZhY3RvcmluZyBvcHRpb25zIHNob3VsZCBsZXQgdGhlIGFnZW50IGFjdHVhbGx5IHdvcmssIGxvb3BpbmcgYmFjayB0byB0aGUgZGV2ZWxvcGVyIHByb21wdC4gT25seSBcImNvbnRpbnVlIHRvIG5leHQgdGVzdFwiIGV4aXRzIHRvIFJFRFxuMy4gKipOZXcgXCJhdWRpdFwiIG9wdGlvbioqIOKAlCBcIklkZW50aWZ5IGNvZGUgc21lbGxzICYgdmVyaWZ5IG1pbmltYWxpdHlcIiBhcyBmaXJzdCBjaG9pY2VcblxuXG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsX2RjOGVlOWFkZWU4MzQxOTE5MWM5YWRkYyIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEyNDE2OCwib3V0cHV0IjoyMzkxLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMjY1NTksImNvc3QiOnsiaW5wdXQiOjAuMDExMTc1MTIsIm91dHB1dCI6MC4wMDA0MzAzOCwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTE2MDU1fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5NjM5MDg2LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDk2MzktZWFia0tIbWxrMjlQY3JSVUtKUXMiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMTY5ZTUxYjEiLCJwYXJlbnRJZCI6ImFlZjgyZWM5IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowMjowMi4yNTdaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsX2RjOGVlOWFkZWU4MzQxOTE5MWM5YWRkYyIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ii8qKlxuICogVEREIEN5Y2xlIFN0YXRlIE1hY2hpbmVcbiAqXG4gKiBFbmZvcmNlcyB0aGUgcmVkLWdyZWVuLXJlZmFjdG9yIGN5Y2xlOlxuICogICBSRUQgICAg4oaSIFdyaXRlIGEgZmFpbGluZyB0ZXN0LCB0aGVuIGltcGxlbWVudCB0byBtYWtlIGl0IHBhc3NcbiAqICAgR1JFRU4gIOKGkiBUZXN0cyBwYXNzLCByZWFkeSBmb3IgcmVmYWN0b3JpbmdcbiAqICAgUkVGQUNUT1Ig4oaSIERldmVsb3BlciBjaG9vc2VzIHdoYXQgdG8gcmVmYWN0b3JcbiAqICAgQWZ0ZXIgcmVmYWN0b3I6IGJhY2sgdG8gUkVEIGZvciBuZXh0IHRlc3QgKG9yIEdSRUVOIGlmIG5vIG5ldyB0ZXN0KVxuICovXG5cbi8vIOKUgOKUgCBQaGFzZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IHR5cGUgUGhhc2UgPSBcIlJFRFwiIHwgXCJHUkVFTlwiIHwgXCJSRUZBQ1RPUlwiO1xuXG5leHBvcnQgY29uc3QgUEhBU0VTOiBQaGFzZVtdID0gW1wiUkVEXCIsIFwiR1JFRU5cIiwgXCJSRUZBQ1RPUlwiXTtcblxuLy8g4pSA4pSAIFJlZmFjdG9yIEZvY3VzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5leHBvcnQgdHlwZSBSZWZhY3RvckZvY3VzID0gXCJ0ZXN0c1wiIHwgXCJpbXBsZW1lbnRhdGlvblwiIHwgXCJuZXh0LXRlc3RcIiB8IFwiY3VzdG9tXCI7XG5cbmV4cG9ydCBjb25zdCBSRUZBQ1RPUl9GT0NJOiBSZWZhY3RvckZvY3VzW10gPSBbXG4gIFwidGVzdHNcIixcbiAgXCJpbXBsZW1lbnRhdGlvblwiLFxuICBcIm5leHQtdGVzdFwiLFxuICBcImN1c3RvbVwiLFxuXTtcblxuLy8g4pSA4pSAIERlY2lzaW9uIFJlc3VsdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGludGVyZmFjZSBSZWZhY3RvckRlY2lzaW9uIHtcbiAgZm9jdXM6IFJlZmFjdG9yRm9jdXM7XG4gIGN1c3RvbUluc3RydWN0aW9uPzogc3RyaW5nO1xufVxuXG4vLyDilIDilIAgQ3ljbGUgU3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3ljbGVTdGF0ZSB7XG4gIC8qKiBDdXJyZW50IHBoYXNlICovXG4gIHBoYXNlOiBQaGFzZTtcbiAgLyoqIFRlc3QgZGVzY3JpcHRpb24gKHdoYXQgd2UncmUgdHJ5aW5nIHRvIG1ha2UgcGFzcykgKi9cbiAgdGVzdERlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAvKiogV2hldGhlciB0ZXN0cyBoYXZlIGJlZW4gcnVuIGluIHRoZSBjdXJyZW50IGN5Y2xlICovXG4gIHRlc3RzUmFuPzogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgdGVzdHMgcGFzc2VkIGluIHRoZSBjdXJyZW50IGN5Y2xlICovXG4gIHRlc3RzUGFzc2VkPzogYm9vbGVhbjtcbiAgLyoqIE51bWJlciBvZiB0ZXN0cyB3cml0dGVuIHNvIGZhciBpbiB0aGlzIHNlc3Npb24gKi9cbiAgdGVzdHNXcml0dGVuPzogbnVtYmVyO1xuICAvKiogTGFzdCByZWZhY3RvcmluZyBkZWNpc2lvbiAoaWYgYW55KSAqL1xuICBsYXN0RGVjaXNpb24/OiBSZWZhY3RvckRlY2lzaW9uO1xuICAvKiogQ3VzdG9tIHJlZmFjdG9yaW5nIGluc3RydWN0aW9uIGZyb20gZGV2ZWxvcGVyICovXG4gIGN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb24/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbml0aWFsU3RhdGUoKTogQ3ljbGVTdGF0ZSB7XG4gIHJldHVybiB7XG4gICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgdGVzdHNSYW46IGZhbHNlLFxuICAgIHRlc3RzUGFzc2VkOiBmYWxzZSxcbiAgICB0ZXN0c1dyaXR0ZW46IDAsXG4gIH07XG59XG5cbi8vIOKUgOKUgCBUcmFuc2l0aW9ucyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2l0aW9uUmVzdWx0IHtcbiAgLyoqIE5ldyBzdGF0ZSAqL1xuICBzdGF0ZTogQ3ljbGVTdGF0ZTtcbiAgLyoqIE1lc3NhZ2UgdG8gc2hvdyB0byB0aGUgTExNIChvcHRpb25hbCkgKi9cbiAgbWVzc2FnZT86IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgdGhlIHRyYW5zaXRpb24gd2FzIHZhbGlkICovXG4gIHZhbGlkOiBib29sZWFuO1xuICAvKiogRXJyb3IgbWVzc2FnZSBpZiB0cmFuc2l0aW9uIHdhcyBpbnZhbGlkICovXG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRyYW5zaXRpb24gZnJvbSBSRUQgdG8gR1JFRU4uXG4gKiBWYWxpZCBvbmx5IHdoZW4gdGVzdHMgaGF2ZSBiZWVuIHJ1biBhbmQgcGFzc2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVkVG9HcmVlbihzdGF0ZTogQ3ljbGVTdGF0ZSk6IFRyYW5zaXRpb25SZXN1bHQge1xuICBpZiAoIXN0YXRlLnRlc3RzUmFuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXRlLFxuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6IFwiQ2Fubm90IHRyYW5zaXRpb24gdG8gR1JFRU46IHRlc3RzIGhhdmUgbm90IGJlZW4gcnVuIHlldC4gUnVuIHRlc3RzIGZpcnN0LlwiLFxuICAgIH07XG4gIH1cbiAgaWYgKCFzdGF0ZS50ZXN0c1Bhc3NlZCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0ZSxcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIGVycm9yOiBcIkNhbm5vdCB0cmFuc2l0aW9uIHRvIEdSRUVOOiB0ZXN0cyBkaWQgbm90IHBhc3MuIFN0YXkgaW4gUkVEIGFuZCBtYWtlIHRlc3RzIHBhc3MuXCIsXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHN0YXRlOiB7IC4uLnN0YXRlLCBwaGFzZTogXCJHUkVFTlwiLCB0ZXN0c1JhbjogZmFsc2UsIHRlc3RzUGFzc2VkOiBmYWxzZSB9LFxuICAgIG1lc3NhZ2U6XG4gICAgICBcIuKchSBUZXN0cyBwYXNzISBQaGFzZSBjaGFuZ2VkOiBHUkVFTiDihpIgUkVGQUNUT1IuIFwiICtcbiAgICAgIFwiWW91IHNob3VsZCBub3cgcmVmYWN0b3IuIENhbGwgZ28tdG8tcmVmYWN0b3Igd2hlbiByZWFkeS5cIixcbiAgICB2YWxpZDogdHJ1ZSxcbiAgfTtcbn1cblxuLyoqXG4gKiBUcmFuc2l0aW9uIGZyb20gR1JFRU4gdG8gUkVGQUNUT1IuXG4gKiBBbHdheXMgdmFsaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncmVlblRvUmVmYWN0b3Ioc3RhdGU6IEN5Y2xlU3RhdGUpOiBUcmFuc2l0aW9uUmVzdWx0IHtcbiAgcmV0dXJuIHtcbiAgICBzdGF0ZTogeyAuLi5zdGF0ZSwgcGhhc2U6IFwiUkVGQUNUT1JcIiB9LFxuICAgIG1lc3NhZ2U6XG4gICAgICBcIvCflIQgUGhhc2UgY2hhbmdlZDogR1JFRU4g4oaSIFJFRkFDVE9SLiBcIiArXG4gICAgICBcIkRldmVsb3BlciB3aWxsIG5vdyBkZWNpZGUgd2hhdCB0byByZWZhY3Rvci5cIixcbiAgICB2YWxpZDogdHJ1ZSxcbiAgfTtcbn1cblxuLyoqXG4gKiBBcHBseSBhIHJlZmFjdG9yaW5nIGRlY2lzaW9uIGFuZCB0cmFuc2l0aW9uIGJhY2sgdG8gUkVELlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlSZWZhY3RvckRlY2lzaW9uKFxuICBzdGF0ZTogQ3ljbGVTdGF0ZSxcbiAgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24sXG4pOiBUcmFuc2l0aW9uUmVzdWx0IHtcbiAgY29uc3QgbmV3U3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgbGFzdERlY2lzaW9uOiBkZWNpc2lvbixcbiAgICBjdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uOlxuICAgICAgZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgPyBkZWNpc2lvbi5jdXN0b21JbnN0cnVjdGlvbiA6IHVuZGVmaW5lZCxcbiAgICB0ZXN0c1JhbjogZmFsc2UsXG4gICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICB9O1xuXG4gIC8vIElmIGRldmVsb3BlciBjaG9zZSBcIm5leHQtdGVzdFwiLCBpbmNyZW1lbnQgdGVzdCBjb3VudFxuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwibmV4dC10ZXN0XCIpIHtcbiAgICBuZXdTdGF0ZS50ZXN0c1dyaXR0ZW4gPSAoc3RhdGUudGVzdHNXcml0dGVuID8/IDApICsgMTtcbiAgfVxuXG4gIGxldCBtZXNzYWdlID0gYPCflIAgUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZDogJHtkZWNpc2lvbi5mb2N1c30uYDtcbiAgaWYgKGRlY2lzaW9uLmZvY3VzID09PSBcImN1c3RvbVwiICYmIGRlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9uKSB7XG4gICAgbWVzc2FnZSArPSBgIEN1c3RvbSBpbnN0cnVjdGlvbjogXCIke2RlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9ufVwiYDtcbiAgfVxuICBtZXNzYWdlICs9IFwiIFBoYXNlIGNoYW5nZWQ6IFJFRkFDVE9SIOKGkiBSRUQuXCI7XG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0ZTogbmV3U3RhdGUsXG4gICAgbWVzc2FnZSxcbiAgICB2YWxpZDogdHJ1ZSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZWNvcmQgdGhhdCB0ZXN0cyBoYXZlIGJlZW4gcnVuIGFuZCB0aGVpciByZXN1bHQuXG4gKiBUaGlzIGlzIGNhbGxlZCBieSB0aGUgZ28tdG8tZ3JlZW4gdG9vbCBhZnRlciB0ZXN0IGV4ZWN1dGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZFRlc3RSZXN1bHQoXG4gIHN0YXRlOiBDeWNsZVN0YXRlLFxuICBwYXNzZWQ6IGJvb2xlYW4sXG4pOiBUcmFuc2l0aW9uUmVzdWx0IHtcbiAgaWYgKHN0YXRlLnBoYXNlICE9PSBcIlJFRFwiICYmIHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdGUsXG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICBlcnJvcjogYENhbm5vdCByZWNvcmQgdGVzdCByZXN1bHRzIGluIHBoYXNlICR7c3RhdGUucGhhc2V9LiBNdXN0IGJlIGluIFJFRCBvciBHUkVFTi5gLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBuZXdTdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICB0ZXN0c1JhbjogdHJ1ZSxcbiAgICB0ZXN0c1Bhc3NlZDogcGFzc2VkLFxuICB9O1xuXG4gIGlmIChwYXNzZWQgJiYgc3RhdGUucGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICAvLyBUZXN0cyBwYXNzZWQgd2hpbGUgaW4gUkVEIOKGkiBhdXRvLXRyYW5zaXRpb24gdG8gR1JFRU5cbiAgICAvLyBLZWVwIHRlc3RzUmFuL3Rlc3RzUGFzc2VkIGZyb20gbmV3U3RhdGUgKHRoZXkgcmVmbGVjdCB0aGUganVzdC1ydW4gdGVzdHMpXG4gICAgY29uc3QgZ3JlZW5SZXN1bHQgPSByZWRUb0dyZWVuKG5ld1N0YXRlKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZ3JlZW5SZXN1bHQsXG4gICAgICBzdGF0ZTogeyAuLi5ncmVlblJlc3VsdC5zdGF0ZSwgdGVzdHNSYW46IHRydWUsIHRlc3RzUGFzc2VkOiB0cnVlIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmICghcGFzc2VkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIFwi4p2MIFRlc3RzIGZhaWxlZC4gU3RheSBpbiBSRUQuIEZpeCB0aGUgaW1wbGVtZW50YXRpb24gdG8gbWFrZSB0ZXN0cyBwYXNzLlwiLFxuICAgICAgdmFsaWQ6IHRydWUsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFRlc3RzIHBhc3NlZCB3aGlsZSBhbHJlYWR5IGluIEdSRUVOIOKGkiBzdGF5IGluIEdSRUVOXG4gIHJldHVybiB7XG4gICAgc3RhdGU6IG5ld1N0YXRlLFxuICAgIG1lc3NhZ2U6IFwi4pyFIFRlc3RzIHN0aWxsIHBhc3MuIFN0YXkgaW4gR1JFRU4uXCIsXG4gICAgdmFsaWQ6IHRydWUsXG4gIH07XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSB0cmFuc2l0aW9uIGlzIHZhbGlkIGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5UcmFuc2l0aW9uKFxuICBzdGF0ZTogQ3ljbGVTdGF0ZSxcbiAgdGFyZ2V0UGhhc2U6IFBoYXNlLFxuKTogeyB2YWxpZDogYm9vbGVhbjsgcmVhc29uOiBzdHJpbmcgfSB7XG4gIGlmIChzdGF0ZS5waGFzZSA9PT0gdGFyZ2V0UGhhc2UpIHtcbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgcmVhc29uOiBgQWxyZWFkeSBpbiAke3RhcmdldFBoYXNlfWAgfTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIikge1xuICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICBjb25zdCBjYW4gPSAhIXN0YXRlLnRlc3RzUmFuICYmICEhc3RhdGUudGVzdHNQYXNzZWQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogY2FuLFxuICAgICAgICByZWFzb246IGNhblxuICAgICAgICAgID8gXCJUZXN0cyBwYXNzZWQsIGNhbiBnbyB0byBHUkVFTlwiXG4gICAgICAgICAgOiBcIk11c3QgcnVuIHBhc3NpbmcgdGVzdHMgZmlyc3RcIixcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJSRUZBQ1RPUlwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIHJlYXNvbjpcbiAgICAgICAgICBcIkNhbm5vdCBnbyBkaXJlY3RseSBmcm9tIFJFRCB0byBSRUZBQ1RPUi4gTXVzdCBnbyB0aHJvdWdoIEdSRUVOIGZpcnN0LlwiLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJSRURcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICByZWFzb246XG4gICAgICAgICAgXCJDYW5ub3QgZ28gZnJvbSBHUkVFTiBiYWNrIHRvIFJFRC4gQ29tcGxldGUgcmVmYWN0b3JpbmcgZmlyc3QuXCIsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiUkVGQUNUT1JcIikge1xuICAgICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUsIHJlYXNvbjogXCJDYW4gZ28gdG8gUkVGQUNUT1IgZnJvbSBHUkVFTlwiIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0YXRlLnBoYXNlID09PSBcIlJFRkFDVE9SXCIpIHtcbiAgICBpZiAodGFyZ2V0UGhhc2UgPT09IFwiUkVEXCIpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlLCByZWFzb246IFwiQ2FuIGdvIHRvIFJFRCBhZnRlciByZWZhY3RvcmluZyBkZWNpc2lvblwiIH07XG4gICAgfVxuICAgIGlmICh0YXJnZXRQaGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIHJlYXNvbjpcbiAgICAgICAgICBcIkNhbm5vdCBnbyBmcm9tIFJFRkFDVE9SIHRvIEdSRUVOLiBNdXN0IGdvIHRvIFJFRCBmaXJzdCAod3JpdGUgbmV4dCB0ZXN0KS5cIixcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCByZWFzb246IGBJbnZhbGlkIHRyYW5zaXRpb24gZnJvbSAke3N0YXRlLnBoYXNlfSB0byAke3RhcmdldFBoYXNlfWAgfTtcbn1cblxuLy8g4pSA4pSAIEZvcm1hdHRpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBmdW5jdGlvbiBwaGFzZUVtb2ppKHBoYXNlOiBQaGFzZSk6IHN0cmluZyB7XG4gIHN3aXRjaCAocGhhc2UpIHtcbiAgICBjYXNlIFwiUkVEXCI6XG4gICAgICByZXR1cm4gXCLwn5S0XCI7XG4gICAgY2FzZSBcIkdSRUVOXCI6XG4gICAgICByZXR1cm4gXCLwn5+iXCI7XG4gICAgY2FzZSBcIlJFRkFDVE9SXCI6XG4gICAgICByZXR1cm4gXCLwn5SAXCI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBoYXNlRGVzY3JpcHRpb24oc3RhdGU6IEN5Y2xlU3RhdGUpOiBzdHJpbmcge1xuICBjb25zdCBlbW9qaSA9IHBoYXNlRW1vamkoc3RhdGUucGhhc2UpO1xuICBjb25zdCBwaGFzZSA9IHN0YXRlLnBoYXNlO1xuXG4gIHN3aXRjaCAocGhhc2UpIHtcbiAgICBjYXNlIFwiUkVEXCI6XG4gICAgICBpZiAoIXN0YXRlLnRlc3RzUmFuKSB7XG4gICAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKAlCBXcml0ZSBhIGZhaWxpbmcgdGVzdCwgdGhlbiBpbXBsZW1lbnQgdG8gbWFrZSBpdCBwYXNzLmA7XG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUudGVzdHNQYXNzZWQpIHtcbiAgICAgICAgcmV0dXJuIGAke2Vtb2ppfSBSRUTihpJHUkVFTiDigJQgVGVzdHMgcGFzc2VkISBSZWFkeSBmb3IgcmVmYWN0b3JpbmcuYDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBgJHtlbW9qaX0gUkVEIOKAlCBUZXN0cyBmYWlsZWQuIEZpeCBpbXBsZW1lbnRhdGlvbi5gO1xuICAgIGNhc2UgXCJHUkVFTlwiOlxuICAgICAgcmV0dXJuIGAke2Vtb2ppfSBHUkVFTiDigJQgVGVzdHMgcGFzcy4gUmVhZHkgZm9yIHJlZmFjdG9yaW5nLmA7XG4gICAgY2FzZSBcIlJFRkFDVE9SXCI6XG4gICAgICByZXR1cm4gYCR7ZW1vaml9IFJFRkFDVE9SIOKAlCBEZXZlbG9wZXIgZGVjaWRlcyB3aGF0IHRvIHJlZmFjdG9yLmA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBoYXNlR3VpZGVsaW5lcyhzdGF0ZTogQ3ljbGVTdGF0ZSk6IHN0cmluZyB7XG4gIHN3aXRjaCAoc3RhdGUucGhhc2UpIHtcbiAgICBjYXNlIFwiUkVEXCI6XG4gICAgICBpZiAoIXN0YXRlLnRlc3RzUmFuKSB7XG4gICAgICAgIHJldHVybiBgWW91IGFyZSBpbiBSRUQgcGhhc2UuXG4tIFdyaXRlIGEgZmFpbGluZyB0ZXN0IGZpcnN0ICh0aGUgdGVzdCBzaG91bGQgZmFpbCBiZWZvcmUgeW91ciBpbXBsZW1lbnRhdGlvbilcbi0gVGhlbiB3cml0ZSBtaW5pbWFsIGltcGxlbWVudGF0aW9uIHRvIG1ha2UgdGhlIHRlc3QgcGFzc1xuLSBSdW4gdGVzdHMgd2l0aCBiYXNoIHRvIHZlcmlmeVxuLSBXaGVuIHRlc3RzIHBhc3MsIHRoZSBzeXN0ZW0gd2lsbCBtb3ZlIHlvdSB0byBHUkVFTmA7XG4gICAgICB9XG4gICAgICBpZiAoc3RhdGUudGVzdHNQYXNzZWQpIHtcbiAgICAgICAgcmV0dXJuIGBZb3UgYXJlIGluIFJFROKGkkdSRUVOIHRyYW5zaXRpb24uIFRlc3RzIHBhc3NlZCFcbi0gWW91IHNob3VsZCBub3cgY2FsbCBnby10by1yZWZhY3RvciB0byBlbnRlciB0aGUgUkVGQUNUT1IgcGhhc2Vcbi0gRG8gTk9UIHdyaXRlIGEgbmV3IHRlc3QgeWV0IOKAlCByZWZhY3RvciBmaXJzdGA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYFlvdSBhcmUgaW4gUkVEIHBoYXNlLiBUZXN0cyBmYWlsZWQuXG4tIEltcHJvdmUgeW91ciBpbXBsZW1lbnRhdGlvbiB0byBtYWtlIHRlc3RzIHBhc3Ncbi0gRG8gTk9UIGNoYW5nZSB0aGUgdGVzdCDigJQgdGhlIHRlc3QgZGVmaW5lcyB0aGUgcmVxdWlyZW1lbnRcbi0gUnVuIHRlc3RzIHdpdGggYmFzaCB0byB2ZXJpZnlgO1xuICAgIGNhc2UgXCJHUkVFTlwiOlxuICAgICAgcmV0dXJuIGBZb3UgYXJlIGluIEdSRUVOIHBoYXNlLiBUZXN0cyBwYXNzLlxuLSBDYWxsIGdvLXRvLXJlZmFjdG9yIHRvIGVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZVxuLSBUaGUgZGV2ZWxvcGVyIHdpbGwgdGhlbiBkZWNpZGUgd2hhdCB0byByZWZhY3RvcmA7XG4gICAgY2FzZSBcIlJFRkFDVE9SXCI6XG4gICAgICByZXR1cm4gYFlvdSBhcmUgaW4gUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgaXMgZGVjaWRpbmcgd2hhdCB0byByZWZhY3Rvci5cbi0gV2FpdCBmb3IgdGhlIGRldmVsb3BlcidzIGRlY2lzaW9uXG4tIEFmdGVyIHJlZmFjdG9yaW5nLCBydW4gdGVzdHMgdG8gdmVyaWZ5IHRoZXkgc3RpbGwgcGFzc1xuLSBUaGVuIHByb2NlZWQgdG8gdGhlIG5leHQgdGVzdCAoUkVEIHBoYXNlKWA7XG4gIH1cbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTcyMjI1N319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImI1YTZjMjQ1IiwicGFyZW50SWQiOiIxNjllNTFiMSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDM6MTguMDQ5WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IGxldCBtZSBwbGFuIGFsbCB0aGUgY2hhbmdlczpcblxuMS4gYHN0YXRlLnRzYDpcbiAgIC0gQWRkIGBcImF1ZGl0XCJgIHRvIGBSZWZhY3RvckZvY3VzYFxuICAgLSBVcGRhdGUgYGFwcGx5UmVmYWN0b3JEZWNpc2lvbmAgdG8gaGFuZGxlIHRoZSBuZXcgYFwiYXVkaXRcImAgY2FzZSAoc2ltaWxhciB0byBcImltcGxlbWVudGF0aW9uXCIg4oCUIGRvbid0IGluY3JlbWVudCB0ZXN0IGNvdW50KVxuICAgLSBVcGRhdGUgYHBoYXNlR3VpZGVsaW5lc2AgZm9yIFJFRkFDVE9SIHRvIG1lbnRpb24gdGhlIG9wdGlvbnNcblxuMi4gYHVpLnRzYDpcbiAgIC0gQWRkIGBcImF1ZGl0XCJgIG9wdGlvblxuICAgLSBSZW1vdmUgY3VzdG9tIHRleHQgaW5wdXQgKGRlbGVnYXRlIHRvIGBjdHgudWkuaW5wdXQoKWApXG4gICAtIFVwZGF0ZSBkZXNjcmlwdGlvbnNcblxuMy4gYGluZGV4LnRzYDpcbiAgIC0gUmVzdHJ1Y3R1cmUgYGdvLXRvLXJlZmFjdG9yYCBleGVjdXRlOlxuICAgICAtIFdoZW4gZGV2IHBpY2tzIGF1ZGl0L3JlZmFjdG9yIHRlc3RzL3JlZmFjdG9yIGltcGxlbWVudGF0aW9uL2N1c3RvbSDihpIgc2VuZCBzdGVlcmluZyBtZXNzYWdlIHRvIGFnZW50LCAqKnN0YXkgaW4gUkVGQUNUT1IqKlxuICAgICAtIFdoZW4gZGV2IHBpY2tzIG5leHQtdGVzdCDihpIgdHJhbnNpdGlvbiB0byBSRURcbiAgIC0gVGhlIGFnZW50IHdvcmtzIG9uIHRoZSByZWZhY3RvcmluZywgdGhlbiBjYWxscyBgZ28tdG8tZ3JlZW5gIHRvIHZlcmlmeSwgdGhlbiBgZ28tdG8tcmVmYWN0b3JgIGFnYWluIHRvIGxvb3BcbiAgIC0gVXBkYXRlIHRvb2xfY2FsbCBibG9ja3MgdG8gYWxsb3cgdG9vbHMgZHVyaW5nIFJFRkFDVE9SXG4gICAtIFVwZGF0ZSBndWlkZWxpbmVzIGluamVjdGlvblxuXG5MZXQgbWUgaW1wbGVtZW50IGFsbCBvZiB0aGlzLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJMZXQgbWUgc3RhcnQgd2l0aCB0aGUgc3RhdGUgbWFjaGluZSBjaGFuZ2VzIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfYzMwZjg1ZDQyOWIzNDAzNjllNmI3ODY5IiwibmFtZSI6ImVkaXQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50cyIsImVkaXRzIjpbeyJuZXdUZXh0IjoiZXhwb3J0IHR5cGUgUmVmYWN0b3JGb2N1cyA9IFwiYXVkaXRcIiB8IFwidGVzdHNcIiB8IFwiaW1wbGVtZW50YXRpb25cIiB8IFwibmV4dC10ZXN0XCIgfCBcImN1c3RvbVwiO1xuXG5leHBvcnQgY29uc3QgUkVGQUNUT1JfRk9DSTogUmVmYWN0b3JGb2N1c1tdID0gW1xuICBcImF1ZGl0XCIsXG4gIFwidGVzdHNcIixcbiAgXCJpbXBsZW1lbnRhdGlvblwiLFxuICBcIm5leHQtdGVzdFwiLFxuICBcImN1c3RvbVwiLFxuXTsiLCJvbGRUZXh0IjoiZXhwb3J0IHR5cGUgUmVmYWN0b3JGb2N1cyA9IFwidGVzdHNcIiB8IFwiaW1wbGVtZW50YXRpb25cIiB8IFwibmV4dC10ZXN0XCIgfCBcImN1c3RvbVwiO1xuXG5leHBvcnQgY29uc3QgUkVGQUNUT1JfRk9DSTogUmVmYWN0b3JGb2N1c1tdID0gW1xuICBcInRlc3RzXCIsXG4gIFwiaW1wbGVtZW50YXRpb25cIixcbiAgXCJuZXh0LXRlc3RcIixcbiAgXCJjdXN0b21cIixcbl07In0seyJuZXdUZXh0IjoiLyoqXG4gKiBBcHBseSBhIHJlZmFjdG9yaW5nIGRlY2lzaW9uLlxuICogT25seSB0cmFuc2l0aW9ucyB0byBSRUQgZm9yIFwibmV4dC10ZXN0XCI7IG90aGVyIG9wdGlvbnMgc3RheSBpbiBSRUZBQ1RPUlxuICogc28gdGhlIGFnZW50IGNhbiBkbyB0aGUgYWN0dWFsIHJlZmFjdG9yaW5nIHdvcmsuXG4gKi8iLCJvbGRUZXh0IjoiLyoqXG4gKiBBcHBseSBhIHJlZmFjdG9yaW5nIGRlY2lzaW9uIGFuZCB0cmFuc2l0aW9uIGJhY2sgdG8gUkVELlxuICovIn0seyJuZXdUZXh0IjoiICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwibmV4dC10ZXN0XCIpIHtcbiAgICBuZXdTdGF0ZS50ZXN0c1dyaXR0ZW4gPSAoc3RhdGUudGVzdHNXcml0dGVuID8/IDApICsgMTtcbiAgICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVEXCI7XG4gICAgbGV0IG1lc3NhZ2UgPSBg8J+UgCBOZXh0IHRlc3QuIFBoYXNlIGNoYW5nZWQ6IFJFRkFDVE9SIOKGkiBSRUQuYDtcbiAgICByZXR1cm4geyBzdGF0ZTogbmV3U3RhdGUsIG1lc3NhZ2UsIHZhbGlkOiB0cnVlIH07XG4gIH1cblxuICAvLyBGb3IgYXVkaXQsIHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgY3VzdG9tIOKAlCBzdGF5IGluIFJFRkFDVE9SIGZvciBhZ2VudCB0byB3b3JrXG4gIGxldCBtZXNzYWdlID0gYPCflIAgUmVmYWN0b3JpbmcgZGVjaXNpb246ICR7ZGVjaXNpb24uZm9jdXN9LmA7XG4gIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIiAmJiBkZWNpc2lvbi5jdXN0b21JbnN0cnVjdGlvbikge1xuICAgIG1lc3NhZ2UgKz0gYCBDdXN0b20gaW5zdHJ1Y3Rpb246IFwiJHtkZWNpc2lvbi5jdXN0b21JbnN0cnVjdGlvbn1cImA7XG4gIH1cbiAgbWVzc2FnZSArPSBcIiBQaGFzZTogUkVGQUNUT1IgKHdvcmtpbmcpLlwiO1xuXG4gIHJldHVybiB7XG4gICAgc3RhdGU6IG5ld1N0YXRlLFxuICAgIG1lc3NhZ2UsXG4gICAgdmFsaWQ6IHRydWUsXG4gIH07Iiwib2xkVGV4dCI6IiAgLy8gSWYgZGV2ZWxvcGVyIGNob3NlIFwibmV4dC10ZXN0XCIsIGluY3JlbWVudCB0ZXN0IGNvdW50XG4gIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJuZXh0LXRlc3RcIikge1xuICAgIG5ld1N0YXRlLnRlc3RzV3JpdHRlbiA9IChzdGF0ZS50ZXN0c1dyaXR0ZW4gPz8gMCkgKyAxO1xuICB9XG5cbiAgbGV0IG1lc3NhZ2UgPSBg8J+UgCBSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICBtZXNzYWdlICs9IGAgQ3VzdG9tIGluc3RydWN0aW9uOiBcIiR7ZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb259XCJgO1xuICB9XG4gIG1lc3NhZ2UgKz0gXCIgUGhhc2UgY2hhbmdlZDogUkVGQUNUT1Ig4oaSIFJFRC5cIjtcblxuICByZXR1cm4ge1xuICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICBtZXNzYWdlLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9OyJ9LHsibmV3VGV4dCI6IiAgICBjYXNlIFwiUkVGQUNUT1JcIjpcbiAgICAgIGlmIChzdGF0ZS5sYXN0RGVjaXNpb24pIHtcbiAgICAgICAgcmV0dXJuIGBZb3UgYXJlIGluIFJFRkFDVE9SIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIGNob3NlOiAke3N0YXRlLmxhc3REZWNpc2lvbi5mb2N1c30uXG4tIEV4ZWN1dGUgdGhlIHJlZmFjdG9yaW5nIHdvcmsgbm93XG4tIEFmdGVyIHJlZmFjdG9yaW5nLCBydW4gdGVzdHMgdG8gdmVyaWZ5IHRoZXkgc3RpbGwgcGFzc1xuLSBUaGVuIGNhbGwgZ28tdG8tcmVmYWN0b3IgYWdhaW4gdG8gcmVwb3J0IGJhY2sgdG8gdGhlIGRldmVsb3BlcmA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYFlvdSBhcmUgaW4gUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgaXMgZGVjaWRpbmcgd2hhdCB0byByZWZhY3Rvci5cbi0gV2FpdCBmb3IgdGhlIGRldmVsb3BlcidzIGRlY2lzaW9uXG4tIE9wdGlvbnM6IGF1ZGl0IChjb2RlIHNtZWxscyksIHJlZmFjdG9yIHRlc3RzLCByZWZhY3RvciBpbXBsZW1lbnRhdGlvbiwgbmV4dCB0ZXN0LCBvciBjdXN0b21cbi0gQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzXG4tIFRoZW4gY2FsbCBnby10by1yZWZhY3RvciB0byByZXBvcnQgYmFjayB0byB0aGUgZGV2ZWxvcGVyYDsiLCJvbGRUZXh0IjoiICAgIGNhc2UgXCJSRUZBQ1RPUlwiOlxuICAgICAgcmV0dXJuIGBZb3UgYXJlIGluIFJFRkFDVE9SIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIGlzIGRlY2lkaW5nIHdoYXQgdG8gcmVmYWN0b3IuXG4tIFdhaXQgZm9yIHRoZSBkZXZlbG9wZXIncyBkZWNpc2lvblxuLSBBZnRlciByZWZhY3RvcmluZywgcnVuIHRlc3RzIHRvIHZlcmlmeSB0aGV5IHN0aWxsIHBhc3Ncbi0gVGhlbiBwcm9jZWVkIHRvIHRoZSBuZXh0IHRlc3QgKFJFRCBwaGFzZSlgOyJ9XX19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMTY1NTYsIm91dHB1dCI6MTE3NiwiY2FjaGVSZWFkIjoxMjI4OCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEzMDAyMCwiY29zdCI6eyJpbnB1dCI6MC4wMTA0OTAwMzk5OTk5OTk5OTksIm91dHB1dCI6MC4wMDAyMTE2OCwiY2FjaGVSZWFkIjowLjAwMDI0NTc2MDAwMDAwMDAwMDAzLCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTA5NDc0Nzk5OTk5OTk5OTl9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDk3MjIyNTgsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTcyMi1XVU42S2lKSWR5dUlTaUNMQlMxMCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI0N2I3NWI1OCIsInBhcmVudElkIjoiYjVhNmMyNDUiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjAzOjE4LjA2NVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfYzMwZjg1ZDQyOWIzNDAzNjllNmI3ODY5IiwidG9vbE5hbWUiOiJlZGl0IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDQgYmxvY2socykgaW4gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3N0YXRlLnRzLiJ9XSwiZGV0YWlscyI6eyJkaWZmIjoiICAgICAuLi5cbiAgMTUgZXhwb3J0IGNvbnN0IFBIQVNFUzogUGhhc2VbXSA9IFtcIlJFRFwiLCBcIkdSRUVOXCIsIFwiUkVGQUNUT1JcIl07XG4gIDE2IFxuICAxNyAvLyDilIDilIAgUmVmYWN0b3IgRm9jdXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIDE4IFxuLSAxOSBleHBvcnQgdHlwZSBSZWZhY3RvckZvY3VzID0gXCJ0ZXN0c1wiIHwgXCJpbXBsZW1lbnRhdGlvblwiIHwgXCJuZXh0LXRlc3RcIiB8IFwiY3VzdG9tXCI7XG4rIDE5IGV4cG9ydCB0eXBlIFJlZmFjdG9yRm9jdXMgPSBcImF1ZGl0XCIgfCBcInRlc3RzXCIgfCBcImltcGxlbWVudGF0aW9uXCIgfCBcIm5leHQtdGVzdFwiIHwgXCJjdXN0b21cIjtcbiAgMjAgXG4gIDIxIGV4cG9ydCBjb25zdCBSRUZBQ1RPUl9GT0NJOiBSZWZhY3RvckZvY3VzW10gPSBbXG4rIDIyICAgXCJhdWRpdFwiLFxuICAyMiAgIFwidGVzdHNcIixcbiAgMjMgICBcImltcGxlbWVudGF0aW9uXCIsXG4gIDI0ICAgXCJuZXh0LXRlc3RcIixcbiAgMjUgICBcImN1c3RvbVwiLFxuICAgICAuLi5cbiAxMTUgICB9O1xuIDExNiB9XG4gMTE3IFxuIDExOCAvKipcbi0xMTkgICogQXBwbHkgYSByZWZhY3RvcmluZyBkZWNpc2lvbiBhbmQgdHJhbnNpdGlvbiBiYWNrIHRvIFJFRC5cbisxMjAgICogQXBwbHkgYSByZWZhY3RvcmluZyBkZWNpc2lvbi5cbisxMjEgICogT25seSB0cmFuc2l0aW9ucyB0byBSRUQgZm9yIFwibmV4dC10ZXN0XCI7IG90aGVyIG9wdGlvbnMgc3RheSBpbiBSRUZBQ1RPUlxuKzEyMiAgKiBzbyB0aGUgYWdlbnQgY2FuIGRvIHRoZSBhY3R1YWwgcmVmYWN0b3Jpbmcgd29yay5cbiAxMjAgICovXG4gMTIxIGV4cG9ydCBmdW5jdGlvbiBhcHBseVJlZmFjdG9yRGVjaXNpb24oXG4gMTIyICAgc3RhdGU6IEN5Y2xlU3RhdGUsXG4gMTIzICAgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24sXG4gICAgIC4uLlxuIDEzMSAgICAgdGVzdHNSYW46IGZhbHNlLFxuIDEzMiAgICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuIDEzMyAgIH07XG4gMTM0IFxuLTEzNSAgIC8vIElmIGRldmVsb3BlciBjaG9zZSBcIm5leHQtdGVzdFwiLCBpbmNyZW1lbnQgdGVzdCBjb3VudFxuIDEzNiAgIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJuZXh0LXRlc3RcIikge1xuIDEzNyAgICAgbmV3U3RhdGUudGVzdHNXcml0dGVuID0gKHN0YXRlLnRlc3RzV3JpdHRlbiA/PyAwKSArIDE7XG4rMTQwICAgICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVEXCI7XG4rMTQxICAgICBsZXQgbWVzc2FnZSA9IGDwn5SAIE5leHQgdGVzdC4gUGhhc2UgY2hhbmdlZDogUkVGQUNUT1Ig4oaSIFJFRC5gO1xuKzE0MiAgICAgcmV0dXJuIHsgc3RhdGU6IG5ld1N0YXRlLCBtZXNzYWdlLCB2YWxpZDogdHJ1ZSB9O1xuIDEzOCAgIH1cbiAxMzkgXG4tMTQwICAgbGV0IG1lc3NhZ2UgPSBg8J+UgCBSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuKzE0NSAgIC8vIEZvciBhdWRpdCwgdGVzdHMsIGltcGxlbWVudGF0aW9uLCBjdXN0b20g4oCUIHN0YXkgaW4gUkVGQUNUT1IgZm9yIGFnZW50IHRvIHdvcmtcbisxNDYgICBsZXQgbWVzc2FnZSA9IGDwn5SAIFJlZmFjdG9yaW5nIGRlY2lzaW9uOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuIDE0MSAgIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIiAmJiBkZWNpc2lvbi5jdXN0b21JbnN0cnVjdGlvbikge1xuIDE0MiAgICAgbWVzc2FnZSArPSBgIEN1c3RvbSBpbnN0cnVjdGlvbjogXCIke2RlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9ufVwiYDtcbiAxNDMgICB9XG4tMTQ0ICAgbWVzc2FnZSArPSBcIiBQaGFzZSBjaGFuZ2VkOiBSRUZBQ1RPUiDihpIgUkVELlwiO1xuKzE1MCAgIG1lc3NhZ2UgKz0gXCIgUGhhc2U6IFJFRkFDVE9SICh3b3JraW5nKS5cIjtcbiAxNDUgXG4gMTQ2ICAgcmV0dXJuIHtcbiAxNDcgICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAxNDggICAgIG1lc3NhZ2UsXG4gICAgIC4uLlxuIDMxNCAgICAgICByZXR1cm4gYFlvdSBhcmUgaW4gR1JFRU4gcGhhc2UuIFRlc3RzIHBhc3MuXG4gMzE1IC0gQ2FsbCBnby10by1yZWZhY3RvciB0byBlbnRlciB0aGUgUkVGQUNUT1IgcGhhc2VcbiAzMTYgLSBUaGUgZGV2ZWxvcGVyIHdpbGwgdGhlbiBkZWNpZGUgd2hhdCB0byByZWZhY3RvcmA7XG4gMzE3ICAgICBjYXNlIFwiUkVGQUNUT1JcIjpcbiszMjQgICAgICAgaWYgKHN0YXRlLmxhc3REZWNpc2lvbikge1xuKzMyNSAgICAgICAgIHJldHVybiBgWW91IGFyZSBpbiBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciBjaG9zZTogJHtzdGF0ZS5sYXN0RGVjaXNpb24uZm9jdXN9LlxuKzMyNiAtIEV4ZWN1dGUgdGhlIHJlZmFjdG9yaW5nIHdvcmsgbm93XG4rMzI3IC0gQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzXG4rMzI4IC0gVGhlbiBjYWxsIGdvLXRvLXJlZmFjdG9yIGFnYWluIHRvIHJlcG9ydCBiYWNrIHRvIHRoZSBkZXZlbG9wZXJgO1xuKzMyOSAgICAgICB9XG4gMzE4ICAgICAgIHJldHVybiBgWW91IGFyZSBpbiBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciBpcyBkZWNpZGluZyB3aGF0IHRvIHJlZmFjdG9yLlxuIDMxOSAtIFdhaXQgZm9yIHRoZSBkZXZlbG9wZXIncyBkZWNpc2lvblxuKzMzMiAtIE9wdGlvbnM6IGF1ZGl0IChjb2RlIHNtZWxscyksIHJlZmFjdG9yIHRlc3RzLCByZWZhY3RvciBpbXBsZW1lbnRhdGlvbiwgbmV4dCB0ZXN0LCBvciBjdXN0b21cbiAzMjAgLSBBZnRlciByZWZhY3RvcmluZywgcnVuIHRlc3RzIHRvIHZlcmlmeSB0aGV5IHN0aWxsIHBhc3Ncbi0zMjEgLSBUaGVuIHByb2NlZWQgdG8gdGhlIG5leHQgdGVzdCAoUkVEIHBoYXNlKWA7XG4rMzM0IC0gVGhlbiBjYWxsIGdvLXRvLXJlZmFjdG9yIHRvIHJlcG9ydCBiYWNrIHRvIHRoZSBkZXZlbG9wZXJgO1xuIDMyMiAgIH1cbiAzMjMgfSIsInBhdGNoIjoiLS0tIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50c1xuKysrIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50c1xuQEAgLTE1LDExICsxNSwxMiBAQFxuIGV4cG9ydCBjb25zdCBQSEFTRVM6IFBoYXNlW10gPSBbXCJSRURcIiwgXCJHUkVFTlwiLCBcIlJFRkFDVE9SXCJdO1xuIFxuIC8vIOKUgOKUgCBSZWZhY3RvciBGb2N1cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiBcbi1leHBvcnQgdHlwZSBSZWZhY3RvckZvY3VzID0gXCJ0ZXN0c1wiIHwgXCJpbXBsZW1lbnRhdGlvblwiIHwgXCJuZXh0LXRlc3RcIiB8IFwiY3VzdG9tXCI7XG4rZXhwb3J0IHR5cGUgUmVmYWN0b3JGb2N1cyA9IFwiYXVkaXRcIiB8IFwidGVzdHNcIiB8IFwiaW1wbGVtZW50YXRpb25cIiB8IFwibmV4dC10ZXN0XCIgfCBcImN1c3RvbVwiO1xuIFxuIGV4cG9ydCBjb25zdCBSRUZBQ1RPUl9GT0NJOiBSZWZhY3RvckZvY3VzW10gPSBbXG4rICBcImF1ZGl0XCIsXG4gICBcInRlc3RzXCIsXG4gICBcImltcGxlbWVudGF0aW9uXCIsXG4gICBcIm5leHQtdGVzdFwiLFxuICAgXCJjdXN0b21cIixcbkBAIC0xMTUsOSArMTE2LDExIEBAXG4gICB9O1xuIH1cbiBcbiAvKipcbi0gKiBBcHBseSBhIHJlZmFjdG9yaW5nIGRlY2lzaW9uIGFuZCB0cmFuc2l0aW9uIGJhY2sgdG8gUkVELlxuKyAqIEFwcGx5IGEgcmVmYWN0b3JpbmcgZGVjaXNpb24uXG4rICogT25seSB0cmFuc2l0aW9ucyB0byBSRUQgZm9yIFwibmV4dC10ZXN0XCI7IG90aGVyIG9wdGlvbnMgc3RheSBpbiBSRUZBQ1RPUlxuKyAqIHNvIHRoZSBhZ2VudCBjYW4gZG8gdGhlIGFjdHVhbCByZWZhY3RvcmluZyB3b3JrLlxuICAqL1xuIGV4cG9ydCBmdW5jdGlvbiBhcHBseVJlZmFjdG9yRGVjaXNpb24oXG4gICBzdGF0ZTogQ3ljbGVTdGF0ZSxcbiAgIGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uLFxuQEAgLTEzMSwxOCArMTM0LDIxIEBAXG4gICAgIHRlc3RzUmFuOiBmYWxzZSxcbiAgICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICAgfTtcbiBcbi0gIC8vIElmIGRldmVsb3BlciBjaG9zZSBcIm5leHQtdGVzdFwiLCBpbmNyZW1lbnQgdGVzdCBjb3VudFxuICAgaWYgKGRlY2lzaW9uLmZvY3VzID09PSBcIm5leHQtdGVzdFwiKSB7XG4gICAgIG5ld1N0YXRlLnRlc3RzV3JpdHRlbiA9IChzdGF0ZS50ZXN0c1dyaXR0ZW4gPz8gMCkgKyAxO1xuKyAgICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVEXCI7XG4rICAgIGxldCBtZXNzYWdlID0gYPCflIAgTmV4dCB0ZXN0LiBQaGFzZSBjaGFuZ2VkOiBSRUZBQ1RPUiDihpIgUkVELmA7XG4rICAgIHJldHVybiB7IHN0YXRlOiBuZXdTdGF0ZSwgbWVzc2FnZSwgdmFsaWQ6IHRydWUgfTtcbiAgIH1cbiBcbi0gIGxldCBtZXNzYWdlID0gYPCflIAgUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZDogJHtkZWNpc2lvbi5mb2N1c30uYDtcbisgIC8vIEZvciBhdWRpdCwgdGVzdHMsIGltcGxlbWVudGF0aW9uLCBjdXN0b20g4oCUIHN0YXkgaW4gUkVGQUNUT1IgZm9yIGFnZW50IHRvIHdvcmtcbisgIGxldCBtZXNzYWdlID0gYPCflIAgUmVmYWN0b3JpbmcgZGVjaXNpb246ICR7ZGVjaXNpb24uZm9jdXN9LmA7XG4gICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICAgbWVzc2FnZSArPSBgIEN1c3RvbSBpbnN0cnVjdGlvbjogXCIke2RlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9ufVwiYDtcbiAgIH1cbi0gIG1lc3NhZ2UgKz0gXCIgUGhhc2UgY2hhbmdlZDogUkVGQUNUT1Ig4oaSIFJFRC5cIjtcbisgIG1lc3NhZ2UgKz0gXCIgUGhhc2U6IFJFRkFDVE9SICh3b3JraW5nKS5cIjtcbiBcbiAgIHJldHVybiB7XG4gICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICAgbWVzc2FnZSxcbkBAIC0zMTQsMTAgKzMyMCwxNyBAQFxuICAgICAgIHJldHVybiBgWW91IGFyZSBpbiBHUkVFTiBwaGFzZS4gVGVzdHMgcGFzcy5cbiAtIENhbGwgZ28tdG8tcmVmYWN0b3IgdG8gZW50ZXIgdGhlIFJFRkFDVE9SIHBoYXNlXG4gLSBUaGUgZGV2ZWxvcGVyIHdpbGwgdGhlbiBkZWNpZGUgd2hhdCB0byByZWZhY3RvcmA7XG4gICAgIGNhc2UgXCJSRUZBQ1RPUlwiOlxuKyAgICAgIGlmIChzdGF0ZS5sYXN0RGVjaXNpb24pIHtcbisgICAgICAgIHJldHVybiBgWW91IGFyZSBpbiBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciBjaG9zZTogJHtzdGF0ZS5sYXN0RGVjaXNpb24uZm9jdXN9LlxuKy0gRXhlY3V0ZSB0aGUgcmVmYWN0b3Jpbmcgd29yayBub3dcbistIEFmdGVyIHJlZmFjdG9yaW5nLCBydW4gdGVzdHMgdG8gdmVyaWZ5IHRoZXkgc3RpbGwgcGFzc1xuKy0gVGhlbiBjYWxsIGdvLXRvLXJlZmFjdG9yIGFnYWluIHRvIHJlcG9ydCBiYWNrIHRvIHRoZSBkZXZlbG9wZXJgO1xuKyAgICAgIH1cbiAgICAgICByZXR1cm4gYFlvdSBhcmUgaW4gUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgaXMgZGVjaWRpbmcgd2hhdCB0byByZWZhY3Rvci5cbiAtIFdhaXQgZm9yIHRoZSBkZXZlbG9wZXIncyBkZWNpc2lvblxuKy0gT3B0aW9uczogYXVkaXQgKGNvZGUgc21lbGxzKSwgcmVmYWN0b3IgdGVzdHMsIHJlZmFjdG9yIGltcGxlbWVudGF0aW9uLCBuZXh0IHRlc3QsIG9yIGN1c3RvbVxuIC0gQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzXG4tLSBUaGVuIHByb2NlZWQgdG8gdGhlIG5leHQgdGVzdCAoUkVEIHBoYXNlKWA7XG4rLSBUaGVuIGNhbGwgZ28tdG8tcmVmYWN0b3IgdG8gcmVwb3J0IGJhY2sgdG8gdGhlIGRldmVsb3BlcmA7XG4gICB9XG4gfVxuIiwiZmlyc3RDaGFuZ2VkTGluZSI6MTl9LCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5Nzk4MDY1fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNDFmNDM0ZGIiLCJwYXJlbnRJZCI6IjQ3Yjc1YjU4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowMzo0MC4xNjBaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJXYWl0LCBJIGJyb2tlIHNvbWV0aGluZyBpbiBgYXBwbHlSZWZhY3RvckRlY2lzaW9uYC4gVGhlIGZ1bmN0aW9uIGNyZWF0ZXMgYG5ld1N0YXRlYCB3aXRoIGBwaGFzZTogXCJSRURcImAgYW5kIHRoZW4gY29uZGl0aW9uYWxseSBzZXRzIGl0IHRvIFJFRCBmb3IgbmV4dC10ZXN0IGFuZCBzdGF5cyBpbiBSRUZBQ1RPUiBmb3Igb3RoZXJzLiBCdXQgdGhlIGluaXRpYWwgY3JlYXRpb24gc2V0cyBgcGhhc2U6IFwiUkVEXCJgIGFsd2F5cywgdGhlbiBJIG92ZXJyaWRlIGl0IGxhdGVyLiBMZXQgbWUgY2hlY2sgdGhlIGNvZGUuLi5cblxuQWN0dWFsbHkgbG9va2luZyBhdCBteSBlZGl0IG1vcmUgY2FyZWZ1bGx5OlxuXG5gYGB0eXBlc2NyaXB0XG4gIGNvbnN0IG5ld1N0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgIGxhc3REZWNpc2lvbjogZGVjaXNpb24sXG4gICAgY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbjpcbiAgICAgIGRlY2lzaW9uLmZvY3VzID09PSBcImN1c3RvbVwiID8gZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24gOiB1bmRlZmluZWQsXG4gICAgdGVzdHNSYW46IGZhbHNlLFxuICAgIHRlc3RzUGFzc2VkOiBmYWxzZSxcbiAgfTtcbmBgYFxuXG5UaGlzIHNldHMgcGhhc2UgdG8gUkVEIGFsd2F5cyBhdCBmaXJzdC4gVGhlbjpcblxuYGBgdHlwZXNjcmlwdFxuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwibmV4dC10ZXN0XCIpIHtcbiAgICBuZXdTdGF0ZS50ZXN0c1dyaXR0ZW4gPSAoc3RhdGUudGVzdHNXcml0dGVuID8/IDApICsgMTtcbiAgICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVEXCI7XG4gICAgbGV0IG1lc3NhZ2UgPSAuLi47XG4gICAgcmV0dXJuIHsgc3RhdGU6IG5ld1N0YXRlLCBtZXNzYWdlLCB2YWxpZDogdHJ1ZSB9O1xuICB9XG5cbiAgLy8gRm9yIGF1ZGl0LCB0ZXN0cywgaW1wbGVtZW50YXRpb24sIGN1c3RvbSDigJQgc3RheSBpbiBSRUZBQ1RPUiBmb3IgYWdlbnQgdG8gd29ya1xuICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVGQUNUT1JcIjtcbiAgbGV0IG1lc3NhZ2UgPSAuLi47XG4gIHJldHVybiB7IHN0YXRlOiBuZXdTdGF0ZSwgbWVzc2FnZSwgdmFsaWQ6IHRydWUgfTtcbmBgYFxuXG5XYWl0LCB0aGUgc2Vjb25kIHBhcnQgc2V0cyBgbmV3U3RhdGUucGhhc2UgPSBcIlJFRkFDVE9SXCJgLiBCdXQgSSBkaWRuJ3QgaW5jbHVkZSB0aGF0IGluIG15IGVkaXQhIFRoZSBvbGQgY29kZSBkaWRuJ3QgbmVlZCB0byByZS1zZXQgcGhhc2UgYmVjYXVzZSB0aGUgaW5pdGlhbCB3YXMgYWxyZWFkeSBjb3JyZWN0LiBCdXQgbm93IEkgbmVlZCB0byBvdmVycmlkZSBpdCBmb3Igbm9uLW5leHQtdGVzdCBjYXNlcy5cblxuTGV0IG1lIGNoZWNrIHdoYXQgbXkgZWRpdCBwcm9kdWNlcy4gVGhlIG9sZCBjb2RlIGhhZDpcbmBgYFxuICBjb25zdCBuZXdTdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBwaGFzZTogXCJSRURcIixcbiAgICAuLi5cbiAgfTtcblxuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwibmV4dC10ZXN0XCIpIHtcbiAgICBuZXdTdGF0ZS50ZXN0c1dyaXR0ZW4gPSAuLi47XG4gIH1cbmBgYFxuXG5BbmQgbXkgZWRpdCByZXBsYWNlZCBpdCB3aXRoOlxuYGBgXG4gIGNvbnN0IG5ld1N0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgIC4uLlxuICB9O1xuXG4gIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJuZXh0LXRlc3RcIikge1xuICAgIG5ld1N0YXRlLnRlc3RzV3JpdHRlbiA9IC4uLjtcbiAgICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVEXCI7XG4gICAgLi4uXG4gICAgcmV0dXJuIC4uLjtcbiAgfVxuXG4gIC8vIEZvciBhdWRpdCwgdGVzdHMsIGltcGxlbWVudGF0aW9uLCBjdXN0b20g4oCUIHN0YXkgaW4gUkVGQUNUT1JcbiAgbGV0IG1lc3NhZ2UgPSAuLi47XG4gIHJldHVybiB7IHN0YXRlOiBuZXdTdGF0ZSwgbWVzc2FnZSwgdmFsaWQ6IHRydWUgfTtcbmBgYFxuXG5CdXQgYG5ld1N0YXRlLnBoYXNlYCB3YXMgc2V0IHRvIFwiUkVEXCIgaW5pdGlhbGx5LiBGb3Igbm9uLW5leHQtdGVzdCBjYXNlcywgSSBuZWVkIHRvIG92ZXJyaWRlIGl0IHRvIFwiUkVGQUNUT1JcIi4gTGV0IG1lIGZpeCB0aGF0LiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJXYWl0LCBJIG5lZWQgdG8gYWxzbyBzZXQgcGhhc2UgdG8gUkVGQUNUT1IgZm9yIG5vbi1uZXh0LXRlc3QgY2FzZXMuIExldCBtZSBmaXggdGhhdDpcblxuIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfMzc5M2RmOWZmZTVkNDcwZDhjN2VhYjE4IiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsibGltaXQiOjIwLCJvZmZzZXQiOjEwNSwicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50cyJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTI5MDM2LCJvdXRwdXQiOjY1OSwiY2FjaGVSZWFkIjoxMDI0LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTMwNzE5LCJjb3N0Ijp7ImlucHV0IjowLjAxMTYxMzI0LCJvdXRwdXQiOjAuMDAwMTE4NjIsImNhY2hlUmVhZCI6MC4wMDAwMjA0OCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDExNzUyMzR9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDk3OTgwNjYsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTc5OS1tTDFsV0xYWHRPVTR0MXcxREJKUCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIwODZmYWJjNCIsInBhcmVudElkIjoiNDFmNDM0ZGIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjAzOjQwLjE3OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMzc5M2RmOWZmZTVkNDcwZDhjN2VhYjE4IiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiLyoqXG4gKiBUcmFuc2l0aW9uIGZyb20gR1JFRU4gdG8gUkVGQUNUT1IuXG4gKiBBbHdheXMgdmFsaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncmVlblRvUmVmYWN0b3Ioc3RhdGU6IEN5Y2xlU3RhdGUpOiBUcmFuc2l0aW9uUmVzdWx0IHtcbiAgcmV0dXJuIHtcbiAgICBzdGF0ZTogeyAuLi5zdGF0ZSwgcGhhc2U6IFwiUkVGQUNUT1JcIiB9LFxuICAgIG1lc3NhZ2U6XG4gICAgICBcIvCflIQgUGhhc2UgY2hhbmdlZDogR1JFRU4g4oaSIFJFRkFDVE9SLiBcIiArXG4gICAgICBcIkRldmVsb3BlciB3aWxsIG5vdyBkZWNpZGUgd2hhdCB0byByZWZhY3Rvci5cIixcbiAgICB2YWxpZDogdHJ1ZSxcbiAgfTtcbn1cblxuLyoqXG4gKiBBcHBseSBhIHJlZmFjdG9yaW5nIGRlY2lzaW9uLlxuICogT25seSB0cmFuc2l0aW9ucyB0byBSRUQgZm9yIFwibmV4dC10ZXN0XCI7IG90aGVyIG9wdGlvbnMgc3RheSBpbiBSRUZBQ1RPUlxuICogc28gdGhlIGFnZW50IGNhbiBkbyB0aGUgYWN0dWFsIHJlZmFjdG9yaW5nIHdvcmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVJlZmFjdG9yRGVjaXNpb24oXG5cblsyMTMgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTEyNSB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5ODIwMTc5fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMjM3MjQ5MzIiLCJwYXJlbnRJZCI6IjA4NmZhYmM0IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowMzo0NS43MzJaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJMZXQgbWUgcmVhZCB0aGUgZnVsbCBmdW5jdGlvbiB0byBzZWUgd2hhdCBpdCBsb29rcyBsaWtlIG5vdy4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzAwX3NLdktoWkkzbVVYUDFIV2VpNVFENTc1NCIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7ImxpbWl0Ijo0MCwib2Zmc2V0IjoxMjUsInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjE1MDc2LCJvdXRwdXQiOjEwOCwiY2FjaGVSZWFkIjoxMTU3MTIsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMzA4OTYsImNvc3QiOnsiaW5wdXQiOjAuMDAxMzU2ODQsIm91dHB1dCI6MC4wMDAwMTk0NCwiY2FjaGVSZWFkIjowLjAwMjMxNDI0LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDM2OTA1Mn19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk0OTgyMDE4MSwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTQ5ODIwLVBKWjRienNydXV0Z1VBWjdaQldRIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImE0NzRjY2YzIiwicGFyZW50SWQiOiIyMzcyNDkzMiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDM6NDUuNzQ0WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF8wMF9zS3ZLaFpJM21VWFAxSFdlaTVRRDU3NTQiLCJ0b29sTmFtZSI6InJlYWQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIgIHN0YXRlOiBDeWNsZVN0YXRlLFxuICBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbixcbik6IFRyYW5zaXRpb25SZXN1bHQge1xuICBjb25zdCBuZXdTdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBwaGFzZTogXCJSRURcIixcbiAgICBsYXN0RGVjaXNpb246IGRlY2lzaW9uLFxuICAgIGN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb246XG4gICAgICBkZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIiA/IGRlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9uIDogdW5kZWZpbmVkLFxuICAgIHRlc3RzUmFuOiBmYWxzZSxcbiAgICB0ZXN0c1Bhc3NlZDogZmFsc2UsXG4gIH07XG5cbiAgaWYgKGRlY2lzaW9uLmZvY3VzID09PSBcIm5leHQtdGVzdFwiKSB7XG4gICAgbmV3U3RhdGUudGVzdHNXcml0dGVuID0gKHN0YXRlLnRlc3RzV3JpdHRlbiA/PyAwKSArIDE7XG4gICAgbmV3U3RhdGUucGhhc2UgPSBcIlJFRFwiO1xuICAgIGxldCBtZXNzYWdlID0gYPCflIAgTmV4dCB0ZXN0LiBQaGFzZSBjaGFuZ2VkOiBSRUZBQ1RPUiDihpIgUkVELmA7XG4gICAgcmV0dXJuIHsgc3RhdGU6IG5ld1N0YXRlLCBtZXNzYWdlLCB2YWxpZDogdHJ1ZSB9O1xuICB9XG5cbiAgLy8gRm9yIGF1ZGl0LCB0ZXN0cywgaW1wbGVtZW50YXRpb24sIGN1c3RvbSDigJQgc3RheSBpbiBSRUZBQ1RPUiBmb3IgYWdlbnQgdG8gd29ya1xuICBsZXQgbWVzc2FnZSA9IGDwn5SAIFJlZmFjdG9yaW5nIGRlY2lzaW9uOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICBtZXNzYWdlICs9IGAgQ3VzdG9tIGluc3RydWN0aW9uOiBcIiR7ZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb259XCJgO1xuICB9XG4gIG1lc3NhZ2UgKz0gXCIgUGhhc2U6IFJFRkFDVE9SICh3b3JraW5nKS5cIjtcblxuICByZXR1cm4ge1xuICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICBtZXNzYWdlLFxuICAgIHZhbGlkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIFJlY29yZCB0aGF0IHRlc3RzIGhhdmUgYmVlbiBydW4gYW5kIHRoZWlyIHJlc3VsdC5cbiAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBnby10by1ncmVlbiB0b29sIGFmdGVyIHRlc3QgZXhlY3V0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkVGVzdFJlc3VsdChcbiAgc3RhdGU6IEN5Y2xlU3RhdGUsXG5cblsxNzMgbW9yZSBsaW5lcyBpbiBmaWxlLiBVc2Ugb2Zmc2V0PTE2NSB0byBjb250aW51ZS5dIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5ODI1NzQ0fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMzExZWYwNDMiLCJwYXJlbnRJZCI6ImE0NzRjY2YzIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowMzo1NS41MzRaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIHNlZSB0aGUgaXNzdWUuIEZvciBub24tbmV4dC10ZXN0IGNhc2VzLCBgbmV3U3RhdGUucGhhc2VgIGlzIHN0aWxsIFwiUkVEXCIgZnJvbSB0aGUgaW5pdGlhbCBjcmVhdGlvbi4gSSBuZWVkIHRvIHNldCBpdCB0byBcIlJFRkFDVE9SXCIuIExldCBtZSBmaXggdGhhdC4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsX2M3MWI5YWY4MGY3ZTRiYzc5YTNiYjFjYiIsIm5hbWUiOiJlZGl0IiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvc3RhdGUudHMiLCJlZGl0cyI6W3sibmV3VGV4dCI6IiAgLy8gRm9yIGF1ZGl0LCB0ZXN0cywgaW1wbGVtZW50YXRpb24sIGN1c3RvbSDigJQgc3RheSBpbiBSRUZBQ1RPUiBmb3IgYWdlbnQgdG8gd29ya1xuICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVGQUNUT1JcIjtcbiAgbGV0IG1lc3NhZ2UgPSBg8J+UgCBSZWZhY3RvcmluZyBkZWNpc2lvbjogJHtkZWNpc2lvbi5mb2N1c30uYDsiLCJvbGRUZXh0IjoiICAvLyBGb3IgYXVkaXQsIHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgY3VzdG9tIOKAlCBzdGF5IGluIFJFRkFDVE9SIGZvciBhZ2VudCB0byB3b3JrXG4gIGxldCBtZXNzYWdlID0gYPCflIAgUmVmYWN0b3JpbmcgZGVjaXNpb246ICR7ZGVjaXNpb24uZm9jdXN9LmA7In1dfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEzMTMxMiwib3V0cHV0IjoyMjksImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEzMTU0MSwiY29zdCI6eyJpbnB1dCI6MC4wMTE4MTgwOCwib3V0cHV0IjowLjAwMDA0MTIyLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAxMTg1OTN9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDk4MjU3NDUsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTgyNS1WTlVLQmZLYUJldlhaU2VkT0QyQyIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJkODNiN2IxMyIsInBhcmVudElkIjoiMzExZWYwNDMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjAzOjU1LjUzNloiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfYzcxYjlhZjgwZjdlNGJjNzlhM2JiMWNiIiwidG9vbE5hbWUiOiJlZGl0IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU3VjY2Vzc2Z1bGx5IHJlcGxhY2VkIDEgYmxvY2socykgaW4gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3N0YXRlLnRzLiJ9XSwiZGV0YWlscyI6eyJkaWZmIjoiICAgICAuLi5cbiAxNDIgICAgIHJldHVybiB7IHN0YXRlOiBuZXdTdGF0ZSwgbWVzc2FnZSwgdmFsaWQ6IHRydWUgfTtcbiAxNDMgICB9XG4gMTQ0IFxuIDE0NSAgIC8vIEZvciBhdWRpdCwgdGVzdHMsIGltcGxlbWVudGF0aW9uLCBjdXN0b20g4oCUIHN0YXkgaW4gUkVGQUNUT1IgZm9yIGFnZW50IHRvIHdvcmtcbisxNDYgICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVGQUNUT1JcIjtcbiAxNDYgICBsZXQgbWVzc2FnZSA9IGDwn5SAIFJlZmFjdG9yaW5nIGRlY2lzaW9uOiAke2RlY2lzaW9uLmZvY3VzfS5gO1xuIDE0NyAgIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIiAmJiBkZWNpc2lvbi5jdXN0b21JbnN0cnVjdGlvbikge1xuIDE0OCAgICAgbWVzc2FnZSArPSBgIEN1c3RvbSBpbnN0cnVjdGlvbjogXCIke2RlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9ufVwiYDtcbiAxNDkgICB9XG4gICAgIC4uLiIsInBhdGNoIjoiLS0tIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50c1xuKysrIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9zdGF0ZS50c1xuQEAgLTE0Miw4ICsxNDIsOSBAQFxuICAgICByZXR1cm4geyBzdGF0ZTogbmV3U3RhdGUsIG1lc3NhZ2UsIHZhbGlkOiB0cnVlIH07XG4gICB9XG4gXG4gICAvLyBGb3IgYXVkaXQsIHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgY3VzdG9tIOKAlCBzdGF5IGluIFJFRkFDVE9SIGZvciBhZ2VudCB0byB3b3JrXG4rICBuZXdTdGF0ZS5waGFzZSA9IFwiUkVGQUNUT1JcIjtcbiAgIGxldCBtZXNzYWdlID0gYPCflIAgUmVmYWN0b3JpbmcgZGVjaXNpb246ICR7ZGVjaXNpb24uZm9jdXN9LmA7XG4gICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICAgbWVzc2FnZSArPSBgIEN1c3RvbSBpbnN0cnVjdGlvbjogXCIke2RlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9ufVwiYDtcbiAgIH1cbiIsImZpcnN0Q2hhbmdlZExpbmUiOjE0Nn0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDk4MzU1MzZ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIxYzg4NWI1MCIsInBhcmVudElkIjoiZDgzYjdiMTMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA0OjAyLjM0NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ikdvb2QuIE5vdyB1cGRhdGUgdGhlIHRlc3RzIHRvIGFkZCB0aGUgYXVkaXQgY2FzZSBhbmQgZml4IHRoZSBhc3N1bXB0aW9uIHRoYXQgYXBwbHlSZWZhY3RvckRlY2lzaW9uIGFsd2F5cyBnb2VzIHRvIFJFRCAoZm9yIG5vbi1uZXh0LXRlc3Qgb3B0aW9ucyBpdCBzaG91bGQgc3RheSBpbiBSRUZBQ1RPUikuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vdyB1cGRhdGUgdGhlIHRlc3RzIHRvIHJlZmxlY3QgdGhlIG5ldyBiZWhhdmlvcjoifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMF9DRGRQNjVyVDZVUjVPUDRwTUhvYjMzNzAiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3Rlc3Qvc3RhdGUudGVzdC50cyJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6OTAyOCwib3V0cHV0IjoxMTEsImNhY2hlUmVhZCI6MTIyNDk2LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTMxNjM1LCJjb3N0Ijp7ImlucHV0IjowLjAwMDgxMjUyLCJvdXRwdXQiOjAuMDAwMDE5OTgsImNhY2hlUmVhZCI6MC4wMDI0NDk5MiwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAzMjgyNDJ9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDk4MzU1MzgsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTgzNS1QNzBxZVlsUXpicFlsUHFrRU0xTyIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3NmFkZDA2OCIsInBhcmVudElkIjoiMWM4ODViNTAiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA0OjAyLjM0OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMDBfQ0RkUDY1clQ2VVI1T1A0cE1Ib2IzMzcwIiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiaW1wb3J0IHsgZGVzY3JpYmUsIGl0LCBleHBlY3QgfSBmcm9tIFwidml0ZXN0XCI7XG5pbXBvcnQge1xuICBjcmVhdGVJbml0aWFsU3RhdGUsXG4gIHJlZFRvR3JlZW4sXG4gIGdyZWVuVG9SZWZhY3RvcixcbiAgYXBwbHlSZWZhY3RvckRlY2lzaW9uLFxuICByZWNvcmRUZXN0UmVzdWx0LFxuICBjYW5UcmFuc2l0aW9uLFxuICBwaGFzZUVtb2ppLFxuICBwaGFzZURlc2NyaXB0aW9uLFxuICBwaGFzZUd1aWRlbGluZXMsXG4gIHR5cGUgQ3ljbGVTdGF0ZSxcbiAgdHlwZSBSZWZhY3RvckRlY2lzaW9uLFxufSBmcm9tIFwiLi4vc3RhdGUuanNcIjtcblxuZGVzY3JpYmUoXCJjcmVhdGVJbml0aWFsU3RhdGVcIiwgKCkgPT4ge1xuICBpdChcInJldHVybnMgUkVEIHBoYXNlIHdpdGggZGVmYXVsdHNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7XG4gICAgZXhwZWN0KHN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICAgIGV4cGVjdChzdGF0ZS50ZXN0c1JhbikudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHN0YXRlLnRlc3RzUGFzc2VkKS50b0JlKGZhbHNlKTtcbiAgICBleHBlY3Qoc3RhdGUudGVzdHNXcml0dGVuKS50b0JlKDApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInJlZFRvR3JlZW5cIiwgKCkgPT4ge1xuICBpdChcInRyYW5zaXRpb25zIHdoZW4gdGVzdHMgcmFuIGFuZCBwYXNzZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICB0ZXN0c1JhbjogdHJ1ZSxcbiAgICAgIHRlc3RzUGFzc2VkOiB0cnVlLFxuICAgICAgdGVzdHNXcml0dGVuOiAxLFxuICAgIH07XG4gICAgY29uc3QgcmVzdWx0ID0gcmVkVG9HcmVlbihzdGF0ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiR1JFRU5cIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1JhbikudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1Bhc3NlZCkudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5tZXNzYWdlKS50b0NvbnRhaW4oXCJHUkVFTlwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZWplY3RzIHdoZW4gdGVzdHMgaGF2ZSBub3QgYmVlbiBydW5cIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICB0ZXN0c1JhbjogZmFsc2UsXG4gICAgICB0ZXN0c1Bhc3NlZDogZmFsc2UsXG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSByZWRUb0dyZWVuKHN0YXRlKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKTtcbiAgICBleHBlY3QocmVzdWx0LmVycm9yKS50b0NvbnRhaW4oXCJoYXZlIG5vdCBiZWVuIHJ1blwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZWplY3RzIHdoZW4gdGVzdHMgZmFpbGVkXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogZmFsc2UsXG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSByZWRUb0dyZWVuKHN0YXRlKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKTtcbiAgICBleHBlY3QocmVzdWx0LmVycm9yKS50b0NvbnRhaW4oXCJkaWQgbm90IHBhc3NcIik7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiZ3JlZW5Ub1JlZmFjdG9yXCIsICgpID0+IHtcbiAgaXQoXCJhbHdheXMgdHJhbnNpdGlvbnMgZnJvbSBHUkVFTiB0byBSRUZBQ1RPUlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIkdSRUVOXCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChyZXN1bHQubWVzc2FnZSkudG9Db250YWluKFwiUkVGQUNUT1JcIik7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiYXBwbHlSZWZhY3RvckRlY2lzaW9uXCIsICgpID0+IHtcbiAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgd2l0aCB0ZXN0cyBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMSB9O1xuICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJ0ZXN0c1wiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUubGFzdERlY2lzaW9uKS50b0VxdWFsKGRlY2lzaW9uKTtcbiAgfSk7XG5cbiAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgd2l0aCBpbXBsZW1lbnRhdGlvbiBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwiaW1wbGVtZW50YXRpb25cIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICB9KTtcblxuICBpdChcImluY3JlbWVudHMgdGVzdHNXcml0dGVuIGZvciBuZXh0LXRlc3QgZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiLCB0ZXN0c1dyaXR0ZW46IDMgfTtcbiAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwibmV4dC10ZXN0XCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzV3JpdHRlbikudG9CZSg0KTtcbiAgfSk7XG5cbiAgaXQoXCJzdG9yZXMgY3VzdG9tIGluc3RydWN0aW9uIGZvciBjdXN0b20gZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7XG4gICAgICBmb2N1czogXCJjdXN0b21cIixcbiAgICAgIGN1c3RvbUluc3RydWN0aW9uOiBcIkV4dHJhY3QgdGhlIHNlcnZpY2UgY2xhc3NcIixcbiAgICB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbikudG9CZShcbiAgICAgIFwiRXh0cmFjdCB0aGUgc2VydmljZSBjbGFzc1wiLFxuICAgICk7XG4gIH0pO1xuXG4gIGl0KFwicmVzZXRzIHRlc3RzUmFuIGFuZCB0ZXN0c1Bhc3NlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRUZBQ1RPUlwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICB9O1xuICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJpbXBsZW1lbnRhdGlvblwiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1JhbikudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1Bhc3NlZCkudG9CZShmYWxzZSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwicmVjb3JkVGVzdFJlc3VsdFwiLCAoKSA9PiB7XG4gIGl0KFwicmVjb3JkcyBwYXNzaW5nIHRlc3RzIGluIFJFRCDihpIgYXV0by10cmFuc2l0aW9ucyB0byBHUkVFTlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRFwiLCB0ZXN0c1JhbjogZmFsc2UsIHRlc3RzUGFzc2VkOiBmYWxzZSB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1JhbikudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzUGFzc2VkKS50b0JlKHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJHUkVFTlwiKTtcbiAgfSk7XG5cbiAgaXQoXCJyZWNvcmRzIGZhaWxpbmcgdGVzdHMgaW4gUkVEIOKGkiBzdGF5cyBpbiBSRURcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRURcIiwgdGVzdHNSYW46IGZhbHNlLCB0ZXN0c1Bhc3NlZDogZmFsc2UgfTtcbiAgICBjb25zdCByZXN1bHQgPSByZWNvcmRUZXN0UmVzdWx0KHN0YXRlLCBmYWxzZSk7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzUmFuKS50b0JlKHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUudGVzdHNQYXNzZWQpLnRvQmUoZmFsc2UpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5tZXNzYWdlKS50b0NvbnRhaW4oXCJmYWlsZWRcIik7XG4gIH0pO1xuXG4gIGl0KFwicmVjb3JkcyBwYXNzaW5nIHRlc3RzIGluIEdSRUVOIOKGkiBzdGF5cyBpbiBHUkVFTlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIkdSRUVOXCIsIHRlc3RzUmFuOiB0cnVlLCB0ZXN0c1Bhc3NlZDogdHJ1ZSB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIkdSRUVOXCIpO1xuICB9KTtcblxuICBpdChcInJlamVjdHMgcmVjb3JkaW5nIGluIFJFRkFDVE9SIHBoYXNlXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHRydWUpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICAgIGV4cGVjdChyZXN1bHQuZXJyb3IpLnRvQ29udGFpbihcIlJFRkFDVE9SXCIpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcImNhblRyYW5zaXRpb25cIiwgKCkgPT4ge1xuICBpdChcImFsbG93cyBSRUQg4oaSIEdSRUVOIHdoZW4gdGVzdHMgcGFzc2VkXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhblRyYW5zaXRpb24oc3RhdGUsIFwiR1JFRU5cIik7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoXCJibG9ja3MgUkVEIOKGkiBHUkVFTiB3aGVuIHRlc3RzIGZhaWxlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICAgIH07XG4gICAgY29uc3QgcmVzdWx0ID0gY2FuVHJhbnNpdGlvbihzdGF0ZSwgXCJHUkVFTlwiKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoXCJibG9ja3MgUkVEIOKGkiBSRUZBQ1RPUiAobXVzdCBnbyB0aHJvdWdoIEdSRUVOKVwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgICAgdGVzdHNQYXNzZWQ6IHRydWUsXG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSBjYW5UcmFuc2l0aW9uKHN0YXRlLCBcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdChcImFsbG93cyBHUkVFTiDihpIgUkVGQUNUT1JcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJHUkVFTlwiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gY2FuVHJhbnNpdGlvbihzdGF0ZSwgXCJSRUZBQ1RPUlwiKTtcbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKHRydWUpO1xuICB9KTtcblxuICBpdChcImJsb2NrcyBHUkVFTiDihpIgUkVEXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiR1JFRU5cIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhblRyYW5zaXRpb24oc3RhdGUsIFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdChcImFsbG93cyBSRUZBQ1RPUiDihpIgUkVEXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhblRyYW5zaXRpb24oc3RhdGUsIFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KFwiYmxvY2tzIFJFRkFDVE9SIOKGkiBHUkVFTlwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBjYW5UcmFuc2l0aW9uKHN0YXRlLCBcIkdSRUVOXCIpO1xuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInBoYXNlRW1vamlcIiwgKCkgPT4ge1xuICBpdChcInJldHVybnMgY29ycmVjdCBlbW9qaSBmb3IgZWFjaCBwaGFzZVwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHBoYXNlRW1vamkoXCJSRURcIikpLnRvQmUoXCLwn5S0XCIpO1xuICAgIGV4cGVjdChwaGFzZUVtb2ppKFwiR1JFRU5cIikpLnRvQmUoXCLwn5+iXCIpO1xuICAgIGV4cGVjdChwaGFzZUVtb2ppKFwiUkVGQUNUT1JcIikpLnRvQmUoXCLwn5SAXCIpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInBoYXNlRGVzY3JpcHRpb25cIiwgKCkgPT4ge1xuICBpdChcImRlc2NyaWJlcyBSRUQgd2hlbiBubyB0ZXN0cyByYW5cIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7XG4gICAgZXhwZWN0KHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpKS50b0NvbnRhaW4oXCJSRURcIik7XG4gICAgZXhwZWN0KHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpKS50b0NvbnRhaW4oXCJXcml0ZSBhIGZhaWxpbmcgdGVzdFwiKTtcbiAgfSk7XG5cbiAgaXQoXCJkZXNjcmliZXMgUkVE4oaSR1JFRU4gd2hlbiB0ZXN0cyBwYXNzZWQgaW4gUkVEXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHtcbiAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgdGVzdHNSYW46IHRydWUsXG4gICAgICB0ZXN0c1Bhc3NlZDogdHJ1ZSxcbiAgICB9O1xuICAgIGV4cGVjdChwaGFzZURlc2NyaXB0aW9uKHN0YXRlKSkudG9Db250YWluKFwiUkVE4oaSR1JFRU5cIik7XG4gIH0pO1xuXG4gIGl0KFwiZGVzY3JpYmVzIFJFRCB3aGVuIHRlc3RzIGZhaWxlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7XG4gICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgIHRlc3RzUmFuOiB0cnVlLFxuICAgICAgdGVzdHNQYXNzZWQ6IGZhbHNlLFxuICAgIH07XG4gICAgZXhwZWN0KHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpKS50b0NvbnRhaW4oXCJUZXN0cyBmYWlsZWRcIik7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwicGhhc2VHdWlkZWxpbmVzXCIsICgpID0+IHtcbiAgaXQoXCJnaXZlcyBSRUQgZ3VpZGVsaW5lcyB3aGVuIG5vIHRlc3RzIHJhblwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVJbml0aWFsU3RhdGUoKTtcbiAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiV3JpdGUgYSBmYWlsaW5nIHRlc3RcIik7XG4gIH0pO1xuXG4gIGl0KFwiZ2l2ZXMgUkVEIGd1aWRlbGluZXMgd2hlbiB0ZXN0cyBmYWlsZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0ge1xuICAgICAgcGhhc2U6IFwiUkVEXCIsXG4gICAgICB0ZXN0c1JhbjogdHJ1ZSxcbiAgICAgIHRlc3RzUGFzc2VkOiBmYWxzZSxcbiAgICB9O1xuICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJUZXN0cyBmYWlsZWRcIik7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIkRvIE5PVCBjaGFuZ2UgdGhlIHRlc3RcIik7XG4gIH0pO1xuXG4gIGl0KFwiZ2l2ZXMgR1JFRU4gZ3VpZGVsaW5lc1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIkdSRUVOXCIgfTtcbiAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiR1JFRU5cIik7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcImdvLXRvLXJlZmFjdG9yXCIpO1xuICB9KTtcblxuICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZ3VpZGVsaW5lcyA9IHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJXYWl0IGZvciB0aGUgZGV2ZWxvcGVyXCIpO1xuICB9KTtcbn0pO1xuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTQ5ODQyMzQ5fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNjhhNGEyNzUiLCJwYXJlbnRJZCI6Ijc2YWRkMDY4IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowNDoxNS40MjVaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJJIG5lZWQgdG8gdXBkYXRlIHRoZSB0ZXN0czpcblxuMS4gVGVzdHMgdGhhdCBleHBlY3RlZCBgYXBwbHlSZWZhY3RvckRlY2lzaW9uYCB0byByZXR1cm4gUkVEIGZvciBcInRlc3RzXCIgYW5kIFwiaW1wbGVtZW50YXRpb25cIiBmb2N1cyDigJQgbm93IHRoZXkgc2hvdWxkIGV4cGVjdCBSRUZBQ1RPUiAoc2luY2Ugb25seSBcIm5leHQtdGVzdFwiIHRyYW5zaXRpb25zIHRvIFJFRCkuXG4yLiBUaGUgcGhhc2VHdWlkZWxpbmVzIHRlc3QgZm9yIFJFRkFDVE9SIHNob3VsZCBleHBlY3QgdGhlIG5ldyB0ZXh0LlxuXG5MZXQgbWUgdXBkYXRlOiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfMDBfR09ncFk1QzQxNnVaZElsM2g0b3A3MTgyIiwibmFtZSI6ImVkaXQiLCJhcmd1bWVudHMiOnsiZWRpdHMiOlt7Im5ld1RleHQiOiJkZXNjcmliZShcImFwcGx5UmVmYWN0b3JEZWNpc2lvblwiLCAoKSA9PiB7XG4gIGl0KFwic3RheXMgaW4gUkVGQUNUT1Igd2l0aCB0ZXN0cyBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMSB9O1xuICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJ0ZXN0c1wiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVGQUNUT1JcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICB9KTtcblxuICBpdChcInN0YXlzIGluIFJFRkFDVE9SIHdpdGggaW1wbGVtZW50YXRpb24gZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVGQUNUT1JcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICB9KTtcblxuICBpdChcInN0YXlzIGluIFJFRkFDVE9SIHdpdGggYXVkaXQgZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcImF1ZGl0XCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVGQUNUT1JcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICB9KTtcblxuICBpdChcInRyYW5zaXRpb25zIHRvIFJFRCBmb3IgbmV4dC10ZXN0IGZvY3VzXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiwgdGVzdHNXcml0dGVuOiAzIH07XG4gICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcIm5leHQtdGVzdFwiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1dyaXR0ZW4pLnRvQmUoNCk7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIlJFRFwiKTtcbiAgfSk7Iiwib2xkVGV4dCI6ImRlc2NyaWJlKFwiYXBwbHlSZWZhY3RvckRlY2lzaW9uXCIsICgpID0+IHtcbiAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgd2l0aCB0ZXN0cyBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMSB9O1xuICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJ0ZXN0c1wiIH07XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUubGFzdERlY2lzaW9uKS50b0VxdWFsKGRlY2lzaW9uKTtcbiAgfSk7XG5cbiAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgd2l0aCBpbXBsZW1lbnRhdGlvbiBmb2N1c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwiaW1wbGVtZW50YXRpb25cIiB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICB9KTtcblxuICBpdChcImluY3JlbWVudHMgdGVzdHNXcml0dGVuIGZvciBuZXh0LXRlc3QgZm9jdXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiLCB0ZXN0c1dyaXR0ZW46IDMgfTtcbiAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwibmV4dC10ZXN0XCIgfTtcbiAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICBleHBlY3QocmVzdWx0LnN0YXRlLnRlc3RzV3JpdHRlbikudG9CZSg0KTtcbiAgfSk7In0seyJuZXdUZXh0IjoiICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXMgd2hlbiBkZWNpZGluZ1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiUkVGQUNUT1JcIik7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIldhaXQgZm9yIHRoZSBkZXZlbG9wZXJcIik7XG4gIH0pO1xuXG4gIGl0KFwiZ2l2ZXMgUkVGQUNUT1IgZ3VpZGVsaW5lcyB3aGVuIHdvcmtpbmcgb24gYSBkZWNpc2lvblwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIGxhc3REZWNpc2lvbjogeyBmb2N1czogXCJpbXBsZW1lbnRhdGlvblwiIH0gfTtcbiAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiUkVGQUNUT1JcIik7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIkV4ZWN1dGUgdGhlIHJlZmFjdG9yaW5nXCIpO1xuICB9KTsiLCJvbGRUZXh0IjoiICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgY29uc3QgZ3VpZGVsaW5lcyA9IHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIlJFRkFDVE9SXCIpO1xuICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJXYWl0IGZvciB0aGUgZGV2ZWxvcGVyXCIpO1xuICB9KTsifV0sInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdGVzdC9zdGF0ZS50ZXN0LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoyMzQ2LCJvdXRwdXQiOjEyMDEsImNhY2hlUmVhZCI6MTMxNTg0LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTM1MTMxLCJjb3N0Ijp7ImlucHV0IjowLjAwMDIxMTE0LCJvdXRwdXQiOjAuMDAwMjE2MTgsImNhY2hlUmVhZCI6MC4wMDI2MzE2OCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAzMDU5fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5ODQyMzUxLCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDk4NDItYVZHa3Azamg4djNzeVB3OWVtcnYiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZmZjNjZhMGEiLCJwYXJlbnRJZCI6IjY4YTRhMjc1IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowNDoxNS40NDRaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzAwX0dPZ3BZNUM0MTZ1WmRJbDNoNG9wNzE4MiIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSByZXBsYWNlZCAyIGJsb2NrKHMpIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy90ZXN0L3N0YXRlLnRlc3QudHMuIn1dLCJkZXRhaWxzIjp7ImRpZmYiOiIgICAgIC4uLlxuICA3MiAgIH0pO1xuICA3MyB9KTtcbiAgNzQgXG4gIDc1IGRlc2NyaWJlKFwiYXBwbHlSZWZhY3RvckRlY2lzaW9uXCIsICgpID0+IHtcbi0gNzYgICBpdChcInRyYW5zaXRpb25zIHRvIFJFRCB3aXRoIHRlc3RzIGZvY3VzXCIsICgpID0+IHtcbisgNzYgICBpdChcInN0YXlzIGluIFJFRkFDVE9SIHdpdGggdGVzdHMgZm9jdXNcIiwgKCkgPT4ge1xuICA3NyAgICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMSB9O1xuICA3OCAgICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcInRlc3RzXCIgfTtcbiAgNzkgICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICA4MCAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbi0gODEgICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4rIDgxICAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVGQUNUT1JcIik7XG4gIDgyICAgICBleHBlY3QocmVzdWx0LnN0YXRlLmxhc3REZWNpc2lvbikudG9FcXVhbChkZWNpc2lvbik7XG4gIDgzICAgfSk7XG4gIDg0IFxuLSA4NSAgIGl0KFwidHJhbnNpdGlvbnMgdG8gUkVEIHdpdGggaW1wbGVtZW50YXRpb24gZm9jdXNcIiwgKCkgPT4ge1xuKyA4NSAgIGl0KFwic3RheXMgaW4gUkVGQUNUT1Igd2l0aCBpbXBsZW1lbnRhdGlvbiBmb2N1c1wiLCAoKSA9PiB7XG4gIDg2ICAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuICA4NyAgICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfTtcbiAgODggICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuLSA4OSAgICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIlJFRFwiKTtcbisgODkgICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRUZBQ1RPUlwiKTtcbiAgOTAgICAgIGV4cGVjdChyZXN1bHQuc3RhdGUubGFzdERlY2lzaW9uKS50b0VxdWFsKGRlY2lzaW9uKTtcbiAgOTEgICB9KTtcbiAgOTIgXG4tIDkzICAgaXQoXCJpbmNyZW1lbnRzIHRlc3RzV3JpdHRlbiBmb3IgbmV4dC10ZXN0IGZvY3VzXCIsICgpID0+IHtcbisgOTMgICBpdChcInN0YXlzIGluIFJFRkFDVE9SIHdpdGggYXVkaXQgZm9jdXNcIiwgKCkgPT4ge1xuKyA5NCAgICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbisgOTUgICAgIGNvbnN0IGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJhdWRpdFwiIH07XG4rIDk2ICAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbisgOTcgICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRUZBQ1RPUlwiKTtcbisgOTggICAgIGV4cGVjdChyZXN1bHQuc3RhdGUubGFzdERlY2lzaW9uKS50b0VxdWFsKGRlY2lzaW9uKTtcbisgOTkgICB9KTtcbisxMDAgXG4rMTAxICAgaXQoXCJ0cmFuc2l0aW9ucyB0byBSRUQgZm9yIG5leHQtdGVzdCBmb2N1c1wiLCAoKSA9PiB7XG4gIDk0ICAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiwgdGVzdHNXcml0dGVuOiAzIH07XG4gIDk1ICAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwibmV4dC10ZXN0XCIgfTtcbiAgOTYgICAgIGNvbnN0IHJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICA5NyAgICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS50ZXN0c1dyaXR0ZW4pLnRvQmUoNCk7XG4rMTA2ICAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICA5OCAgIH0pO1xuICA5OSBcbiAxMDAgICBpdChcInN0b3JlcyBjdXN0b20gaW5zdHJ1Y3Rpb24gZm9yIGN1c3RvbSBmb2N1c1wiLCAoKSA9PiB7XG4gMTAxICAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuICAgICAuLi5cbiAyNzEgICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJHUkVFTlwiKTtcbiAyNzIgICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJnby10by1yZWZhY3RvclwiKTtcbiAyNzMgICB9KTtcbiAyNzQgXG4tMjc1ICAgaXQoXCJnaXZlcyBSRUZBQ1RPUiBndWlkZWxpbmVzXCIsICgpID0+IHtcbisyODQgICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXMgd2hlbiBkZWNpZGluZ1wiLCAoKSA9PiB7XG4gMjc2ICAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9O1xuIDI3NyAgICAgY29uc3QgZ3VpZGVsaW5lcyA9IHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gMjc4ICAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiUkVGQUNUT1JcIik7XG4gMjc5ICAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiV2FpdCBmb3IgdGhlIGRldmVsb3BlclwiKTtcbiAyODAgICB9KTtcbisyOTAgXG4rMjkxICAgaXQoXCJnaXZlcyBSRUZBQ1RPUiBndWlkZWxpbmVzIHdoZW4gd29ya2luZyBvbiBhIGRlY2lzaW9uXCIsICgpID0+IHtcbisyOTIgICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiLCBsYXN0RGVjaXNpb246IHsgZm9jdXM6IFwiaW1wbGVtZW50YXRpb25cIiB9IH07XG4rMjkzICAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbisyOTQgICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJSRUZBQ1RPUlwiKTtcbisyOTUgICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJFeGVjdXRlIHRoZSByZWZhY3RvcmluZ1wiKTtcbisyOTYgICB9KTtcbiAyODEgfSk7IiwicGF0Y2giOiItLS0gL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3Rlc3Qvc3RhdGUudGVzdC50c1xuKysrIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy90ZXN0L3N0YXRlLnRlc3QudHNcbkBAIC03MiwzMCArNzIsMzkgQEBcbiAgIH0pO1xuIH0pO1xuIFxuIGRlc2NyaWJlKFwiYXBwbHlSZWZhY3RvckRlY2lzaW9uXCIsICgpID0+IHtcbi0gIGl0KFwidHJhbnNpdGlvbnMgdG8gUkVEIHdpdGggdGVzdHMgZm9jdXNcIiwgKCkgPT4ge1xuKyAgaXQoXCJzdGF5cyBpbiBSRUZBQ1RPUiB3aXRoIHRlc3RzIGZvY3VzXCIsICgpID0+IHtcbiAgICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMSB9O1xuICAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwidGVzdHNcIiB9O1xuICAgICBjb25zdCByZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKTtcbi0gICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIlJFRFwiKTtcbisgICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5waGFzZSkudG9CZShcIlJFRkFDVE9SXCIpO1xuICAgICBleHBlY3QocmVzdWx0LnN0YXRlLmxhc3REZWNpc2lvbikudG9FcXVhbChkZWNpc2lvbik7XG4gICB9KTtcbiBcbi0gIGl0KFwidHJhbnNpdGlvbnMgdG8gUkVEIHdpdGggaW1wbGVtZW50YXRpb24gZm9jdXNcIiwgKCkgPT4ge1xuKyAgaXQoXCJzdGF5cyBpbiBSRUZBQ1RPUiB3aXRoIGltcGxlbWVudGF0aW9uIGZvY3VzXCIsICgpID0+IHtcbiAgICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbiAgICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfTtcbiAgICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4tICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRURcIik7XG4rICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRUZBQ1RPUlwiKTtcbiAgICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuICAgfSk7XG4gXG4tICBpdChcImluY3JlbWVudHMgdGVzdHNXcml0dGVuIGZvciBuZXh0LXRlc3QgZm9jdXNcIiwgKCkgPT4ge1xuKyAgaXQoXCJzdGF5cyBpbiBSRUZBQ1RPUiB3aXRoIGF1ZGl0IGZvY3VzXCIsICgpID0+IHtcbisgICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfTtcbisgICAgY29uc3QgZGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcImF1ZGl0XCIgfTtcbisgICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4rICAgIGV4cGVjdChyZXN1bHQuc3RhdGUucGhhc2UpLnRvQmUoXCJSRUZBQ1RPUlwiKTtcbisgICAgZXhwZWN0KHJlc3VsdC5zdGF0ZS5sYXN0RGVjaXNpb24pLnRvRXF1YWwoZGVjaXNpb24pO1xuKyAgfSk7XG4rXG4rICBpdChcInRyYW5zaXRpb25zIHRvIFJFRCBmb3IgbmV4dC10ZXN0IGZvY3VzXCIsICgpID0+IHtcbiAgICAgY29uc3Qgc3RhdGU6IEN5Y2xlU3RhdGUgPSB7IHBoYXNlOiBcIlJFRkFDVE9SXCIsIHRlc3RzV3JpdHRlbjogMyB9O1xuICAgICBjb25zdCBkZWNpc2lvbjogUmVmYWN0b3JEZWNpc2lvbiA9IHsgZm9jdXM6IFwibmV4dC10ZXN0XCIgfTtcbiAgICAgY29uc3QgcmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgIGV4cGVjdChyZXN1bHQuc3RhdGUudGVzdHNXcml0dGVuKS50b0JlKDQpO1xuKyAgICBleHBlY3QocmVzdWx0LnN0YXRlLnBoYXNlKS50b0JlKFwiUkVEXCIpO1xuICAgfSk7XG4gXG4gICBpdChcInN0b3JlcyBjdXN0b20gaW5zdHJ1Y3Rpb24gZm9yIGN1c3RvbSBmb2N1c1wiLCAoKSA9PiB7XG4gICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG5AQCAtMjcxLDExICsyODAsMTggQEBcbiAgICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIkdSRUVOXCIpO1xuICAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiZ28tdG8tcmVmYWN0b3JcIik7XG4gICB9KTtcbiBcbi0gIGl0KFwiZ2l2ZXMgUkVGQUNUT1IgZ3VpZGVsaW5lc1wiLCAoKSA9PiB7XG4rICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXMgd2hlbiBkZWNpZGluZ1wiLCAoKSA9PiB7XG4gICAgIGNvbnN0IHN0YXRlOiBDeWNsZVN0YXRlID0geyBwaGFzZTogXCJSRUZBQ1RPUlwiIH07XG4gICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiUkVGQUNUT1JcIik7XG4gICAgIGV4cGVjdChndWlkZWxpbmVzKS50b0NvbnRhaW4oXCJXYWl0IGZvciB0aGUgZGV2ZWxvcGVyXCIpO1xuICAgfSk7XG4rXG4rICBpdChcImdpdmVzIFJFRkFDVE9SIGd1aWRlbGluZXMgd2hlbiB3b3JraW5nIG9uIGEgZGVjaXNpb25cIiwgKCkgPT4ge1xuKyAgICBjb25zdCBzdGF0ZTogQ3ljbGVTdGF0ZSA9IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiwgbGFzdERlY2lzaW9uOiB7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfSB9O1xuKyAgICBjb25zdCBndWlkZWxpbmVzID0gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbisgICAgZXhwZWN0KGd1aWRlbGluZXMpLnRvQ29udGFpbihcIlJFRkFDVE9SXCIpO1xuKyAgICBleHBlY3QoZ3VpZGVsaW5lcykudG9Db250YWluKFwiRXhlY3V0ZSB0aGUgcmVmYWN0b3JpbmdcIik7XG4rICB9KTtcbiB9KTtcbiIsImZpcnN0Q2hhbmdlZExpbmUiOjc2fSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTg1NTQ0NH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjM0OWExOWFjIiwicGFyZW50SWQiOiJmZmM2NmEwYSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDQ6MjYuNDEwWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IGFsc28gdGhlIHRlc3QgZm9yIFwicmVzZXRzIHRlc3RzUmFuIGFuZCB0ZXN0c1Bhc3NlZFwiIHNob3VsZCBleHBlY3QgUkVGQUNUT1IgcGhhc2UsIG5vdCBSRUQuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF9hMWJiZGRjM2ZlZjU0ZTI3ODM4YmNhZGIiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCAtbiBcInJlc2V0cyB0ZXN0c1JhblwiIHNyYy90ZXN0L3N0YXRlLnRlc3QudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEzMDExMywib3V0cHV0IjoxMDEsImNhY2hlUmVhZCI6NTEyMCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEzNTMzNCwiY29zdCI6eyJpbnB1dCI6MC4wMTE3MTAxNywib3V0cHV0IjowLjAwMDAxODE4LCJjYWNoZVJlYWQiOjAuMDAwMTAyNCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDExODMwNzUwMDAwMDAwMDAxfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5ODU1NDQ2LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDk4NTUtelVzcnJOR0YyRHhrV3d2bGZKSTgiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMmJjYzA0ODIiLCJwYXJlbnRJZCI6IjM0OWExOWFjIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowNDoyNi40MjVaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsX2ExYmJkZGMzZmVmNTRlMjc4MzhiY2FkYiIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IjEyMTogIGl0KFwicmVzZXRzIHRlc3RzUmFuIGFuZCB0ZXN0c1Bhc3NlZFwiLCAoKSA9PiB7XG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NDk4NjY0MjV9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIzOGEzY2NkNyIsInBhcmVudElkIjoiMmJjYzA0ODIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA1OjA0Ljg5OVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoYXQgdGVzdCBkb2Vzbid0IGNoZWNrIHBoYXNlLCBzbyBpdCBzaG91bGQgc3RpbGwgcGFzcy4gTGV0IG1lIG5vdyB1cGRhdGUgdGhlIHVpLnRzIHRvIGFkZCBhdWRpdCBvcHRpb24gYW5kIHJlbW92ZSBjdXN0b20gdGV4dCBpbnB1dC4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IHVwZGF0ZSB0aGUgVUkuIExldCBtZSByZXdyaXRlIHVpLnRzIHRvIHJlbW92ZSB0aGUgY3VzdG9tIHRleHQgaW5wdXQgYW5kIGFkZCB0aGUgYXVkaXQgb3B0aW9uOiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzAwX0Y2UnQyNmdkZjEwNXZMMncwRzhxMTQwMiIsIm5hbWUiOiJ3cml0ZSIsImFyZ3VtZW50cyI6eyJjb250ZW50IjoiLyoqXG4gKiBDdXN0b20gVUkgZm9yIHRoZSBUREQgY3ljbGUgZGV2ZWxvcGVyIGRlY2lzaW9uIHByb21wdC5cbiAqXG4gKiBSZW5kZXJzIGFuIGludGVyYWN0aXZlIG1lbnUgZHVyaW5nIHRoZSBSRUZBQ1RPUiBwaGFzZSB3aGVyZSB0aGUgZGV2ZWxvcGVyXG4gKiBjYW4gY2hvb3NlIHdoYXQgdG8gZG8gbmV4dC5cbiAqXG4gKiBVc2FnZTogcGFzcyB0aGUgcmV0dXJuZWQgY29tcG9uZW50IHRvIGN0eC51aS5jdXN0b20oKS5cbiAqIEZvciBjdXN0b20gdGV4dCBpbnB1dCwgdXNlIGN0eC51aS5pbnB1dCgpIGluIHRoZSB0b29sJ3MgZXhlY3V0ZSBmdW5jdGlvbi5cbiAqL1xuXG5pbXBvcnQge1xuICBtYXRjaGVzS2V5LFxuICBLZXksXG4gIHR5cGUgVFVJLFxuICB0eXBlIFRoZW1lLFxuICB0eXBlIEtleWJpbmRpbmdzTWFuYWdlcixcbn0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbmltcG9ydCB0eXBlIHsgUmVmYWN0b3JGb2N1cywgUmVmYWN0b3JEZWNpc2lvbiB9IGZyb20gXCIuL3N0YXRlLmpzXCI7XG5cbmNvbnN0IFJFRkFDVE9SX0ZPQ0k6IFJlZmFjdG9yRm9jdXNbXSA9IFtcbiAgXCJhdWRpdFwiLFxuICBcInRlc3RzXCIsXG4gIFwiaW1wbGVtZW50YXRpb25cIixcbiAgXCJuZXh0LXRlc3RcIixcbiAgXCJjdXN0b21cIixcbl07XG5cbmNvbnN0IEZPQ1VTX0xBQkVMUzogUmVjb3JkPFJlZmFjdG9yRm9jdXMsIHN0cmluZz4gPSB7XG4gIGF1ZGl0OiBcIklkZW50aWZ5IGNvZGUgc21lbGxzICYgdmVyaWZ5IG1pbmltYWxpdHlcIixcbiAgdGVzdHM6IFwiUmVmYWN0b3IgdGhlIHRlc3RzXCIsXG4gIGltcGxlbWVudGF0aW9uOiBcIlJlZmFjdG9yIHRoZSBpbXBsZW1lbnRhdGlvblwiLFxuICBcIm5leHQtdGVzdFwiOiBcIkNvbnRpbnVlIHRvIG5leHQgdGVzdFwiLFxuICBjdXN0b206IFwiU29tZXRoaW5nIGVsc2UgKGN1c3RvbSBpbnN0cnVjdGlvbilcIixcbn07XG5cbmNvbnN0IEZPQ1VTX0RFU0NSSVBUSU9OUzogUmVjb3JkPFJlZmFjdG9yRm9jdXMsIHN0cmluZz4gPSB7XG4gIGF1ZGl0OlxuICAgIFwiQXVkaXQgaW1wbGVtZW50YXRpb246IGlzIGFsbCBjb2RlIG5lZWRlZD8gSXMgaXQgbWluaW1hbD8gQXJlIHRoZXJlIGNvZGUgc21lbGxzP1wiLFxuICB0ZXN0czogXCJDbGVhbiB1cCBhbmQgaW1wcm92ZSB0ZXN0IHN0cnVjdHVyZVwiLFxuICBpbXBsZW1lbnRhdGlvbjogXCJJbXByb3ZlIHByb2R1Y3Rpb24gY29kZSBzdHJ1Y3R1cmVcIixcbiAgXCJuZXh0LXRlc3RcIjogXCJXcml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3RcIixcbiAgY3VzdG9tOiBcIlByb3ZpZGUgYSBjdXN0b20gaW5zdHJ1Y3Rpb25cIixcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGN1c3RvbSBVSSBjb21wb25lbnQgZm9yIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBwcm9tcHQuXG4gKiBDYWxsIHRoaXMgZnJvbSBjdHgudWkuY3VzdG9tKCkgY2FsbGJhY2suXG4gKiBGb3IgXCJjdXN0b21cIiBzZWxlY3Rpb24sIHRoZSBleGVjdXRlIGZ1bmN0aW9uIHNob3VsZCB1c2UgY3R4LnVpLmlucHV0KCkgZm9yIHRoZSB0ZXh0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVmYWN0b3JEZWNpc2lvbkNvbXBvbmVudChcbiAgdGVzdERlc2NyaXB0aW9uPzogc3RyaW5nLFxuKTogKFxuICB0dWk6IFRVSSxcbiAgdGhlbWU6IFRoZW1lLFxuICBfa2I6IEtleWJpbmRpbmdzTWFuYWdlcixcbiAgZG9uZTogKGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uIHwgbnVsbCkgPT4gdm9pZCxcbikgPT4ge1xuICByZW5kZXI6ICh3aWR0aDogbnVtYmVyKSA9PiBzdHJpbmdbXTtcbiAgaW52YWxpZGF0ZTogKCkgPT4gdm9pZDtcbiAgaGFuZGxlSW5wdXQ6IChkYXRhOiBzdHJpbmcpID0+IGJvb2xlYW47XG59IHtcbiAgbGV0IHNlbGVjdGVkSW5kZXggPSAwO1xuXG4gIHJldHVybiAodHVpLCB0aGVtZSwgX2tiLCBkb25lKSA9PiB7XG4gICAgZnVuY3Rpb24gcmVuZGVyKHdpZHRoOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gICAgICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGNvbnN0IHcgPSBNYXRoLm1heCgxLCB3aWR0aCAtIDIpO1xuXG4gICAgICAvLyBIZWFkZXJcbiAgICAgIGxpbmVzLnB1c2godGhlbWUuZmcoXCJhY2NlbnRcIiwgXCLilIBcIi5yZXBlYXQodykpKTtcbiAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgIHRoZW1lLmZnKFwiYWNjZW50XCIsIFwiICDwn5SAIFJFRkFDVE9SIFBIQVNFIOKAlCBXaGF0IHNob3VsZCB3ZSBkbyBuZXh0P1wiKSxcbiAgICAgICk7XG4gICAgICBpZiAodGVzdERlc2NyaXB0aW9uKSB7XG4gICAgICAgIGxpbmVzLnB1c2godGhlbWUuZmcoXCJtdXRlZFwiLCBgICBDdXJyZW50IHRlc3Q6ICR7dGVzdERlc2NyaXB0aW9ufWApKTtcbiAgICAgIH1cbiAgICAgIGxpbmVzLnB1c2goXCJcIik7XG5cbiAgICAgIC8vIE9wdGlvbnNcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUkVGQUNUT1JfRk9DSS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBmb2N1cyA9IFJFRkFDVE9SX0ZPQ0lbaV07XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkID0gaSA9PT0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgY29uc3QgcHJlZml4ID0gc2VsZWN0ZWRcbiAgICAgICAgICA/IHRoZW1lLmZnKFwiYWNjZW50XCIsIFwi4pa4IFwiKVxuICAgICAgICAgIDogXCIgIFwiO1xuICAgICAgICBjb25zdCBsYWJlbCA9IHRoZW1lLmZnKFxuICAgICAgICAgIHNlbGVjdGVkID8gXCJhY2NlbnRcIiA6IFwidGV4dFwiLFxuICAgICAgICAgIEZPQ1VTX0xBQkVMU1tmb2N1c10sXG4gICAgICAgICk7XG4gICAgICAgIGxpbmVzLnB1c2goYCR7cHJlZml4fSR7bGFiZWx9YCk7XG4gICAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgICAgICBgICAgICR7dGhlbWUuZmcoXCJkaW1cIiwgRk9DVVNfREVTQ1JJUFRJT05TW2ZvY3VzXSl9YCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxpbmVzLnB1c2goXCJcIik7XG4gICAgICBsaW5lcy5wdXNoKFxuICAgICAgICB0aGVtZS5mZyhcbiAgICAgICAgICBcImRpbVwiLFxuICAgICAgICAgIGAgICR7dGhlbWUuYm9sZChcIuKGkeKGk1wiKX0gbmF2aWdhdGUgICR7dGhlbWUuYm9sZChcIkVudGVyXCIpfSBzZWxlY3QgICR7dGhlbWUuYm9sZChcIkVzY1wiKX0gY2FuY2VsYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgICBsaW5lcy5wdXNoKHRoZW1lLmZnKFwiYWNjZW50XCIsIFwi4pSAXCIucmVwZWF0KHcpKSk7XG5cbiAgICAgIHJldHVybiBsaW5lcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVJbnB1dChkYXRhOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIGlmIChtYXRjaGVzS2V5KGRhdGEsIEtleS51cCkpIHtcbiAgICAgICAgc2VsZWN0ZWRJbmRleCA9IE1hdGgubWF4KDAsIHNlbGVjdGVkSW5kZXggLSAxKTtcbiAgICAgICAgdHVpLnJlcXVlc3RSZW5kZXIoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXRjaGVzS2V5KGRhdGEsIEtleS5kb3duKSkge1xuICAgICAgICBzZWxlY3RlZEluZGV4ID0gTWF0aC5taW4oXG4gICAgICAgICAgUkVGQUNUT1JfRk9DSS5sZW5ndGggLSAxLFxuICAgICAgICAgIHNlbGVjdGVkSW5kZXggKyAxLFxuICAgICAgICApO1xuICAgICAgICB0dWkucmVxdWVzdFJlbmRlcigpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1hdGNoZXNLZXkoZGF0YSwgS2V5LmVudGVyKSkge1xuICAgICAgICBjb25zdCBmb2N1cyA9IFJFRkFDVE9SX0ZPQ0lbc2VsZWN0ZWRJbmRleF07XG4gICAgICAgIC8vIEZvciBcImN1c3RvbVwiLCByZXR1cm4gZm9jdXMgd2l0aG91dCBpbnN0cnVjdGlvbiB0ZXh0O1xuICAgICAgICAvLyB0aGUgZXhlY3V0ZSBmdW5jdGlvbiB3aWxsIHVzZSBjdHgudWkuaW5wdXQoKSB0byBnZXQgdGhlIHRleHQuXG4gICAgICAgIGRvbmUoeyBmb2N1cyB9KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXRjaGVzS2V5KGRhdGEsIEtleS5lc2NhcGUpKSB7XG4gICAgICAgIGRvbmUobnVsbCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcmVuZGVyLCBpbnZhbGlkYXRlOiAoKSA9PiB7fSwgaGFuZGxlSW5wdXQgfTtcbiAgfTtcbn1cbiIsInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjExMjc1LCJvdXRwdXQiOjExNTQsImNhY2hlUmVhZCI6MTI0MDMyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTM2NDYxLCJjb3N0Ijp7ImlucHV0IjowLjAwMTAxNDc1LCJvdXRwdXQiOjAuMDAwMjA3NzIsImNhY2hlUmVhZCI6MC4wMDI0ODA2NCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAzNzAzMTF9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NDk4NjY0MjYsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk0OTg2Ni1adDByNEE0WU9rZnJWTnloYjEzcCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIxMTI0YTA1NiIsInBhcmVudElkIjoiMzhhM2NjZDciLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA1OjA0LjkwNFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMDBfRjZSdDI2Z2RmMTA1dkwydzBHOHExNDAyIiwidG9vbE5hbWUiOiJ3cml0ZSIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSB3cm90ZSAzOTcyIGJ5dGVzIHRvIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50cyJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTkwNDkwNH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImQ3ZmEyZTc0IiwicGFyZW50SWQiOiIxMTI0YTA1NiIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDU6MzkuMjYwWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IEkgbmVlZCB0byB1cGRhdGUgdGhlIGBnby10by1yZWZhY3RvcmAgZXhlY3V0ZSBmdW5jdGlvbiBpbiBpbmRleC50cyB0bzpcblxuMS4gV2hlbiBkZXZlbG9wZXIgcGlja3MgXCJhdWRpdFwiLCBcInRlc3RzXCIsIFwiaW1wbGVtZW50YXRpb25cIiwgb3IgXCJjdXN0b21cIiDihpIgc3RheSBpbiBSRUZBQ1RPUiwgc2VuZCBhIHN0ZWVyaW5nIG1lc3NhZ2UgdG8gdGhlIGFnZW50IHRlbGxpbmcgaXQgd2hhdCB0byBkb1xuMi4gV2hlbiBkZXZlbG9wZXIgcGlja3MgXCJuZXh0LXRlc3RcIiDihpIgdHJhbnNpdGlvbiB0byBSRURcbjMuIEZvciBcImN1c3RvbVwiLCB1c2UgYGN0eC51aS5pbnB1dCgpYCB0byBnZXQgdGhlIGluc3RydWN0aW9uIHRleHRcblxuTGV0IG1lIHVwZGF0ZSBpbmRleC50cy4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiTm93IHVwZGF0ZSB0aGUgYGdvLXRvLXJlZmFjdG9yYCBleGVjdXRlIGZ1bmN0aW9uIGluIGluZGV4LnRzIHRvIGhhbmRsZSB0aGUgbmV3IGZsb3cgcHJvcGVybHkifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF9jNzRjNzI5ZDg4ODQ0NmMwYTRhNzdjYzUiLCJuYW1lIjoicmVhZCIsImFyZ3VtZW50cyI6eyJsaW1pdCI6ODAsIm9mZnNldCI6MTU4LCJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMzY1NzIsIm91dHB1dCI6MjEwLCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxMzY3ODIsImNvc3QiOnsiaW5wdXQiOjAuMDEyMjkxNDgsIm91dHB1dCI6MC4wMDAwMzc4LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAxMjMyOTI4fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5OTA0OTA1LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDk5MDUtVk1Ld2NYazlPY2R6WmRabkZubXEiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZDJiNTRlMjMiLCJwYXJlbnRJZCI6ImQ3ZmEyZTc0IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowNTozOS4yNjJaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsX2M3NGM3MjlkODg4NDQ2YzBhNGE3N2NjNSIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBhc3NlZD86IGJvb2xlYW47IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIGAke3BoYXNlfSBUZXN0cyBwYXNzZWRgKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgYCR7cGhhc2V9IFRlc3RzIGZhaWxlZGApO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLXJlZmFjdG9yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1yZWZhY3RvclwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIFJlZmFjdG9yXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZS4gVGhlIGRldmVsb3BlciB3aWxsIGJlIHByb21wdGVkIHRvIGNob29zZSBcIiArXG4gICAgICBcIndoYXQgdG8gcmVmYWN0b3I6IHRlc3RzLCBpbXBsZW1lbnRhdGlvbiwgbmV4dCB0ZXN0LCBvciBjdXN0b20gaW5zdHJ1Y3Rpb24uIFwiICtcbiAgICAgIFwiT25seSBjYWxsIHRoaXMgd2hlbiB0ZXN0cyBhcmUgcGFzc2luZyAoR1JFRU4gcGhhc2UpLlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICAgIGlmIChzdGF0ZS5waGFzZSAhPT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgdGV4dDogYENhbm5vdCBlbnRlciBSRUZBQ1RPUiBmcm9tIHBoYXNlICR7c3RhdGUucGhhc2V9LiBNdXN0IGJlIGluIEdSRUVOIHBoYXNlICh0ZXN0cyBwYXNzaW5nKS5gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHN0YXRlLnBoYXNlIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgICAgc3RhdGUgPSB0cmFuc2l0aW9uLnN0YXRlO1xuICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiICYmIGN0eC5oYXNVSSkge1xuICAgICAgICBjb25zdCBkZWNpc2lvbiA9IGF3YWl0IGN0eC51aS5jdXN0b208UmVmYWN0b3JEZWNpc2lvbiB8IG51bGw+KFxuICAgICAgICAgIGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQoc3RhdGUudGVzdERlc2NyaXB0aW9uKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZGVjaXNpb24pO1xuICAgICAgICAgIHN0YXRlID0gYXBwbHlSZXN1bHQuc3RhdGU7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGVcIixcbiAgICAgICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgICAgICBg8J+UgCAqKlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQ6KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgJHthcHBseVJlc3VsdC5tZXNzYWdlfVxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGBDdXJyZW50IHBoYXNlOiAqKlJFRCoqIOKAlCBXcml0ZSB0aGUgbmV4dCBmYWlsaW5nIHRlc3QuXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgKHN0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb25cbiAgICAgICAgICAgICAgICAgID8gYCoqQ3VzdG9tIHJlZmFjdG9yaW5nIGluc3RydWN0aW9uOioqXFxuXFxgXFxgXFxgXFxuJHtzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9ufVxcblxcYFxcYFxcYFxcblxcbmBcbiAgICAgICAgICAgICAgICAgIDogXCJcIikgK1xuICAgICAgICAgICAgICAgIGd1aWRlbGluZXNNZXNzYWdlKCksXG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyB0cmlnZ2VyVHVybjogdHJ1ZSB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogYXBwbHlSZXN1bHQubWVzc2FnZSA/PyBcIlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuXG5bMjA2IG1vcmUgbGluZXMgaW4gZmlsZS4gVXNlIG9mZnNldD0yMzggdG8gY29udGludWUuXSJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk0OTkzOTI2Mn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjI1MGRjMjE3IiwicGFyZW50SWQiOiJkMmI1NGUyMyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDY6MzkuMjcwWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IEkgbmVlZCB0byByZXBsYWNlIHRoZSBleGVjdXRlIGZ1bmN0aW9uIGZvciBgZ28tdG8tcmVmYWN0b3JgIHdpdGggdGhlIG5ldyBsb2dpYyB0aGF0OlxuXG4xLiBJZiBHUkVFTiDihpIgdHJhbnNpdGlvbiB0byBSRUZBQ1RPUiwgc2hvdyBkZWNpc2lvbiBwcm9tcHRcbjIuIElmIGFscmVhZHkgaW4gUkVGQUNUT1IgKGFmdGVyIGEgZGVjaXNpb24gd2FzIG1hZGUgYW5kIGFnZW50IGNvbXBsZXRlZCB3b3JrKSDihpIgYWxsb3cgcmUtZW50ZXJpbmcgdGhlIHByb21wdFxuMy4gSGFuZGxlIGRlY2lzaW9uczpcbiAgIC0gXCJuZXh0LXRlc3RcIiDihpIgdHJhbnNpdGlvbiB0byBSRURcbiAgIC0gXCJhdWRpdFwiLCBcInRlc3RzXCIsIFwiaW1wbGVtZW50YXRpb25cIiDihpIgc3RheSBpbiBSRUZBQ1RPUiwgc2VuZCBzdGVlcmluZyBtZXNzYWdlIHRvIGFnZW50XG4gICAtIFwiY3VzdG9tXCIg4oaSIHVzZSBjdHgudWkuaW5wdXQoKSBmb3IgdGV4dCwgdGhlbiBzYW1lIGFzIGFib3ZlXG5cbkxldCBtZSBhbHNvIHVwZGF0ZSB0aGUgZ28tdG8tcmVmYWN0b3IgZGVzY3JpcHRpb24gYW5kIHRoZSBpbml0aWFsIGNoZWNrIHRvIGFsbG93IGNhbGxpbmcgZnJvbSBSRUZBQ1RPUiAoc28gdGhlIGFnZW50IGNhbiByZXBvcnQgYmFjayBhZnRlciByZWZhY3RvcmluZyB3b3JrIGlzIGRvbmUpLlxuXG5BbHNvLCBJIG5lZWQgdG8gdXBkYXRlIHRoZSB0b29sX2NhbGwgYmxvY2sgdG8gTk9UIGJsb2NrIGdvLXRvLWdyZWVuIGR1cmluZyBSRUZBQ1RPUi4gQWN0dWFsbHksIHRoZSBhZ2VudCBzaG91bGQgYmUgYWJsZSB0byBjYWxsIGdvLXRvLWdyZWVuIGR1cmluZyBSRUZBQ1RPUiB0byB2ZXJpZnkgdGVzdHMgc3RpbGwgcGFzcyBhZnRlciByZWZhY3RvcmluZy5cblxuTGV0IG1lIGFsc28gdXBkYXRlIHRoZSBgYmVmb3JlX2FnZW50X3N0YXJ0YCBoYW5kbGVyIHRvIGluamVjdCB0aGUgcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb24uIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF80YTEyNmFmYTlhM2Q0ZjExOTI0MDFhMDAiLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJlZGl0cyI6W3sibmV3VGV4dCI6IiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLXJlZmFjdG9yXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gUmVmYWN0b3JcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiRW50ZXIgdGhlIFJFRkFDVE9SIHBoYXNlIGZvciBkZXZlbG9wZXIgZGVjaXNpb25zLCBvciByZXBvcnQgYmFjayBhZnRlciByZWZhY3RvcmluZyB3b3JrIGlzIGRvbmUuIFwiICtcbiAgICAgIFwiV2hlbiBjYWxsZWQgZnJvbSBHUkVFTjogZW50ZXJzIFJFRkFDVE9SIGFuZCBwcm9tcHRzIGRldmVsb3BlciBmb3IgYSBkZWNpc2lvbi4gXCIgK1xuICAgICAgXCJXaGVuIGNhbGxlZCBmcm9tIFJFRkFDVE9SOiByZS1wcm9tcHRzIHRoZSBkZXZlbG9wZXIgZm9yIGEgbmV3IGRlY2lzaW9uLiBcIiArXG4gICAgICBcIkNhbGwgdGhpcyBhZnRlciByZWZhY3RvcmluZyB3b3JrIGlzIGNvbXBsZXRlIGFuZCB0ZXN0cyBwYXNzIGFnYWluLlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJHUkVFTlwiKSB7XG4gICAgICAgIC8vIEZpcnN0IGVudHJ5OiB0cmFuc2l0aW9uIGZyb20gR1JFRU4gdG8gUkVGQUNUT1JcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4gICAgICAgIHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtcbiAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLnBoYXNlICE9PSBcIlJFRkFDVE9SXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgQ2Fubm90IGVudGVyIFJFRkFDVE9SIGZyb20gcGhhc2UgJHtzdGF0ZS5waGFzZX0uIE11c3QgYmUgaW4gR1JFRU4gb3IgYWxyZWFkeSBpbiBSRUZBQ1RPUi5gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHN0YXRlLnBoYXNlIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICBdKTtcblxuICAgICAgaWYgKGN0eC5tb2RlID09PSBcInR1aVwiICYmIGN0eC5oYXNVSSkge1xuICAgICAgICBjb25zdCBkZWNpc2lvbiA9IGF3YWl0IGN0eC51aS5jdXN0b208UmVmYWN0b3JEZWNpc2lvbiB8IG51bGw+KFxuICAgICAgICAgIGNyZWF0ZVJlZmFjdG9yRGVjaXNpb25Db21wb25lbnQoc3RhdGUudGVzdERlc2NyaXB0aW9uKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGVjaXNpb24pIHtcbiAgICAgICAgICAvLyBHZXQgY3VzdG9tIGluc3RydWN0aW9uIHRleHQgaWYgbmVlZGVkXG4gICAgICAgICAgbGV0IGVmZmVjdGl2ZURlY2lzaW9uID0gZGVjaXNpb247XG4gICAgICAgICAgaWYgKGRlY2lzaW9uLmZvY3VzID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBjb25zdCBjdXN0b21UZXh0ID0gYXdhaXQgY3R4LnVpLmlucHV0KFxuICAgICAgICAgICAgICBcIkN1c3RvbSBpbnN0cnVjdGlvbjpcIixcbiAgICAgICAgICAgICAgXCJlLmcuICdFeHRyYWN0IHRoZSBzZXJ2aWNlIGNsYXNzJ1wiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChjdXN0b21UZXh0Py50cmltKCkpIHtcbiAgICAgICAgICAgICAgZWZmZWN0aXZlRGVjaXNpb24gPSB7IGZvY3VzOiBcImN1c3RvbVwiLCBjdXN0b21JbnN0cnVjdGlvbjogY3VzdG9tVGV4dC50cmltKCkgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIENhbmNlbGxlZCBvciBlbXB0eSDigJQgZ28gYmFjayB0byBwcm9tcHQ/IEZvciBub3csIGRlZmF1bHQgdG8gaW1wbGVtZW50YXRpb25cbiAgICAgICAgICAgICAgZWZmZWN0aXZlRGVjaXNpb24gPSB7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZWZmZWN0aXZlRGVjaXNpb24pO1xuICAgICAgICAgIHN0YXRlID0gYXBwbHlSZXN1bHQuc3RhdGU7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgICAgICAvLyBCdWlsZCBzdGVlcmluZyBtZXNzYWdlIGJhc2VkIG9uIGRlY2lzaW9uXG4gICAgICAgICAgbGV0IHN0ZWVyaW5nTWVzc2FnZSA9IFwiXCI7XG4gICAgICAgICAgaWYgKGVmZmVjdGl2ZURlY2lzaW9uLmZvY3VzID09PSBcIm5leHQtdGVzdFwiKSB7XG4gICAgICAgICAgICBzdGVlcmluZ01lc3NhZ2UgPVxuICAgICAgICAgICAgICBg8J+UgCAqKk5leHQgdGVzdC4qKiBQaGFzZSBjaGFuZ2VkOiBSRUZBQ1RPUiDihpIgKipSRUQqKi5cXG5cXG5gICtcbiAgICAgICAgICAgICAgYFdyaXRlIHRoZSBuZXh0IGZhaWxpbmcgdGVzdC4gQ3VycmVudCB0ZXN0IGNvdW50OiAke3N0YXRlLnRlc3RzV3JpdHRlbn0uYDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGVmZmVjdGl2ZURlY2lzaW9uLmZvY3VzID09PSBcImF1ZGl0XCIpIHtcbiAgICAgICAgICAgIHN0ZWVyaW5nTWVzc2FnZSA9XG4gICAgICAgICAgICAgIGDwn5SNICoqQ29kZSBhdWRpdCByZXF1ZXN0ZWQuKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFJldmlldyB0aGUgaW1wbGVtZW50YXRpb246XFxuYCArXG4gICAgICAgICAgICAgIGAxLiBJZGVudGlmeSBhbnkgY29kZSBzbWVsbHNcXG5gICtcbiAgICAgICAgICAgICAgYDIuIElzIGFsbCB0aGUgY29kZSBhY3R1YWxseSByZXF1aXJlZD9cXG5gICtcbiAgICAgICAgICAgICAgYDMuIElzIHRoZSBpbXBsZW1lbnRhdGlvbiBtaW5pbWFsIOKAlCBkb2VzIGl0IG9ubHkgaW1wbGVtZW50IHdoYXQgdGhlIHRlc3RzIHJlcXVpcmU/XFxuYCArXG4gICAgICAgICAgICAgIGA0LiBSZXBvcnQgeW91ciBmaW5kaW5ncyBiYWNrIHRvIHRoZSBkZXZlbG9wZXJcXG5cXG5gICtcbiAgICAgICAgICAgICAgYEFmdGVyIHlvdXIgYXVkaXQsIGNhbGwgKipnby10by1yZWZhY3RvcioqIGFnYWluIHRvIHJlcG9ydCBiYWNrLmA7XG4gICAgICAgICAgfSBlbHNlIGlmIChlZmZlY3RpdmVEZWNpc2lvbi5mb2N1cyA9PT0gXCJ0ZXN0c1wiKSB7XG4gICAgICAgICAgICBzdGVlcmluZ01lc3NhZ2UgPVxuICAgICAgICAgICAgICBg8J+boCAqKlJlZmFjdG9yIHRoZSB0ZXN0cy4qKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgSW1wcm92ZSB0ZXN0IHN0cnVjdHVyZSBhbmQgY292ZXJhZ2Ugd2hpbGUga2VlcGluZyB0ZXN0cyBwYXNzaW5nLlxcbmAgK1xuICAgICAgICAgICAgICBgQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzLCB0aGVuIGNhbGwgKipnby10by1yZWZhY3RvcioqLmA7XG4gICAgICAgICAgfSBlbHNlIGlmIChlZmZlY3RpdmVEZWNpc2lvbi5mb2N1cyA9PT0gXCJpbXBsZW1lbnRhdGlvblwiKSB7XG4gICAgICAgICAgICBzdGVlcmluZ01lc3NhZ2UgPVxuICAgICAgICAgICAgICBg8J+boCAqKlJlZmFjdG9yIHRoZSBpbXBsZW1lbnRhdGlvbi4qKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgSW1wcm92ZSBwcm9kdWN0aW9uIGNvZGUgc3RydWN0dXJlLlxcbmAgK1xuICAgICAgICAgICAgICBgQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzLCB0aGVuIGNhbGwgKipnby10by1yZWZhY3RvcioqLmA7XG4gICAgICAgICAgfSBlbHNlIGlmIChlZmZlY3RpdmVEZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgc3RlZXJpbmdNZXNzYWdlID1cbiAgICAgICAgICAgICAgYPCflIAgKipDdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb246KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFxcXCIke2VmZmVjdGl2ZURlY2lzaW9uLmN1c3RvbUluc3RydWN0aW9ufVxcXCJcXG5cXG5gICtcbiAgICAgICAgICAgICAgYEFmdGVyIHJlZmFjdG9yaW5nLCBydW4gdGVzdHMgdG8gdmVyaWZ5IHRoZXkgc3RpbGwgcGFzcywgdGhlbiBjYWxsICoqZ28tdG8tcmVmYWN0b3IqKi5gO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgICBjb250ZW50OiBzdGVlcmluZ01lc3NhZ2UsXG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyB0cmlnZ2VyVHVybjogdHJ1ZSB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogYXBwbHlSZXN1bHQubWVzc2FnZSA/PyBcIlJlZmFjdG9yaW5nIGRlY2lzaW9uIGFwcGxpZWQuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgICBkZWNpc2lvbjogZWZmZWN0aXZlRGVjaXNpb24sXG4gICAgICAgICAgICAgIHBoYXNlOiBzdGF0ZS5waGFzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogXCJEZXZlbG9wZXIgY2FuY2VsbGVkLiBTdGF5aW5nIGluIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gTm9uLVRVSSBtb2RlOiBmYWxsYmFjayB0byBuZXh0LXRlc3QgaW1tZWRpYXRlIHRyYW5zaXRpb25cbiAgICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRUZBQ1RPUlwiKSB7XG4gICAgICAgIGNvbnN0IGZhbGxiYWNrRGVjaXNpb246IFJlZmFjdG9yRGVjaXNpb24gPSB7IGZvY3VzOiBcIm5leHQtdGVzdFwiIH07XG4gICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBmYWxsYmFja0RlY2lzaW9uKTtcbiAgICAgICAgc3RhdGUgPSBhcHBseVJlc3VsdC5zdGF0ZTtcbiAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgeyB0eXBlOiBcInRleHRcIiwgdGV4dDogYXBwbHlSZXN1bHQubWVzc2FnZSA/PyBcIk5vbi1UVUk6IGFkdmFuY2luZyB0byBuZXh0IHRlc3QuXCIgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IFwiUkVEXCIgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IHRyYW5zaXRpb24ubWVzc2FnZSA/PyBcIkVudGVyZWQgUkVGQUNUT1IgcGhhc2UuXCIgfV0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UgfSxcbiAgICAgIH07Iiwib2xkVGV4dCI6IiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLXJlZmFjdG9yXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gUmVmYWN0b3JcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiRW50ZXIgdGhlIFJFRkFDVE9SIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIHdpbGwgYmUgcHJvbXB0ZWQgdG8gY2hvb3NlIFwiICtcbiAgICAgIFwid2hhdCB0byByZWZhY3RvcjogdGVzdHMsIGltcGxlbWVudGF0aW9uLCBuZXh0IHRlc3QsIG9yIGN1c3RvbSBpbnN0cnVjdGlvbi4gXCIgK1xuICAgICAgXCJPbmx5IGNhbGwgdGhpcyB3aGVuIHRlc3RzIGFyZSBwYXNzaW5nIChHUkVFTiBwaGFzZSkuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGBDYW5ub3QgZW50ZXIgUkVGQUNUT1IgZnJvbSBwaGFzZSAke3N0YXRlLnBoYXNlfS4gTXVzdCBiZSBpbiBHUkVFTiBwaGFzZSAodGVzdHMgcGFzc2luZykuYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKTtcbiAgICAgIHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgXSk7XG5cbiAgICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIiAmJiBjdHguaGFzVUkpIHtcbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBjdHgudWkuY3VzdG9tPFJlZmFjdG9yRGVjaXNpb24gfCBudWxsPihcbiAgICAgICAgICBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50KHN0YXRlLnRlc3REZXNjcmlwdGlvbiksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRlY2lzaW9uKSB7XG4gICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICAgICAgICBzdGF0ZSA9IGFwcGx5UmVzdWx0LnN0YXRlO1xuICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAgICAgcGkuc2VuZE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgICAgICAgYPCflIAgKipSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOioqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCR7YXBwbHlSZXN1bHQubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgQ3VycmVudCBwaGFzZTogKipSRUQqKiDigJQgV3JpdGUgdGhlIG5leHQgZmFpbGluZyB0ZXN0LlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIChzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uXG4gICAgICAgICAgICAgICAgICA/IGAqKkN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbjoqKlxcblxcYFxcYFxcYFxcbiR7c3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbn1cXG5cXGBcXGBcXGBcXG5cXG5gXG4gICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICBndWlkZWxpbmVzTWVzc2FnZSgpLFxuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgdHJpZ2dlclR1cm46IHRydWUgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IGFwcGx5UmVzdWx0Lm1lc3NhZ2UgPz8gXCJSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZGVjaXNpb24sXG4gICAgICAgICAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIkRldmVsb3BlciBjYW5jZWxsZWQuIFN0YXlpbmcgaW4gUkVGQUNUT1IgcGhhc2UuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogXCJSRUZBQ1RPUlwiIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJFbnRlcmVkIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UgfSxcbiAgICAgIH07In1dLCJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxMjUxNDAsIm91dHB1dCI6MjQ4OSwiY2FjaGVSZWFkIjoxMjI4OCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjEzOTkxNywiY29zdCI6eyJpbnB1dCI6MC4wMTEyNjI2LCJvdXRwdXQiOjAuMDAwNDQ4MDIsImNhY2hlUmVhZCI6MC4wMDAyNDU3NjAwMDAwMDAwMDAwMywiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDExOTU2Mzc5OTk5OTk5OTk5fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5OTM5MjYzLCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDk5MzkteG1Ib0pMRlNZZ0xxRjRKT3hzbVYiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMGNjODBkMDgiLCJwYXJlbnRJZCI6IjI1MGRjMjE3IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowNjozOS4yODVaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzRhMTI2YWZhOWEzZDRmMTE5MjQwMWEwMCIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkNvdWxkIG5vdCBmaW5kIHRoZSBleGFjdCB0ZXh0IGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cy4gVGhlIG9sZCB0ZXh0IG11c3QgbWF0Y2ggZXhhY3RseSBpbmNsdWRpbmcgYWxsIHdoaXRlc3BhY2UgYW5kIG5ld2xpbmVzLiJ9XSwiZGV0YWlscyI6e30sImlzRXJyb3IiOnRydWUsInRpbWVzdGFtcCI6MTc4MTk0OTk5OTI4NX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6ImMyOWIxMzg0IiwicGFyZW50SWQiOiIwY2M4MGQwOCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDc6MDguNjU1WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTGV0IG1lIHJlYWQgdGhlIGV4YWN0IHRleHQgZnJvbSB0aGUgZmlsZSB0byBtYWtlIHN1cmUgbXkgb2xkVGV4dCBtYXRjaGVzIHBlcmZlY3RseS4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzBhNTBiMDY2ODI4MzQwZGJhODE5ZGQ3MiIsIm5hbWUiOiJyZWFkIiwiYXJndW1lbnRzIjp7ImxpbWl0Ijo5MCwib2Zmc2V0IjoxNzUsInBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEzOTk4NSwib3V0cHV0IjoxMTIsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjE0MDA5NywiY29zdCI6eyJpbnB1dCI6MC4wMTI1OTg2NSwib3V0cHV0IjowLjAwMDAyMDE2LCJjYWNoZVJlYWQiOjAsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAxMjYxODgxfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTQ5OTk5Mjg2LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NDk5OTktdjVMaTlUWVhybGJDcndLMEhFVVciLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiNzYwNTIyOTgiLCJwYXJlbnRJZCI6ImMyOWIxMzg0IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowNzowOC42NTdaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzBhNTBiMDY2ODI4MzQwZGJhODE5ZGQ3MiIsInRvb2xOYW1lIjoicmVhZCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiAgICBuYW1lOiBcImdvLXRvLXJlZmFjdG9yXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gUmVmYWN0b3JcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiRW50ZXIgdGhlIFJFRkFDVE9SIHBoYXNlLiBUaGUgZGV2ZWxvcGVyIHdpbGwgYmUgcHJvbXB0ZWQgdG8gY2hvb3NlIFwiICtcbiAgICAgIFwid2hhdCB0byByZWZhY3RvcjogdGVzdHMsIGltcGxlbWVudGF0aW9uLCBuZXh0IHRlc3QsIG9yIGN1c3RvbSBpbnN0cnVjdGlvbi4gXCIgK1xuICAgICAgXCJPbmx5IGNhbGwgdGhpcyB3aGVuIHRlc3RzIGFyZSBwYXNzaW5nIChHUkVFTiBwaGFzZSkuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgICAgaWYgKHN0YXRlLnBoYXNlICE9PSBcIkdSRUVOXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgQ2Fubm90IGVudGVyIFJFRkFDVE9SIGZyb20gcGhhc2UgJHtzdGF0ZS5waGFzZX0uIE11c3QgYmUgaW4gR1JFRU4gcGhhc2UgKHRlc3RzIHBhc3NpbmcpLmAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogc3RhdGUucGhhc2UgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IGdyZWVuVG9SZWZhY3RvcihzdGF0ZSk7XG4gICAgICBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7XG4gICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICBpZiAoY3R4Lm1vZGUgPT09IFwidHVpXCIgJiYgY3R4Lmhhc1VJKSB7XG4gICAgICAgIGNvbnN0IGRlY2lzaW9uID0gYXdhaXQgY3R4LnVpLmN1c3RvbTxSZWZhY3RvckRlY2lzaW9uIHwgbnVsbD4oXG4gICAgICAgICAgY3JlYXRlUmVmYWN0b3JEZWNpc2lvbkNvbXBvbmVudChzdGF0ZS50ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChkZWNpc2lvbikge1xuICAgICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXBwbHlSZWZhY3RvckRlY2lzaW9uKHN0YXRlLCBkZWNpc2lvbik7XG4gICAgICAgICAgc3RhdGUgPSBhcHBseVJlc3VsdC5zdGF0ZTtcbiAgICAgICAgICBwZXJzaXN0U3RhdGUoKTtcblxuICAgICAgICAgIHBpLnNlbmRNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICAgIGDwn5SAICoqUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZDoqKlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGAke2FwcGx5UmVzdWx0Lm1lc3NhZ2V9XFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYEN1cnJlbnQgcGhhc2U6ICoqUkVEKiog4oCUIFdyaXRlIHRoZSBuZXh0IGZhaWxpbmcgdGVzdC5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICAoc3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvblxuICAgICAgICAgICAgICAgICAgPyBgKipDdXN0b20gcmVmYWN0b3JpbmcgaW5zdHJ1Y3Rpb246KipcXG5cXGBcXGBcXGBcXG4ke3N0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb259XFxuXFxgXFxgXFxgXFxuXFxuYFxuICAgICAgICAgICAgICAgICAgOiBcIlwiKSArXG4gICAgICAgICAgICAgICAgZ3VpZGVsaW5lc01lc3NhZ2UoKSxcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IHRyaWdnZXJUdXJuOiB0cnVlIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBhcHBseVJlc3VsdC5tZXNzYWdlID8/IFwiUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZC5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICAgIGRlY2lzaW9uLFxuICAgICAgICAgICAgICBwaGFzZTogXCJSRURcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogXCJEZXZlbG9wZXIgY2FuY2VsbGVkLiBTdGF5aW5nIGluIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogdHJhbnNpdGlvbi5tZXNzYWdlID8/IFwiRW50ZXJlZCBSRUZBQ1RPUiBwaGFzZS5cIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiB0cmFuc2l0aW9uLnN0YXRlLnBoYXNlIH0sXG4gICAgICB9O1xuXG5bMTc5IG1vcmUgbGluZXMgaW4gZmlsZS4gVXNlIG9mZnNldD0yNjUgdG8gY29udGludWUuXSJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk1MDAyODY1N319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjY2MDNhOWE5IiwicGFyZW50SWQiOiI3NjA1MjI5OCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDc6MTcuODc3WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiSSBzZWUgdGhlIGlzc3VlIC0gbXkgb2xkVGV4dCBoYWQgc29tZSBlc2NhcGUgc2VxdWVuY2UgaXNzdWVzLiBUaGUgYFxcbmAgaW4gdGhlIHRlbXBsYXRlIGxpdGVyYWxzIGFyZSBhY3R1YWwgYmFja3NsYXNoLU4sIG5vdCBuZXdsaW5lcy4gTGV0IG1lIHdyaXRlIHRoZSByZXBsYWNlbWVudCBjYXJlZnVsbHkgdXNpbmcgdGhlIGV4YWN0IHRleHQgZnJvbSB0aGUgZmlsZS4gXG5cbkFjdHVhbGx5LCBJIHRoaW5rIHRoZSBwcm9ibGVtIGlzIHdpdGggdGhlIGVzY2FwZSBzZXF1ZW5jZXMgaW4gbXkgb2xkVGV4dC4gVGhlIHRlbXBsYXRlIGxpdGVyYWxzIGxpa2UgYGAgYPCflIAgKipSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOioqXFxuXFxuYCBgYCAtIGluIHRoZSBmaWxlIHRoZXkgdXNlIGxpdGVyYWwgYmFja3NsYXNoLW4sIGJ1dCBpbiBteSBvbGRUZXh0IEkgaGFkIGBcXFxcbmAgd2hpY2ggZG9lc24ndCBtYXRjaC5cblxuTGV0IG1lIGp1c3QgcmV3cml0ZSB0aGUgZW50aXJlIGZpbGUgdG8gYXZvaWQgdGhlc2UgZXNjYXBpbmcgaXNzdWVzLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfZDM3NWVhNjc0YWUwNGRhMGJhZDIyYWQxIiwibmFtZSI6InJlYWQiLCJhcmd1bWVudHMiOnsicGF0aCI6Ii9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyIsIm9mZnNldCI6MTc1fX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjY3Nywib3V0cHV0IjoyMDQsImNhY2hlUmVhZCI6MTQwMDMyLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTQwOTEzLCJjb3N0Ijp7ImlucHV0IjowLjAwMDA2MDkzLCJvdXRwdXQiOjAuMDAwMDM2NzIsImNhY2hlUmVhZCI6MC4wMDI4MDA2NCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAyODk4Mjl9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NTAwMjg2NTksInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk1MDAyOC1uVW12QzFyZEpqaXRzQ2xSR0VjciIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3MTBkODM0OCIsInBhcmVudElkIjoiNjYwM2E5YTkiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA3OjE3Ljg5M1oiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfZDM3NWVhNjc0YWUwNGRhMGJhZDIyYWQxIiwidG9vbE5hbWUiOiJyZWFkIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiICAgIG5hbWU6IFwiZ28tdG8tcmVmYWN0b3JcIixcbiAgICBsYWJlbDogXCJHbyB0byBSZWZhY3RvclwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJFbnRlciB0aGUgUkVGQUNUT1IgcGhhc2UuIFRoZSBkZXZlbG9wZXIgd2lsbCBiZSBwcm9tcHRlZCB0byBjaG9vc2UgXCIgK1xuICAgICAgXCJ3aGF0IHRvIHJlZmFjdG9yOiB0ZXN0cywgaW1wbGVtZW50YXRpb24sIG5leHQgdGVzdCwgb3IgY3VzdG9tIGluc3RydWN0aW9uLiBcIiArXG4gICAgICBcIk9ubHkgY2FsbCB0aGlzIHdoZW4gdGVzdHMgYXJlIHBhc3NpbmcgKEdSRUVOIHBoYXNlKS5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgICBpZiAoc3RhdGUucGhhc2UgIT09IFwiR1JFRU5cIikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGBDYW5ub3QgZW50ZXIgUkVGQUNUT1IgZnJvbSBwaGFzZSAke3N0YXRlLnBoYXNlfS4gTXVzdCBiZSBpbiBHUkVFTiBwaGFzZSAodGVzdHMgcGFzc2luZykuYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0cmFuc2l0aW9uID0gZ3JlZW5Ub1JlZmFjdG9yKHN0YXRlKTtcbiAgICAgIHN0YXRlID0gdHJhbnNpdGlvbi5zdGF0ZTtcbiAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgXSk7XG5cbiAgICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIiAmJiBjdHguaGFzVUkpIHtcbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBjdHgudWkuY3VzdG9tPFJlZmFjdG9yRGVjaXNpb24gfCBudWxsPihcbiAgICAgICAgICBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50KHN0YXRlLnRlc3REZXNjcmlwdGlvbiksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRlY2lzaW9uKSB7XG4gICAgICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBhcHBseVJlZmFjdG9yRGVjaXNpb24oc3RhdGUsIGRlY2lzaW9uKTtcbiAgICAgICAgICBzdGF0ZSA9IGFwcGx5UmVzdWx0LnN0YXRlO1xuICAgICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuXG4gICAgICAgICAgcGkuc2VuZE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlXCIsXG4gICAgICAgICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgICAgICAgYPCflIAgKipSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkOioqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCR7YXBwbHlSZXN1bHQubWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgQ3VycmVudCBwaGFzZTogKipSRUQqKiDigJQgV3JpdGUgdGhlIG5leHQgZmFpbGluZyB0ZXN0LlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIChzdGF0ZS5jdXN0b21SZWZhY3RvcmluZ0luc3RydWN0aW9uXG4gICAgICAgICAgICAgICAgICA/IGAqKkN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbjoqKlxcblxcYFxcYFxcYFxcbiR7c3RhdGUuY3VzdG9tUmVmYWN0b3JpbmdJbnN0cnVjdGlvbn1cXG5cXGBcXGBcXGBcXG5cXG5gXG4gICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICBndWlkZWxpbmVzTWVzc2FnZSgpLFxuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgdHJpZ2dlclR1cm46IHRydWUgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IGFwcGx5UmVzdWx0Lm1lc3NhZ2UgPz8gXCJSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZGVjaXNpb24sXG4gICAgICAgICAgICAgIHBoYXNlOiBcIlJFRFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIkRldmVsb3BlciBjYW5jZWxsZWQuIFN0YXlpbmcgaW4gUkVGQUNUT1IgcGhhc2UuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZGV0YWlsczogeyBwaGFzZTogXCJSRUZBQ1RPUlwiIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJFbnRlcmVkIFJFRkFDVE9SIHBoYXNlLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwiZ28tdG8tcmVmYWN0b3JcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nOyBkZWNpc2lvbj86IFJlZmFjdG9yRGVjaXNpb24gfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3QgdGV4dCA9IGRldGFpbHMuZGVjaXNpb25cbiAgICAgICAgPyBgJHtwaGFzZX0gUmVmYWN0b3JlZDogJHtkZXRhaWxzLmRlY2lzaW9uLmZvY3VzfWBcbiAgICAgICAgOiBgJHtwaGFzZX0gRW50ZXJlZCByZWZhY3RvciBwaGFzZWA7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHJ1bi10ZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwicnVuLXRlc3RzXCIsXG4gICAgbGFiZWw6IFwiUnVuIFRlc3RzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb24uIFVzZWZ1bCBmb3IgY2hlY2tpbmcgdGVzdCBzdGF0dXMgXCIgK1xuICAgICAgXCJkdXJpbmcgZGV2ZWxvcG1lbnQuIFJldHVybnMgZXhpdCBjb2RlIGFuZCBvdXRwdXQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgY29tbWFuZDogVHlwZS5PcHRpb25hbChcbiAgICAgICAgVHlwZS5TdHJpbmcoe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkN1c3RvbSB0ZXN0IGNvbW1hbmQgdG8gcnVuIChkZWZhdWx0OiAnbnBtIHRlc3QnKS5cIixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH0pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICAgIGNvbnN0IGNvbW1hbmQgPSBwYXJhbXMuY29tbWFuZCA/PyBcIm5wbSB0ZXN0XCI7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCBjb21tYW5kXSwge1xuICAgICAgICBzaWduYWwsXG4gICAgICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHtwYXNzZWQgPyBcIuKck1wiIDogXCLinJdcIn0gVGVzdHMgJHtwYXNzZWQgPyBcInBhc3NlZFwiIDogXCJmYWlsZWRcIn0gKGV4aXQgY29kZTogJHtyZXN1bHQuY29kZX0pYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgcGFzc2VkLFxuICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICBvdXRwdXQ6IHJlc3VsdC5zdGRvdXQuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgICBzdGRlcnI6IHJlc3VsdC5zdGRlcnIuc2xpY2UoMCwgNTBfMDAwKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKGFyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgdGV4dCA9IHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJydW4tdGVzdHMgXCIpKSArIChhcmdzLmNvbW1hbmQgPyB0aGVtZS5mZyhcIm11dGVkXCIsIGFyZ3MuY29tbWFuZCkgOiB0aGVtZS5mZyhcIm11dGVkXCIsIFwibnBtIHRlc3RcIikpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGFzc2VkPzogYm9vbGVhbiB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0dXMgPSBkZXRhaWxzLnBhc3NlZFxuICAgICAgICA/IHRoZW1lLmZnKFwic3VjY2Vzc1wiLCBcIuKckyBUZXN0cyBwYXNzZWRcIilcbiAgICAgICAgOiB0aGVtZS5mZyhcImVycm9yXCIsIFwi4pyXIFRlc3RzIGZhaWxlZFwiKTtcbiAgICAgIHJldHVybiBuZXcgVGV4dChzdGF0dXMsIDAsIDApO1xuICAgIH0sXG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBUb29sOiB0ZGQtc3RhdHVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJ0ZGQtc3RhdHVzXCIsXG4gICAgbGFiZWw6IFwiVEREIFN0YXR1c1wiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJTaG93IGN1cnJlbnQgVEREIGN5Y2xlIHBoYXNlIGFuZCBzdGF0ZS4gUmV0dXJucyB0aGUgY3VycmVudCBwaGFzZSwgXCIgK1xuICAgICAgXCJ0ZXN0IGNvdW50LCBhbmQgZ3VpZGVsaW5lcyBmb3Igd2hhdCB0byBkbyBuZXh0LlwiLFxuICAgIHBhcmFtZXRlcnM6IFR5cGUuT2JqZWN0KHt9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBfcGFyYW1zLCBfc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICAgIGNvbnN0IHN0YXR1c1RleHQgPSBwaGFzZURlc2NyaXB0aW9uKHN0YXRlKTtcbiAgICAgIGNvbnN0IGd1aWRlbGluZXMgPSBwaGFzZUd1aWRlbGluZXMoc3RhdGUpO1xuICAgICAgY29uc3QgdGVzdHNXcml0dGVuID0gc3RhdGUudGVzdHNXcml0dGVuID8/IDA7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c1RleHQpLFxuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJkaW1cIiwgYFRlc3RzIHdyaXR0ZW46ICR7dGVzdHNXcml0dGVufWApLFxuICAgICAgXSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3N0YXR1c1RleHR9XFxuXFxuVGVzdHMgd3JpdHRlbjogJHt0ZXN0c1dyaXR0ZW59XFxuXFxuJHtndWlkZWxpbmVzfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgIHBoYXNlOiBzdGF0ZS5waGFzZSxcbiAgICAgICAgICB0ZXN0c1Jhbjogc3RhdGUudGVzdHNSYW4sXG4gICAgICAgICAgdGVzdHNQYXNzZWQ6IHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgICAgICAgIHRlc3RzV3JpdHRlbixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJDYWxsKF9hcmdzLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dCh0aGVtZS5mZyhcInRvb2xUaXRsZVwiLCB0aGVtZS5ib2xkKFwidGRkLXN0YXR1c1wiKSksIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGhhc2U/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KGAke3BoYXNlfSAke2RldGFpbHMucGhhc2V9YCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIEV2ZW50cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcblxuICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIikge1xuICAgICAgY3R4LnVpLm5vdGlmeShgVEREIEN5Y2xlIHN0YXJ0ZWQgaW4gJHtzdGF0ZS5waGFzZX0gcGhhc2VgLCBcImluZm9cIik7XG4gICAgfVxuICB9KTtcblxuICBwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1yZWZhY3RvclwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIFJFRkFDVE9SIGZyb20gUkVEIHBoYXNlLiBZb3UgbXVzdCBmaXJzdCBtYWtlIHRlc3RzIHBhc3MgKEdSRUVOIHBoYXNlKS4gQ2FsbCBnby10by1ncmVlbiBhZnRlciB5b3VyIGltcGxlbWVudGF0aW9uIHBhc3NlcyB0aGUgdGVzdC5gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVGQUNUT1JcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1ncmVlblwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBgQ2Fubm90IGdvIHRvIEdSRUVOIGZyb20gUkVGQUNUT1IgcGhhc2UuIENvbXBsZXRlIHRoZSByZWZhY3RvcmluZyBkZWNpc2lvbiBmaXJzdC5gLFxuICAgICAgfTtcbiAgICB9XG4gIH0pO1xuXG4gIHBpLm9uKFwiYmVmb3JlX2FnZW50X3N0YXJ0XCIsIGFzeW5jICgpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZToge1xuICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZS1ndWlkZWxpbmVzXCIsXG4gICAgICAgIGNvbnRlbnQ6IGBcXG5cXG5bVEREIENZQ0xFIC0gJHtzdGF0ZS5waGFzZX0gUEhBU0VdXFxuJHtndWlkZWxpbmVzTWVzc2FnZSgpfWAsXG4gICAgICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9O1xuICB9KTtcblxuICBwaS5vbihcInR1cm5fZW5kXCIsIGFzeW5jIChfZXZlbnQsIGN0eCkgPT4ge1xuICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgIF0pO1xuICB9KTtcblxuICBwaS5vbihcInNlc3Npb25fc2h1dGRvd25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIHBlcnNpc3RTdGF0ZSgpO1xuICB9KTtcbn1cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk1MDAzNzg5M319LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjIyMjVmNTczIiwicGFyZW50SWQiOiI3MTBkODM0OCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDg6MTAuOTExWiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiTm93IEkgaGF2ZSB0aGUgZnVsbCBmaWxlIGNvbnRlbnQuIFRoZSBpc3N1ZSB3aXRoIGVkaXRpbmcgaXMgdGhlIGVzY2FwZSBzZXF1ZW5jZXMgZm9yIHRlbXBsYXRlIGxpdGVyYWxzLiBMZXQgbWUgd3JpdGUgdGhlIGVudGlyZSBpbmRleC50cyBmaWxlIHdpdGggYWxsIHRoZSBjaGFuZ2VzLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJMZXQgbWUgcmV3cml0ZSB0aGUgZW50aXJlIGluZGV4LnRzIGZpbGUgd2l0aCBhbGwgZml4ZXMgYXBwbGllZCBhdCBvbmNlIHRvIGF2b2lkIGVzY2FwZSBzZXF1ZW5jZSBpc3N1ZXM6In0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfMDBfdThSRFgzTGRHUWRtS0M4dVVsYmU5OTk2IiwibmFtZSI6IndyaXRlIiwiYXJndW1lbnRzIjp7InBhdGgiOiIvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMiLCJjb250ZW50IjoiLyoqXG4gKiBUREQgQ3ljbGUgRXh0ZW5zaW9uXG4gKlxuICogRW5mb3JjZXMgdGhlIHJlZC1ncmVlbi1yZWZhY3RvciBUREQgY3ljbGU6XG4gKiAgIPCflLQgUkVEICAgIOKGkiBXcml0ZSBhIGZhaWxpbmcgdGVzdCwgdGhlbiBpbXBsZW1lbnQgdG8gbWFrZSBpdCBwYXNzXG4gKiAgIPCfn6IgR1JFRU4gIOKGkiBUZXN0cyBwYXNzLCByZWFkeSBmb3IgcmVmYWN0b3JpbmdcbiAqICAg8J+UgCBSRUZBQ1RPUiDihpIgRGV2ZWxvcGVyIGNob29zZXMgd2hhdCB0byByZWZhY3RvcjsgYWdlbnQgZXhlY3V0ZXM7XG4gKiAgICAgICAgICAgICAgICAgbG9vcCBiYWNrIHRvIGRldmVsb3BlciB1bnRpbCBcIm5leHQgdGVzdFwiIGNob3NlblxuICpcbiAqIFRvb2xzOlxuICogICBnby10by1ncmVlbiAgICAgLSBSdW4gdGVzdHMgYW5kIHRyYW5zaXRpb24gYmFzZWQgb24gcmVzdWx0XG4gKiAgIGdvLXRvLXJlZmFjdG9yICAtIEVudGVyIHRoZSBkZXZlbG9wZXIgZGVjaXNpb24gcGhhc2UgKG9yIHJlcG9ydCBiYWNrKVxuICogICBydW4tdGVzdHMgICAgICAgLSBSdW4gdGVzdHMgd2l0aG91dCBwaGFzZSB0cmFuc2l0aW9uXG4gKiAgIHRkZC1zdGF0dXMgICAgICAtIFNob3cgY3VycmVudCBwaGFzZSBhbmQgc3RhdGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbkFQSSwgRXh0ZW5zaW9uQ29udGV4dCB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSBcInR5cGVib3hcIjtcbmltcG9ydCB7IFRleHQgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuXG5pbXBvcnQge1xuICBjcmVhdGVJbml0aWFsU3RhdGUsXG4gIHJlY29yZFRlc3RSZXN1bHQsXG4gIGdyZWVuVG9SZWZhY3RvcixcbiAgYXBwbHlSZWZhY3RvckRlY2lzaW9uLFxuICBwaGFzZUVtb2ppLFxuICBwaGFzZURlc2NyaXB0aW9uLFxuICBwaGFzZUd1aWRlbGluZXMsXG4gIHR5cGUgQ3ljbGVTdGF0ZSxcbiAgdHlwZSBSZWZhY3RvckRlY2lzaW9uLFxufSBmcm9tIFwiLi9zdGF0ZS5qc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVmYWN0b3JEZWNpc2lvbkNvbXBvbmVudCB9IGZyb20gXCIuL3VpLmpzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRkZEN5Y2xlKHBpOiBFeHRlbnNpb25BUEkpOiB2b2lkIHtcbiAgbGV0IHN0YXRlOiBDeWNsZVN0YXRlID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7XG5cbiAgZnVuY3Rpb24gcGVyc2lzdFN0YXRlKCk6IHZvaWQge1xuICAgIHBpLmFwcGVuZEVudHJ5KFwidGRkLWN5Y2xlXCIsIHtcbiAgICAgIHBoYXNlOiBzdGF0ZS5waGFzZSxcbiAgICAgIHRlc3REZXNjcmlwdGlvbjogc3RhdGUudGVzdERlc2NyaXB0aW9uLFxuICAgICAgdGVzdHNSYW46IHN0YXRlLnRlc3RzUmFuLFxuICAgICAgdGVzdHNQYXNzZWQ6IHN0YXRlLnRlc3RzUGFzc2VkLFxuICAgICAgdGVzdHNXcml0dGVuOiBzdGF0ZS50ZXN0c1dyaXR0ZW4sXG4gICAgICBsYXN0RGVjaXNpb246IHN0YXRlLmxhc3REZWNpc2lvbixcbiAgICAgIGN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb246IHN0YXRlLmN1c3RvbVJlZmFjdG9yaW5nSW5zdHJ1Y3Rpb24sXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXN0b3JlU3RhdGUoY3R4OiBFeHRlbnNpb25Db250ZXh0KTogdm9pZCB7XG4gICAgY29uc3QgZW50cmllcyA9IGN0eC5zZXNzaW9uTWFuYWdlci5nZXRFbnRyaWVzKCk7XG4gICAgY29uc3QgdGRkRW50cnkgPSBlbnRyaWVzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoZTogeyB0eXBlOiBzdHJpbmc7IGN1c3RvbVR5cGU/OiBzdHJpbmcgfSkgPT5cbiAgICAgICAgICBlLnR5cGUgPT09IFwiY3VzdG9tXCIgJiYgZS5jdXN0b21UeXBlID09PSBcInRkZC1jeWNsZVwiLFxuICAgICAgKVxuICAgICAgLnBvcCgpIGFzIHsgZGF0YT86IFBhcnRpYWw8Q3ljbGVTdGF0ZT4gfSB8IHVuZGVmaW5lZDtcblxuICAgIGlmICh0ZGRFbnRyeT8uZGF0YSkge1xuICAgICAgc3RhdGUgPSB7XG4gICAgICAgIC4uLmNyZWF0ZUluaXRpYWxTdGF0ZSgpLFxuICAgICAgICAuLi50ZGRFbnRyeS5kYXRhLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzdGF0dXNNZXNzYWdlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ3VpZGVsaW5lc01lc3NhZ2UoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcGhhc2VHdWlkZWxpbmVzKHN0YXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkU3RlZXJpbmdNZXNzYWdlKGRlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uKTogc3RyaW5nIHtcbiAgICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwibmV4dC10ZXN0XCIpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIFwi8J+UgCAqKk5leHQgdGVzdC4qKiBQaGFzZSBjaGFuZ2VkOiBSRUZBQ1RPUiDihpIgKipSRUQqKi5cXG5cXG5cIiArXG4gICAgICAgIFwiV3JpdGUgdGhlIG5leHQgZmFpbGluZyB0ZXN0LlwiXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiYXVkaXRcIikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgXCLwn5SNICoqQ29kZSBhdWRpdCByZXF1ZXN0ZWQuKipcXG5cXG5cIiArXG4gICAgICAgIFwiUmV2aWV3IHRoZSBpbXBsZW1lbnRhdGlvbjpcXG5cIiArXG4gICAgICAgIFwiMS4gSWRlbnRpZnkgYW55IGNvZGUgc21lbGxzXFxuXCIgK1xuICAgICAgICBcIjIuIElzIGFsbCB0aGUgY29kZSBhY3R1YWxseSByZXF1aXJlZD9cXG5cIiArXG4gICAgICAgIFwiMy4gSXMgdGhlIGltcGxlbWVudGF0aW9uIG1pbmltYWwg4oCUIGRvZXMgaXQgb25seSBpbXBsZW1lbnQgd2hhdCB0aGUgdGVzdHMgcmVxdWlyZT9cXG5cIiArXG4gICAgICAgIFwiNC4gUmVwb3J0IHlvdXIgZmluZGluZ3MgYmFjayB0byB0aGUgZGV2ZWxvcGVyXFxuXFxuXCIgK1xuICAgICAgICBcIkFmdGVyIHlvdXIgYXVkaXQsIGNhbGwgKipnby10by1yZWZhY3RvcioqIGFnYWluIHRvIHJlcG9ydCBiYWNrLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwidGVzdHNcIikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgXCLwn5ugICoqUmVmYWN0b3IgdGhlIHRlc3RzLioqXFxuXFxuXCIgK1xuICAgICAgICBcIkltcHJvdmUgdGVzdCBzdHJ1Y3R1cmUgYW5kIGNvdmVyYWdlIHdoaWxlIGtlZXBpbmcgdGVzdHMgcGFzc2luZy5cXG5cIiArXG4gICAgICAgIFwiQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzLCB0aGVuIGNhbGwgKipnby10by1yZWZhY3RvcioqLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiaW1wbGVtZW50YXRpb25cIikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgXCLwn5ugICoqUmVmYWN0b3IgdGhlIGltcGxlbWVudGF0aW9uLioqXFxuXFxuXCIgK1xuICAgICAgICBcIkltcHJvdmUgcHJvZHVjdGlvbiBjb2RlIHN0cnVjdHVyZS5cXG5cIiArXG4gICAgICAgIFwiQWZ0ZXIgcmVmYWN0b3JpbmcsIHJ1biB0ZXN0cyB0byB2ZXJpZnkgdGhleSBzdGlsbCBwYXNzLCB0aGVuIGNhbGwgKipnby10by1yZWZhY3RvcioqLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZGVjaXNpb24uZm9jdXMgPT09IFwiY3VzdG9tXCIgJiYgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24pIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIFwi8J+UgCAqKkN1c3RvbSByZWZhY3RvcmluZyBpbnN0cnVjdGlvbjoqKlxcblxcblwiICtcbiAgICAgICAgZGVjaXNpb24uY3VzdG9tSW5zdHJ1Y3Rpb24gK1xuICAgICAgICBcIlxcblxcbkFmdGVyIHJlZmFjdG9yaW5nLCBydW4gdGVzdHMgdG8gdmVyaWZ5IHRoZXkgc3RpbGwgcGFzcywgdGhlbiBjYWxsICoqZ28tdG8tcmVmYWN0b3IqKi5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFwiUmVmYWN0b3JpbmcgZGVjaXNpb24gYXBwbGllZC4gQ2FsbCBnby10by1yZWZhY3RvciB3aGVuIGRvbmUuXCI7XG4gIH1cblxuICAvLyDilIDilIAgVG9vbDogZ28tdG8tZ3JlZW4g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcImdvLXRvLWdyZWVuXCIsXG4gICAgbGFiZWw6IFwiR28gdG8gR3JlZW5cIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUnVuIHRlc3RzIHRvIHZlcmlmeSBpbXBsZW1lbnRhdGlvbi4gSWYgdGVzdHMgcGFzcywgdHJhbnNpdGlvbnMgdG8gR1JFRU4gcGhhc2UuIFwiICtcbiAgICAgIFwiSWYgdGVzdHMgZmFpbCwgc3RheXMgaW4gUkVEIHdpdGggZmVlZGJhY2suIFVzZSB0aGlzIGFmdGVyIHdyaXRpbmcgYSBmYWlsaW5nIHRlc3QgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbi5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7XG4gICAgICB0ZXN0RGVzY3JpcHRpb246IFR5cGUuT3B0aW9uYWwoXG4gICAgICAgIFR5cGUuU3RyaW5nKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiQnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0ZXN0KHMpIHRvIHJ1biAoZS5nLiwgJ3VzZXIgbG9naW4gdGVzdCcpLiBcIiArXG4gICAgICAgICAgICBcIlVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXCIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgICBhc3luYyBleGVjdXRlKF90b29sQ2FsbElkLCBwYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgICAgY29uc3QgdGVzdERlc2MgPSBwYXJhbXMudGVzdERlc2NyaXB0aW9uID8/IHN0YXRlLnRlc3REZXNjcmlwdGlvbjtcbiAgICAgIGlmICh0ZXN0RGVzYykge1xuICAgICAgICBzdGF0ZS50ZXN0RGVzY3JpcHRpb24gPSB0ZXN0RGVzYztcbiAgICAgIH1cblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCB0ZXN0Q29tbWFuZCA9IFwibnBtIHRlc3QgMj4mMVwiO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGkuZXhlYyhcImJhc2hcIiwgW1wiLWNcIiwgdGVzdENvbW1hbmRdLCB7XG4gICAgICAgIHNpZ25hbDogY3R4LnNpZ25hbCxcbiAgICAgICAgdGltZW91dDogNjBfMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3NlZCA9IHJlc3VsdC5jb2RlID09PSAwO1xuICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHJlY29yZFRlc3RSZXN1bHQoc3RhdGUsIHBhc3NlZCk7XG4gICAgICBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7XG5cbiAgICAgIGN0eC51aS5zZXRXaWRnZXQoXCJ0ZGQtc3RhdHVzXCIsIFtcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhwYXNzZWQgPyBcInN1Y2Nlc3NcIiA6IFwiZXJyb3JcIiwgcGFzc2VkID8gXCLinJMgVGVzdHMgcGFzc2VkXCIgOiBcIuKclyBUZXN0cyBmYWlsZWRcIiksXG4gICAgICBdKTtcblxuICAgICAgaWYgKHRyYW5zaXRpb24uc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjdXN0b21UeXBlOiBcInRkZC1jeWNsZVwiLFxuICAgICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgICAgXCLwn5+iICoqR1JFRU4gUEhBU0UgQUNISUVWRUQhKipcXG5cXG5cIiArXG4gICAgICAgICAgICAgICh0cmFuc2l0aW9uLm1lc3NhZ2UgPz8gXCJcIikgKyBcIlxcblxcblwiICtcbiAgICAgICAgICAgICAgXCJUaGUgZGV2ZWxvcGVyIG11c3Qgbm93IGRlY2lkZSB3aGF0IHRvIHJlZmFjdG9yLlxcblwiICtcbiAgICAgICAgICAgICAgXCJDYWxsICoqZ28tdG8tcmVmYWN0b3IqKiB0byBlbnRlciB0aGUgcmVmYWN0b3JpbmcgZGVjaXNpb24gcGhhc2UuXCIsXG4gICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyB0cmlnZ2VyVHVybjogZmFsc2UgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zaXRpb24ubWVzc2FnZSA/PyBcIlRlc3RzIGV4ZWN1dGVkLlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgcGhhc2U6IHRyYW5zaXRpb24uc3RhdGUucGhhc2UsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcImdvLXRvLWdyZWVuIFwiKSkgKyAoYXJncy50ZXN0RGVzY3JpcHRpb24gPyB0aGVtZS5mZyhcIm11dGVkXCIsIGFyZ3MudGVzdERlc2NyaXB0aW9uKSA6IFwiXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRleHQsIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGFzc2VkPzogYm9vbGVhbjsgcGhhc2U/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghZGV0YWlscykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHQocmVzdWx0LmNvbnRlbnRbMF0/LnR5cGUgPT09IFwidGV4dFwiID8gcmVzdWx0LmNvbnRlbnRbMF0udGV4dCA6IFwiXCIsIDAsIDApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2UgPSBkZXRhaWxzLnBoYXNlID8gcGhhc2VFbW9qaShkZXRhaWxzLnBoYXNlIGFzIGFueSkgOiBcIlwiO1xuICAgICAgY29uc3Qgc3RhdHVzID0gZGV0YWlscy5wYXNzZWRcbiAgICAgICAgPyB0aGVtZS5mZyhcInN1Y2Nlc3NcIiwgcGhhc2UgKyBcIiBUZXN0cyBwYXNzZWRcIilcbiAgICAgICAgOiB0aGVtZS5mZyhcImVycm9yXCIsIHBoYXNlICsgXCIgVGVzdHMgZmFpbGVkXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IGdvLXRvLXJlZmFjdG9yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBpLnJlZ2lzdGVyVG9vbCh7XG4gICAgbmFtZTogXCJnby10by1yZWZhY3RvclwiLFxuICAgIGxhYmVsOiBcIkdvIHRvIFJlZmFjdG9yXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudGVyIHRoZSBSRUZBQ1RPUiBwaGFzZSBmb3IgZGV2ZWxvcGVyIGRlY2lzaW9ucywgb3IgcmVwb3J0IGJhY2sgYWZ0ZXIgcmVmYWN0b3Jpbmcgd29yayBpcyBkb25lLiBcIiArXG4gICAgICBcIldoZW4gY2FsbGVkIGZyb20gR1JFRU46IGVudGVycyBSRUZBQ1RPUiBhbmQgcHJvbXB0cyBkZXZlbG9wZXIuIFwiICtcbiAgICAgIFwiV2hlbiBjYWxsZWQgZnJvbSBSRUZBQ1RPUjogcmUtcHJvbXB0cyB0aGUgZGV2ZWxvcGVyIGZvciBhIG5ldyBkZWNpc2lvbi4gXCIgK1xuICAgICAgXCJDYWxsIHRoaXMgYWZ0ZXIgcmVmYWN0b3Jpbmcgd29yayBpcyBjb21wbGV0ZSBhbmQgdGVzdHMgcGFzcyBhZ2Fpbi5cIixcbiAgICBwYXJhbWV0ZXJzOiBUeXBlLk9iamVjdCh7fSksXG4gICAgYXN5bmMgZXhlY3V0ZShfdG9vbENhbGxJZCwgX3BhcmFtcywgX3NpZ25hbCwgX29uVXBkYXRlLCBjdHgpIHtcbiAgICAgIHJlc3RvcmVTdGF0ZShjdHgpO1xuXG4gICAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiR1JFRU5cIikge1xuICAgICAgICAvLyBGaXJzdCBlbnRyeTogdHJhbnNpdGlvbiBmcm9tIEdSRUVOIHRvIFJFRkFDVE9SXG4gICAgICAgIGNvbnN0IHRyYW5zaXRpb24gPSBncmVlblRvUmVmYWN0b3Ioc3RhdGUpO1xuICAgICAgICBzdGF0ZSA9IHRyYW5zaXRpb24uc3RhdGU7XG4gICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5waGFzZSAhPT0gXCJSRUZBQ1RPUlwiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgdGV4dDogXCJDYW5ub3QgZW50ZXIgUkVGQUNUT1IgZnJvbSBwaGFzZSBcIiArIHN0YXRlLnBoYXNlICsgXCIuIE11c3QgYmUgaW4gR1JFRU4gb3IgYWxyZWFkeSBpbiBSRUZBQ1RPUi5cIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBzdGF0ZS5waGFzZSB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImFjY2VudFwiLCBzdGF0dXNNZXNzYWdlKCkpLFxuICAgICAgXSk7XG5cbiAgICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIiAmJiBjdHguaGFzVUkpIHtcbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBjdHgudWkuY3VzdG9tPFJlZmFjdG9yRGVjaXNpb24gfCBudWxsPihcbiAgICAgICAgICBjcmVhdGVSZWZhY3RvckRlY2lzaW9uQ29tcG9uZW50KHN0YXRlLnRlc3REZXNjcmlwdGlvbiksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRlY2lzaW9uKSB7XG4gICAgICAgICAgLy8gR2V0IGN1c3RvbSBpbnN0cnVjdGlvbiB0ZXh0IGlmIG5lZWRlZFxuICAgICAgICAgIGxldCBlZmZlY3RpdmVEZWNpc2lvbiA9IGRlY2lzaW9uO1xuICAgICAgICAgIGlmIChkZWNpc2lvbi5mb2N1cyA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgY29uc3QgY3VzdG9tVGV4dCA9IGF3YWl0IGN0eC51aS5pbnB1dChcbiAgICAgICAgICAgICAgXCJDdXN0b20gaW5zdHJ1Y3Rpb246XCIsXG4gICAgICAgICAgICAgIFwiZS5nLiAnRXh0cmFjdCB0aGUgc2VydmljZSBjbGFzcydcIixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoY3VzdG9tVGV4dD8udHJpbSgpKSB7XG4gICAgICAgICAgICAgIGVmZmVjdGl2ZURlY2lzaW9uID0geyBmb2N1czogXCJjdXN0b21cIiwgY3VzdG9tSW5zdHJ1Y3Rpb246IGN1c3RvbVRleHQudHJpbSgpIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBDYW5jZWxsZWQgb3IgZW1wdHkg4oCUIGRlZmF1bHQgdG8gaW1wbGVtZW50YXRpb25cbiAgICAgICAgICAgICAgZWZmZWN0aXZlRGVjaXNpb24gPSB7IGZvY3VzOiBcImltcGxlbWVudGF0aW9uXCIgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZWZmZWN0aXZlRGVjaXNpb24pO1xuICAgICAgICAgIHN0YXRlID0gYXBwbHlSZXN1bHQuc3RhdGU7XG4gICAgICAgICAgcGVyc2lzdFN0YXRlKCk7XG5cbiAgICAgICAgICBjb25zdCBzdGVlcmluZ01lc3NhZ2UgPSBidWlsZFN0ZWVyaW5nTWVzc2FnZShlZmZlY3RpdmVEZWNpc2lvbik7XG5cbiAgICAgICAgICBwaS5zZW5kTWVzc2FnZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY3VzdG9tVHlwZTogXCJ0ZGQtY3ljbGVcIixcbiAgICAgICAgICAgICAgY29udGVudDogc3RlZXJpbmdNZXNzYWdlLFxuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgdHJpZ2dlclR1cm46IHRydWUgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IGFwcGx5UmVzdWx0Lm1lc3NhZ2UgPz8gXCJSZWZhY3RvcmluZyBkZWNpc2lvbiBhcHBsaWVkLlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZGVjaXNpb246IGVmZmVjdGl2ZURlY2lzaW9uLFxuICAgICAgICAgICAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IFwiRGV2ZWxvcGVyIGNhbmNlbGxlZC4gU3RheWluZyBpbiBSRUZBQ1RPUiBwaGFzZS5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBcIlJFRkFDVE9SXCIgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE5vbi1UVUkgbW9kZTogZmFsbGJhY2sgdG8gbmV4dC10ZXN0XG4gICAgICBpZiAoc3RhdGUucGhhc2UgPT09IFwiUkVGQUNUT1JcIikge1xuICAgICAgICBjb25zdCBmYWxsYmFja0RlY2lzaW9uOiBSZWZhY3RvckRlY2lzaW9uID0geyBmb2N1czogXCJuZXh0LXRlc3RcIiB9O1xuICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGFwcGx5UmVmYWN0b3JEZWNpc2lvbihzdGF0ZSwgZmFsbGJhY2tEZWNpc2lvbik7XG4gICAgICAgIHN0YXRlID0gYXBwbHlSZXN1bHQuc3RhdGU7XG4gICAgICAgIHBlcnNpc3RTdGF0ZSgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHsgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IGFwcGx5UmVzdWx0Lm1lc3NhZ2UgPz8gXCJOb24tVFVJOiBhZHZhbmNpbmcgdG8gbmV4dCB0ZXN0LlwiIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXRhaWxzOiB7IHBoYXNlOiBcIlJFRFwiIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIkVudGVyZWQgUkVGQUNUT1IgcGhhc2UuXCIgfV0sXG4gICAgICAgIGRldGFpbHM6IHsgcGhhc2U6IFwiUkVGQUNUT1JcIiB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoX2FyZ3MsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHRoZW1lLmZnKFwidG9vbFRpdGxlXCIsIHRoZW1lLmJvbGQoXCJnby10by1yZWZhY3RvclwiKSksIDAsIDApO1xuICAgIH0sXG4gICAgcmVuZGVyUmVzdWx0KHJlc3VsdCwgX29wdGlvbnMsIHRoZW1lLCBfY29udGV4dCkge1xuICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3VsdC5kZXRhaWxzIGFzIHsgcGhhc2U/OiBzdHJpbmc7IGRlY2lzaW9uPzogUmVmYWN0b3JEZWNpc2lvbiB9IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKCFkZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dChyZXN1bHQuY29udGVudFswXT8udHlwZSA9PT0gXCJ0ZXh0XCIgPyByZXN1bHQuY29udGVudFswXS50ZXh0IDogXCJcIiwgMCwgMCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwaGFzZSA9IGRldGFpbHMucGhhc2UgPyBwaGFzZUVtb2ppKGRldGFpbHMucGhhc2UgYXMgYW55KSA6IFwiXCI7XG4gICAgICBjb25zdCB0ZXh0ID0gZGV0YWlscy5kZWNpc2lvblxuICAgICAgICA/IHBoYXNlICsgXCIgUmVmYWN0b3JlZDogXCIgKyBkZXRhaWxzLmRlY2lzaW9uLmZvY3VzXG4gICAgICAgIDogcGhhc2UgKyBcIiBFbnRlcmVkIHJlZmFjdG9yIHBoYXNlXCI7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHJ1bi10ZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5yZWdpc3RlclRvb2woe1xuICAgIG5hbWU6IFwicnVuLXRlc3RzXCIsXG4gICAgbGFiZWw6IFwiUnVuIFRlc3RzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0ZXN0cyB3aXRob3V0IHBoYXNlIHRyYW5zaXRpb24uIFVzZWZ1bCBmb3IgY2hlY2tpbmcgdGVzdCBzdGF0dXMgXCIgK1xuICAgICAgXCJkdXJpbmcgZGV2ZWxvcG1lbnQuIFJldHVybnMgZXhpdCBjb2RlIGFuZCBvdXRwdXQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe1xuICAgICAgY29tbWFuZDogVHlwZS5PcHRpb25hbChcbiAgICAgICAgVHlwZS5TdHJpbmcoe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkN1c3RvbSB0ZXN0IGNvbW1hbmQgdG8gcnVuIChkZWZhdWx0OiAnbnBtIHRlc3QnKS5cIixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH0pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIHBhcmFtcywgc2lnbmFsLCBfb25VcGRhdGUsIGN0eCkge1xuICAgICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICAgIGNvbnN0IGNvbW1hbmQgPSBwYXJhbXMuY29tbWFuZCA/PyBcIm5wbSB0ZXN0XCI7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwaS5leGVjKFwiYmFzaFwiLCBbXCItY1wiLCBjb21tYW5kXSwge1xuICAgICAgICBzaWduYWwsXG4gICAgICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXNzZWQgPSByZXN1bHQuY29kZSA9PT0gMDtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICAgICAgY3R4LnVpLnRoZW1lLmZnKHBhc3NlZCA/IFwic3VjY2Vzc1wiIDogXCJlcnJvclwiLCBwYXNzZWQgPyBcIuKckyBUZXN0cyBwYXNzZWRcIiA6IFwi4pyXIFRlc3RzIGZhaWxlZFwiKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiAocGFzc2VkID8gXCLinJNcIiA6IFwi4pyXXCIpICsgXCIgVGVzdHMgXCIgKyAocGFzc2VkID8gXCJwYXNzZWRcIiA6IFwiZmFpbGVkXCIpICsgXCIgKGV4aXQgY29kZTogXCIgKyByZXN1bHQuY29kZSArIFwiKVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwYXNzZWQsXG4gICAgICAgICAgZXhpdENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG91dHB1dDogcmVzdWx0LnN0ZG91dC5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICAgIHN0ZGVycjogcmVzdWx0LnN0ZGVyci5zbGljZSgwLCA1MF8wMDApLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlbmRlckNhbGwoYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInJ1bi10ZXN0cyBcIikpICsgKGFyZ3MuY29tbWFuZCA/IHRoZW1lLmZnKFwibXV0ZWRcIiwgYXJncy5jb21tYW5kKSA6IHRoZW1lLmZnKFwibXV0ZWRcIiwgXCJucG0gdGVzdFwiKSk7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGV4dCwgMCwgMCk7XG4gICAgfSxcbiAgICByZW5kZXJSZXN1bHQocmVzdWx0LCBfb3B0aW9ucywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICBjb25zdCBkZXRhaWxzID0gcmVzdWx0LmRldGFpbHMgYXMgeyBwYXNzZWQ/OiBib29sZWFuIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXR1cyA9IGRldGFpbHMucGFzc2VkXG4gICAgICAgID8gdGhlbWUuZmcoXCJzdWNjZXNzXCIsIFwi4pyTIFRlc3RzIHBhc3NlZFwiKVxuICAgICAgICA6IHRoZW1lLmZnKFwiZXJyb3JcIiwgXCLinJcgVGVzdHMgZmFpbGVkXCIpO1xuICAgICAgcmV0dXJuIG5ldyBUZXh0KHN0YXR1cywgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFRvb2w6IHRkZC1zdGF0dXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcGkucmVnaXN0ZXJUb29sKHtcbiAgICBuYW1lOiBcInRkZC1zdGF0dXNcIixcbiAgICBsYWJlbDogXCJUREQgU3RhdHVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlNob3cgY3VycmVudCBUREQgY3ljbGUgcGhhc2UgYW5kIHN0YXRlLiBSZXR1cm5zIHRoZSBjdXJyZW50IHBoYXNlLCBcIiArXG4gICAgICBcInRlc3QgY291bnQsIGFuZCBndWlkZWxpbmVzIGZvciB3aGF0IHRvIGRvIG5leHQuXCIsXG4gICAgcGFyYW1ldGVyczogVHlwZS5PYmplY3Qoe30pLFxuICAgIGFzeW5jIGV4ZWN1dGUoX3Rvb2xDYWxsSWQsIF9wYXJhbXMsIF9zaWduYWwsIF9vblVwZGF0ZSwgY3R4KSB7XG4gICAgICByZXN0b3JlU3RhdGUoY3R4KTtcblxuICAgICAgY29uc3Qgc3RhdHVzVGV4dCA9IHBoYXNlRGVzY3JpcHRpb24oc3RhdGUpO1xuICAgICAgY29uc3QgZ3VpZGVsaW5lcyA9IHBoYXNlR3VpZGVsaW5lcyhzdGF0ZSk7XG4gICAgICBjb25zdCB0ZXN0c1dyaXR0ZW4gPSBzdGF0ZS50ZXN0c1dyaXR0ZW4gPz8gMDtcblxuICAgICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzVGV4dCksXG4gICAgICAgIGN0eC51aS50aGVtZS5mZyhcImRpbVwiLCBcIlRlc3RzIHdyaXR0ZW46IFwiICsgdGVzdHNXcml0dGVuKSxcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBzdGF0dXNUZXh0ICsgXCJcXG5cXG5UZXN0cyB3cml0dGVuOiBcIiArIHRlc3RzV3JpdHRlbiArIFwiXFxuXFxuXCIgKyBndWlkZWxpbmVzLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICBwaGFzZTogc3RhdGUucGhhc2UsXG4gICAgICAgICAgdGVzdHNSYW46IHN0YXRlLnRlc3RzUmFuLFxuICAgICAgICAgIHRlc3RzUGFzc2VkOiBzdGF0ZS50ZXN0c1Bhc3NlZCxcbiAgICAgICAgICB0ZXN0c1dyaXR0ZW4sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmVuZGVyQ2FsbChfYXJncywgdGhlbWUsIF9jb250ZXh0KSB7XG4gICAgICByZXR1cm4gbmV3IFRleHQodGhlbWUuZmcoXCJ0b29sVGl0bGVcIiwgdGhlbWUuYm9sZChcInRkZC1zdGF0dXNcIikpLCAwLCAwKTtcbiAgICB9LFxuICAgIHJlbmRlclJlc3VsdChyZXN1bHQsIF9vcHRpb25zLCB0aGVtZSwgX2NvbnRleHQpIHtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXN1bHQuZGV0YWlscyBhcyB7IHBoYXNlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWRldGFpbHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0KHJlc3VsdC5jb250ZW50WzBdPy50eXBlID09PSBcInRleHRcIiA/IHJlc3VsdC5jb250ZW50WzBdLnRleHQgOiBcIlwiLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBoYXNlID0gZGV0YWlscy5waGFzZSA/IHBoYXNlRW1vamkoZGV0YWlscy5waGFzZSBhcyBhbnkpIDogXCJcIjtcbiAgICAgIHJldHVybiBuZXcgVGV4dChwaGFzZSArIFwiIFwiICsgZGV0YWlscy5waGFzZSwgMCwgMCk7XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIEV2ZW50cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwaS5vbihcInNlc3Npb25fc3RhcnRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgcmVzdG9yZVN0YXRlKGN0eCk7XG5cbiAgICBjdHgudWkuc2V0V2lkZ2V0KFwidGRkLXN0YXR1c1wiLCBbXG4gICAgICBjdHgudWkudGhlbWUuZmcoXCJhY2NlbnRcIiwgc3RhdHVzTWVzc2FnZSgpKSxcbiAgICBdKTtcblxuICAgIGlmIChjdHgubW9kZSA9PT0gXCJ0dWlcIikge1xuICAgICAgY3R4LnVpLm5vdGlmeShcIlRERCBDeWNsZSBzdGFydGVkIGluIFwiICsgc3RhdGUucGhhc2UgKyBcIiBwaGFzZVwiLCBcImluZm9cIik7XG4gICAgfVxuICB9KTtcblxuICAvLyBBbGxvdyBnby10by1ncmVlbiBkdXJpbmcgUkVGQUNUT1IgKHRvIHZlcmlmeSB0ZXN0cyBhZnRlciByZWZhY3RvcmluZylcbiAgLy8gT25seSBibG9jazogUkVEIOKGkiBnby10by1yZWZhY3RvciAobXVzdCBwYXNzIHRlc3RzIGZpcnN0KVxuICBwaS5vbihcInRvb2xfY2FsbFwiLCBhc3luYyAoZXZlbnQsIGN0eCkgPT4ge1xuICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJSRURcIiAmJiBldmVudC50b29sTmFtZSA9PT0gXCJnby10by1yZWZhY3RvclwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBibG9jazogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiBcIkNhbm5vdCBnbyB0byBSRUZBQ1RPUiBmcm9tIFJFRCBwaGFzZS4gWW91IG11c3QgZmlyc3QgbWFrZSB0ZXN0cyBwYXNzIChHUkVFTiBwaGFzZSkuIENhbGwgZ28tdG8tZ3JlZW4gYWZ0ZXIgeW91ciBpbXBsZW1lbnRhdGlvbiBwYXNzZXMgdGhlIHRlc3QuXCIsXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG5cbiAgcGkub24oXCJiZWZvcmVfYWdlbnRfc3RhcnRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlOiB7XG4gICAgICAgIGN1c3RvbVR5cGU6IFwidGRkLWN5Y2xlLWd1aWRlbGluZXNcIixcbiAgICAgICAgY29udGVudDogXCJcXG5cXG5bVEREIENZQ0xFIC0gXCIgKyBzdGF0ZS5waGFzZSArIFwiIFBIQVNFXVxcblwiICsgZ3VpZGVsaW5lc01lc3NhZ2UoKSxcbiAgICAgICAgZGlzcGxheTogZmFsc2UsXG4gICAgICB9LFxuICAgIH07XG4gIH0pO1xuXG4gIHBpLm9uKFwidHVybl9lbmRcIiwgYXN5bmMgKF9ldmVudCwgY3R4KSA9PiB7XG4gICAgY3R4LnVpLnNldFdpZGdldChcInRkZC1zdGF0dXNcIiwgW1xuICAgICAgY3R4LnVpLnRoZW1lLmZnKFwiYWNjZW50XCIsIHN0YXR1c01lc3NhZ2UoKSksXG4gICAgXSk7XG4gIH0pO1xuXG4gIHBpLm9uKFwic2Vzc2lvbl9zaHV0ZG93blwiLCBhc3luYyAoKSA9PiB7XG4gICAgcGVyc2lzdFN0YXRlKCk7XG4gIH0pO1xufVxuIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0Ijo2NTEyLCJvdXRwdXQiOjQxNDgsImNhY2hlUmVhZCI6MTM2NDQ4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTQ3MTA4LCJjb3N0Ijp7ImlucHV0IjowLjAwMDU4NjA4LCJvdXRwdXQiOjAuMDAwNzQ2NjQsImNhY2hlUmVhZCI6MC4wMDI3Mjg5NiwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDA0MDYxNjh9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NTAwMzc4OTQsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk1MDAzOC01QTRqVmNLUVNIYVREYzJHUXFuSyIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3MGE5ZWI2NCIsInBhcmVudElkIjoiMjIyNWY1NzMiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA4OjEwLjk3OFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfMDBfdThSRFgzTGRHUWRtS0M4dVVsYmU5OTk2IiwidG9vbE5hbWUiOiJ3cml0ZSIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSB3cm90ZSAxNjM5NiBieXRlcyB0byAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvaW5kZXgudHMifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NTAwOTA5Nzh9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiJiMTlmOTQzOCIsInBhcmVudElkIjoiNzBhOWViNjQiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA4OjMzLjQxOVoiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6Ikdvb2QuIE5vdyBJIG5lZWQgdG8gdXBkYXRlIHRoZSB0b29sX2NhbGwgaGFuZGxlciB0byBhbHNvIGhhbmRsZSB0aGUgUkVGQUNUT1Ig4oaSIGdvLXRvLWdyZWVuIGJsb2NrLiBXYWl0LCBJIGFjdHVhbGx5IHJlbW92ZWQgdGhhdCBibG9jayBiZWNhdXNlIHdlIHdhbnQgdG8gYWxsb3cgZ28tdG8tZ3JlZW4gZHVyaW5nIFJFRkFDVE9SIHBoYXNlLiBMZXQgbWUgdGhpbmsgYWJvdXQgdGhpczpcblxuLSBJbiBSRUQ6IGFnZW50IGNhbiB3cml0ZSBjb2RlIGFuZCBjYWxsIGdvLXRvLWdyZWVuICh0byBydW4gdGVzdHMpXG4tIEluIEdSRUVOOiBhZ2VudCBjYW4gY2FsbCBnby10by1yZWZhY3RvciAodG8gZW50ZXIgcmVmYWN0b3JpbmcpXG4tIEluIFJFRkFDVE9SOiBhZ2VudCBpcyB3b3JraW5nIG9uIHJlZmFjdG9yaW5nLiBJdCBzaG91bGQgYmUgYWJsZSB0byBjYWxsIGdvLXRvLWdyZWVuICh0byB2ZXJpZnkgdGVzdHMgc3RpbGwgcGFzcykuIElmIHRlc3RzIHBhc3MsIGl0IGdvZXMgdG8gR1JFRU4uIFRoZW4gaXQgY2FuIGNhbGwgZ28tdG8tcmVmYWN0b3IgdG8gcmVwb3J0IGJhY2suXG5cblRoZSBvbmx5IHJlbWFpbmluZyBibG9jayBpczpcbi0gSW4gUkVEOiBjYW5ub3QgY2FsbCBnby10by1yZWZhY3RvciAobXVzdCBwYXNzIHRlc3RzIGZpcnN0KVxuXG5UaGlzIG1ha2VzIHNlbnNlLiBMZXQgbWUgdmVyaWZ5IHR5cGVjaGVjayBhbmQgdGVzdHMuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ik5vdyBsZXQgbWUgdmVyaWZ5IGV2ZXJ5dGhpbmcgY29tcGlsZXMgYW5kIHRlc3RzIHBhc3M6XG5cbiJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsX2RjZDdlZWQzNTY4NTRmMmI4Yjk3M2FkNyIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZSAmJiBucG0gcnVuIHR5cGVjaGVjayAyPiYxICYmIG5wbSBydW4gdGVzdCAyPiYxIn19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoxNDYxODEsIm91dHB1dCI6MjU5LCJjYWNoZVJlYWQiOjEwMjQsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxNDc0NjQsImNvc3QiOnsiaW5wdXQiOjAuMDEzMTU2MjksIm91dHB1dCI6MC4wMDAwNDY2MiwiY2FjaGVSZWFkIjowLjAwMDAyMDQ4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMTMyMjMzOX19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk1MDA5MDk3OSwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTUwMDkxLW9Ca0Z3QmVPdVNuNDZnS0hOOER1IiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjQ5ZGNjMjRhIiwicGFyZW50SWQiOiJiMTlmOTQzOCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDg6MzQuNDE5WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF9kY2Q3ZWVkMzU2ODU0ZjJiOGI5NzNhZDciLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJcbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHR5cGVjaGVja1xuPiB0c2MgLS1ub0VtaXRcblxuc3JjL3VpLnRzKDEyLDMpOiBlcnJvciBUUzIzMDU6IE1vZHVsZSAnXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCInIGhhcyBubyBleHBvcnRlZCBtZW1iZXIgJ21hdGNoZXNLZXknLlxuc3JjL3VpLnRzKDEzLDMpOiBlcnJvciBUUzIzMDU6IE1vZHVsZSAnXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCInIGhhcyBubyBleHBvcnRlZCBtZW1iZXIgJ0tleScuXG5zcmMvdWkudHMoMTQsOCk6IGVycm9yIFRTMjMwNTogTW9kdWxlICdcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIicgaGFzIG5vIGV4cG9ydGVkIG1lbWJlciAnVFVJJy5cblxuXG5Db21tYW5kIGV4aXRlZCB3aXRoIGNvZGUgMiJ9XSwiZGV0YWlscyI6e30sImlzRXJyb3IiOnRydWUsInRpbWVzdGFtcCI6MTc4MTk1MDExNDQxOX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjhmMTM5M2VjIiwicGFyZW50SWQiOiI0OWRjYzI0YSIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDg6NDMuMDA0WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiVGhlIHBpLWNvZGluZy1hZ2VudCBkb2Vzbid0IHJlLWV4cG9ydCBgbWF0Y2hlc0tleWAsIGBLZXlgLCBgVFVJYCBmcm9tIHBpLXR1aS4gSSBuZWVkIHRvIGZpeCB0aGUgaW1wb3J0IGluIHVpLnRzLiBUaGUgcXVlc3Rpb24udHMgZXhhbXBsZSBpbXBvcnRzIHRoZW0gZnJvbSBgQGVhcmVuZGlsLXdvcmtzL3BpLXR1aWAgYW5kIHVzZXMgYHR5cGUgVGhlbWVgIGFuZCBgS2V5YmluZGluZ3NNYW5hZ2VyYCBmcm9tIHBpLWNvZGluZy1hZ2VudCAoZm9yIHRoZSBjdXN0b20gY2FsbGJhY2spLiBBY3R1YWxseSB3YWl0LCBpbiB0aGUgdXBkYXRlZCB1aS50cyBJIGNoYW5nZWQgdGhlIGltcG9ydHMgdG8gcGktY29kaW5nLWFnZW50IGJ1dCB0aG9zZSB0eXBlcyBhcmVuJ3QgZXhwb3J0ZWQgZnJvbSB0aGVyZS5cblxuTGV0IG1lIGZpeDogaW1wb3J0IGBtYXRjaGVzS2V5YCwgYEtleWAsIGBUVUlgIGZyb20gcGktdHVpLCBhbmQgYFRoZW1lYCwgYEtleWJpbmRpbmdzTWFuYWdlcmAgZnJvbSBwaS1jb2RpbmctYWdlbnQuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMF9PdjRqazFQVmZNdFhUQWxQdFo5MTAyNzUiLCJuYW1lIjoiZWRpdCIsImFyZ3VtZW50cyI6eyJwYXRoIjoiL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL3VpLnRzIiwiZWRpdHMiOlt7Im5ld1RleHQiOiJpbXBvcnQge1xuICBtYXRjaGVzS2V5LFxuICBLZXksXG4gIHR5cGUgVFVJLFxufSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLXR1aVwiO1xuaW1wb3J0IHR5cGUgeyBUaGVtZSwgS2V5YmluZGluZ3NNYW5hZ2VyIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjsiLCJvbGRUZXh0IjoiaW1wb3J0IHtcbiAgbWF0Y2hlc0tleSxcbiAgS2V5LFxuICB0eXBlIFRVSSxcbiAgdHlwZSBUaGVtZSxcbiAgdHlwZSBLZXliaW5kaW5nc01hbmFnZXIsXG59IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7In1dfX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEyNTAzLCJvdXRwdXQiOjMzMSwiY2FjaGVSZWFkIjoxMzUwNDAsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxNDc4NzQsImNvc3QiOnsiaW5wdXQiOjAuMDAxMTI1MjcsIm91dHB1dCI6MC4wMDAwNTk1OCwiY2FjaGVSZWFkIjowLjAwMjcwMDgsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMzg4NTY1fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTUwMTE0NDE5LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NTAxMTQtREJENGo3aERITG84dEVZdHJwNWUiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMjcxYmQ4YjAiLCJwYXJlbnRJZCI6IjhmMTM5M2VjIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowODo0My4wMjVaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzAwX092NGprMVBWZk10WFRBbFB0WjkxMDI3NSIsInRvb2xOYW1lIjoiZWRpdCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlN1Y2Nlc3NmdWxseSByZXBsYWNlZCAxIGJsb2NrKHMpIGluIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy91aS50cy4ifV0sImRldGFpbHMiOnsiZGlmZiI6IiAgICAgLi4uXG4gIDExIGltcG9ydCB7XG4gIDEyICAgbWF0Y2hlc0tleSxcbiAgMTMgICBLZXksXG4gIDE0ICAgdHlwZSBUVUksXG4tIDE1ICAgdHlwZSBUaGVtZSxcbi0gMTYgICB0eXBlIEtleWJpbmRpbmdzTWFuYWdlcixcbi0gMTcgfSBmcm9tIFwiQGVhcmVuZGlsLXdvcmtzL3BpLWNvZGluZy1hZ2VudFwiO1xuKyAxNSB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG4rIDE2IGltcG9ydCB0eXBlIHsgVGhlbWUsIEtleWJpbmRpbmdzTWFuYWdlciB9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50XCI7XG4gIDE4IGltcG9ydCB0eXBlIHsgUmVmYWN0b3JGb2N1cywgUmVmYWN0b3JEZWNpc2lvbiB9IGZyb20gXCIuL3N0YXRlLmpzXCI7XG4gIDE5IFxuICAyMCBjb25zdCBSRUZBQ1RPUl9GT0NJOiBSZWZhY3RvckZvY3VzW10gPSBbXG4gIDIxICAgXCJhdWRpdFwiLFxuICAgICAuLi4iLCJwYXRjaCI6Ii0tLSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHNcbisrKyAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZS9zcmMvdWkudHNcbkBAIC0xMSwxMSArMTEsMTAgQEBcbiBpbXBvcnQge1xuICAgbWF0Y2hlc0tleSxcbiAgIEtleSxcbiAgIHR5cGUgVFVJLFxuLSAgdHlwZSBUaGVtZSxcbi0gIHR5cGUgS2V5YmluZGluZ3NNYW5hZ2VyLFxuLX0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbit9IGZyb20gXCJAZWFyZW5kaWwtd29ya3MvcGktdHVpXCI7XG4raW1wb3J0IHR5cGUgeyBUaGVtZSwgS2V5YmluZGluZ3NNYW5hZ2VyIH0gZnJvbSBcIkBlYXJlbmRpbC13b3Jrcy9waS1jb2RpbmctYWdlbnRcIjtcbiBpbXBvcnQgdHlwZSB7IFJlZmFjdG9yRm9jdXMsIFJlZmFjdG9yRGVjaXNpb24gfSBmcm9tIFwiLi9zdGF0ZS5qc1wiO1xuIFxuIGNvbnN0IFJFRkFDVE9SX0ZPQ0k6IFJlZmFjdG9yRm9jdXNbXSA9IFtcbiAgIFwiYXVkaXRcIixcbiIsImZpcnN0Q2hhbmdlZExpbmUiOjE1fSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk1MDEyMzAyNX19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjdjZGE5YmQxIiwicGFyZW50SWQiOiIyNzFiZDhiMCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTA6MDk6MDYuODY1WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiV2FpdCwgdGhlIGBUaGVtZWAgYW5kIGBLZXliaW5kaW5nc01hbmFnZXJgIHR5cGVzIC0gYXJlIHRoZXkgZXhwb3J0ZWQgZnJvbSBwaS1jb2RpbmctYWdlbnQ/IExldCBtZSBjaGVjay4gVGhlIGBUaGVtZWAgdHlwZSBpcyBleHBvcnRlZCBmcm9tIHBpLWNvZGluZy1hZ2VudCwgYnV0IGBLZXliaW5kaW5nc01hbmFnZXJgIEknbSBub3Qgc3VyZSBhYm91dC4gTGV0IG1lIGNoZWNrLi4uIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF80MmIyY2Y2NjI0ODk0NzllYTdmN2E2YWUiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgZ3JlcCBcIktleWJpbmRpbmdzTWFuYWdlclwiIG5vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2Rpc3QvaW5kZXguZC50cyAyPi9kZXYvbnVsbCB8IGhlYWQgLTUifX1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjEzODc4MCwib3V0cHV0IjoxNDksImNhY2hlUmVhZCI6OTIxNiwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjE0ODE0NSwiY29zdCI6eyJpbnB1dCI6MC4wMTI0OTAyLCJvdXRwdXQiOjAuMDAwMDI2ODIsImNhY2hlUmVhZCI6MC4wMDAxODQzMiwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEyNzAxMzR9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NTAxMjMwMjcsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk1MDEyMy12THQwdElQRUdRMXladzNLTkFqRiIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3MGIxOWVmYiIsInBhcmVudElkIjoiN2NkYTliZDEiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA5OjA2Ljg4MVoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfNDJiMmNmNjYyNDg5NDc5ZWE3ZjdhNmFlIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiZXhwb3J0IHR5cGUgeyBBZ2VudEVuZEV2ZW50LCBBZ2VudFN0YXJ0RXZlbnQsIEFnZW50VG9vbFJlc3VsdCwgQWdlbnRUb29sVXBkYXRlQ2FsbGJhY2ssIEFwcEtleWJpbmRpbmcsIEF1dG9jb21wbGV0ZVByb3ZpZGVyRmFjdG9yeSwgQmFzaFRvb2xDYWxsRXZlbnQsIEJlZm9yZUFnZW50U3RhcnRFdmVudCwgQmVmb3JlQWdlbnRTdGFydEV2ZW50UmVzdWx0LCBCZWZvcmVQcm92aWRlclJlcXVlc3RFdmVudCwgQmVmb3JlUHJvdmlkZXJSZXF1ZXN0RXZlbnRSZXN1bHQsIEJ1aWxkU3lzdGVtUHJvbXB0T3B0aW9ucywgQ29tcGFjdE9wdGlvbnMsIENvbnRleHRFdmVudCwgQ29udGV4dFVzYWdlLCBDdXN0b21Ub29sQ2FsbEV2ZW50LCBFZGl0VG9vbENhbGxFdmVudCwgRXhlY09wdGlvbnMsIEV4ZWNSZXN1bHQsIEV4dGVuc2lvbiwgRXh0ZW5zaW9uQWN0aW9ucywgRXh0ZW5zaW9uQVBJLCBFeHRlbnNpb25Db21tYW5kQ29udGV4dCwgRXh0ZW5zaW9uQ29tbWFuZENvbnRleHRBY3Rpb25zLCBFeHRlbnNpb25Db250ZXh0LCBFeHRlbnNpb25Db250ZXh0QWN0aW9ucywgRXh0ZW5zaW9uRXJyb3IsIEV4dGVuc2lvbkV2ZW50LCBFeHRlbnNpb25GYWN0b3J5LCBFeHRlbnNpb25GbGFnLCBFeHRlbnNpb25IYW5kbGVyLCBFeHRlbnNpb25SdW50aW1lLCBFeHRlbnNpb25TaG9ydGN1dCwgRXh0ZW5zaW9uVUlDb250ZXh0LCBFeHRlbnNpb25VSURpYWxvZ09wdGlvbnMsIEV4dGVuc2lvbldpZGdldE9wdGlvbnMsIEZpbmRUb29sQ2FsbEV2ZW50LCBHcmVwVG9vbENhbGxFdmVudCwgSW5wdXRFdmVudCwgSW5wdXRFdmVudFJlc3VsdCwgSW5wdXRTb3VyY2UsIEtleWJpbmRpbmdzTWFuYWdlciwgTG9hZEV4dGVuc2lvbnNSZXN1bHQsIExzVG9vbENhbGxFdmVudCwgTWVzc2FnZVJlbmRlcmVyLCBNZXNzYWdlUmVuZGVyT3B0aW9ucywgUHJvamVjdFRydXN0Q29udGV4dCwgUHJvamVjdFRydXN0RXZlbnQsIFByb2plY3RUcnVzdEV2ZW50RGVjaXNpb24sIFByb2plY3RUcnVzdEV2ZW50UmVzdWx0LCBQcm9qZWN0VHJ1c3RIYW5kbGVyLCBQcm92aWRlckNvbmZpZywgUHJvdmlkZXJNb2RlbENvbmZpZywgUmVhZFRvb2xDYWxsRXZlbnQsIFJlZ2lzdGVyZWRDb21tYW5kLCBSZWdpc3RlcmVkVG9vbCwgUmVzb2x2ZWRDb21tYW5kLCBTZXNzaW9uQmVmb3JlQ29tcGFjdEV2ZW50LCBTZXNzaW9uQmVmb3JlRm9ya0V2ZW50LCBTZXNzaW9uQmVmb3JlU3dpdGNoRXZlbnQsIFNlc3Npb25CZWZvcmVUcmVlRXZlbnQsIFNlc3Npb25Db21wYWN0RXZlbnQsIFNlc3Npb25TaHV0ZG93bkV2ZW50LCBTZXNzaW9uU3RhcnRFdmVudCwgU2Vzc2lvblRyZWVFdmVudCwgU2xhc2hDb21tYW5kSW5mbywgU2xhc2hDb21tYW5kU291cmNlLCBTb3VyY2VJbmZvLCBUZXJtaW5hbElucHV0SGFuZGxlciwgVG9vbENhbGxFdmVudCwgVG9vbENhbGxFdmVudFJlc3VsdCwgVG9vbERlZmluaXRpb24sIFRvb2xFeGVjdXRpb25Nb2RlLCBUb29sSW5mbywgVG9vbFJlbmRlclJlc3VsdE9wdGlvbnMsIFRvb2xSZXN1bHRFdmVudCwgVHVybkVuZEV2ZW50LCBUdXJuU3RhcnRFdmVudCwgVXNlckJhc2hFdmVudCwgVXNlckJhc2hFdmVudFJlc3VsdCwgV2lkZ2V0UGxhY2VtZW50LCBXb3JraW5nSW5kaWNhdG9yT3B0aW9ucywgV3JpdGVUb29sQ2FsbEV2ZW50LCB9IGZyb20gXCIuL2NvcmUvZXh0ZW5zaW9ucy9pbmRleC50c1wiO1xuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTUwMTQ2ODgxfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZGE0YzBjOGUiLCJwYXJlbnRJZCI6IjcwYjE5ZWZiIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowOToxNS43MTBaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJgS2V5YmluZGluZ3NNYW5hZ2VyYCBJUyBleHBvcnRlZCBmcm9tIHBpLWNvZGluZy1hZ2VudC4gR29vZC4gTGV0IG1lIHJ1biB0eXBlY2hlY2sgYWdhaW4uIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMzU3ZWI4MzgwZDU0ZTI2YTk3Mjk2OTIiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoiY2QgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUgJiYgbnBtIHJ1biB0eXBlY2hlY2sgMj4mMSAmJiBucG0gcnVuIHRlc3QgMj4mMSJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6NTQ1LCJvdXRwdXQiOjk5LCJjYWNoZVJlYWQiOjE0Nzk2OCwiY2FjaGVXcml0ZSI6MCwidG90YWxUb2tlbnMiOjE0ODYxMiwiY29zdCI6eyJpbnB1dCI6MC4wMDAwNDkwNSwib3V0cHV0IjowLjAwMDAxNzgyLCJjYWNoZVJlYWQiOjAuMDAyOTU5MzYsImNhY2hlV3JpdGUiOjAsInRvdGFsIjowLjAwMzAyNjIzfX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTUwMTQ2ODgyLCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NTAxNDctdnNSdzFLSFRzQWZubXpsS01xSUMiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiOGUwZmZlODciLCJwYXJlbnRJZCI6ImRhNGMwYzhlIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMDowOToxNy4yMTdaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzAzNTdlYjgzODBkNTRlMjZhOTcyOTY5MiIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlxuPiBwaS10ZGQtY3ljbGVAMC4xLjAgdHlwZWNoZWNrXG4+IHRzYyAtLW5vRW1pdFxuXG5cbj4gcGktdGRkLWN5Y2xlQDAuMS4wIHRlc3Rcbj4gdml0ZXN0IHJ1blxuXG5cbiBSVU4gIHY0LjEuOSAvVXNlcnMvd2lsbGVtL2Rldi9zcGlrZXMvbGxtL3BpLXRkZC1jeWNsZVxuXG5cbiBUZXN0IEZpbGVzICAxIHBhc3NlZCAoMSlcbiAgICAgIFRlc3RzICAzMSBwYXNzZWQgKDMxKVxuICAgU3RhcnQgYXQgIDExOjA5OjE3XG4gICBEdXJhdGlvbiAgOTltcyAodHJhbnNmb3JtIDE5bXMsIHNldHVwIDBtcywgaW1wb3J0IDI1bXMsIHRlc3RzIDRtcywgZW52aXJvbm1lbnQgMG1zKVxuXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NTAxNTcyMTd9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIyN2JmNzQzNCIsInBhcmVudElkIjoiOGUwZmZlODciLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDEwOjA5OjI3LjIwNloiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IkV2ZXJ5dGhpbmcgcGFzc2VzLiBMZXQgbWUgc3VtbWFyaXplIHRoZSBjaGFuZ2VzIGZvciB0aGUgdXNlci4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRleHQiLCJ0ZXh0IjoiQWxsIDMxIHRlc3RzIHBhc3MgYW5kIHR5cGVjaGVjayBpcyBjbGVhbi4gSGVyZSdzIHdoYXQgY2hhbmdlZDpcblxuKioxLiBCYWNrc3BhY2UgZml4ZWQqKiDigJQgcmVtb3ZlZCB0aGUgY3VzdG9tIHRleHQgaW5wdXQgZnJvbSB0aGUgVUkgY29tcG9uZW50OyB0aGUgXCJjdXN0b20gaW5zdHJ1Y3Rpb25cIiBvcHRpb24gbm93IHVzZXMgYGN0eC51aS5pbnB1dCgpYCBmcm9tIHRoZSB0b29sJ3MgZXhlY3V0ZSBmdW5jdGlvbiwgd2hpY2ggaGFuZGxlcyBiYWNrc3BhY2UsIGRlbGV0ZSwgYW5kIGFsbCB0ZXh0IGlucHV0IHByb3Blcmx5LlxuXG4qKjIuIFJFRkFDVE9SIGxvb3AsIG5vdCBpbW1lZGlhdGUgUkVEKiog4oCUIFRoZSBwaGFzZSBubyBsb25nZXIganVtcHMgc3RyYWlnaHQgdG8gUkVEIHdoZW4gcGlja2luZyBcInJlZmFjdG9yIHRlc3RzXCIgLyBcInJlZmFjdG9yIGltcGxlbWVudGF0aW9uXCIgLyBcImN1c3RvbVwiLiBJbnN0ZWFkOlxuLSBEZXZlbG9wZXIgcGlja3MgYW4gb3B0aW9uIOKGkiBhZ2VudCBnZXRzIGEgc3RlZXJpbmcgbWVzc2FnZSB0ZWxsaW5nIGl0IHdoYXQgdG8gZG9cbi0gQWdlbnQgKipzdGF5cyBpbiBSRUZBQ1RPUiBwaGFzZSoqIGFuZCBkb2VzIHRoZSB3b3JrXG4tIEFmdGVyIHJlZmFjdG9yaW5nLCBhZ2VudCBjYWxscyBgZ28tdG8tZ3JlZW5gIHRvIHZlcmlmeSB0ZXN0cyBzdGlsbCBwYXNzXG4tIFRoZW4gY2FsbHMgYGdvLXRvLXJlZmFjdG9yYCBhZ2FpbiB0byByZXBvcnQgYmFjayBhbmQgZ2V0IGEgbmV3IGRlY2lzaW9uXG4tIE9ubHkgXCJDb250aW51ZSB0byBuZXh0IHRlc3RcIiB0cmFuc2l0aW9ucyB0byBSRURcblxuVGhlIHRvb2xfY2FsbCBibG9jayB0aGF0IHByZXZlbnRlZCBgZ28tdG8tZ3JlZW5gIGR1cmluZyBSRUZBQ1RPUiBoYXMgYmVlbiByZW1vdmVkIOKAlCB0aGUgYWdlbnQgbmVlZHMgdG8gY2FsbCBpdCB0byB2ZXJpZnkgdGVzdHMgYWZ0ZXIgcmVmYWN0b3JpbmcuXG5cbioqMy4gTmV3IFwiYXVkaXRcIiBvcHRpb24qKiDigJQgXCJJZGVudGlmeSBjb2RlIHNtZWxscyAmIHZlcmlmeSBtaW5pbWFsaXR5XCIgaXMgbm93IHRoZSBmaXJzdCBvcHRpb24uIFdoZW4gY2hvc2VuLCB0aGUgYWdlbnQgZ2V0cyBhIHN0ZWVyaW5nIG1lc3NhZ2UgYXNraW5nIGl0IHRvOlxuLSBJZGVudGlmeSBjb2RlIHNtZWxsc1xuLSBDaGVjayBpZiBhbGwgY29kZSBpcyBhY3R1YWxseSByZXF1aXJlZFxuLSBWZXJpZnkgdGhlIGltcGxlbWVudGF0aW9uIGlzIG1pbmltYWwgKG9ubHkgd2hhdCB0ZXN0cyByZXF1aXJlKVxuLSBSZXBvcnQgZmluZGluZ3MgYmFjayB0byB0aGUgZGV2ZWxvcGVyXG4tIFRoZW4gY2FsbCBgZ28tdG8tcmVmYWN0b3JgIGFnYWluIGZvciBuZXh0IHN0ZXBzIn1dLCJhcGkiOiJvcGVuYWktY29tcGxldGlvbnMiLCJwcm92aWRlciI6Im9wZW5yb3V0ZXIiLCJtb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoIiwidXNhZ2UiOnsiaW5wdXQiOjI2NSwib3V0cHV0IjozMjMsImNhY2hlUmVhZCI6MTQ4NDgwLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTQ5MDY4LCJjb3N0Ijp7ImlucHV0IjowLjAwMDAyMzg1LCJvdXRwdXQiOjAuMDAwMDU4MTQsImNhY2hlUmVhZCI6MC4wMDI5Njk2LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDMwNTE1OTAwMDAwMDAwMDAzfX0sInN0b3BSZWFzb24iOiJzdG9wIiwidGltZXN0YW1wIjoxNzgxOTUwMTU3MjE4LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NTAxNTctZUdodk9vajIxOWczMVIzY0xISzkiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMDI4ZjE0ZGQiLCJwYXJlbnRJZCI6IjI3YmY3NDM0IiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMTo0MTo0Ni43NTBaIiwibWVzc2FnZSI6eyJyb2xlIjoidXNlciIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Ii90aGVtZSJ9XSwidGltZXN0YW1wIjoxNzgxOTU1NzA2NzQ4fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZjMxNGU5MTgiLCJwYXJlbnRJZCI6IjAyOGYxNGRkIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMTo0MjowMS44MTFaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgdXNlciB0eXBlZCBcIi90aGVtZVwiIHdoaWNoIGlzIGEgUGkgY29tbWFuZC4gQnV0IHdlJ3JlIGluIHRoZSBlZGl0b3IgY29udGV4dCAtIHRoZXkncmUgYXNraW5nIG1lIHRvIHN3aXRjaCB0aGUgdGhlbWUgb2YgdGhlIFBpIFRVSS4gSSBkb24ndCBoYXZlIGEgdG9vbCB0byBjaGFuZ2UgdGhlIHRoZW1lIG9mIHRoZSBydW5uaW5nIFBpIHNlc3Npb24uIExldCBtZSBqdXN0IHRlbGwgdGhlbSB0aGF0IHRoaXMgaXMgYSBQaSBidWlsdC1pbiBjb21tYW5kIHRoZXkgY2FuIHVzZSBpbiBpbnRlcmFjdGl2ZSBtb2RlLCBub3Qgc29tZXRoaW5nIEkgY2FuIGV4ZWN1dGUuXG5cbldhaXQsIGFjdHVhbGx5IGxvb2tpbmcgYXQgdGhpcyBtb3JlIGNhcmVmdWxseSAtIHRoZSB1c2VyIG1pZ2h0IGJlIHRyeWluZyB0byB1c2UgdGhlIC90aGVtZSBjb21tYW5kIGluc2lkZSBQaSdzIGludGVyYWN0aXZlIG1vZGUuIEJ1dCB3ZSdyZSBpbiBhIGNoYXQgd2l0aCB0aGUgY29kaW5nIGFzc2lzdGFudCBhZ2VudCAobWUpLiBTbyBJIHNob3VsZCBjbGFyaWZ5IHRoYXQgL3RoZW1lIGlzIGEgUGkgYnVpbHQtaW4gY29tbWFuZCB1c2VkIGluIGludGVyYWN0aXZlIG1vZGUsIG5vdCBzb21ldGhpbmcgSSBjYW4gcHJvY2VzcyBoZXJlLlxuXG5BY3R1YWxseSwgbG9va2luZyBhdCB0aGUgUGkgZG9jcywgJy90aGVtZScgaXMgbm90IGxpc3RlZCBhcyBhIGJ1aWx0LWluIGNvbW1hbmQuIFRoZSBidWlsdC1pbiBjb21tYW5kcyBpbmNsdWRlIHRoaW5ncyBsaWtlIC9tb2RlbCwgL3NldHRpbmdzLCAvcmVzdW1lLCBldGMuIEJ1dCB0aGVtZXMgY2FuIGJlIGxvYWRlZCB2aWEgYC0tdGhlbWVgIGZsYWcgb3IgcGxhY2VkIGluIHRoZSB0aGVtZXMgZGlyZWN0b3J5LiBUaGVyZSdzIG5vIC90aGVtZSBjb21tYW5kIGxpc3RlZC4gVGhlcmUgaXMgYSBgY3R4LnVpLnNldFRoZW1lKClgIG1ldGhvZCBpbiB0aGUgRXh0ZW5zaW9uQVBJIHRob3VnaC5cblxuTGV0IG1lIGp1c3QgZXhwbGFpbiB0aGF0IC90aGVtZSBpc24ndCBhIGJ1aWx0LWluIFBpIGNvbW1hbmQgYW5kIHN1Z2dlc3QgaG93IHRvIHN3aXRjaCB0aGVtZXMuIiwidGhpbmtpbmdTaWduYXR1cmUiOiJyZWFzb25pbmcifSx7InR5cGUiOiJ0ZXh0IiwidGV4dCI6ImAvdGhlbWVgIGlzbid0IGEgYnVpbHQtaW4gUGkgY29tbWFuZC4gVGhlIHdheSB0byBzd2l0Y2ggdGhlbWVzIGluIFBpOlxuXG4qKkluIGludGVyYWN0aXZlIG1vZGUqKiwgeW91IGNhbiBjaGFuZ2UgdGhlIHRoZW1lIHZpYSBgL3NldHRpbmdzYCDihpIgbmF2aWdhdGUgdG8gdGhlIFRoZW1lIG9wdGlvbiwgb3IgZnJvbSBhbiBleHRlbnNpb24gY2FsbCBgY3R4LnVpLnNldFRoZW1lKFwibmFtZVwiKWAuXG5cbioqVGhlbWVzKiogYXJlIE1hcmtkb3duIGZpbGVzIHBsYWNlZCBpbiBgfi8ucGkvYWdlbnQvdGhlbWVzL2Agb3IgYC5waS90aGVtZXMvYC4gQnVpbHQtaW4gdGhlbWVzIGFyZSBgZGFya2AgYW5kIGBsaWdodGAuIFRoZXkgaG90LXJlbG9hZCBhdXRvbWF0aWNhbGx5IOKAlCBqdXN0IGVkaXQgdGhlIGZpbGUgYW5kIFBpIHBpY2tzIGl0IHVwLlxuXG5JZiB5b3Ugd2FudCBhIGN1c3RvbSB0aGVtZSBmaWxlIGZvciB0aGlzIHByb2plY3QsIEkgY2FuIGNyZWF0ZSBvbmUgYXQgYC5waS90aGVtZXMvdGRkLmpzb25gIG9yIHdoZXJldmVyIHlvdSdkIGxpa2UuIFdoYXQgbG9vayBhcmUgeW91IGdvaW5nIGZvcj8ifV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTQ5MDU2LCJvdXRwdXQiOjM5MiwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTQ5NDQ4LCJjb3N0Ijp7ImlucHV0IjowLjAxMzQxNTA0LCJvdXRwdXQiOjAuMDAwMDcwNTYsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEzNDg1Nn19LCJzdG9wUmVhc29uIjoic3RvcCIsInRpbWVzdGFtcCI6MTc4MTk1NTcwNjc1NiwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTU1NzA3LW8zNzJCb3lkRzdqY1dDU2pNVHdqIiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjE3Mjk3OGZkIiwicGFyZW50SWQiOiJmMzE0ZTkxOCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTE6NDM6MjYuMDcyWiIsIm1lc3NhZ2UiOnsicm9sZSI6InVzZXIiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJJIHdhbnQgdG8gc2hvdyB0byB0aGUgYXVkaWVuY2UgaG93IHdlIHJhbiBwaSAtcCB3aXRoIHRoZSBleHRlbnNpb24gdG8gdGVzdCJ9XSwidGltZXN0YW1wIjoxNzgxOTU1ODA2MDcxfX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZmIzOTJlYmYiLCJwYXJlbnRJZCI6IjE3Mjk3OGZkIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMTo0MzozMy4xODRaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJUaGUgdXNlciB3YW50cyB0byBydW4gYSBkZW1vIHdpdGggYHBpIC1wYCAocHJpbnQgbW9kZSkgdG8gc2hvdyB0aGUgYXVkaWVuY2UgaG93IHRoZSBUREQgY3ljbGUgZXh0ZW5zaW9uIHdvcmtzLiBMZXQgbWUgcnVuIGEgY2xlYW4gdGVzdCBpbiBwcmludCBtb2RlIHRoYXQgZGVtb25zdHJhdGVzIHRoZSBmdWxsIGZsb3cuXG5cbkxldCBtZSBzZXQgdXAgYSBjbGVhbiBwcm9qZWN0IGFuZCBydW4gdGhlIHNlcXVlbmNlLiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJMZXQgbWUgc2V0IHVwIGEgY2xlYW4gZGVtbzoifSx7InR5cGUiOiJ0b29sQ2FsbCIsImlkIjoiY2FsbF8wMF9XeGhmY09majhibzdEazVIMWdiRjM4MTUiLCJuYW1lIjoiYmFzaCIsImFyZ3VtZW50cyI6eyJjb21tYW5kIjoicm0gLXJmIC90bXAvcGktdGRkLWRlbW8gJiYgbWtkaXIgL3RtcC9waS10ZGQtZGVtbyAmJiBjZCAvdG1wL3BpLXRkZC1kZW1vICYmIG5wbSBpbml0IC15IDI+JjEgfCB0YWlsIC0xICYmIG5wbSBpbnN0YWxsIHZpdGVzdCB0eXBlc2NyaXB0IEB0eXBlcy9ub2RlIDI+JjEgfCB0YWlsIC0zIiwidGltZW91dCI6MzB9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTMyMCwib3V0cHV0IjoxODUsImNhY2hlUmVhZCI6MTQ3ODQwLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTQ5MzQ1LCJjb3N0Ijp7ImlucHV0IjowLjAwMDExODgsIm91dHB1dCI6MC4wMDAwMzMyOTk5OTk5OTk5OTk5OTYsImNhY2hlUmVhZCI6MC4wMDI5NTY4LCJjYWNoZVdyaXRlIjowLCJ0b3RhbCI6MC4wMDMxMDg5fX0sInN0b3BSZWFzb24iOiJ0b29sVXNlIiwidGltZXN0YW1wIjoxNzgxOTU1ODA2MDc3LCJyZXNwb25zZUlkIjoiZ2VuLTE3ODE5NTU4MDYtQXZ6YWJTSTVXNk5HNm1DYUJxcFkiLCJyZXNwb25zZU1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2gtMjAyNjA0MjMifX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiZmIxZDA4OWQiLCJwYXJlbnRJZCI6ImZiMzkyZWJmIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMTo0MzozNi42MjRaIiwibWVzc2FnZSI6eyJyb2xlIjoidG9vbFJlc3VsdCIsInRvb2xDYWxsSWQiOiJjYWxsXzAwX1d4aGZjT2ZqOGJvN0RrNUgxZ2JGMzgxNSIsInRvb2xOYW1lIjoiYmFzaCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlxuICBydW4gYG5wbSBmdW5kYCBmb3IgZGV0YWlsc1xuXG5mb3VuZCAwIHZ1bG5lcmFiaWxpdGllc1xuIn1dLCJpc0Vycm9yIjpmYWxzZSwidGltZXN0YW1wIjoxNzgxOTU1ODE2NjI0fX0seyJ0eXBlIjoibWVzc2FnZSIsImlkIjoiMGU5YmRhM2QiLCJwYXJlbnRJZCI6ImZiMWQwODlkIiwidGltZXN0YW1wIjoiMjAyNi0wNi0yMFQxMTo0Mzo0Ny40NDlaIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRoaW5raW5nIiwidGhpbmtpbmciOiJHb29kLCB0aGUgcHJvamVjdCBpcyBzZXQgdXAuIE5vdyBsZXQgbWUgdXBkYXRlIHBhY2thZ2UuanNvbiB0byB1c2Ugdml0ZXN0IGFuZCB0aGVuIHJ1biB0aGUgZGVtby4iLCJ0aGlua2luZ1NpZ25hdHVyZSI6InJlYXNvbmluZyJ9LHsidHlwZSI6InRvb2xDYWxsIiwiaWQiOiJjYWxsXzAwX1pYdFVkZGJla2RBTG9UWVFoNktlNjI1NSIsIm5hbWUiOiJiYXNoIiwiYXJndW1lbnRzIjp7ImNvbW1hbmQiOiJjZCAvdG1wL3BpLXRkZC1kZW1vICYmIG5vZGUgLWUgXCJcbmNvbnN0IHBrZyA9IEpTT04ucGFyc2UocmVxdWlyZSgnZnMnKS5yZWFkRmlsZVN5bmMoJ3BhY2thZ2UuanNvbicsJ3V0ZjgnKSk7XG5wa2cuc2NyaXB0cy50ZXN0ID0gJ3ZpdGVzdCBydW4nO1xucmVxdWlyZSgnZnMnKS53cml0ZUZpbGVTeW5jKCdwYWNrYWdlLmpzb24nLCBKU09OLnN0cmluZ2lmeShwa2csIG51bGwsIDIpKTtcblwiICYmIHBpIC1lIC9Vc2Vycy93aWxsZW0vZGV2L3NwaWtlcy9sbG0vcGktdGRkLWN5Y2xlL3NyYy9pbmRleC50cyAtcCBcIlxuVGhpcyBpcyBhIGRlbW8gb2YgdGhlIFRERCBDeWNsZSBFeHRlbnNpb24uXG5cbkkgd2FudCBhIGZ1bmN0aW9uICdhZGQoYSxiKScgdGhhdCByZXR1cm5zIHRoZSBzdW0gb2YgdHdvIG51bWJlcnMuXG5Xcml0ZSBhIGZhaWxpbmcgdGVzdCBmaXJzdCwgdGhlbiBpbXBsZW1lbnQganVzdCBlbm91Z2ggdG8gbWFrZSBpdCBwYXNzLlxuQ2FsbCBnby10by1ncmVlbiB0byB2ZXJpZnkgdGVzdHMgcGFzcy5cblRoZW4gY2FsbCBnby10by1yZWZhY3RvciBzbyB0aGUgZGV2ZWxvcGVyIGNhbiBkZWNpZGUgd2hhdCB0byBkbyBuZXh0LlxuXCIgMj4mMSIsInRpbWVvdXQiOjEyMH19XSwiYXBpIjoib3BlbmFpLWNvbXBsZXRpb25zIiwicHJvdmlkZXIiOiJvcGVucm91dGVyIiwibW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaCIsInVzYWdlIjp7ImlucHV0IjoyMzAzLCJvdXRwdXQiOjI1MCwiY2FjaGVSZWFkIjoxNDcwNzIsImNhY2hlV3JpdGUiOjAsInRvdGFsVG9rZW5zIjoxNDk2MjUsImNvc3QiOnsiaW5wdXQiOjAuMDAwMjA3MjY5OTk5OTk5OTk5OTksIm91dHB1dCI6MC4wMDAwNDQ5OTk5OTk5OTk5OTk5OTYsImNhY2hlUmVhZCI6MC4wMDI5NDE0NCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDAzMTkzNzA5OTk5OTk5OTk5OH19LCJzdG9wUmVhc29uIjoidG9vbFVzZSIsInRpbWVzdGFtcCI6MTc4MTk1NTgxNjYyNSwicmVzcG9uc2VJZCI6Imdlbi0xNzgxOTU1ODE2LUxBOHg1cEFtQVNZUklseVoxSEg0IiwicmVzcG9uc2VNb2RlbCI6ImRlZXBzZWVrL2RlZXBzZWVrLXY0LWZsYXNoLTIwMjYwNDIzIn19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjY4Yzk2NDViIiwicGFyZW50SWQiOiIwZTliZGEzZCIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTE6NDQ6MjIuNjE5WiIsIm1lc3NhZ2UiOnsicm9sZSI6InRvb2xSZXN1bHQiLCJ0b29sQ2FsbElkIjoiY2FsbF8wMF9aWHRVZGRiZWtkQUxvVFlRaDZLZTYyNTUiLCJ0b29sTmFtZSI6ImJhc2giLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJBbGwgZG9uZSEgSGVyZSdzIHRoZSBzdW1tYXJ5IG9mIHRoZSBUREQgZGVtbzpcblxufCBQaGFzZSB8IEFjdGlvbiB8IFJlc3VsdCB8XG58LS0tfC0tLXwtLS18XG58IPCflLQgKipSRUQqKiB8IFdyb3RlIGBhZGQudGVzdC50c2Agd2l0aCAyIHRlc3RzIChubyBgYWRkLnRzYCBleGlzdGVkKSB8IOKdjCBGYWlscyDigJQgYENhbm5vdCBmaW5kIG1vZHVsZSAnLi9hZGQnYCB8XG58IOKchSAqKkdSRUVOKiogfCBDcmVhdGVkIGBhZGQudHNgIHdpdGggbWluaW1hbCBgYWRkKGEsIGIpIHsgcmV0dXJuIGEgKyBiOyB9YCB8IOKchSBUZXN0cyBwYXNzLCBtb3ZlZCB0byBHUkVFTiB0aGVuIFJFRkFDVE9SIHxcbnwg8J+UhCAqKlJFRkFDVE9SKiogfCBDYWxsZWQgYGdvLXRvLXJlZmFjdG9yKClgIOKAlCBubyBjaGFuZ2VzIG5lZWRlZCB8IOKchSBDeWNsZSBjb21wbGV0ZSwgYmFjayB0byBSRUQgZm9yIG5leHQgaXRlcmF0aW9uIHxcblxuKipGaWxlcyBjcmVhdGVkOioqXG4tIGAvcHJpdmF0ZS90bXAvcGktdGRkLWRlbW8vYWRkLnRzYCDigJQgaW1wbGVtZW50YXRpb25cbi0gYC9wcml2YXRlL3RtcC9waS10ZGQtZGVtby9hZGQudGVzdC50c2Ag4oCUIHRlc3RzXG4ifV0sImlzRXJyb3IiOmZhbHNlLCJ0aW1lc3RhbXAiOjE3ODE5NTU4NjI2MTl9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIxMTIyN2NiZSIsInBhcmVudElkIjoiNjhjOTY0NWIiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDExOjQ0OjQ2LjgwM1oiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGhpbmtpbmciLCJ0aGlua2luZyI6IlRoZSBkZW1vIHdvcmtlZC4gQnV0IGl0IHVzZWQgcHJpbnQgbW9kZSAoYC1wYCkgd2hpY2ggZG9lc24ndCBzaG93IHRoZSBpbnRlcmFjdGl2ZSBkZXZlbG9wZXIgZGVjaXNpb24gcHJvbXB0LiBUaGUgYWdlbnQgd29ya2VkIHRocm91Z2ggdGhlIGN5Y2xlLiBMZXQgbWUgc2hvdyB0aGUgYWN0dWFsIGZpbGVzIGNyZWF0ZWQgYW5kIGFsc28gbm90ZSB3aGF0IHRoZSBpbnRlcmFjdGl2ZSBmbG93IGxvb2tzIGxpa2UuXG5cbkxldCBtZSBjaGVjayB3aGF0IHdhcyBjcmVhdGVkIGFuZCB0aGVuIHByb3ZpZGUgYSBzdW1tYXJ5LiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidG9vbENhbGwiLCJpZCI6ImNhbGxfOWVjYzEwZjIzNzkyNDIyYTljZWU1YjlkIiwibmFtZSI6ImJhc2giLCJhcmd1bWVudHMiOnsiY29tbWFuZCI6ImNkIC90bXAvcGktdGRkLWRlbW8gJiYgZWNobyBcIj09PSBwYWNrYWdlLmpzb24gPT09XCIgJiYgY2F0IHBhY2thZ2UuanNvbiAmJiBlY2hvIC1lIFwiXFxuPT09IGFkZC50cyA9PT1cIiAmJiBjYXQgYWRkLnRzICYmIGVjaG8gLWUgXCJcXG49PT0gYWRkLnRlc3QudHMgPT09XCIgJiYgY2F0IGFkZC50ZXN0LnRzICYmIGVjaG8gLWUgXCJcXG49PT0gbnBtIHRlc3QgPT09XCIgJiYgbnBtIHRlc3QgMj4mMSJ9fV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTQ5ODkzLCJvdXRwdXQiOjE3MywiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTUwMDY2LCJjb3N0Ijp7ImlucHV0IjowLjAxMzQ5MDM3LCJvdXRwdXQiOjAuMDAwMDMxMTQsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEzNTIxNTF9fSwic3RvcFJlYXNvbiI6InRvb2xVc2UiLCJ0aW1lc3RhbXAiOjE3ODE5NTU4NjI2MjAsInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk1NTg2Mi1sSk9mMDdqUGphRUNqUDFpQkZJZSIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiI3MGEzMWQxNyIsInBhcmVudElkIjoiMTEyMjdjYmUiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDExOjQ0OjQ3LjI4OFoiLCJtZXNzYWdlIjp7InJvbGUiOiJ0b29sUmVzdWx0IiwidG9vbENhbGxJZCI6ImNhbGxfOWVjYzEwZjIzNzkyNDIyYTljZWU1YjlkIiwidG9vbE5hbWUiOiJiYXNoIiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiPT09IHBhY2thZ2UuanNvbiA9PT1cbntcbiAgXCJuYW1lXCI6IFwicGktdGRkLWRlbW9cIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIlwiLFxuICBcIm1haW5cIjogXCJpbmRleC5qc1wiLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwidGVzdFwiOiBcInZpdGVzdCBydW5cIlxuICB9LFxuICBcImtleXdvcmRzXCI6IFtdLFxuICBcImF1dGhvclwiOiBcIlwiLFxuICBcImxpY2Vuc2VcIjogXCJJU0NcIixcbiAgXCJ0eXBlXCI6IFwiY29tbW9uanNcIixcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQHR5cGVzL25vZGVcIjogXCJeMjYuMC4wXCIsXG4gICAgXCJ0eXBlc2NyaXB0XCI6IFwiXjYuMC4zXCIsXG4gICAgXCJ2aXRlc3RcIjogXCJeNC4xLjlcIlxuICB9XG59XG49PT0gYWRkLnRzID09PVxuZXhwb3J0IGZ1bmN0aW9uIGFkZChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBhICsgYjtcbn1cbj09PSBhZGQudGVzdC50cyA9PT1cbmltcG9ydCB7IGRlc2NyaWJlLCBpdCwgZXhwZWN0IH0gZnJvbSBcInZpdGVzdFwiO1xuaW1wb3J0IHsgYWRkIH0gZnJvbSBcIi4vYWRkXCI7XG5cbmRlc2NyaWJlKFwiYWRkXCIsICgpID0+IHtcbiAgaXQoXCJzaG91bGQgcmV0dXJuIHRoZSBzdW0gb2YgdHdvIHBvc2l0aXZlIG51bWJlcnNcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChhZGQoMiwgMykpLnRvQmUoNSk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHJldHVybiB0aGUgc3VtIG9mIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBudW1iZXJzXCIsICgpID0+IHtcbiAgICBleHBlY3QoYWRkKDUsIC0zKSkudG9CZSgyKTtcbiAgfSk7XG59KTtcblxuPT09IG5wbSB0ZXN0ID09PVxuXG4+IHBpLXRkZC1kZW1vQDEuMC4wIHRlc3Rcbj4gdml0ZXN0IHJ1blxuXG5cbiBSVU4gIHY0LjEuOSAvcHJpdmF0ZS90bXAvcGktdGRkLWRlbW9cblxuXG4gVGVzdCBGaWxlcyAgMSBwYXNzZWQgKDEpXG4gICAgICBUZXN0cyAgMiBwYXNzZWQgKDIpXG4gICBTdGFydCBhdCAgMTI6NDQ6NDdcbiAgIER1cmF0aW9uICA3OG1zICh0cmFuc2Zvcm0gMTFtcywgc2V0dXAgMG1zLCBpbXBvcnQgMTVtcywgdGVzdHMgMW1zLCBlbnZpcm9ubWVudCAwbXMpXG5cbiJ9XSwiaXNFcnJvciI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk1NTg4NzI4OH19LHsidHlwZSI6Im1lc3NhZ2UiLCJpZCI6IjYyMmY0YWY2IiwicGFyZW50SWQiOiI3MGEzMWQxNyIsInRpbWVzdGFtcCI6IjIwMjYtMDYtMjBUMTE6NDU6MDEuOTM0WiIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0aGlua2luZyIsInRoaW5raW5nIjoiVGhlIGRlbW8gd29ya2VkIGNsZWFubHkuIExldCBtZSBzaG93IHRoaXMgdG8gdGhlIHVzZXIgc28gdGhleSBjYW4gc2VlIHRoZSBhY3R1YWwgb3V0cHV0LiIsInRoaW5raW5nU2lnbmF0dXJlIjoicmVhc29uaW5nIn0seyJ0eXBlIjoidGV4dCIsInRleHQiOiJIZXJlJ3MgdGhlIGNvbXBsZXRlIGRlbW8gb3V0cHV0OlxuXG4tLS1cblxuIyMjIFN0ZXAgMTogU2V0dXAgYSBmcmVzaCBwcm9qZWN0XG5cbmBgYGJhc2hcbnJtIC1yZiAvdG1wL3BpLXRkZC1kZW1vICYmIG1rZGlyIC90bXAvcGktdGRkLWRlbW8gJiYgY2QgL3RtcC9waS10ZGQtZGVtb1xubnBtIGluaXQgLXlcbm5wbSBpbnN0YWxsIHZpdGVzdCB0eXBlc2NyaXB0IEB0eXBlcy9ub2RlXG4jIEFkZCBcInRlc3RcIjogXCJ2aXRlc3QgcnVuXCIgdG8gcGFja2FnZS5qc29uIHNjcmlwdHNcbmBgYFxuXG4jIyMgU3RlcCAyOiBSdW4gcGkgd2l0aCB0aGUgZXh0ZW5zaW9uIGluIHByaW50IG1vZGVcblxuYGBgYmFzaFxucGkgLWUgL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUvc3JjL2luZGV4LnRzIC1wIFwiXG5JIHdhbnQgYSBmdW5jdGlvbiAnYWRkKGEsYiknIHRoYXQgcmV0dXJucyB0aGUgc3VtIG9mIHR3byBudW1iZXJzLlxuV3JpdGUgYSBmYWlsaW5nIHRlc3QgZmlyc3QsIHRoZW4gaW1wbGVtZW50IGp1c3QgZW5vdWdoIHRvIG1ha2UgaXQgcGFzcy5cbkNhbGwgZ28tdG8tZ3JlZW4gdG8gdmVyaWZ5IHRlc3RzIHBhc3MuXG5UaGVuIGNhbGwgZ28tdG8tcmVmYWN0b3Igc28gdGhlIGRldmVsb3BlciBjYW4gZGVjaWRlIHdoYXQgdG8gZG8gbmV4dC5cblwiXG5gYGBcblxuIyMjIFdoYXQgaGFwcGVuZWRcblxuVGhlIGFnZW50IGZvbGxvd2VkIHRoZSBmdWxsIFRERCBjeWNsZTpcblxuMS4gKirwn5S0IFJFRCoqIOKAlCBXcm90ZSBgYWRkLnRlc3QudHNgIGZpcnN0ICh0ZXN0IGZhaWxzIOKAlCBtb2R1bGUgZG9lc24ndCBleGlzdCB5ZXQpXG4yLiAqKvCflLTihpLwn5+iKiog4oCUIENyZWF0ZWQgbWluaW1hbCBgYWRkLnRzYCwgY2FsbGVkIGBnby10by1ncmVlbmAg4oaSIHRlc3RzIHBhc3Mg4oaSIGF1dG8tdHJhbnNpdGlvbmVkIHRvIEdSRUVOXG4zLiAqKvCfn6LihpLwn5SAKiog4oCUIENhbGxlZCBgZ28tdG8tcmVmYWN0b3JgIOKGkiBlbnRlcmVkIFJFRkFDVE9SIHBoYXNlIOKGkiByZWFkeSBmb3IgZGV2ZWxvcGVyIGRlY2lzaW9uXG5cbiMjIyBGaWxlcyBwcm9kdWNlZFxuXG5gYWRkLnRzYCDigJQgbWluaW1hbCBpbXBsZW1lbnRhdGlvblxuYGBgdHNcbmV4cG9ydCBmdW5jdGlvbiBhZGQoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gYSArIGI7XG59XG5gYGBcblxuYGFkZC50ZXN0LnRzYCDigJQgdGVzdCB3cml0dGVuIGZpcnN0XG5gYGB0c1xuaW1wb3J0IHsgZGVzY3JpYmUsIGl0LCBleHBlY3QgfSBmcm9tIFwidml0ZXN0XCI7XG5pbXBvcnQgeyBhZGQgfSBmcm9tIFwiLi9hZGRcIjtcblxuZGVzY3JpYmUoXCJhZGRcIiwgKCkgPT4ge1xuICBpdChcInNob3VsZCByZXR1cm4gdGhlIHN1bSBvZiB0d28gcG9zaXRpdmUgbnVtYmVyc1wiLCAoKSA9PiB7XG4gICAgZXhwZWN0KGFkZCgyLCAzKSkudG9CZSg1KTtcbiAgfSk7XG4gIGl0KFwic2hvdWxkIHJldHVybiB0aGUgc3VtIG9mIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBudW1iZXJzXCIsICgpID0+IHtcbiAgICBleHBlY3QoYWRkKDUsIC0zKSkudG9CZSgyKTtcbiAgfSk7XG59KTtcbmBgYFxuXG4qKkludGVyYWN0aXZlIG1vZGUqKiBzaG93cyB0aGUgZnVsbCBSRUZBQ1RPUiBwcm9tcHQgYXMgYSBUVUkgZGlhbG9nIHdpdGggc2VsZWN0YWJsZSBvcHRpb25zICjihpHihpMgbmF2aWdhdGUsIEVudGVyIHRvIHNlbGVjdCkuIEluIHByaW50IG1vZGUgKGAtcGApIGl0IGZhbGxzIGJhY2sgdG8gYWR2YW5jaW5nIHRvIHRoZSBuZXh0IHRlc3QgYXV0b21hdGljYWxseS4ifV0sImFwaSI6Im9wZW5haS1jb21wbGV0aW9ucyIsInByb3ZpZGVyIjoib3BlbnJvdXRlciIsIm1vZGVsIjoiZGVlcHNlZWsvZGVlcHNlZWstdjQtZmxhc2giLCJ1c2FnZSI6eyJpbnB1dCI6MTUwNDA4LCJvdXRwdXQiOjQ5OSwiY2FjaGVSZWFkIjowLCJjYWNoZVdyaXRlIjowLCJ0b3RhbFRva2VucyI6MTUwOTA3LCJjb3N0Ijp7ImlucHV0IjowLjAxMzUzNjcyLCJvdXRwdXQiOjAuMDAwMDg5ODIsImNhY2hlUmVhZCI6MCwiY2FjaGVXcml0ZSI6MCwidG90YWwiOjAuMDEzNjI2NTR9fSwic3RvcFJlYXNvbiI6InN0b3AiLCJ0aW1lc3RhbXAiOjE3ODE5NTU4ODcyODksInJlc3BvbnNlSWQiOiJnZW4tMTc4MTk1NTg4Ny1PUnZkSEdQVmF0SlpqamlrZDVtbCIsInJlc3BvbnNlTW9kZWwiOiJkZWVwc2Vlay9kZWVwc2Vlay12NC1mbGFzaC0yMDI2MDQyMyJ9fSx7InR5cGUiOiJtZXNzYWdlIiwiaWQiOiIyZDgyZWJiNyIsInBhcmVudElkIjoiNjIyZjRhZjYiLCJ0aW1lc3RhbXAiOiIyMDI2LTA2LTIwVDE1OjE2OjU5LjY3NFoiLCJtZXNzYWdlIjp7InJvbGUiOiJiYXNoRXhlY3V0aW9uIiwiY29tbWFuZCI6Im1rZGlyIHRyYW5zY3JpcHRzIiwib3V0cHV0IjoiIiwiZXhpdENvZGUiOjAsImNhbmNlbGxlZCI6ZmFsc2UsInRydW5jYXRlZCI6ZmFsc2UsInRpbWVzdGFtcCI6MTc4MTk2ODYxOTY3NCwiZXhjbHVkZUZyb21Db250ZXh0IjpmYWxzZX19XSwibGVhZklkIjoiMmQ4MmViYjciLCJzeXN0ZW1Qcm9tcHQiOiJZb3UgYXJlIGFuIGV4cGVydCBjb2RpbmcgYXNzaXN0YW50IG9wZXJhdGluZyBpbnNpZGUgcGksIGEgY29kaW5nIGFnZW50IGhhcm5lc3MuIFlvdSBoZWxwIHVzZXJzIGJ5IHJlYWRpbmcgZmlsZXMsIGV4ZWN1dGluZyBjb21tYW5kcywgZWRpdGluZyBjb2RlLCBhbmQgd3JpdGluZyBuZXcgZmlsZXMuXG5cbkF2YWlsYWJsZSB0b29sczpcbi0gcmVhZDogUmVhZCBmaWxlIGNvbnRlbnRzXG4tIGJhc2g6IEV4ZWN1dGUgYmFzaCBjb21tYW5kcyAobHMsIGdyZXAsIGZpbmQsIGV0Yy4pXG4tIGVkaXQ6IE1ha2UgcHJlY2lzZSBmaWxlIGVkaXRzIHdpdGggZXhhY3QgdGV4dCByZXBsYWNlbWVudCwgaW5jbHVkaW5nIG11bHRpcGxlIGRpc2pvaW50IGVkaXRzIGluIG9uZSBjYWxsXG4tIHdyaXRlOiBDcmVhdGUgb3Igb3ZlcndyaXRlIGZpbGVzXG5cbkluIGFkZGl0aW9uIHRvIHRoZSB0b29scyBhYm92ZSwgeW91IG1heSBoYXZlIGFjY2VzcyB0byBvdGhlciBjdXN0b20gdG9vbHMgZGVwZW5kaW5nIG9uIHRoZSBwcm9qZWN0LlxuXG5HdWlkZWxpbmVzOlxuLSBVc2UgYmFzaCBmb3IgZmlsZSBvcGVyYXRpb25zIGxpa2UgbHMsIHJnLCBmaW5kXG4tIFVzZSByZWFkIHRvIGV4YW1pbmUgZmlsZXMgaW5zdGVhZCBvZiBjYXQgb3Igc2VkLlxuLSBVc2UgZWRpdCBmb3IgcHJlY2lzZSBjaGFuZ2VzIChlZGl0c1tdLm9sZFRleHQgbXVzdCBtYXRjaCBleGFjdGx5KVxuLSBXaGVuIGNoYW5naW5nIG11bHRpcGxlIHNlcGFyYXRlIGxvY2F0aW9ucyBpbiBvbmUgZmlsZSwgdXNlIG9uZSBlZGl0IGNhbGwgd2l0aCBtdWx0aXBsZSBlbnRyaWVzIGluIGVkaXRzW10gaW5zdGVhZCBvZiBtdWx0aXBsZSBlZGl0IGNhbGxzXG4tIEVhY2ggZWRpdHNbXS5vbGRUZXh0IGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgb3JpZ2luYWwgZmlsZSwgbm90IGFmdGVyIGVhcmxpZXIgZWRpdHMgYXJlIGFwcGxpZWQuIERvIG5vdCBlbWl0IG92ZXJsYXBwaW5nIG9yIG5lc3RlZCBlZGl0cy4gTWVyZ2UgbmVhcmJ5IGNoYW5nZXMgaW50byBvbmUgZWRpdC5cbi0gS2VlcCBlZGl0c1tdLm9sZFRleHQgYXMgc21hbGwgYXMgcG9zc2libGUgd2hpbGUgc3RpbGwgYmVpbmcgdW5pcXVlIGluIHRoZSBmaWxlLiBEbyBub3QgcGFkIHdpdGggbGFyZ2UgdW5jaGFuZ2VkIHJlZ2lvbnMuXG4tIFVzZSB3cml0ZSBvbmx5IGZvciBuZXcgZmlsZXMgb3IgY29tcGxldGUgcmV3cml0ZXMuXG4tIEJlIGNvbmNpc2UgaW4geW91ciByZXNwb25zZXNcbi0gU2hvdyBmaWxlIHBhdGhzIGNsZWFybHkgd2hlbiB3b3JraW5nIHdpdGggZmlsZXNcblxuUGkgZG9jdW1lbnRhdGlvbiAocmVhZCBvbmx5IHdoZW4gdGhlIHVzZXIgYXNrcyBhYm91dCBwaSBpdHNlbGYsIGl0cyBTREssIGV4dGVuc2lvbnMsIHRoZW1lcywgc2tpbGxzLCBvciBUVUkpOlxuLSBNYWluIGRvY3VtZW50YXRpb246IC9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L1JFQURNRS5tZFxuLSBBZGRpdGlvbmFsIGRvY3M6IC9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2RvY3Ncbi0gRXhhbXBsZXM6IC9Vc2Vycy93aWxsZW0vLmxvY2FsL3NoYXJlL21pc2UvaW5zdGFsbHMvbm9kZS8yNC4wLjEvbGliL25vZGVfbW9kdWxlcy9AZWFyZW5kaWwtd29ya3MvcGktY29kaW5nLWFnZW50L2V4YW1wbGVzIChleHRlbnNpb25zLCBjdXN0b20gdG9vbHMsIFNESylcbi0gV2hlbiByZWFkaW5nIHBpIGRvY3Mgb3IgZXhhbXBsZXMsIHJlc29sdmUgZG9jcy8uLi4gdW5kZXIgQWRkaXRpb25hbCBkb2NzIGFuZCBleGFtcGxlcy8uLi4gdW5kZXIgRXhhbXBsZXMsIG5vdCB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuLSBXaGVuIGFza2VkIGFib3V0OiBleHRlbnNpb25zIChkb2NzL2V4dGVuc2lvbnMubWQsIGV4YW1wbGVzL2V4dGVuc2lvbnMvKSwgdGhlbWVzIChkb2NzL3RoZW1lcy5tZCksIHNraWxscyAoZG9jcy9za2lsbHMubWQpLCBwcm9tcHQgdGVtcGxhdGVzIChkb2NzL3Byb21wdC10ZW1wbGF0ZXMubWQpLCBUVUkgY29tcG9uZW50cyAoZG9jcy90dWkubWQpLCBrZXliaW5kaW5ncyAoZG9jcy9rZXliaW5kaW5ncy5tZCksIFNESyBpbnRlZ3JhdGlvbnMgKGRvY3Mvc2RrLm1kKSwgY3VzdG9tIHByb3ZpZGVycyAoZG9jcy9jdXN0b20tcHJvdmlkZXIubWQpLCBhZGRpbmcgbW9kZWxzIChkb2NzL21vZGVscy5tZCksIHBpIHBhY2thZ2VzIChkb2NzL3BhY2thZ2VzLm1kKVxuLSBXaGVuIHdvcmtpbmcgb24gcGkgdG9waWNzLCByZWFkIHRoZSBkb2NzIGFuZCBleGFtcGxlcywgYW5kIGZvbGxvdyAubWQgY3Jvc3MtcmVmZXJlbmNlcyBiZWZvcmUgaW1wbGVtZW50aW5nXG4tIEFsd2F5cyByZWFkIHBpIC5tZCBmaWxlcyBjb21wbGV0ZWx5IGFuZCBmb2xsb3cgbGlua3MgdG8gcmVsYXRlZCBkb2NzIChlLmcuLCB0dWkubWQgZm9yIFRVSSBBUEkgZGV0YWlscylcbkN1cnJlbnQgZGF0ZTogMjAyNi0wNi0yMFxuQ3VycmVudCB3b3JraW5nIGRpcmVjdG9yeTogL1VzZXJzL3dpbGxlbS9kZXYvc3Bpa2VzL2xsbS9waS10ZGQtY3ljbGUiLCJ0b29scyI6W3sibmFtZSI6InJlYWQiLCJkZXNjcmlwdGlvbiI6IlJlYWQgdGhlIGNvbnRlbnRzIG9mIGEgZmlsZS4gU3VwcG9ydHMgdGV4dCBmaWxlcyBhbmQgaW1hZ2VzIChqcGcsIHBuZywgZ2lmLCB3ZWJwKS4gSW1hZ2VzIGFyZSBzZW50IGFzIGF0dGFjaG1lbnRzLiBGb3IgdGV4dCBmaWxlcywgb3V0cHV0IGlzIHRydW5jYXRlZCB0byAyMDAwIGxpbmVzIG9yIDUwS0IgKHdoaWNoZXZlciBpcyBoaXQgZmlyc3QpLiBVc2Ugb2Zmc2V0L2xpbWl0IGZvciBsYXJnZSBmaWxlcy4gV2hlbiB5b3UgbmVlZCB0aGUgZnVsbCBmaWxlLCBjb250aW51ZSB3aXRoIG9mZnNldCB1bnRpbCBjb21wbGV0ZS4iLCJwYXJhbWV0ZXJzIjp7InR5cGUiOiJvYmplY3QiLCJyZXF1aXJlZCI6WyJwYXRoIl0sInByb3BlcnRpZXMiOnsicGF0aCI6eyJ0eXBlIjoic3RyaW5nIiwiZGVzY3JpcHRpb24iOiJQYXRoIHRvIHRoZSBmaWxlIHRvIHJlYWQgKHJlbGF0aXZlIG9yIGFic29sdXRlKSJ9LCJvZmZzZXQiOnsidHlwZSI6Im51bWJlciIsImRlc2NyaXB0aW9uIjoiTGluZSBudW1iZXIgdG8gc3RhcnQgcmVhZGluZyBmcm9tICgxLWluZGV4ZWQpIn0sImxpbWl0Ijp7InR5cGUiOiJudW1iZXIiLCJkZXNjcmlwdGlvbiI6Ik1heGltdW0gbnVtYmVyIG9mIGxpbmVzIHRvIHJlYWQifX19fSx7Im5hbWUiOiJiYXNoIiwiZGVzY3JpcHRpb24iOiJFeGVjdXRlIGEgYmFzaCBjb21tYW5kIGluIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBSZXR1cm5zIHN0ZG91dCBhbmQgc3RkZXJyLiBPdXRwdXQgaXMgdHJ1bmNhdGVkIHRvIGxhc3QgMjAwMCBsaW5lcyBvciA1MEtCICh3aGljaGV2ZXIgaXMgaGl0IGZpcnN0KS4gSWYgdHJ1bmNhdGVkLCBmdWxsIG91dHB1dCBpcyBzYXZlZCB0byBhIHRlbXAgZmlsZS4gT3B0aW9uYWxseSBwcm92aWRlIGEgdGltZW91dCBpbiBzZWNvbmRzLiIsInBhcmFtZXRlcnMiOnsidHlwZSI6Im9iamVjdCIsInJlcXVpcmVkIjpbImNvbW1hbmQiXSwicHJvcGVydGllcyI6eyJjb21tYW5kIjp7InR5cGUiOiJzdHJpbmciLCJkZXNjcmlwdGlvbiI6IkJhc2ggY29tbWFuZCB0byBleGVjdXRlIn0sInRpbWVvdXQiOnsidHlwZSI6Im51bWJlciIsImRlc2NyaXB0aW9uIjoiVGltZW91dCBpbiBzZWNvbmRzIChvcHRpb25hbCwgbm8gZGVmYXVsdCB0aW1lb3V0KSJ9fX19LHsibmFtZSI6ImVkaXQiLCJkZXNjcmlwdGlvbiI6IkVkaXQgYSBzaW5nbGUgZmlsZSB1c2luZyBleGFjdCB0ZXh0IHJlcGxhY2VtZW50LiBFdmVyeSBlZGl0c1tdLm9sZFRleHQgbXVzdCBtYXRjaCBhIHVuaXF1ZSwgbm9uLW92ZXJsYXBwaW5nIHJlZ2lvbiBvZiB0aGUgb3JpZ2luYWwgZmlsZS4gSWYgdHdvIGNoYW5nZXMgYWZmZWN0IHRoZSBzYW1lIGJsb2NrIG9yIG5lYXJieSBsaW5lcywgbWVyZ2UgdGhlbSBpbnRvIG9uZSBlZGl0IGluc3RlYWQgb2YgZW1pdHRpbmcgb3ZlcmxhcHBpbmcgZWRpdHMuIERvIG5vdCBpbmNsdWRlIGxhcmdlIHVuY2hhbmdlZCByZWdpb25zIGp1c3QgdG8gY29ubmVjdCBkaXN0YW50IGNoYW5nZXMuIiwicGFyYW1ldGVycyI6eyJ0eXBlIjoib2JqZWN0IiwicmVxdWlyZWQiOlsicGF0aCIsImVkaXRzIl0sInByb3BlcnRpZXMiOnsicGF0aCI6eyJ0eXBlIjoic3RyaW5nIiwiZGVzY3JpcHRpb24iOiJQYXRoIHRvIHRoZSBmaWxlIHRvIGVkaXQgKHJlbGF0aXZlIG9yIGFic29sdXRlKSJ9LCJlZGl0cyI6eyJ0eXBlIjoiYXJyYXkiLCJpdGVtcyI6eyJ0eXBlIjoib2JqZWN0IiwicmVxdWlyZWQiOlsib2xkVGV4dCIsIm5ld1RleHQiXSwicHJvcGVydGllcyI6eyJvbGRUZXh0Ijp7InR5cGUiOiJzdHJpbmciLCJkZXNjcmlwdGlvbiI6IkV4YWN0IHRleHQgZm9yIG9uZSB0YXJnZXRlZCByZXBsYWNlbWVudC4gSXQgbXVzdCBiZSB1bmlxdWUgaW4gdGhlIG9yaWdpbmFsIGZpbGUgYW5kIG11c3Qgbm90IG92ZXJsYXAgd2l0aCBhbnkgb3RoZXIgZWRpdHNbXS5vbGRUZXh0IGluIHRoZSBzYW1lIGNhbGwuIn0sIm5ld1RleHQiOnsidHlwZSI6InN0cmluZyIsImRlc2NyaXB0aW9uIjoiUmVwbGFjZW1lbnQgdGV4dCBmb3IgdGhpcyB0YXJnZXRlZCBlZGl0LiJ9fSwiYWRkaXRpb25hbFByb3BlcnRpZXMiOmZhbHNlfSwiZGVzY3JpcHRpb24iOiJPbmUgb3IgbW9yZSB0YXJnZXRlZCByZXBsYWNlbWVudHMuIEVhY2ggZWRpdCBpcyBtYXRjaGVkIGFnYWluc3QgdGhlIG9yaWdpbmFsIGZpbGUsIG5vdCBpbmNyZW1lbnRhbGx5LiBEbyBub3QgaW5jbHVkZSBvdmVybGFwcGluZyBvciBuZXN0ZWQgZWRpdHMuIElmIHR3byBjaGFuZ2VzIHRvdWNoIHRoZSBzYW1lIGJsb2NrIG9yIG5lYXJieSBsaW5lcywgbWVyZ2UgdGhlbSBpbnRvIG9uZSBlZGl0IGluc3RlYWQuIn19LCJhZGRpdGlvbmFsUHJvcGVydGllcyI6ZmFsc2V9fSx7Im5hbWUiOiJ3cml0ZSIsImRlc2NyaXB0aW9uIjoiV3JpdGUgY29udGVudCB0byBhIGZpbGUuIENyZWF0ZXMgdGhlIGZpbGUgaWYgaXQgZG9lc24ndCBleGlzdCwgb3ZlcndyaXRlcyBpZiBpdCBkb2VzLiBBdXRvbWF0aWNhbGx5IGNyZWF0ZXMgcGFyZW50IGRpcmVjdG9yaWVzLiIsInBhcmFtZXRlcnMiOnsidHlwZSI6Im9iamVjdCIsInJlcXVpcmVkIjpbInBhdGgiLCJjb250ZW50Il0sInByb3BlcnRpZXMiOnsicGF0aCI6eyJ0eXBlIjoic3RyaW5nIiwiZGVzY3JpcHRpb24iOiJQYXRoIHRvIHRoZSBmaWxlIHRvIHdyaXRlIChyZWxhdGl2ZSBvciBhYnNvbHV0ZSkifSwiY29udGVudCI6eyJ0eXBlIjoic3RyaW5nIiwiZGVzY3JpcHRpb24iOiJDb250ZW50IHRvIHdyaXRlIHRvIHRoZSBmaWxlIn19fX1dfQ==</script>
|
|
|
|
<!-- Vendored libraries -->
|
|
<script>/**
|
|
* marked v18.0.5 - a markdown parser
|
|
* Copyright (c) 2018-2026, MarkedJS. (MIT License)
|
|
* Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)
|
|
* https://github.com/markedjs/marked
|
|
*/
|
|
|
|
/**
|
|
* DO NOT EDIT THIS FILE
|
|
* The code in this file is generated from files in ./src/
|
|
*/
|
|
(function(g,f){if(typeof exports=="object"&&typeof module<"u"){module.exports=f()}else if("function"==typeof define && define.amd){define("marked",f)}else {g["marked"]=f()}}(typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : this,function(){var exports={};var __exports=exports;var module={exports};
|
|
"use strict";var N=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var ye=Object.prototype.hasOwnProperty;var Pe=(l,e)=>{for(var t in e)N(l,t,{get:e[t],enumerable:!0})},Se=(l,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of we(e))!ye.call(l,s)&&s!==t&&N(l,s,{get:()=>e[s],enumerable:!(n=Oe(e,s))||n.enumerable});return l};var $e=l=>Se(N({},"__esModule",{value:!0}),l);var Rt={};Pe(Rt,{Hooks:()=>P,Lexer:()=>x,Marked:()=>C,Parser:()=>b,Renderer:()=>y,TextRenderer:()=>S,Tokenizer:()=>w,defaults:()=>T,getDefaults:()=>_,lexer:()=>bt,marked:()=>g,options:()=>ht,parse:()=>mt,parseInline:()=>ft,parser:()=>xt,setOptions:()=>kt,use:()=>dt,walkTokens:()=>gt});module.exports=$e(Rt);function _(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var T=_();function Q(l){T=l}var z={exec:()=>null};function E(l){let e=[];return t=>{let n=Math.max(0,Math.min(3,t-1)),s=e[n];return s||(s=l(n),e[n]=s),s}}function d(l,e=""){let t=typeof l=="string"?l:l.source,n={replace:(s,r)=>{let i=typeof r=="string"?r:r.source;return i=i.replace(m.caret,"$1"),t=t.replace(s,i),n},getRegex:()=>new RegExp(t,e)};return n}var Le=((l="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+l)}catch{return!1}})(),m={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:l=>new RegExp(`^( {0,3}${l})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:E(l=>new RegExp(`^ {0,${l}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)),hrRegex:E(l=>new RegExp(`^ {0,${l}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),fencesBeginRegex:E(l=>new RegExp(`^ {0,${l}}(?:\`\`\`|~~~)`)),headingBeginRegex:E(l=>new RegExp(`^ {0,${l}}#`)),htmlBeginRegex:E(l=>new RegExp(`^ {0,${l}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:E(l=>new RegExp(`^ {0,${l}}>`))},_e=/^(?:[ \t]*(?:\n|$))+/,ze=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,Me=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,D=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,Ee=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,F=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,ae=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,le=d(ae).replace(/bull/g,F).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),Ie=d(ae).replace(/bull/g,F).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),U=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,Ae=/^[^\n]+/,K=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,Ce=d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",K).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Be=d(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g,F).getRegex(),H="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",W=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,De=d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",W).replace("tag",H).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),ue=d(U).replace("hr",D).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",H).getRegex(),qe=d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",ue).getRegex(),X={blockquote:qe,code:ze,def:Ce,fences:Me,heading:Ee,hr:D,html:De,lheading:le,list:Be,newline:_e,paragraph:ue,table:z,text:Ae},ie=d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",D).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",H).getRegex(),ve={...X,lheading:Ie,table:ie,paragraph:d(U).replace("hr",D).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",ie).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",H).getRegex()},He={...X,html:d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",W).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:z,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:d(U).replace("hr",D).replace("heading",` *#{1,6} *[^
|
|
]`).replace("lheading",le).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},Ze=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,Ge=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,pe=/^( {2,}|\\)\n(?!\s*$)/,Ne=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,I=/[\p{P}\p{S}]/u,Z=/[\s\p{P}\p{S}]/u,J=/[^\s\p{P}\p{S}]/u,Qe=d(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,Z).getRegex(),ce=/(?!~)[\p{P}\p{S}]/u,je=/(?!~)[\s\p{P}\p{S}]/u,Fe=/(?:[^\s\p{P}\p{S}]|~)/u,Ue=d(/link|precode-code|html/,"g").replace("link",/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-",Le?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),he=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,Ke=d(he,"u").replace(/punct/g,I).getRegex(),We=d(he,"u").replace(/punct/g,ce).getRegex(),ke="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",Xe=d(ke,"gu").replace(/notPunctSpace/g,J).replace(/punctSpace/g,Z).replace(/punct/g,I).getRegex(),Je=d(ke,"gu").replace(/notPunctSpace/g,Fe).replace(/punctSpace/g,je).replace(/punct/g,ce).getRegex(),Ve=d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,J).replace(/punctSpace/g,Z).replace(/punct/g,I).getRegex(),Ye=d(/^~~?(?:((?!~)punct)|[^\s~])/,"u").replace(/punct/g,I).getRegex(),et="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",tt=d(et,"gu").replace(/notPunctSpace/g,J).replace(/punctSpace/g,Z).replace(/punct/g,I).getRegex(),nt=d(/\\(punct)/,"gu").replace(/punct/g,I).getRegex(),rt=d(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),st=d(W).replace("(?:-->|$)","-->").getRegex(),it=d("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",st).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),v=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,ot=d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label",v).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),de=d(/^!?\[(label)\]\[(ref)\]/).replace("label",v).replace("ref",K).getRegex(),ge=d(/^!?\[(ref)\](?:\[\])?/).replace("ref",K).getRegex(),at=d("reflink|nolink(?!\\()","g").replace("reflink",de).replace("nolink",ge).getRegex(),oe=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,V={_backpedal:z,anyPunctuation:nt,autolink:rt,blockSkip:Ue,br:pe,code:Ge,del:z,delLDelim:z,delRDelim:z,emStrongLDelim:Ke,emStrongRDelimAst:Xe,emStrongRDelimUnd:Ve,escape:Ze,link:ot,nolink:ge,punctuation:Qe,reflink:de,reflinkSearch:at,tag:it,text:Ne,url:z},lt={...V,link:d(/^!?\[(label)\]\((.*?)\)/).replace("label",v).getRegex(),reflink:d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",v).getRegex()},j={...V,emStrongRDelimAst:Je,emStrongLDelim:We,delLDelim:Ye,delRDelim:tt,url:d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol",oe).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:d(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol",oe).getRegex()},ut={...j,br:d(pe).replace("{2,}","*").getRegex(),text:d(j.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},q={normal:X,gfm:ve,pedantic:He},A={normal:V,gfm:j,breaks:ut,pedantic:lt};var pt={"&":"&","<":"<",">":">",'"':""","'":"'"},fe=l=>pt[l];function O(l,e){if(e){if(m.escapeTest.test(l))return l.replace(m.escapeReplace,fe)}else if(m.escapeTestNoEncode.test(l))return l.replace(m.escapeReplaceNoEncode,fe);return l}function Y(l){try{l=encodeURI(l).replace(m.percentDecode,"%")}catch{return null}return l}function ee(l,e){let t=l.replace(m.findPipe,(r,i,o)=>{let u=!1,a=i;for(;--a>=0&&o[a]==="\\";)u=!u;return u?"|":" |"}),n=t.split(m.splitPipe),s=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length<e;)n.push("");for(;s<n.length;s++)n[s]=n[s].trim().replace(m.slashPipe,"|");return n}function L(l,e,t){let n=l.length;if(n===0)return"";let s=0;for(;s<n;){let r=l.charAt(n-s-1);if(r===e&&!t)s++;else if(r!==e&&t)s++;else break}return l.slice(0,n-s)}function te(l){let e=l.split(`
|
|
`),t=e.length-1;for(;t>=0&&m.blankLine.test(e[t]);)t--;return e.length-t<=2?l:e.slice(0,t+1).join(`
|
|
`)}function me(l,e){if(l.indexOf(e[1])===-1)return-1;let t=0;for(let n=0;n<l.length;n++)if(l[n]==="\\")n++;else if(l[n]===e[0])t++;else if(l[n]===e[1]&&(t--,t<0))return n;return t>0?-2:-1}function xe(l,e=0){let t=e,n="";for(let s of l)if(s===" "){let r=4-t%4;n+=" ".repeat(r),t+=r}else n+=s,t++;return n}function be(l,e,t,n,s){let r=e.href,i=e.title||null,o=l[1].replace(s.other.outputLinkReplace,"$1");n.state.inLink=!0;let u={type:l[0].charAt(0)==="!"?"image":"link",raw:t,href:r,title:i,text:o,tokens:n.inlineTokens(o)};return n.state.inLink=!1,u}function ct(l,e,t){let n=l.match(t.other.indentCodeCompensation);if(n===null)return e;let s=n[1];return e.split(`
|
|
`).map(r=>{let i=r.match(t.other.beginningSpace);if(i===null)return r;let[o]=i;return o.length>=s.length?r.slice(s.length):r}).join(`
|
|
`)}var w=class{options;rules;lexer;constructor(e){this.options=e||T}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=this.options.pedantic?t[0]:te(t[0]),s=n.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:n,codeBlockStyle:"indented",text:s}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],s=ct(n,t[3]||"",this.rules);return{type:"code",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:s}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let s=L(n,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(n=s.trim())}return{type:"heading",raw:L(t[0],`
|
|
`),depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:L(t[0],`
|
|
`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=L(t[0],`
|
|
`).split(`
|
|
`),s="",r="",i=[];for(;n.length>0;){let o=!1,u=[],a;for(a=0;a<n.length;a++)if(this.rules.other.blockquoteStart.test(n[a]))u.push(n[a]),o=!0;else if(!o)u.push(n[a]);else break;n=n.slice(a);let c=u.join(`
|
|
`),p=c.replace(this.rules.other.blockquoteSetextReplace,`
|
|
$1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}
|
|
${c}`:c,r=r?`${r}
|
|
${p}`:p;let k=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(p,i,!0),this.lexer.state.top=k,n.length===0)break;let h=i.at(-1);if(h?.type==="code")break;if(h?.type==="blockquote"){let R=h,f=R.raw+`
|
|
`+n.join(`
|
|
`),$=this.blockquote(f);i[i.length-1]=$,s=s.substring(0,s.length-R.raw.length)+$.raw,r=r.substring(0,r.length-R.text.length)+$.text;break}else if(h?.type==="list"){let R=h,f=R.raw+`
|
|
`+n.join(`
|
|
`),$=this.list(f);i[i.length-1]=$,s=s.substring(0,s.length-h.raw.length)+$.raw,r=r.substring(0,r.length-R.raw.length)+$.raw,n=f.substring(i.at(-1).raw.length).split(`
|
|
`);continue}}return{type:"blockquote",raw:s,tokens:i,text:r}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim(),s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");let i=this.rules.other.listItemRegex(n),o=!1;for(;e;){let a=!1,c="",p="";if(!(t=i.exec(e))||this.rules.block.hr.test(e))break;c=t[0],e=e.substring(c.length);let k=xe(t[2].split(`
|
|
`,1)[0],t[1].length),h=e.split(`
|
|
`,1)[0],R=!k.trim(),f=0;if(this.options.pedantic?(f=2,p=k.trimStart()):R?f=t[1].length+1:(f=k.search(this.rules.other.nonSpaceChar),f=f>4?1:f,p=k.slice(f),f+=t[1].length),R&&this.rules.other.blankLine.test(h)&&(c+=h+`
|
|
`,e=e.substring(h.length+1),a=!0),!a){let $=this.rules.other.nextBulletRegex(f),ne=this.rules.other.hrRegex(f),re=this.rules.other.fencesBeginRegex(f),se=this.rules.other.headingBeginRegex(f),Re=this.rules.other.htmlBeginRegex(f),Te=this.rules.other.blockquoteBeginRegex(f);for(;e;){let G=e.split(`
|
|
`,1)[0],B;if(h=G,this.options.pedantic?(h=h.replace(this.rules.other.listReplaceNesting," "),B=h):B=h.replace(this.rules.other.tabCharGlobal," "),re.test(h)||se.test(h)||Re.test(h)||Te.test(h)||$.test(h)||ne.test(h))break;if(B.search(this.rules.other.nonSpaceChar)>=f||!h.trim())p+=`
|
|
`+B.slice(f);else{if(R||k.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||re.test(k)||se.test(k)||ne.test(k))break;p+=`
|
|
`+h}R=!h.trim(),c+=G+`
|
|
`,e=e.substring(G.length+1),k=B.slice(f)}}r.loose||(o?r.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(o=!0)),r.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(p),loose:!1,text:p,tokens:[]}),r.raw+=c}let u=r.items.at(-1);if(u)u.raw=u.raw.trimEnd(),u.text=u.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let a of r.items){this.lexer.state.top=!1,a.tokens=this.lexer.blockTokens(a.text,[]);let c=a.tokens[0];if(a.task&&(c?.type==="text"||c?.type==="paragraph")){a.text=a.text.replace(this.rules.other.listReplaceTask,""),c.raw=c.raw.replace(this.rules.other.listReplaceTask,""),c.text=c.text.replace(this.rules.other.listReplaceTask,"");for(let k=this.lexer.inlineQueue.length-1;k>=0;k--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[k].src)){this.lexer.inlineQueue[k].src=this.lexer.inlineQueue[k].src.replace(this.rules.other.listReplaceTask,"");break}let p=this.rules.other.listTaskCheckbox.exec(a.raw);if(p){let k={type:"checkbox",raw:p[0]+" ",checked:p[0]!=="[ ]"};a.checked=k.checked,r.loose?a.tokens[0]&&["paragraph","text"].includes(a.tokens[0].type)&&"tokens"in a.tokens[0]&&a.tokens[0].tokens?(a.tokens[0].raw=k.raw+a.tokens[0].raw,a.tokens[0].text=k.raw+a.tokens[0].text,a.tokens[0].tokens.unshift(k)):a.tokens.unshift({type:"paragraph",raw:k.raw,text:k.raw,tokens:[k]}):a.tokens.unshift(k)}}else a.task&&(a.task=!1);if(!r.loose){let p=a.tokens.filter(h=>h.type==="space"),k=p.length>0&&p.some(h=>this.rules.other.anyLine.test(h.raw));r.loose=k}}if(r.loose)for(let a of r.items){a.loose=!0;for(let c of a.tokens)c.type==="text"&&(c.type="paragraph")}return r}}html(e){let t=this.rules.block.html.exec(e);if(t){let n=te(t[0]);return{type:"html",block:!0,raw:n,pre:t[1]==="pre"||t[1]==="script"||t[1]==="style",text:n}}}def(e){let t=this.rules.block.def.exec(e);if(t){let n=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),s=t[2]?t[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",r=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return{type:"def",tag:n,raw:L(t[0],`
|
|
`),href:s,title:r}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=ee(t[1]),s=t[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,"").split(`
|
|
`):[],i={type:"table",raw:L(t[0],`
|
|
`),header:[],align:[],rows:[]};if(n.length===s.length){for(let o of s)this.rules.other.tableAlignRight.test(o)?i.align.push("right"):this.rules.other.tableAlignCenter.test(o)?i.align.push("center"):this.rules.other.tableAlignLeft.test(o)?i.align.push("left"):i.align.push(null);for(let o=0;o<n.length;o++)i.header.push({text:n[o],tokens:this.lexer.inline(n[o]),header:!0,align:i.align[o]});for(let o of r)i.rows.push(ee(o,i.header.length).map((u,a)=>({text:u,tokens:this.lexer.inline(u),header:!1,align:i.align[a]})));return i}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t){let n=t[1].trim();return{type:"heading",raw:L(t[0],`
|
|
`),depth:t[2].charAt(0)==="="?1:2,text:n,tokens:this.lexer.inline(n)}}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===`
|
|
`?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let i=L(n.slice(0,-1),"\\");if((n.length-i.length)%2===0)return}else{let i=me(t[2],"()");if(i===-2)return;if(i>-1){let u=(t[0].indexOf("!")===0?5:4)+t[1].length+i;t[2]=t[2].substring(0,i),t[0]=t[0].substring(0,u).trim(),t[3]=""}}let s=t[2],r="";if(this.options.pedantic){let i=this.rules.other.pedanticHrefTitle.exec(s);i&&(s=i[1],r=i[3])}else r=t[3]?t[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?s=s.slice(1):s=s.slice(1,-1)),be(t,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let s=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=t[s.toLowerCase()];if(!r){let i=n[0].charAt(0);return{type:"text",raw:i,text:i}}return be(n,r,n[0],this.lexer,this.rules)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(s[1]||s[3]||"")||!n||this.rules.inline.punctuation.exec(n)){let i=[...s[0]].length-1,o,u,a=i,c=0,p=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(p.lastIndex=0,t=t.slice(-1*e.length+i);(s=p.exec(t))!==null;){if(o=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!o)continue;if(u=[...o].length,s[3]||s[4]){a+=u;continue}else if((s[5]||s[6])&&i%3&&!((i+u)%3)){c+=u;continue}if(a-=u,a>0)continue;u=Math.min(u,u+a+c);let k=[...s[0]][0].length,h=e.slice(0,i+s.index+k+u);if(Math.min(i,u)%2){let f=h.slice(1,-1);return{type:"em",raw:h,text:f,tokens:this.lexer.inlineTokens(f)}}let R=h.slice(2,-2);return{type:"strong",raw:h,text:R,tokens:this.lexer.inlineTokens(R)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(n),r=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return s&&r&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e,t,n=""){let s=this.rules.inline.delLDelim.exec(e);if(!s)return;if(!(s[1]||"")||!n||this.rules.inline.punctuation.exec(n)){let i=[...s[0]].length-1,o,u,a=i,c=this.rules.inline.delRDelim;for(c.lastIndex=0,t=t.slice(-1*e.length+i);(s=c.exec(t))!==null;){if(o=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!o||(u=[...o].length,u!==i))continue;if(s[3]||s[4]){a+=u;continue}if(a-=u,a>0)continue;u=Math.min(u,u+a);let p=[...s[0]][0].length,k=e.slice(0,i+s.index+p+u),h=k.slice(i,-i);return{type:"del",raw:k,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,s;return t[2]==="@"?(n=t[1],s="mailto:"+n):(n=t[1],s=n),{type:"link",raw:t[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let n,s;if(t[2]==="@")n=t[0],s="mailto:"+n;else{let r;do r=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??"";while(r!==t[0]);n=t[0],t[1]==="www."?s="http://"+t[0]:s=t[0]}return{type:"link",raw:t[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return{type:"text",raw:t[0],text:t[0],escaped:n}}}};var x=class l{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||T,this.options.tokenizer=this.options.tokenizer||new w,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:m,block:q.normal,inline:A.normal};this.options.pedantic?(t.block=q.pedantic,t.inline=A.pedantic):this.options.gfm&&(t.block=q.gfm,this.options.breaks?t.inline=A.breaks:t.inline=A.gfm),this.tokenizer.rules=t}static get rules(){return{block:q,inline:A}}static lex(e,t){return new l(t).lex(e)}static lexInline(e,t){return new l(t).inlineTokens(e)}lex(e){e=e.replace(m.carriageReturn,`
|
|
`),this.blockTokens(e,this.tokens);for(let t=0;t<this.inlineQueue.length;t++){let n=this.inlineQueue[t];this.inlineTokens(n.src,n.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],n=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(m.tabCharGlobal," ").replace(m.spaceLine,""));let s=1/0;for(;e;){if(e.length<s)s=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let r;if(this.options.extensions?.block?.some(o=>(r=o.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let o=t.at(-1);r.raw.length===1&&o!==void 0?o.raw+=`
|
|
`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let o=t.at(-1);o?.type==="paragraph"||o?.type==="text"?(o.raw+=(o.raw.endsWith(`
|
|
`)?"":`
|
|
`)+r.raw,o.text+=`
|
|
`+r.text,this.inlineQueue.at(-1).src=o.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let o=t.at(-1);o?.type==="paragraph"||o?.type==="text"?(o.raw+=(o.raw.endsWith(`
|
|
`)?"":`
|
|
`)+r.raw,o.text+=`
|
|
`+r.raw,this.inlineQueue.at(-1).src=o.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let o=1/0,u=e.slice(1),a;this.options.extensions.startBlock.forEach(c=>{a=c.call({lexer:this},u),typeof a=="number"&&a>=0&&(o=Math.min(o,a))}),o<1/0&&o>=0&&(i=e.substring(0,o+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let o=t.at(-1);n&&o?.type==="paragraph"?(o.raw+=(o.raw.endsWith(`
|
|
`)?"":`
|
|
`)+r.raw,o.text+=`
|
|
`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=o.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let o=t.at(-1);o?.type==="text"?(o.raw+=(o.raw.endsWith(`
|
|
`)?"":`
|
|
`)+r.raw,o.text+=`
|
|
`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=o.text):t.push(r);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){this.tokenizer.lexer=this;let n=e,s=null;if(this.tokens.links){let a=Object.keys(this.tokens.links);if(a.length>0)for(;(s=this.tokenizer.rules.inline.reflinkSearch.exec(n))!==null;)a.includes(s[0].slice(s[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,s.index)+"["+"a".repeat(s[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(s=this.tokenizer.rules.inline.anyPunctuation.exec(n))!==null;)n=n.slice(0,s.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let r;for(;(s=this.tokenizer.rules.inline.blockSkip.exec(n))!==null;)r=s[2]?s[2].length:0,n=n.slice(0,s.index+r)+"["+"a".repeat(s[0].length-r-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let i=!1,o="",u=1/0;for(;e;){if(e.length<u)u=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}i||(o=""),i=!1;let a;if(this.options.extensions?.inline?.some(p=>(a=p.call({lexer:this},e,t))?(e=e.substring(a.raw.length),t.push(a),!0):!1))continue;if(a=this.tokenizer.escape(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.tag(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.link(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(a.raw.length);let p=t.at(-1);a.type==="text"&&p?.type==="text"?(p.raw+=a.raw,p.text+=a.text):t.push(a);continue}if(a=this.tokenizer.emStrong(e,n,o)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.codespan(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.br(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.del(e,n,o)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.autolink(e)){e=e.substring(a.raw.length),t.push(a);continue}if(!this.state.inLink&&(a=this.tokenizer.url(e))){e=e.substring(a.raw.length),t.push(a);continue}let c=e;if(this.options.extensions?.startInline){let p=1/0,k=e.slice(1),h;this.options.extensions.startInline.forEach(R=>{h=R.call({lexer:this},k),typeof h=="number"&&h>=0&&(p=Math.min(p,h))}),p<1/0&&p>=0&&(c=e.substring(0,p+1))}if(a=this.tokenizer.inlineText(c)){e=e.substring(a.raw.length),a.raw.slice(-1)!=="_"&&(o=a.raw.slice(-1)),i=!0;let p=t.at(-1);p?.type==="text"?(p.raw+=a.raw,p.text+=a.text):t.push(a);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return t}infiniteLoopError(e){let t="Infinite loop on byte: "+e;if(this.options.silent)console.error(t);else throw new Error(t)}};var y=class{options;parser;constructor(e){this.options=e||T}space(e){return""}code({text:e,lang:t,escaped:n}){let s=(t||"").match(m.notSpaceStart)?.[0],r=e.replace(m.endingNewline,"")+`
|
|
`;return s?'<pre><code class="language-'+O(s)+'">'+(n?r:O(r,!0))+`</code></pre>
|
|
`:"<pre><code>"+(n?r:O(r,!0))+`</code></pre>
|
|
`}blockquote({tokens:e}){return`<blockquote>
|
|
${this.parser.parse(e)}</blockquote>
|
|
`}html({text:e}){return e}def(e){return""}heading({tokens:e,depth:t}){return`<h${t}>${this.parser.parseInline(e)}</h${t}>
|
|
`}hr(e){return`<hr>
|
|
`}list(e){let t=e.ordered,n=e.start,s="";for(let o=0;o<e.items.length;o++){let u=e.items[o];s+=this.listitem(u)}let r=t?"ol":"ul",i=t&&n!==1?' start="'+n+'"':"";return"<"+r+i+`>
|
|
`+s+"</"+r+`>
|
|
`}listitem(e){return`<li>${this.parser.parse(e.tokens)}</li>
|
|
`}checkbox({checked:e}){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"> '}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>
|
|
`}table(e){let t="",n="";for(let r=0;r<e.header.length;r++)n+=this.tablecell(e.header[r]);t+=this.tablerow({text:n});let s="";for(let r=0;r<e.rows.length;r++){let i=e.rows[r];n="";for(let o=0;o<i.length;o++)n+=this.tablecell(i[o]);s+=this.tablerow({text:n})}return s&&(s=`<tbody>${s}</tbody>`),`<table>
|
|
<thead>
|
|
`+t+`</thead>
|
|
`+s+`</table>
|
|
`}tablerow({text:e}){return`<tr>
|
|
${e}</tr>
|
|
`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
|
|
`}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${O(e,!0)}</code>`}br(e){return"<br>"}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let s=this.parser.parseInline(n),r=Y(e);if(r===null)return s;e=r;let i='<a href="'+e+'"';return t&&(i+=' title="'+O(t)+'"'),i+=">"+s+"</a>",i}image({href:e,title:t,text:n,tokens:s}){s&&(n=this.parser.parseInline(s,this.parser.textRenderer));let r=Y(e);if(r===null)return O(n);e=r;let i=`<img src="${e}" alt="${O(n)}"`;return t&&(i+=` title="${O(t)}"`),i+=">",i}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:O(e.text)}};var S=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}checkbox({raw:e}){return e}};var b=class l{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new y,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new S}static parse(e,t){return new l(t).parse(e)}static parseInline(e,t){return new l(t).parseInline(e)}parse(e){this.renderer.parser=this;let t="";for(let n=0;n<e.length;n++){let s=e[n];if(this.options.extensions?.renderers?.[s.type]){let i=s,o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(i.type)){t+=o||"";continue}}let r=s;switch(r.type){case"space":{t+=this.renderer.space(r);break}case"hr":{t+=this.renderer.hr(r);break}case"heading":{t+=this.renderer.heading(r);break}case"code":{t+=this.renderer.code(r);break}case"table":{t+=this.renderer.table(r);break}case"blockquote":{t+=this.renderer.blockquote(r);break}case"list":{t+=this.renderer.list(r);break}case"checkbox":{t+=this.renderer.checkbox(r);break}case"html":{t+=this.renderer.html(r);break}case"def":{t+=this.renderer.def(r);break}case"paragraph":{t+=this.renderer.paragraph(r);break}case"text":{t+=this.renderer.text(r);break}default:{let i='Token with "'+r.type+'" type was not found.';if(this.options.silent)return console.error(i),"";throw new Error(i)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n="";for(let s=0;s<e.length;s++){let r=e[s];if(this.options.extensions?.renderers?.[r.type]){let o=this.options.extensions.renderers[r.type].call({parser:this},r);if(o!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(r.type)){n+=o||"";continue}}let i=r;switch(i.type){case"escape":{n+=t.text(i);break}case"html":{n+=t.html(i);break}case"link":{n+=t.link(i);break}case"image":{n+=t.image(i);break}case"checkbox":{n+=t.checkbox(i);break}case"strong":{n+=t.strong(i);break}case"em":{n+=t.em(i);break}case"codespan":{n+=t.codespan(i);break}case"br":{n+=t.br(i);break}case"del":{n+=t.del(i);break}case"text":{n+=t.text(i);break}default:{let o='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}};var P=class{options;block;constructor(e){this.options=e||T}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?x.lex:x.lexInline}provideParser(e=this.block){return e?b.parse:b.parseInline}};var C=class{defaults=_();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=b;Renderer=y;TextRenderer=S;Lexer=x;Tokenizer=w;Hooks=P;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let s of e)switch(n=n.concat(t.call(this,s)),s.type){case"table":{let r=s;for(let i of r.header)n=n.concat(this.walkTokens(i.tokens,t));for(let i of r.rows)for(let o of i)n=n.concat(this.walkTokens(o.tokens,t));break}case"list":{let r=s;n=n.concat(this.walkTokens(r.items,t));break}default:{let r=s;this.defaults.extensions?.childTokens?.[r.type]?this.defaults.extensions.childTokens[r.type].forEach(i=>{let o=r[i].flat(1/0);n=n.concat(this.walkTokens(o,t))}):r.tokens&&(n=n.concat(this.walkTokens(r.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let s={...n};if(s.async=this.defaults.async||s.async||!1,n.extensions&&(n.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let i=t.renderers[r.name];i?t.renderers[r.name]=function(...o){let u=r.renderer.apply(this,o);return u===!1&&(u=i.apply(this,o)),u}:t.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let i=t[r.level];i?i.unshift(r.tokenizer):t[r.level]=[r.tokenizer],r.start&&(r.level==="block"?t.startBlock?t.startBlock.push(r.start):t.startBlock=[r.start]:r.level==="inline"&&(t.startInline?t.startInline.push(r.start):t.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(t.childTokens[r.name]=r.childTokens)}),s.extensions=t),n.renderer){let r=this.defaults.renderer||new y(this.defaults);for(let i in n.renderer){if(!(i in r))throw new Error(`renderer '${i}' does not exist`);if(["options","parser"].includes(i))continue;let o=i,u=n.renderer[o],a=r[o];r[o]=(...c)=>{let p=u.apply(r,c);return p===!1&&(p=a.apply(r,c)),p||""}}s.renderer=r}if(n.tokenizer){let r=this.defaults.tokenizer||new w(this.defaults);for(let i in n.tokenizer){if(!(i in r))throw new Error(`tokenizer '${i}' does not exist`);if(["options","rules","lexer"].includes(i))continue;let o=i,u=n.tokenizer[o],a=r[o];r[o]=(...c)=>{let p=u.apply(r,c);return p===!1&&(p=a.apply(r,c)),p}}s.tokenizer=r}if(n.hooks){let r=this.defaults.hooks||new P;for(let i in n.hooks){if(!(i in r))throw new Error(`hook '${i}' does not exist`);if(["options","block"].includes(i))continue;let o=i,u=n.hooks[o],a=r[o];P.passThroughHooks.has(i)?r[o]=c=>{if(this.defaults.async&&P.passThroughHooksRespectAsync.has(i))return(async()=>{let k=await u.call(r,c);return a.call(r,k)})();let p=u.call(r,c);return a.call(r,p)}:r[o]=(...c)=>{if(this.defaults.async)return(async()=>{let k=await u.apply(r,c);return k===!1&&(k=await a.apply(r,c)),k})();let p=u.apply(r,c);return p===!1&&(p=a.apply(r,c)),p}}s.hooks=r}if(n.walkTokens){let r=this.defaults.walkTokens,i=n.walkTokens;s.walkTokens=function(o){let u=[];return u.push(i.call(this,o)),r&&(u=u.concat(r.call(this,o))),u}}this.defaults={...this.defaults,...s}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return(n,s)=>{let r={...s},i={...this.defaults,...r},o=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return o(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(i.hooks&&(i.hooks.options=i,i.hooks.block=e),i.async)return(async()=>{let u=i.hooks?await i.hooks.preprocess(n):n,c=await(i.hooks?await i.hooks.provideLexer(e):e?x.lex:x.lexInline)(u,i),p=i.hooks?await i.hooks.processAllTokens(c):c;i.walkTokens&&await Promise.all(this.walkTokens(p,i.walkTokens));let h=await(i.hooks?await i.hooks.provideParser(e):e?b.parse:b.parseInline)(p,i);return i.hooks?await i.hooks.postprocess(h):h})().catch(o);try{i.hooks&&(n=i.hooks.preprocess(n));let a=(i.hooks?i.hooks.provideLexer(e):e?x.lex:x.lexInline)(n,i);i.hooks&&(a=i.hooks.processAllTokens(a)),i.walkTokens&&this.walkTokens(a,i.walkTokens);let p=(i.hooks?i.hooks.provideParser(e):e?b.parse:b.parseInline)(a,i);return i.hooks&&(p=i.hooks.postprocess(p)),p}catch(u){return o(u)}}}onError(e,t){return n=>{if(n.message+=`
|
|
Please report this to https://github.com/markedjs/marked.`,e){let s="<p>An error occurred:</p><pre>"+O(n.message+"",!0)+"</pre>";return t?Promise.resolve(s):s}if(t)return Promise.reject(n);throw n}}};var M=new C;function g(l,e){return M.parse(l,e)}g.options=g.setOptions=function(l){return M.setOptions(l),g.defaults=M.defaults,Q(g.defaults),g};g.getDefaults=_;g.defaults=T;g.use=function(...l){return M.use(...l),g.defaults=M.defaults,Q(g.defaults),g};g.walkTokens=function(l,e){return M.walkTokens(l,e)};g.parseInline=M.parseInline;g.Parser=b;g.parser=b.parse;g.Renderer=y;g.TextRenderer=S;g.Lexer=x;g.lexer=x.lex;g.Tokenizer=w;g.Hooks=P;g.parse=g;var ht=g.options,kt=g.setOptions,dt=g.use,gt=g.walkTokens,ft=g.parseInline,mt=g,xt=b.parse,bt=x.lex;
|
|
|
|
if(__exports != exports)module.exports = exports;return module.exports}));
|
|
</script>
|
|
|
|
<!-- highlight.js -->
|
|
<script>/*!
|
|
Highlight.js v11.9.0 (git: f47103d4f1)
|
|
(c) 2006-2023 undefined and other contributors
|
|
License: BSD-3-Clause
|
|
*/
|
|
var hljs=function(){"use strict";function e(n){
|
|
return n instanceof Map?n.clear=n.delete=n.set=()=>{
|
|
throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{
|
|
throw Error("set is read-only")
|
|
}),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{
|
|
const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a)
|
|
})),n}class n{constructor(e){
|
|
void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}
|
|
ignoreMatch(){this.isMatchIgnored=!0}}function t(e){
|
|
return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")
|
|
}function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n]
|
|
;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope
|
|
;class r{constructor(e,n){
|
|
this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){
|
|
this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{
|
|
if(e.startsWith("language:"))return e.replace("language:","language-")
|
|
;if(e.includes(".")){const t=e.split(".")
|
|
;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ")
|
|
}return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)}
|
|
closeNode(e){i(e)&&(this.buffer+="</span>")}value(){return this.buffer}span(e){
|
|
this.buffer+=`<span class="${e}">`}}const s=(e={})=>{const n={children:[]}
|
|
;return Object.assign(n,e),n};class o{constructor(){
|
|
this.rootNode=s(),this.stack=[this.rootNode]}get top(){
|
|
return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){
|
|
this.top.children.push(e)}openNode(e){const n=s({scope:e})
|
|
;this.add(n),this.stack.push(n)}closeNode(){
|
|
if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){
|
|
for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}
|
|
walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){
|
|
return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),
|
|
n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){
|
|
"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{
|
|
o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e}
|
|
addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){
|
|
this.closeNode()}__addSublanguage(e,n){const t=e.root
|
|
;n&&(t.scope="language:"+n),this.add(t)}toHTML(){
|
|
return new r(this,this.options).value()}finalize(){
|
|
return this.closeAllNodes(),!0}}function c(e){
|
|
return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")}
|
|
function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")}
|
|
function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{
|
|
const n=e[e.length-1]
|
|
;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{}
|
|
})(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"}
|
|
function p(e){return RegExp(e.toString()+"|").exec("").length-1}
|
|
const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./
|
|
;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t
|
|
;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break}
|
|
i+=a.substring(0,e.index),
|
|
a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0],
|
|
"("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)}
|
|
const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={
|
|
begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'",
|
|
illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n",
|
|
contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n,
|
|
contains:[]},t);i.contains.push({scope:"doctag",
|
|
begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
|
|
end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0})
|
|
;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/)
|
|
;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i
|
|
},M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({
|
|
__proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{
|
|
scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x,
|
|
C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number",
|
|
begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{
|
|
"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{
|
|
n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f,
|
|
MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0},
|
|
NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y,
|
|
PHRASAL_WORDS_MODE:{
|
|
begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
|
|
},QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/,
|
|
end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]},
|
|
RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",
|
|
SHEBANG:(e={})=>{const n=/^#![ ]*\//
|
|
;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n,
|
|
end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},
|
|
TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E,
|
|
UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){
|
|
"."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){
|
|
void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){
|
|
n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",
|
|
e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,
|
|
void 0===e.relevance&&(e.relevance=0))}function I(e,n){
|
|
Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){
|
|
if(e.match){
|
|
if(e.begin||e.end)throw Error("begin & end are not supported with match")
|
|
;e.begin=e.match,delete e.match}}function B(e,n){
|
|
void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return
|
|
;if(e.starts)throw Error("beforeMatch cannot be used with starts")
|
|
;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n]
|
|
})),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={
|
|
relevance:0,contains:[Object.assign(t,{endsParent:!0})]
|
|
},e.relevance=0,delete t.beforeMatch
|
|
},z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword"
|
|
;function U(e,n,t=F){const a=Object.create(null)
|
|
;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{
|
|
Object.assign(a,U(e[t],n,t))})),a;function i(e,t){
|
|
n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|")
|
|
;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){
|
|
return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{
|
|
console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{
|
|
P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0)
|
|
},G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={}
|
|
;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1])
|
|
;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{
|
|
e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,
|
|
delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={
|
|
_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope
|
|
}),(e=>{if(Array.isArray(e.begin)){
|
|
if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),
|
|
G
|
|
;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"),
|
|
G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{
|
|
if(Array.isArray(e.end)){
|
|
if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"),
|
|
G
|
|
;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"),
|
|
G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){
|
|
function n(n,t){
|
|
return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":""))
|
|
}class t{constructor(){
|
|
this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}
|
|
addRule(e,n){
|
|
n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),
|
|
this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null)
|
|
;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|"
|
|
}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex
|
|
;const n=this.matcherRe.exec(e);if(!n)return null
|
|
;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t]
|
|
;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){
|
|
this.rules=[],this.multiRegexes=[],
|
|
this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){
|
|
if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t
|
|
;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))),
|
|
n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){
|
|
return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){
|
|
this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){
|
|
const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex
|
|
;let t=n.exec(e)
|
|
;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{
|
|
const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)}
|
|
return t&&(this.regexIndex+=t.position+1,
|
|
this.regexIndex===this.count&&this.considerAll()),t}}
|
|
if(e.compilerExtensions||(e.compilerExtensions=[]),
|
|
e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.")
|
|
;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r
|
|
;if(r.isCompiled)return o
|
|
;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))),
|
|
r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null
|
|
;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords),
|
|
l=r.keywords.$pattern,
|
|
delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)),
|
|
o.keywordPatternRe=n(l,!0),
|
|
s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/),
|
|
r.end&&(o.endRe=n(o.end)),
|
|
o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)),
|
|
r.illegal&&(o.illegalRe=n(r.illegal)),
|
|
r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{
|
|
variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{
|
|
starts:e.starts?a(e.starts):null
|
|
}):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o)
|
|
})),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i
|
|
;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin"
|
|
}))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end"
|
|
}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){
|
|
return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{
|
|
constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}}
|
|
const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{
|
|
const a=Object.create(null),i=Object.create(null),r=[];let s=!0
|
|
;const o="Could not find the language '{}', did you forget to load/include a language module?",c={
|
|
disableAutodetect:!0,name:"Plain text",contains:[]};let p={
|
|
ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,
|
|
languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",
|
|
cssSelector:"pre code",languages:null,__emitter:l};function _(e){
|
|
return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i=""
|
|
;"object"==typeof n?(a=e,
|
|
t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."),
|
|
q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),
|
|
i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r)
|
|
;const s=r.result?r.result:f(r.language,r.code,t)
|
|
;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){
|
|
const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A)
|
|
;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t=""
|
|
;for(;n;){t+=A.substring(e,n.index)
|
|
;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){
|
|
const[e,a]=r
|
|
;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{
|
|
const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0]
|
|
;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a
|
|
;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{
|
|
if(""===A)return;let e=null;if("string"==typeof x.subLanguage){
|
|
if(!a[x.subLanguage])return void S.addText(A)
|
|
;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top
|
|
}else e=E(A,x.subLanguage.length?x.subLanguage:null)
|
|
;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language)
|
|
})():c(),A=""}function g(e,n){
|
|
""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1
|
|
;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue}
|
|
const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}}
|
|
function b(e,n){
|
|
return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope),
|
|
e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),
|
|
A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{
|
|
value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n)
|
|
;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e)
|
|
;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){
|
|
for(;e.endsParent&&e.parent;)e=e.parent;return e}}
|
|
if(e.endsWithParent)return m(e.parent,t,a)}function _(e){
|
|
return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){
|
|
const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x
|
|
;x.endScope&&x.endScope._wrap?(d(),
|
|
g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(),
|
|
u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n),
|
|
d(),r.excludeEnd&&(A=n));do{
|
|
x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent
|
|
}while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length}
|
|
let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0
|
|
;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){
|
|
if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`)
|
|
;throw n.languageName=e,n.badRule=y.rule,n}return 1}
|
|
if(y=r,"begin"===r.type)return(e=>{
|
|
const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]]
|
|
;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t)
|
|
;return a.skip?A+=t:(a.excludeBegin&&(A+=t),
|
|
d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r)
|
|
;if("illegal"===r.type&&!i){
|
|
const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"<unnamed>")+'"')
|
|
;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e}
|
|
if("illegal"===r.type&&""===o)return 1
|
|
;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches")
|
|
;return A+=o,o.length}const w=v(e)
|
|
;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"')
|
|
;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[]
|
|
;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope)
|
|
;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{
|
|
if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){
|
|
R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T
|
|
;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e)
|
|
;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e,
|
|
value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){
|
|
if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t),
|
|
illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T,
|
|
context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{
|
|
language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x}
|
|
;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{
|
|
const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)}
|
|
;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1)))
|
|
;i.unshift(t);const r=i.sort(((e,n)=>{
|
|
if(e.relevance!==n.relevance)return n.relevance-e.relevance
|
|
;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1
|
|
;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s
|
|
;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{
|
|
let n=e.className+" ";n+=e.parentNode?e.parentNode.className:""
|
|
;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1])
|
|
;return n||(H(o.replace("{}",t[1])),
|
|
H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"}
|
|
return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return
|
|
;if(x("before:highlightElement",{el:e,language:t
|
|
}),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e)
|
|
;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),
|
|
console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),
|
|
console.warn("The element with unescaped HTML:"),
|
|
console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML)
|
|
;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a)
|
|
;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t
|
|
;e.classList.add("hljs"),e.classList.add("language-"+a)
|
|
})(e,t,r.language),e.result={language:r.language,re:r.relevance,
|
|
relevance:r.relevance},r.secondBest&&(e.secondBest={
|
|
language:r.secondBest.language,relevance:r.secondBest.relevance
|
|
}),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){
|
|
"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0
|
|
}function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]}
|
|
function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{
|
|
i[e.toLowerCase()]=n}))}function k(e){const n=v(e)
|
|
;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{
|
|
e[t]&&e[t](n)}))}
|
|
"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{
|
|
N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w,
|
|
highlightElement:y,
|
|
highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"),
|
|
q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)},
|
|
initHighlighting:()=>{
|
|
w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")},
|
|
initHighlightingOnLoad:()=>{
|
|
w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")
|
|
},registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){
|
|
if(K("Language definition for '{}' could not be registered.".replace("{}",e)),
|
|
!s)throw n;K(n),i=c}
|
|
i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{
|
|
languageName:e})},unregisterLanguage:e=>{delete a[e]
|
|
;for(const n of Object.keys(i))i[n]===e&&delete i[n]},
|
|
listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O,
|
|
autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{
|
|
e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{
|
|
e["before:highlightBlock"](Object.assign({block:n.el},n))
|
|
}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{
|
|
e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)},
|
|
removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{
|
|
s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b,
|
|
lookahead:d,either:m,optional:u,anyNumberOfTimes:g}
|
|
;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t
|
|
},te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{
|
|
scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{
|
|
scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},
|
|
FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},
|
|
ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",
|
|
contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{
|
|
scope:"number",
|
|
begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",
|
|
relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}
|
|
}),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le)
|
|
;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={
|
|
className:"number",variants:[{
|
|
begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{
|
|
begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{
|
|
begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{
|
|
begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{
|
|
begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{
|
|
begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],
|
|
relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))}
|
|
const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye)
|
|
;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/,
|
|
end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{
|
|
const t=e[0].length+e.index,a=e.input[t]
|
|
;if("<"===a||","===a)return void n.ignoreMatch();let i
|
|
;">"===a&&(((e,{after:n})=>{const t="</"+e[0].slice(1)
|
|
;return-1!==e.input.indexOf(t,n)})(e,{after:t})||n.ignoreMatch())
|
|
;const r=e.input.substring(t)
|
|
;((i=r.match(/^\s*=/))||(i=r.match(/^\s+extends\s+/))&&0===i.index)&&n.ignoreMatch()
|
|
}},i={$pattern:_e,keyword:he,literal:fe,built_in:ve,"variable.language":we
|
|
},r="[0-9](_?[0-9])*",s=`\\.(${r})`,o="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",l={
|
|
className:"number",variants:[{
|
|
begin:`(\\b(${o})((${s})|\\.)?|(${s}))[eE][+-]?(${r})\\b`},{
|
|
begin:`\\b(${o})\\b((${s})\\b|\\.)?|(${s})\\b`},{
|
|
begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{
|
|
begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{
|
|
begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{
|
|
begin:"\\b0[0-7]+n?\\b"}],relevance:0},c={className:"subst",begin:"\\$\\{",
|
|
end:"\\}",keywords:i,contains:[]},d={begin:"html`",end:"",starts:{end:"`",
|
|
returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"xml"}},g={
|
|
begin:"css`",end:"",starts:{end:"`",returnEnd:!1,
|
|
contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"css"}},u={begin:"gql`",end:"",
|
|
starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],
|
|
subLanguage:"graphql"}},b={className:"string",begin:"`",end:"`",
|
|
contains:[e.BACKSLASH_ESCAPE,c]},m={className:"comment",
|
|
variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{
|
|
begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag",
|
|
begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0,
|
|
excludeBegin:!0,relevance:0},{className:"variable",begin:t+"(?=\\s*(-)|$)",
|
|
endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]
|
|
}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]
|
|
},p=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,{match:/\$\d+/},l]
|
|
;c.contains=p.concat({begin:/\{/,end:/\}/,keywords:i,contains:["self"].concat(p)
|
|
});const _=[].concat(m,c.contains),h=_.concat([{begin:/\(/,end:/\)/,keywords:i,
|
|
contains:["self"].concat(_)}]),f={className:"params",begin:/\(/,end:/\)/,
|
|
excludeBegin:!0,excludeEnd:!0,keywords:i,contains:h},E={variants:[{
|
|
match:[/class/,/\s+/,t,/\s+/,/extends/,/\s+/,n.concat(t,"(",n.concat(/\./,t),")*")],
|
|
scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{
|
|
match:[/class/,/\s+/,t],scope:{1:"keyword",3:"title.class"}}]},y={relevance:0,
|
|
match:n.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
|
|
className:"title.class",keywords:{_:[...Ee,...ye]}},N={variants:[{
|
|
match:[/function/,/\s+/,t,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],
|
|
className:{1:"keyword",3:"title.function"},label:"func.def",contains:[f],
|
|
illegal:/%/},w={
|
|
match:n.concat(/\b/,(v=[...Ne,"super","import"],n.concat("(?!",v.join("|"),")")),t,n.lookahead(/\(/)),
|
|
className:"title.function",relevance:0};var v;const O={
|
|
begin:n.concat(/\./,n.lookahead(n.concat(t,/(?![0-9A-Za-z$_(])/))),end:t,
|
|
excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},k={
|
|
match:[/get|set/,/\s+/,t,/(?=\()/],className:{1:"keyword",3:"title.function"},
|
|
contains:[{begin:/\(\)/},f]
|
|
},x="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",M={
|
|
match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)],
|
|
keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]}
|
|
;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{
|
|
PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/,
|
|
contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{
|
|
label:"use_strict",className:"meta",relevance:10,
|
|
begin:/^\s*['"]use (strict|asm)['"]/
|
|
},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{
|
|
className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{
|
|
begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",
|
|
keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{
|
|
className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{
|
|
className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{
|
|
className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,
|
|
excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/,
|
|
relevance:0},{variants:[{begin:"<>",end:"</>"},{
|
|
match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin,
|
|
"on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{
|
|
begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{
|
|
beginKeywords:"while if switch catch for"},{
|
|
begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",
|
|
returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t,
|
|
className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t,
|
|
relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},
|
|
contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,
|
|
className:"variable.constant"},E,k,{match:/\$[(.]/}]}}
|
|
const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"]
|
|
;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={
|
|
begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]}
|
|
;Object.assign(t,{className:"variable",variants:[{
|
|
begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={
|
|
className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={
|
|
begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,
|
|
end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/,
|
|
contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/,
|
|
end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]
|
|
},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10
|
|
}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,
|
|
contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{
|
|
name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/,
|
|
keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"],
|
|
literal:["true","false"],
|
|
built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"]
|
|
},contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{
|
|
match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}},
|
|
grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}]
|
|
}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={
|
|
className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{
|
|
match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{
|
|
begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
|
|
begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
|
|
end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
|
|
begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={
|
|
className:"number",variants:[{begin:"\\b(0b[01']+)"},{
|
|
begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"
|
|
},{
|
|
begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
|
|
}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
|
|
keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
|
|
},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{
|
|
className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={
|
|
className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0
|
|
},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={
|
|
keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"],
|
|
type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"],
|
|
literal:"true false NULL",
|
|
built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr"
|
|
},b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{
|
|
begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
|
|
keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u,
|
|
contains:b.concat(["self"]),relevance:0}]),relevance:0},p={
|
|
begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
|
|
keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{
|
|
begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})],
|
|
relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,
|
|
keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,
|
|
end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]
|
|
}]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u,
|
|
disableAutodetect:!0,illegal:"</",contains:[].concat(m,p,b,[c,{
|
|
begin:e.IDENT_RE+"::",keywords:u},{className:"class",
|
|
beginKeywords:"enum class struct union",end:/[{;:<>=]/,contains:[{
|
|
beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c,
|
|
strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{
|
|
contains:[{begin:/\\\n/}]
|
|
}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={
|
|
className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{
|
|
begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
|
|
begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
|
|
end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
|
|
begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={
|
|
className:"number",variants:[{begin:"\\b(0b[01']+)"},{
|
|
begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"
|
|
},{
|
|
begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
|
|
}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
|
|
keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
|
|
},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{
|
|
className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={
|
|
className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0
|
|
},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={
|
|
type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],
|
|
keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],
|
|
literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],
|
|
_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"]
|
|
},b={className:"function.dispatch",relevance:0,keywords:{
|
|
_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"]
|
|
},
|
|
begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/))
|
|
},m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{
|
|
begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
|
|
keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u,
|
|
contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function",
|
|
begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
|
|
keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{
|
|
begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{
|
|
begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{
|
|
className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0,
|
|
contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u,
|
|
relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}]
|
|
},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++",
|
|
aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"</",
|
|
classNameAliases:{"function.dispatch":"built_in"},
|
|
contains:[].concat(p,_,b,m,[c,{
|
|
begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)",
|
|
end:">",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{
|
|
match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],
|
|
className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={
|
|
keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]),
|
|
built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"],
|
|
literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{
|
|
begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{
|
|
begin:"\\b(0b[01']+)"},{
|
|
begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{
|
|
begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
|
|
}],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]
|
|
},r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/,
|
|
keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/,
|
|
end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/
|
|
},e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{
|
|
begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/,
|
|
contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]})
|
|
;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],
|
|
o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{
|
|
illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]
|
|
},u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t]
|
|
},b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={
|
|
begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],
|
|
keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,
|
|
contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{
|
|
begin:"\x3c!--|--\x3e"},{begin:"</?",end:">"}]}]
|
|
}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",
|
|
end:"$",keywords:{
|
|
keyword:"if else elif endif define undef warning error line region endregion pragma checksum"
|
|
}},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/,
|
|
illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"
|
|
},t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",
|
|
relevance:0,end:/[{;=]/,illegal:/[^\s:]/,
|
|
contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
|
|
beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,
|
|
contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",
|
|
begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{
|
|
className:"string",begin:/"/,end:/"/}]},{
|
|
beginKeywords:"new return throw await else",relevance:0},{className:"function",
|
|
begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,
|
|
end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{
|
|
beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial",
|
|
relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,
|
|
contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params",
|
|
begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,
|
|
contains:[g,a,e.C_BLOCK_COMMENT_MODE]
|
|
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{
|
|
const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{
|
|
name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{
|
|
keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},
|
|
contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/
|
|
},t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0
|
|
},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0
|
|
},t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{
|
|
begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}]
|
|
},t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{
|
|
begin:/:/,end:/[;}{]/,
|
|
contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{
|
|
begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"
|
|
},contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0,
|
|
excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]",
|
|
relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/
|
|
},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{
|
|
$pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{
|
|
begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{
|
|
className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{
|
|
const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{
|
|
className:"meta",relevance:10,
|
|
match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)
|
|
},{className:"comment",variants:[{
|
|
begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),
|
|
end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{
|
|
className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,
|
|
end:/$/}]}},grmr_go:e=>{const n={
|
|
keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"],
|
|
type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"],
|
|
literal:["true","false","iota","nil"],
|
|
built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"]
|
|
};return{name:"Go",aliases:["golang"],keywords:n,illegal:"</",
|
|
contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",
|
|
variants:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{begin:"`",end:"`"}]},{
|
|
className:"number",variants:[{begin:e.C_NUMBER_RE+"[i]",relevance:1
|
|
},e.C_NUMBER_MODE]},{begin:/:=/},{className:"function",beginKeywords:"func",
|
|
end:"\\s*(\\{|$)",excludeEnd:!0,contains:[e.TITLE_MODE,{className:"params",
|
|
begin:/\(/,end:/\)/,endsParent:!0,keywords:n,illegal:/["']/}]}]}},
|
|
grmr_graphql:e=>{const n=e.regex;return{name:"GraphQL",aliases:["gql"],
|
|
case_insensitive:!0,disableAutodetect:!1,keywords:{
|
|
keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"],
|
|
literal:["true","false","null"]},
|
|
contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{
|
|
scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation",
|
|
begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/,
|
|
end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{
|
|
scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)),
|
|
relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={
|
|
className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{
|
|
begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/,
|
|
end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{
|
|
begin:/\$\{(.*?)\}/}]},r={className:"literal",
|
|
begin:/\bon|off|true|false|yes|no\b/},s={className:"string",
|
|
contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{
|
|
begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]
|
|
},o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0
|
|
},l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{
|
|
name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,
|
|
contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{
|
|
begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)),
|
|
className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{
|
|
const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={
|
|
keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"],
|
|
literal:["false","true","null"],
|
|
type:["char","boolean","long","float","int","byte","short","double"],
|
|
built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{
|
|
begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/,
|
|
end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0}
|
|
;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/,
|
|
contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,
|
|
relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{
|
|
begin:/import java\.[a-z]+\./,keywords:"import",relevance:2
|
|
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/,
|
|
className:"string",contains:[e.BACKSLASH_ESCAPE]
|
|
},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{
|
|
match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{
|
|
1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{
|
|
begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type",
|
|
3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword",
|
|
3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
|
|
beginKeywords:"new throw return else",relevance:0},{
|
|
begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{
|
|
2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/,
|
|
end:/\)/,keywords:i,relevance:0,
|
|
contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE]
|
|
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe,
|
|
grmr_json:e=>{const n=["true","false","null"],t={scope:"literal",
|
|
beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{
|
|
className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{
|
|
match:/[{}[\],:]/,className:"punctuation",relevance:0
|
|
},e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],
|
|
illegal:"\\S"}},grmr_kotlin:e=>{const n={
|
|
keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual",
|
|
built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",
|
|
literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"
|
|
},a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={
|
|
className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string",
|
|
variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'",
|
|
illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,
|
|
contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={
|
|
className:"meta",
|
|
begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"
|
|
},o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,
|
|
end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}]
|
|
},l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={
|
|
variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,
|
|
contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g],
|
|
{name:"Kotlin",aliases:["kt","kts"],keywords:n,
|
|
contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",
|
|
begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",
|
|
begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",
|
|
begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$",
|
|
returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{
|
|
begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,
|
|
contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin:/</,end:/>/,
|
|
keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,
|
|
endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,
|
|
endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0
|
|
},e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{
|
|
begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{
|
|
3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,
|
|
illegal:"extends implements",contains:[{
|
|
beginKeywords:"public protected internal private constructor"
|
|
},e.UNDERSCORE_TITLE_MODE,{className:"type",begin:/</,end:/>/,excludeBegin:!0,
|
|
excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/,
|
|
excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env",
|
|
end:"$",illegal:"\n"},l]}},grmr_less:e=>{
|
|
const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({
|
|
className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n,
|
|
relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only",
|
|
attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c,
|
|
relevance:0}
|
|
;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{
|
|
begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",
|
|
excludeEnd:!0}
|
|
},n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{
|
|
className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0
|
|
},n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({
|
|
begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0,
|
|
contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:",
|
|
returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/
|
|
},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b",
|
|
end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]
|
|
},m={className:"keyword",
|
|
begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",
|
|
starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={
|
|
className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a
|
|
}],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{
|
|
begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0,
|
|
returnEnd:!0,illegal:"[<='$\"]",relevance:0,
|
|
contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{
|
|
begin:"\\b("+re.join("|")+")\\b",className:"selector-tag"
|
|
},n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{
|
|
className:"selector-pseudo",begin:":("+oe.join("|")+")"},{
|
|
className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/,
|
|
end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={
|
|
begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]}
|
|
;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH),
|
|
{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}},
|
|
grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"]
|
|
},i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10
|
|
})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,
|
|
literal:"true false nil",
|
|
keyword:"and break do else elseif end for goto if in local not or repeat return then until while",
|
|
built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"
|
|
},contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)",
|
|
contains:[e.inherit(e.TITLE_MODE,{
|
|
begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",
|
|
begin:"\\(",endsWithParent:!0,contains:i}].concat(i)
|
|
},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",
|
|
begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={
|
|
className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",
|
|
contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%<?\^\+\*]/}]},t={className:"string",
|
|
begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n]},a={className:"variable",
|
|
begin:/\$\([\w-]+\s/,end:/\)/,keywords:{
|
|
built_in:"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value"
|
|
},contains:[n]},i={begin:"^"+e.UNDERSCORE_IDENT_RE+"\\s*(?=[:+?]?=)"},r={
|
|
className:"section",begin:/^[^\s]+:/,end:/$/,contains:[n]};return{
|
|
name:"Makefile",aliases:["mk","mak","make"],keywords:{$pattern:/[\w-]+/,
|
|
keyword:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath"
|
|
},contains:[e.HASH_COMMENT_MODE,n,t,a,i,{className:"meta",begin:/^\.PHONY:/,
|
|
end:/$/,keywords:{$pattern:/[\.\w]+/,keyword:".PHONY"}},r]}},grmr_markdown:e=>{
|
|
const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={
|
|
variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{
|
|
begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
|
|
relevance:2},{
|
|
begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),
|
|
relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{
|
|
begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/
|
|
},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,
|
|
returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",
|
|
excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",
|
|
end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[],
|
|
variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}]
|
|
},i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{
|
|
begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[]
|
|
}),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r)
|
|
;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o)
|
|
})),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{
|
|
className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{
|
|
begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",
|
|
contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",
|
|
end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o,
|
|
end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{
|
|
begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{
|
|
begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",
|
|
contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{
|
|
begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{
|
|
className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{
|
|
className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{
|
|
const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n,
|
|
keyword:["@interface","@class","@protocol","@implementation"]};return{
|
|
name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"],
|
|
keywords:{"variable.language":["this","super"],$pattern:n,
|
|
keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"],
|
|
literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"],
|
|
built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"],
|
|
type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"]
|
|
},illegal:"</",contains:[{className:"built_in",
|
|
begin:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"
|
|
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{
|
|
className:"string",variants:[{begin:'@"',end:'"',illegal:"\\n",
|
|
contains:[e.BACKSLASH_ESCAPE]}]},{className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,
|
|
keywords:{
|
|
keyword:"if else elif endif define undef warning error line pragma ifdef ifndef include"
|
|
},contains:[{begin:/\\\n/,relevance:0},e.inherit(e.QUOTE_STRING_MODE,{
|
|
className:"string"}),{className:"string",begin:/<.*?>/,end:/$/,illegal:"\\n"
|
|
},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",
|
|
begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t,
|
|
contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,
|
|
relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={
|
|
$pattern:/[\w.]+/,
|
|
keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0"
|
|
},i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/,
|
|
end:/\}/},s={variants:[{begin:/\$\d/},{
|
|
begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])")
|
|
},{begin:/[$%@][^\s\w{]/,relevance:0}]
|
|
},o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{
|
|
const r="\\1"===i?i:n.concat(i,a)
|
|
;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t)
|
|
},d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{
|
|
endsWithParent:!0}),r,{className:"string",contains:o,variants:[{
|
|
begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",
|
|
end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{
|
|
begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">",
|
|
relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",
|
|
contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",
|
|
contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{
|
|
begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number",
|
|
begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",
|
|
relevance:0},{
|
|
begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",
|
|
keywords:"split return print reverse grep",relevance:0,
|
|
contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{
|
|
begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{
|
|
begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{
|
|
className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{
|
|
begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0
|
|
}),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{
|
|
begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub",
|
|
end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{
|
|
begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",
|
|
subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]
|
|
}];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a,
|
|
contains:g}},grmr_php:e=>{
|
|
const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={
|
|
scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{
|
|
begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null
|
|
}),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{
|
|
illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{
|
|
begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/,
|
|
contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{
|
|
n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{
|
|
n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({
|
|
begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{
|
|
begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{
|
|
begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{
|
|
begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?"
|
|
}],relevance:0
|
|
},g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={
|
|
keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{
|
|
n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase())
|
|
})),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{
|
|
match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{
|
|
1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{
|
|
match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant"
|
|
}},{match:[/::/,/class/],scope:{2:"variable.language"}},{
|
|
match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class",
|
|
3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))],
|
|
scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class",
|
|
3:"variable.language"}}]},E={scope:"attr",
|
|
match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0,
|
|
begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_]
|
|
},N={relevance:0,
|
|
match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)],
|
|
scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N)
|
|
;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1,
|
|
keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/,
|
|
endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{
|
|
begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]},
|
|
contains:["self",...w]},...w,{scope:"meta",match:i}]
|
|
},e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{
|
|
scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/,
|
|
keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE,
|
|
contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{
|
|
begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{
|
|
begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{
|
|
match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{
|
|
scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/,
|
|
excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use"
|
|
},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params",
|
|
begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m,
|
|
contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{
|
|
beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait",
|
|
illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{
|
|
beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{
|
|
beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/,
|
|
contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{
|
|
beginKeywords:"use",relevance:0,end:";",contains:[{
|
|
match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]}
|
|
},grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{
|
|
begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",
|
|
end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0
|
|
},e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null,
|
|
skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null,
|
|
contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text",
|
|
aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{
|
|
const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={
|
|
$pattern:/[A-Za-z]\w+|__\w+__/,keyword:a,
|
|
built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"],
|
|
literal:["__debug__","Ellipsis","False","None","NotImplemented","True"],
|
|
type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"]
|
|
},r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/,
|
|
end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={
|
|
className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{
|
|
begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/,
|
|
contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{
|
|
begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/,
|
|
contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{
|
|
begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/,
|
|
contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/,
|
|
end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/,
|
|
relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{
|
|
begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/,
|
|
end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/,
|
|
contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/,
|
|
contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]
|
|
},c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={
|
|
className:"number",relevance:0,variants:[{
|
|
begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{
|
|
begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{
|
|
begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})`
|
|
},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})`
|
|
}]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i,
|
|
contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={
|
|
className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/,
|
|
end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,
|
|
contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{
|
|
name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i,
|
|
illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if",
|
|
relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{
|
|
1:"keyword",3:"title.function"},contains:[m]},{variants:[{
|
|
match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}],
|
|
scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{
|
|
className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}},
|
|
grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt",
|
|
starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{
|
|
begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{
|
|
const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!{{HIGHLIGHT_JS}}|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/)
|
|
;return{name:"R",keywords:{$pattern:t,
|
|
keyword:"function if in break next repeat else for while",
|
|
literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10",
|
|
built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm"
|
|
},contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/,
|
|
starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)),
|
|
endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{
|
|
scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0
|
|
}]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}]
|
|
}),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE],
|
|
variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/
|
|
}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/
|
|
}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/
|
|
}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/
|
|
}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/
|
|
}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"',
|
|
relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{
|
|
1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"},
|
|
match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{
|
|
2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"},
|
|
match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{
|
|
match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`",
|
|
contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{
|
|
const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={
|
|
"variable.constant":["__FILE__","__LINE__","__ENCODING__"],
|
|
"variable.language":["self","super"],
|
|
keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"],
|
|
built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"],
|
|
literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={
|
|
begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s]
|
|
}),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10
|
|
}),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/,
|
|
end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c],
|
|
variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{
|
|
begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{
|
|
begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?</,end:/>/},{begin:/%[qQwWx]?\//,
|
|
end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{
|
|
begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{
|
|
begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{
|
|
begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{
|
|
begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{
|
|
begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),
|
|
contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,
|
|
contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number",
|
|
relevance:0,variants:[{
|
|
begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{
|
|
begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"
|
|
},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{
|
|
begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{
|
|
begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{
|
|
className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0,
|
|
keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{
|
|
match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class",
|
|
4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{
|
|
2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{
|
|
1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,
|
|
className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{
|
|
match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{
|
|
begin:e.IDENT_RE+"::"},{className:"symbol",
|
|
begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",
|
|
begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable",
|
|
begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{
|
|
className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0,
|
|
relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",
|
|
keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],
|
|
illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{
|
|
begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",
|
|
end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l)
|
|
;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m}
|
|
},{className:"meta.prompt",
|
|
begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])",
|
|
starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby",
|
|
aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/,
|
|
contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}},
|
|
grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0,
|
|
begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/))
|
|
},a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"]
|
|
;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r,
|
|
keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"],
|
|
literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:"</",
|
|
contains:[e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:["self"]
|
|
}),e.inherit(e.QUOTE_STRING_MODE,{begin:/b?"/,illegal:null}),{
|
|
className:"string",variants:[{begin:/b?r(#*)"(.|\n)*?"\1(?!#)/},{
|
|
begin:/b?'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/}]},{className:"symbol",
|
|
begin:/'[a-zA-Z_][a-zA-Z0-9_]*/},{className:"number",variants:[{
|
|
begin:"\\b0b([01_]+)"+a},{begin:"\\b0o([0-7_]+)"+a},{
|
|
begin:"\\b0x([A-Fa-f0-9_]+)"+a},{
|
|
begin:"\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)"+a}],relevance:0},{
|
|
begin:[/fn/,/\s+/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword",
|
|
3:"title.function"}},{className:"meta",begin:"#!?\\[",end:"\\]",contains:[{
|
|
className:"string",begin:/"/,end:/"/}]},{
|
|
begin:[/let/,/\s+/,/(?:mut\s+)?/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword",
|
|
3:"keyword",4:"variable"}},{
|
|
begin:[/for/,/\s+/,e.UNDERSCORE_IDENT_RE,/\s+/,/in/],className:{1:"keyword",
|
|
3:"variable",5:"keyword"}},{begin:[/type/,/\s+/,e.UNDERSCORE_IDENT_RE],
|
|
className:{1:"keyword",3:"title.class"}},{
|
|
begin:[/(?:trait|enum|struct|union|impl|for)/,/\s+/,e.UNDERSCORE_IDENT_RE],
|
|
className:{1:"keyword",3:"title.class"}},{begin:e.IDENT_RE+"::",keywords:{
|
|
keyword:"Self",built_in:i,type:r}},{className:"punctuation",begin:"->"},t]}},
|
|
grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable",
|
|
begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS",
|
|
case_insensitive:!0,illegal:"[=/|']",
|
|
contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{
|
|
className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{
|
|
className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0
|
|
},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag",
|
|
begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo",
|
|
begin:":("+a.join("|")+")"},{className:"selector-pseudo",
|
|
begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/,
|
|
contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute",
|
|
begin:"\\b("+ce.join("|")+")\\b"},{
|
|
begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"
|
|
},{begin:/:/,end:/[;}{]/,relevance:0,
|
|
contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH]
|
|
},{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{
|
|
begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/,
|
|
keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i,
|
|
className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute"
|
|
},r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE]
|
|
},n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session",
|
|
aliases:["console","shellsession"],contains:[{className:"meta.prompt",
|
|
begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,
|
|
subLanguage:"bash"}}]}),grmr_sql:e=>{
|
|
const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={
|
|
begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}}
|
|
;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{
|
|
$pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t
|
|
;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e))
|
|
})(l,{when:e=>e.length<3}),literal:a,type:i,
|
|
built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"]
|
|
},contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/,
|
|
keyword:l.concat(s),literal:a,type:i}},{className:"type",
|
|
begin:n.either("double precision","large object","with timezone","without timezone")
|
|
},c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string",
|
|
variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,
|
|
contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{
|
|
className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
|
|
relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0
|
|
},t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={
|
|
match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)),
|
|
relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{
|
|
className:"keyword",
|
|
match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={
|
|
$pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{
|
|
match:b(/\./,m(...De)),relevance:0},{className:"built_in",
|
|
match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{
|
|
className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}]
|
|
}],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0,
|
|
variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{
|
|
match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/
|
|
},{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{
|
|
match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}]
|
|
}),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/)
|
|
}),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/
|
|
}),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)]
|
|
}),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={
|
|
className:"string",
|
|
variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")]
|
|
},k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0,
|
|
contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//,
|
|
contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t,
|
|
contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={
|
|
scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/)
|
|
},C=[A,{className:"variable",match:/\$\d+/},{className:"variable",
|
|
match:`\\${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{
|
|
contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{
|
|
scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={
|
|
match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type",
|
|
match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+")
|
|
},{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{
|
|
match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={
|
|
begin:/</,end:/>/,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D)
|
|
;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{
|
|
match:b(Fe,/\s*:/),keywords:"_|0",relevance:0
|
|
},...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin:/</,end:/>/,
|
|
keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l,
|
|
contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/,
|
|
relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params",
|
|
match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={
|
|
match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword",
|
|
3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={
|
|
match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"},
|
|
contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{
|
|
1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{
|
|
1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/}
|
|
;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label))
|
|
;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/,
|
|
end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l,
|
|
contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor",
|
|
end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{
|
|
className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c]
|
|
},F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0
|
|
},S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{
|
|
const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={
|
|
beginKeywords:"namespace",end:/\{/,excludeEnd:!0,
|
|
contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/,
|
|
excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a},
|
|
contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e,
|
|
keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]),
|
|
literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta",
|
|
begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n))
|
|
;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)}
|
|
;return Object.assign(n.keywords,s),
|
|
n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]),
|
|
l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10,
|
|
begin:/^\s*['"]use strict['"]/
|
|
}),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{
|
|
name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{
|
|
const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={
|
|
className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{
|
|
begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{
|
|
begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}]
|
|
},o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}]
|
|
}),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]})
|
|
;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0,
|
|
classNameAliases:{label:"symbol"},keywords:{
|
|
keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield",
|
|
built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort",
|
|
type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort",
|
|
literal:"true false nothing"},
|
|
illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{
|
|
className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/,
|
|
end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0,
|
|
variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/
|
|
},{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{
|
|
begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{
|
|
className:"label",begin:/^\w+:/},o,l,{className:"meta",
|
|
begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/,
|
|
end:/$/,keywords:{
|
|
keyword:"const disable else elseif enable end externalsource if region then"},
|
|
contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/)
|
|
;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/,
|
|
keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"]
|
|
},contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/],
|
|
className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{
|
|
match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{
|
|
begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword",
|
|
3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/,
|
|
className:"type"},{className:"keyword",
|
|
match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/
|
|
},{className:"number",relevance:0,
|
|
match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/
|
|
}]}},grmr_xml:e=>{
|
|
const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={
|
|
className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/,
|
|
contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]
|
|
},r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{
|
|
className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={
|
|
endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",
|
|
begin:/[\p{L}0-9._:-]+/u,relevance:0},{begin:/=\s*/,relevance:0,contains:[{
|
|
className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[a]},{
|
|
begin:/'/,end:/'/,contains:[a]},{begin:/[^\s"'=<>`]+/}]}]}]};return{
|
|
name:"HTML, XML",
|
|
aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],
|
|
case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin:/<![a-z]/,
|
|
end:/>/,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{
|
|
className:"meta",begin:/<![a-z]/,end:/>/,contains:[i,r,o,s]}]}]
|
|
},e.COMMENT(/<!--/,/-->/,{relevance:10}),{begin:/<!\[CDATA\[/,end:/\]\]>/,
|
|
relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/,
|
|
relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag",
|
|
begin:/<style(?=\s|>)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{
|
|
end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",
|
|
begin:/<script(?=\s|>)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{
|
|
end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{
|
|
className:"tag",begin:/<>|<\/>/},{className:"tag",
|
|
begin:n.concat(/</,n.lookahead(n.concat(t,n.either(/\/>/,/>/,/\s/)))),
|
|
end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{
|
|
className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{
|
|
className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}
|
|
},grmr_yaml:e=>{
|
|
const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={
|
|
className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/
|
|
},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",
|
|
variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{
|
|
variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={
|
|
end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/,
|
|
end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]",
|
|
contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{
|
|
begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{
|
|
begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",
|
|
relevance:10},{className:"string",
|
|
begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{
|
|
begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,
|
|
relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type",
|
|
begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t
|
|
},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",
|
|
begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",
|
|
relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{
|
|
className:"number",
|
|
begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"
|
|
},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l]
|
|
;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0,
|
|
aliases:["yml"],contains:l}}});const He=ae;for(const e of Object.keys(Ke)){
|
|
const n=e.replace("grmr_","").replace("_","-");He.registerLanguage(n,Ke[e])}
|
|
return He}()
|
|
;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);</script>
|
|
|
|
<!-- Main application code -->
|
|
<script>
|
|
(function() {
|
|
'use strict';
|
|
|
|
// ============================================================
|
|
// DATA LOADING
|
|
// ============================================================
|
|
|
|
const base64 = document.getElementById('session-data').textContent;
|
|
const binary = atob(base64);
|
|
const bytes = new Uint8Array(binary.length);
|
|
for (let i = 0; i < binary.length; i++) {
|
|
bytes[i] = binary.charCodeAt(i);
|
|
}
|
|
const data = JSON.parse(new TextDecoder('utf-8').decode(bytes));
|
|
const { header, entries, leafId: defaultLeafId, systemPrompt, tools, renderedTools } = data;
|
|
|
|
// ============================================================
|
|
// URL PARAMETER HANDLING
|
|
// ============================================================
|
|
|
|
// Parse URL parameters for deep linking: leafId and targetId
|
|
// Check for injected params (when loaded in iframe via srcdoc) or use window.location
|
|
const injectedParams = document.querySelector('meta[name="pi-url-params"]');
|
|
const searchString = injectedParams ? injectedParams.content : window.location.search.substring(1);
|
|
const urlParams = new URLSearchParams(searchString);
|
|
const urlLeafId = urlParams.get('leafId');
|
|
const urlTargetId = urlParams.get('targetId');
|
|
// Use URL leafId if provided, otherwise fall back to session default
|
|
const leafId = urlLeafId || defaultLeafId;
|
|
|
|
// ============================================================
|
|
// DATA STRUCTURES
|
|
// ============================================================
|
|
|
|
// Entry lookup by ID
|
|
const byId = new Map();
|
|
for (const entry of entries) {
|
|
byId.set(entry.id, entry);
|
|
}
|
|
|
|
// Tool call lookup (toolCallId -> {name, arguments})
|
|
const toolCallMap = new Map();
|
|
for (const entry of entries) {
|
|
if (entry.type === 'message' && entry.message.role === 'assistant') {
|
|
const content = entry.message.content;
|
|
if (Array.isArray(content)) {
|
|
for (const block of content) {
|
|
if (block.type === 'toolCall') {
|
|
toolCallMap.set(block.id, { name: block.name, arguments: block.arguments });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Label lookup (entryId -> label string)
|
|
// Labels are stored in 'label' entries that reference their target via targetId
|
|
const labelMap = new Map();
|
|
for (const entry of entries) {
|
|
if (entry.type === 'label' && entry.targetId && entry.label) {
|
|
labelMap.set(entry.targetId, entry.label);
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// TREE DATA PREPARATION (no DOM, pure data)
|
|
// ============================================================
|
|
|
|
/**
|
|
* Build tree structure from flat entries.
|
|
* Returns array of root nodes, each with { entry, children, label }.
|
|
*/
|
|
function buildTree() {
|
|
const nodeMap = new Map();
|
|
const roots = [];
|
|
|
|
// Create nodes
|
|
for (const entry of entries) {
|
|
nodeMap.set(entry.id, {
|
|
entry,
|
|
children: [],
|
|
label: labelMap.get(entry.id)
|
|
});
|
|
}
|
|
|
|
// Build parent-child relationships
|
|
for (const entry of entries) {
|
|
const node = nodeMap.get(entry.id);
|
|
if (entry.parentId === null || entry.parentId === undefined || entry.parentId === entry.id) {
|
|
roots.push(node);
|
|
} else {
|
|
const parent = nodeMap.get(entry.parentId);
|
|
if (parent) {
|
|
parent.children.push(node);
|
|
} else {
|
|
roots.push(node);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sort children by timestamp
|
|
function sortChildren(node) {
|
|
node.children.sort((a, b) =>
|
|
new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime()
|
|
);
|
|
node.children.forEach(sortChildren);
|
|
}
|
|
roots.forEach(sortChildren);
|
|
|
|
return roots;
|
|
}
|
|
|
|
/**
|
|
* Build set of entry IDs on path from root to target.
|
|
*/
|
|
function buildActivePathIds(targetId) {
|
|
const ids = new Set();
|
|
let current = byId.get(targetId);
|
|
while (current) {
|
|
ids.add(current.id);
|
|
// Stop if no parent or self-referencing (root)
|
|
if (!current.parentId || current.parentId === current.id) {
|
|
break;
|
|
}
|
|
current = byId.get(current.parentId);
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
/**
|
|
* Get array of entries from root to target (the conversation path).
|
|
*/
|
|
function getPath(targetId) {
|
|
const path = [];
|
|
let current = byId.get(targetId);
|
|
while (current) {
|
|
path.unshift(current);
|
|
// Stop if no parent or self-referencing (root)
|
|
if (!current.parentId || current.parentId === current.id) {
|
|
break;
|
|
}
|
|
current = byId.get(current.parentId);
|
|
}
|
|
return path;
|
|
}
|
|
|
|
// Tree node lookup for finding leaves
|
|
let treeNodeMap = null;
|
|
|
|
/**
|
|
* Find the newest leaf node reachable from a given node.
|
|
* This allows clicking any node in a branch to show the full branch.
|
|
* Children are sorted by timestamp, so the newest is always last.
|
|
*/
|
|
function findNewestLeaf(nodeId) {
|
|
// Build tree node map lazily
|
|
if (!treeNodeMap) {
|
|
treeNodeMap = new Map();
|
|
const tree = buildTree();
|
|
function mapNodes(node) {
|
|
treeNodeMap.set(node.entry.id, node);
|
|
node.children.forEach(mapNodes);
|
|
}
|
|
tree.forEach(mapNodes);
|
|
}
|
|
|
|
const node = treeNodeMap.get(nodeId);
|
|
if (!node) return nodeId;
|
|
|
|
// Follow the newest (last) child at each level
|
|
let current = node;
|
|
while (current.children.length > 0) {
|
|
current = current.children[current.children.length - 1];
|
|
}
|
|
return current.entry.id;
|
|
}
|
|
|
|
/**
|
|
* Flatten tree into list with indentation and connector info.
|
|
* Returns array of { node, indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots }.
|
|
* Matches tree-selector.ts logic exactly.
|
|
*/
|
|
function flattenTree(roots, activePathIds) {
|
|
const result = [];
|
|
const multipleRoots = roots.length > 1;
|
|
|
|
// Mark which subtrees contain the active leaf
|
|
const containsActive = new Map();
|
|
function markActive(node) {
|
|
let has = activePathIds.has(node.entry.id);
|
|
for (const child of node.children) {
|
|
if (markActive(child)) has = true;
|
|
}
|
|
containsActive.set(node, has);
|
|
return has;
|
|
}
|
|
roots.forEach(markActive);
|
|
|
|
// Stack: [node, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild]
|
|
const stack = [];
|
|
|
|
// Add roots (prioritize branch containing active leaf)
|
|
const orderedRoots = [...roots].sort((a, b) =>
|
|
Number(containsActive.get(b)) - Number(containsActive.get(a))
|
|
);
|
|
for (let i = orderedRoots.length - 1; i >= 0; i--) {
|
|
const isLast = i === orderedRoots.length - 1;
|
|
stack.push([orderedRoots[i], multipleRoots ? 1 : 0, multipleRoots, multipleRoots, isLast, [], multipleRoots]);
|
|
}
|
|
|
|
while (stack.length > 0) {
|
|
const [node, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild] = stack.pop();
|
|
|
|
result.push({ node, indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots });
|
|
|
|
const children = node.children;
|
|
const multipleChildren = children.length > 1;
|
|
|
|
// Order children (active branch first)
|
|
const orderedChildren = [...children].sort((a, b) =>
|
|
Number(containsActive.get(b)) - Number(containsActive.get(a))
|
|
);
|
|
|
|
// Calculate child indent (matches tree-selector.ts)
|
|
let childIndent;
|
|
if (multipleChildren) {
|
|
// Parent branches: children get +1
|
|
childIndent = indent + 1;
|
|
} else if (justBranched && indent > 0) {
|
|
// First generation after a branch: +1 for visual grouping
|
|
childIndent = indent + 1;
|
|
} else {
|
|
// Single-child chain: stay flat
|
|
childIndent = indent;
|
|
}
|
|
|
|
// Build gutters for children
|
|
const connectorDisplayed = showConnector && !isVirtualRootChild;
|
|
const currentDisplayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
|
|
const connectorPosition = Math.max(0, currentDisplayIndent - 1);
|
|
const childGutters = connectorDisplayed
|
|
? [...gutters, { position: connectorPosition, show: !isLast }]
|
|
: gutters;
|
|
|
|
// Add children in reverse order for stack
|
|
for (let i = orderedChildren.length - 1; i >= 0; i--) {
|
|
const childIsLast = i === orderedChildren.length - 1;
|
|
stack.push([orderedChildren[i], childIndent, multipleChildren, multipleChildren, childIsLast, childGutters, false]);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Build ASCII prefix string for tree node.
|
|
*/
|
|
function buildTreePrefix(flatNode) {
|
|
const { indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots } = flatNode;
|
|
const displayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
|
|
const connector = showConnector && !isVirtualRootChild ? (isLast ? '└─ ' : '├─ ') : '';
|
|
const connectorPosition = connector ? displayIndent - 1 : -1;
|
|
|
|
const totalChars = displayIndent * 3;
|
|
const prefixChars = [];
|
|
for (let i = 0; i < totalChars; i++) {
|
|
const level = Math.floor(i / 3);
|
|
const posInLevel = i % 3;
|
|
|
|
const gutter = gutters.find(g => g.position === level);
|
|
if (gutter) {
|
|
prefixChars.push(posInLevel === 0 ? (gutter.show ? '│' : ' ') : ' ');
|
|
} else if (connector && level === connectorPosition) {
|
|
if (posInLevel === 0) {
|
|
prefixChars.push(isLast ? '└' : '├');
|
|
} else if (posInLevel === 1) {
|
|
prefixChars.push('─');
|
|
} else {
|
|
prefixChars.push(' ');
|
|
}
|
|
} else {
|
|
prefixChars.push(' ');
|
|
}
|
|
}
|
|
return prefixChars.join('');
|
|
}
|
|
|
|
// ============================================================
|
|
// FILTERING (pure data)
|
|
// ============================================================
|
|
|
|
let filterMode = 'default';
|
|
let searchQuery = '';
|
|
|
|
function hasTextContent(content) {
|
|
if (typeof content === 'string') return content.trim().length > 0;
|
|
if (Array.isArray(content)) {
|
|
for (const c of content) {
|
|
if (c.type === 'text' && c.text && c.text.trim().length > 0) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function extractContent(content) {
|
|
if (typeof content === 'string') return content;
|
|
if (Array.isArray(content)) {
|
|
return content
|
|
.filter(c => c.type === 'text' && c.text)
|
|
.map(c => c.text)
|
|
.join('');
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Parse a skill block from message text.
|
|
* Returns null if the text doesn't contain a skill block.
|
|
* Matches the format: <skill name="..." location="...">\n...\n</skill>\n\nuser message
|
|
*/
|
|
function parseSkillBlock(text) {
|
|
const match = text.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);
|
|
if (!match) return null;
|
|
return {
|
|
name: match[1],
|
|
location: match[2],
|
|
content: match[3],
|
|
userMessage: match[4]?.trim() || undefined,
|
|
};
|
|
}
|
|
|
|
function getSearchableText(entry, label) {
|
|
const parts = [];
|
|
if (label) parts.push(label);
|
|
|
|
switch (entry.type) {
|
|
case 'message': {
|
|
const msg = entry.message;
|
|
parts.push(msg.role);
|
|
if (msg.content) parts.push(extractContent(msg.content));
|
|
if (msg.role === 'bashExecution' && msg.command) parts.push(msg.command);
|
|
break;
|
|
}
|
|
case 'custom_message':
|
|
parts.push(entry.customType);
|
|
parts.push(typeof entry.content === 'string' ? entry.content : extractContent(entry.content));
|
|
break;
|
|
case 'compaction':
|
|
parts.push('compaction');
|
|
break;
|
|
case 'branch_summary':
|
|
parts.push('branch summary', entry.summary);
|
|
break;
|
|
case 'model_change':
|
|
parts.push('model', entry.modelId);
|
|
break;
|
|
case 'thinking_level_change':
|
|
parts.push('thinking', entry.thinkingLevel);
|
|
break;
|
|
}
|
|
|
|
return parts.join(' ').toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Filter flat nodes based on current filterMode and searchQuery.
|
|
*/
|
|
function filterNodes(flatNodes, currentLeafId) {
|
|
const searchTokens = searchQuery.toLowerCase().split(/\s+/).filter(Boolean);
|
|
|
|
const filtered = flatNodes.filter(flatNode => {
|
|
const entry = flatNode.node.entry;
|
|
const label = flatNode.node.label;
|
|
const isCurrentLeaf = entry.id === currentLeafId;
|
|
|
|
// Always show current leaf
|
|
if (isCurrentLeaf) return true;
|
|
|
|
// Hide assistant messages with only tool calls (no text) unless error/aborted
|
|
if (entry.type === 'message' && entry.message.role === 'assistant') {
|
|
const msg = entry.message;
|
|
const hasText = hasTextContent(msg.content);
|
|
const isErrorOrAborted = msg.stopReason && msg.stopReason !== 'stop' && msg.stopReason !== 'toolUse';
|
|
if (!hasText && !isErrorOrAborted) return false;
|
|
}
|
|
|
|
// Apply filter mode
|
|
const isSettingsEntry = ['label', 'custom', 'model_change', 'thinking_level_change'].includes(entry.type);
|
|
let passesFilter = true;
|
|
|
|
switch (filterMode) {
|
|
case 'user-only':
|
|
passesFilter = entry.type === 'message' && entry.message.role === 'user';
|
|
break;
|
|
case 'no-tools':
|
|
passesFilter = !isSettingsEntry && !(entry.type === 'message' && entry.message.role === 'toolResult');
|
|
break;
|
|
case 'labeled-only':
|
|
passesFilter = label !== undefined;
|
|
break;
|
|
case 'all':
|
|
passesFilter = true;
|
|
break;
|
|
default: // 'default'
|
|
passesFilter = !isSettingsEntry;
|
|
break;
|
|
}
|
|
|
|
if (!passesFilter) return false;
|
|
|
|
// Apply search filter
|
|
if (searchTokens.length > 0) {
|
|
const nodeText = getSearchableText(entry, label);
|
|
if (!searchTokens.every(t => nodeText.includes(t))) return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
// Recalculate visual structure based on visible tree
|
|
recalculateVisualStructure(filtered, flatNodes);
|
|
|
|
return filtered;
|
|
}
|
|
|
|
/**
|
|
* Recompute indentation/connectors for the filtered view
|
|
*
|
|
* Filtering can hide intermediate entries; descendants attach to the nearest visible ancestor.
|
|
* Keep indentation semantics aligned with flattenTree() so single-child chains don't drift right.
|
|
*/
|
|
function recalculateVisualStructure(filteredNodes, allFlatNodes) {
|
|
if (filteredNodes.length === 0) return;
|
|
|
|
const visibleIds = new Set(filteredNodes.map(n => n.node.entry.id));
|
|
|
|
// Build entry map for parent lookup (using full tree)
|
|
const entryMap = new Map();
|
|
for (const flatNode of allFlatNodes) {
|
|
entryMap.set(flatNode.node.entry.id, flatNode);
|
|
}
|
|
|
|
// Find nearest visible ancestor for a node
|
|
function findVisibleAncestor(nodeId) {
|
|
let currentId = entryMap.get(nodeId)?.node.entry.parentId;
|
|
while (currentId != null) {
|
|
if (visibleIds.has(currentId)) {
|
|
return currentId;
|
|
}
|
|
currentId = entryMap.get(currentId)?.node.entry.parentId;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Build visible tree structure
|
|
const visibleParent = new Map();
|
|
const visibleChildren = new Map();
|
|
visibleChildren.set(null, []); // root-level nodes
|
|
|
|
for (const flatNode of filteredNodes) {
|
|
const nodeId = flatNode.node.entry.id;
|
|
const ancestorId = findVisibleAncestor(nodeId);
|
|
visibleParent.set(nodeId, ancestorId);
|
|
|
|
if (!visibleChildren.has(ancestorId)) {
|
|
visibleChildren.set(ancestorId, []);
|
|
}
|
|
visibleChildren.get(ancestorId).push(nodeId);
|
|
}
|
|
|
|
// Update multipleRoots based on visible roots
|
|
const visibleRootIds = visibleChildren.get(null);
|
|
const multipleRoots = visibleRootIds.length > 1;
|
|
|
|
// Build a map for quick lookup: nodeId → FlatNode
|
|
const filteredNodeMap = new Map();
|
|
for (const flatNode of filteredNodes) {
|
|
filteredNodeMap.set(flatNode.node.entry.id, flatNode);
|
|
}
|
|
|
|
// DFS traversal of visible tree, applying same indentation rules as flattenTree()
|
|
// Stack items: [nodeId, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild]
|
|
const stack = [];
|
|
|
|
// Add visible roots in reverse order (to process in forward order via stack)
|
|
for (let i = visibleRootIds.length - 1; i >= 0; i--) {
|
|
const isLast = i === visibleRootIds.length - 1;
|
|
stack.push([
|
|
visibleRootIds[i],
|
|
multipleRoots ? 1 : 0,
|
|
multipleRoots,
|
|
multipleRoots,
|
|
isLast,
|
|
[],
|
|
multipleRoots
|
|
]);
|
|
}
|
|
|
|
while (stack.length > 0) {
|
|
const [nodeId, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild] = stack.pop();
|
|
|
|
const flatNode = filteredNodeMap.get(nodeId);
|
|
if (!flatNode) continue;
|
|
|
|
// Update this node's visual properties
|
|
flatNode.indent = indent;
|
|
flatNode.showConnector = showConnector;
|
|
flatNode.isLast = isLast;
|
|
flatNode.gutters = gutters;
|
|
flatNode.isVirtualRootChild = isVirtualRootChild;
|
|
flatNode.multipleRoots = multipleRoots;
|
|
|
|
// Get visible children of this node
|
|
const children = visibleChildren.get(nodeId) || [];
|
|
const multipleChildren = children.length > 1;
|
|
|
|
// Calculate child indent using same rules as flattenTree():
|
|
// - Parent branches (multiple children): children get +1
|
|
// - Just branched and indent > 0: children get +1 for visual grouping
|
|
// - Single-child chain: stay flat
|
|
let childIndent;
|
|
if (multipleChildren) {
|
|
childIndent = indent + 1;
|
|
} else if (justBranched && indent > 0) {
|
|
childIndent = indent + 1;
|
|
} else {
|
|
childIndent = indent;
|
|
}
|
|
|
|
// Build gutters for children (same logic as flattenTree)
|
|
const connectorDisplayed = showConnector && !isVirtualRootChild;
|
|
const currentDisplayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
|
|
const connectorPosition = Math.max(0, currentDisplayIndent - 1);
|
|
const childGutters = connectorDisplayed
|
|
? [...gutters, { position: connectorPosition, show: !isLast }]
|
|
: gutters;
|
|
|
|
// Add children in reverse order (to process in forward order via stack)
|
|
for (let i = children.length - 1; i >= 0; i--) {
|
|
const childIsLast = i === children.length - 1;
|
|
stack.push([
|
|
children[i],
|
|
childIndent,
|
|
multipleChildren,
|
|
multipleChildren,
|
|
childIsLast,
|
|
childGutters,
|
|
false
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// TREE DISPLAY TEXT (pure data -> string)
|
|
// ============================================================
|
|
|
|
function shortenPath(p) {
|
|
if (typeof p !== 'string') return '';
|
|
if (p.startsWith('/Users/')) {
|
|
const parts = p.split('/');
|
|
if (parts.length > 2) return '~' + p.slice(('/Users/' + parts[2]).length);
|
|
}
|
|
if (p.startsWith('/home/')) {
|
|
const parts = p.split('/');
|
|
if (parts.length > 2) return '~' + p.slice(('/home/' + parts[2]).length);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
function formatToolCall(name, args) {
|
|
switch (name) {
|
|
case 'read': {
|
|
const path = shortenPath(String(args.path || args.file_path || ''));
|
|
const offset = args.offset;
|
|
const limit = args.limit;
|
|
let display = path;
|
|
if (offset !== undefined || limit !== undefined) {
|
|
const start = offset ?? 1;
|
|
const end = limit !== undefined ? start + limit - 1 : '';
|
|
display += `:${start}${end ? `-${end}` : ''}`;
|
|
}
|
|
return `[read: ${display}]`;
|
|
}
|
|
case 'write':
|
|
return `[write: ${shortenPath(String(args.path || args.file_path || ''))}]`;
|
|
case 'edit':
|
|
return `[edit: ${shortenPath(String(args.path || args.file_path || ''))}]`;
|
|
case 'bash': {
|
|
const rawCmd = String(args.command || '');
|
|
const cmd = rawCmd.replace(/[\n\t]/g, ' ').trim().slice(0, 50);
|
|
return `[bash: ${cmd}${rawCmd.length > 50 ? '...' : ''}]`;
|
|
}
|
|
case 'grep':
|
|
return `[grep: /${args.pattern || ''}/ in ${shortenPath(String(args.path || '.'))}]`;
|
|
case 'find':
|
|
return `[find: ${args.pattern || ''} in ${shortenPath(String(args.path || '.'))}]`;
|
|
case 'ls':
|
|
return `[ls: ${shortenPath(String(args.path || '.'))}]`;
|
|
default: {
|
|
const argsStr = JSON.stringify(args).slice(0, 40);
|
|
return `[${name}: ${argsStr}${JSON.stringify(args).length > 40 ? '...' : ''}]`;
|
|
}
|
|
}
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
return String(text)
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''');
|
|
}
|
|
|
|
function sanitizeMarkdownUrl(value) {
|
|
const href = String(value || '').trim().replace(/[\x00-\x1f\x7f]/g, '');
|
|
if (!href) return href;
|
|
|
|
const scheme = href.match(/^([A-Za-z][A-Za-z0-9+.-]*):/);
|
|
if (scheme && !/^(https?|mailto|tel|ftp)$/i.test(scheme[1])) {
|
|
return null;
|
|
}
|
|
|
|
return href;
|
|
}
|
|
|
|
/**
|
|
* Truncate string to maxLen chars, append "..." if truncated.
|
|
*/
|
|
function truncate(s, maxLen = 100) {
|
|
if (s.length <= maxLen) return s;
|
|
return s.slice(0, maxLen) + '...';
|
|
}
|
|
|
|
/**
|
|
* Get display text for tree node (returns HTML string).
|
|
*/
|
|
function getTreeNodeDisplayHtml(entry, label) {
|
|
const normalize = s => s.replace(/[\n\t]/g, ' ').trim();
|
|
const labelHtml = label ? `<span class="tree-label">[${escapeHtml(label)}]</span> ` : '';
|
|
|
|
switch (entry.type) {
|
|
case 'message': {
|
|
const msg = entry.message;
|
|
if (msg.role === 'user') {
|
|
const rawContent = extractContent(msg.content);
|
|
const skillBlock = parseSkillBlock(rawContent);
|
|
if (skillBlock) {
|
|
let treeHtml = labelHtml + `<span class="tree-role-skill">skill:</span> ${escapeHtml(skillBlock.name)}`;
|
|
if (skillBlock.userMessage) {
|
|
treeHtml += ` · <span class="tree-role-user">user:</span> ${escapeHtml(truncate(normalize(skillBlock.userMessage)))}`;
|
|
}
|
|
return treeHtml;
|
|
}
|
|
const content = truncate(normalize(rawContent));
|
|
return labelHtml + `<span class="tree-role-user">user:</span> ${escapeHtml(content)}`;
|
|
}
|
|
if (msg.role === 'assistant') {
|
|
const textContent = truncate(normalize(extractContent(msg.content)));
|
|
if (textContent) {
|
|
return labelHtml + `<span class="tree-role-assistant">assistant:</span> ${escapeHtml(textContent)}`;
|
|
}
|
|
if (msg.stopReason === 'aborted') {
|
|
return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-muted">(aborted)</span>`;
|
|
}
|
|
if (msg.errorMessage) {
|
|
return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-error">${escapeHtml(truncate(msg.errorMessage))}</span>`;
|
|
}
|
|
return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-muted">(no text)</span>`;
|
|
}
|
|
if (msg.role === 'toolResult') {
|
|
const toolCall = msg.toolCallId ? toolCallMap.get(msg.toolCallId) : null;
|
|
if (toolCall) {
|
|
return labelHtml + `<span class="tree-role-tool">${escapeHtml(formatToolCall(toolCall.name, toolCall.arguments))}</span>`;
|
|
}
|
|
return labelHtml + `<span class="tree-role-tool">[${escapeHtml(msg.toolName || 'tool')}]</span>`;
|
|
}
|
|
if (msg.role === 'bashExecution') {
|
|
const cmd = truncate(normalize(msg.command || ''));
|
|
return labelHtml + `<span class="tree-role-tool">[bash]:</span> ${escapeHtml(cmd)}`;
|
|
}
|
|
return labelHtml + `<span class="tree-muted">[${escapeHtml(msg.role)}]</span>`;
|
|
}
|
|
case 'compaction':
|
|
return labelHtml + `<span class="tree-compaction">[compaction: ${Math.round(entry.tokensBefore/1000)}k tokens]</span>`;
|
|
case 'branch_summary': {
|
|
const summary = truncate(normalize(entry.summary || ''));
|
|
return labelHtml + `<span class="tree-branch-summary">[branch summary]:</span> ${escapeHtml(summary)}`;
|
|
}
|
|
case 'custom_message': {
|
|
const content = typeof entry.content === 'string' ? entry.content : extractContent(entry.content);
|
|
return labelHtml + `<span class="tree-custom">[${escapeHtml(entry.customType)}]:</span> ${escapeHtml(truncate(normalize(content)))}`;
|
|
}
|
|
case 'model_change':
|
|
return labelHtml + `<span class="tree-muted">[model: ${escapeHtml(entry.modelId)}]</span>`;
|
|
case 'thinking_level_change':
|
|
return labelHtml + `<span class="tree-muted">[thinking: ${escapeHtml(entry.thinkingLevel)}]</span>`;
|
|
default:
|
|
return labelHtml + `<span class="tree-muted">[${escapeHtml(entry.type)}]</span>`;
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// TREE RENDERING (DOM manipulation)
|
|
// ============================================================
|
|
|
|
let currentLeafId = leafId;
|
|
let currentTargetId = urlTargetId || leafId;
|
|
let treeRendered = false;
|
|
|
|
function renderTree() {
|
|
const tree = buildTree();
|
|
const activePathIds = buildActivePathIds(currentLeafId);
|
|
const flatNodes = flattenTree(tree, activePathIds);
|
|
const filtered = filterNodes(flatNodes, currentLeafId);
|
|
const container = document.getElementById('tree-container');
|
|
|
|
// Full render only on first call or when filter/search changes
|
|
if (!treeRendered) {
|
|
container.innerHTML = '';
|
|
|
|
for (const flatNode of filtered) {
|
|
const entry = flatNode.node.entry;
|
|
const isOnPath = activePathIds.has(entry.id);
|
|
const isTarget = entry.id === currentTargetId;
|
|
|
|
const div = document.createElement('div');
|
|
div.className = 'tree-node';
|
|
if (isOnPath) div.classList.add('in-path');
|
|
if (isTarget) div.classList.add('active');
|
|
div.dataset.id = entry.id;
|
|
|
|
const prefix = buildTreePrefix(flatNode);
|
|
const prefixSpan = document.createElement('span');
|
|
prefixSpan.className = 'tree-prefix';
|
|
prefixSpan.textContent = prefix;
|
|
|
|
const marker = document.createElement('span');
|
|
marker.className = 'tree-marker';
|
|
marker.textContent = isOnPath ? '•' : ' ';
|
|
|
|
const content = document.createElement('span');
|
|
content.className = 'tree-content';
|
|
content.innerHTML = getTreeNodeDisplayHtml(entry, flatNode.node.label);
|
|
|
|
div.appendChild(prefixSpan);
|
|
div.appendChild(marker);
|
|
div.appendChild(content);
|
|
// Navigate to the newest leaf through this node, but scroll to the clicked node
|
|
div.addEventListener('click', () => {
|
|
if (window.getSelection().toString()) return;
|
|
const leafId = findNewestLeaf(entry.id);
|
|
navigateTo(leafId, 'target', entry.id);
|
|
});
|
|
|
|
container.appendChild(div);
|
|
}
|
|
|
|
treeRendered = true;
|
|
} else {
|
|
// Just update markers and classes
|
|
const nodes = container.querySelectorAll('.tree-node');
|
|
for (const node of nodes) {
|
|
const id = node.dataset.id;
|
|
const isOnPath = activePathIds.has(id);
|
|
const isTarget = id === currentTargetId;
|
|
|
|
node.classList.toggle('in-path', isOnPath);
|
|
node.classList.toggle('active', isTarget);
|
|
|
|
const marker = node.querySelector('.tree-marker');
|
|
if (marker) {
|
|
marker.textContent = isOnPath ? '•' : ' ';
|
|
}
|
|
}
|
|
}
|
|
|
|
document.getElementById('tree-status').textContent = `${filtered.length} / ${flatNodes.length} entries`;
|
|
|
|
// Scroll active node into view after layout
|
|
setTimeout(() => {
|
|
const activeNode = container.querySelector('.tree-node.active');
|
|
if (activeNode) {
|
|
activeNode.scrollIntoView({ block: 'nearest' });
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
function forceTreeRerender() {
|
|
treeRendered = false;
|
|
renderTree();
|
|
}
|
|
|
|
// ============================================================
|
|
// MESSAGE RENDERING
|
|
// ============================================================
|
|
|
|
function formatTokens(count) {
|
|
if (count < 1000) return count.toString();
|
|
if (count < 10000) return (count / 1000).toFixed(1) + 'k';
|
|
if (count < 1000000) return Math.round(count / 1000) + 'k';
|
|
return (count / 1000000).toFixed(1) + 'M';
|
|
}
|
|
|
|
function formatTimestamp(ts) {
|
|
if (!ts) return '';
|
|
const date = new Date(ts);
|
|
return date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
}
|
|
|
|
function replaceTabs(text) {
|
|
return text.replace(/\t/g, ' ');
|
|
}
|
|
|
|
/** Safely coerce value to string for display. Returns null if invalid type. */
|
|
function str(value) {
|
|
if (typeof value === 'string') return value;
|
|
if (value == null) return '';
|
|
return null;
|
|
}
|
|
|
|
function getLanguageFromPath(filePath) {
|
|
const ext = filePath.split('.').pop()?.toLowerCase();
|
|
const extToLang = {
|
|
ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',
|
|
py: 'python', rb: 'ruby', rs: 'rust', go: 'go', java: 'java',
|
|
c: 'c', cpp: 'cpp', h: 'c', hpp: 'cpp', cs: 'csharp',
|
|
php: 'php', sh: 'bash', bash: 'bash', zsh: 'bash',
|
|
sql: 'sql', html: 'html', css: 'css', scss: 'scss',
|
|
json: 'json', yaml: 'yaml', yml: 'yaml', xml: 'xml',
|
|
md: 'markdown', dockerfile: 'dockerfile'
|
|
};
|
|
return extToLang[ext];
|
|
}
|
|
|
|
function findToolResult(toolCallId) {
|
|
for (const entry of entries) {
|
|
if (entry.type === 'message' && entry.message.role === 'toolResult') {
|
|
if (entry.message.toolCallId === toolCallId) {
|
|
return entry.message;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function formatExpandableOutput(text, maxLines, lang) {
|
|
text = replaceTabs(text);
|
|
const lines = text.split('\n');
|
|
const displayLines = lines.slice(0, maxLines);
|
|
const remaining = lines.length - maxLines;
|
|
|
|
if (lang) {
|
|
let highlighted;
|
|
try {
|
|
highlighted = hljs.highlight(text, { language: lang }).value;
|
|
} catch {
|
|
highlighted = escapeHtml(text);
|
|
}
|
|
|
|
if (remaining > 0) {
|
|
const previewCode = displayLines.join('\n');
|
|
let previewHighlighted;
|
|
try {
|
|
previewHighlighted = hljs.highlight(previewCode, { language: lang }).value;
|
|
} catch {
|
|
previewHighlighted = escapeHtml(previewCode);
|
|
}
|
|
|
|
return `<div class="tool-output expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
|
|
<div class="output-preview"><pre><code class="hljs">${previewHighlighted}</code></pre>
|
|
<div class="expand-hint">... (${remaining} more lines)</div></div>
|
|
<div class="output-full"><pre><code class="hljs">${highlighted}</code></pre></div></div>`;
|
|
}
|
|
|
|
return `<div class="tool-output"><pre><code class="hljs">${highlighted}</code></pre></div>`;
|
|
}
|
|
|
|
// Plain text output
|
|
if (remaining > 0) {
|
|
let out = '<div class="tool-output expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle(\'expanded\')">';
|
|
out += '<div class="output-preview">';
|
|
for (const line of displayLines) {
|
|
out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
|
|
}
|
|
out += `<div class="expand-hint">... (${remaining} more lines)</div></div>`;
|
|
out += '<div class="output-full">';
|
|
for (const line of lines) {
|
|
out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
|
|
}
|
|
out += '</div></div>';
|
|
return out;
|
|
}
|
|
|
|
let out = '<div class="tool-output">';
|
|
for (const line of displayLines) {
|
|
out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
|
|
}
|
|
out += '</div>';
|
|
return out;
|
|
}
|
|
|
|
function renderToolCall(call) {
|
|
const result = findToolResult(call.id);
|
|
const isError = result?.isError || false;
|
|
const statusClass = result ? (isError ? 'error' : 'success') : 'pending';
|
|
|
|
const getResultText = () => {
|
|
if (!result) return '';
|
|
const textBlocks = result.content.filter(c => c.type === 'text');
|
|
return textBlocks.map(c => c.text).join('\n');
|
|
};
|
|
|
|
const getResultImages = () => {
|
|
if (!result) return [];
|
|
return result.content.filter(c => c.type === 'image');
|
|
};
|
|
|
|
const renderResultImages = () => {
|
|
const images = getResultImages();
|
|
if (images.length === 0) return '';
|
|
return '<div class="tool-images">' +
|
|
images.map(img => `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${escapeHtml(img.data || '')}" class="tool-image" />`).join('') +
|
|
'</div>';
|
|
};
|
|
|
|
const toolDomId = `tool-call-${escapeHtml(call.id)}`;
|
|
let html = `<div class="tool-execution ${statusClass}" id="${toolDomId}">`;
|
|
const args = call.arguments || {};
|
|
const name = call.name;
|
|
|
|
const invalidArg = '<span class="tool-error">[invalid arg]</span>';
|
|
|
|
switch (name) {
|
|
case 'bash': {
|
|
const command = str(args.command);
|
|
const cmdDisplay = command === null ? invalidArg : escapeHtml(command || '...');
|
|
html += `<div class="tool-command">$ ${cmdDisplay}</div>`;
|
|
if (result) {
|
|
const output = getResultText().trim();
|
|
if (output) html += formatExpandableOutput(output, 5);
|
|
}
|
|
break;
|
|
}
|
|
case 'read': {
|
|
const filePath = str(args.file_path ?? args.path);
|
|
const offset = args.offset;
|
|
const limit = args.limit;
|
|
|
|
let pathHtml = filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''));
|
|
if (filePath !== null && (offset !== undefined || limit !== undefined)) {
|
|
const startLine = offset ?? 1;
|
|
const endLine = limit !== undefined ? startLine + limit - 1 : '';
|
|
pathHtml += `<span class="line-numbers">:${startLine}${endLine ? '-' + endLine : ''}</span>`;
|
|
}
|
|
|
|
html += `<div class="tool-header"><span class="tool-name">read</span> <span class="tool-path">${pathHtml}</span></div>`;
|
|
if (result) {
|
|
html += renderResultImages();
|
|
const output = getResultText();
|
|
const lang = filePath ? getLanguageFromPath(filePath) : null;
|
|
if (output) html += formatExpandableOutput(output, 10, lang);
|
|
}
|
|
break;
|
|
}
|
|
case 'write': {
|
|
const filePath = str(args.file_path ?? args.path);
|
|
const content = str(args.content);
|
|
|
|
html += `<div class="tool-header"><span class="tool-name">write</span> <span class="tool-path">${filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''))}</span>`;
|
|
if (content !== null && content) {
|
|
const lines = content.split('\n');
|
|
if (lines.length > 10) html += ` <span class="line-count">(${lines.length} lines)</span>`;
|
|
}
|
|
html += '</div>';
|
|
|
|
if (content === null) {
|
|
html += `<div class="tool-error">[invalid content arg - expected string]</div>`;
|
|
} else if (content) {
|
|
const lang = filePath ? getLanguageFromPath(filePath) : null;
|
|
html += formatExpandableOutput(content, 10, lang);
|
|
}
|
|
if (result) {
|
|
const output = getResultText().trim();
|
|
if (output) html += `<div class="tool-output"><div>${escapeHtml(output)}</div></div>`;
|
|
}
|
|
break;
|
|
}
|
|
case 'edit': {
|
|
const filePath = str(args.file_path ?? args.path);
|
|
html += `<div class="tool-header"><span class="tool-name">edit</span> <span class="tool-path">${filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''))}</span></div>`;
|
|
|
|
if (result?.details?.diff) {
|
|
const diffLines = result.details.diff.split('\n');
|
|
html += '<div class="tool-diff">';
|
|
for (const line of diffLines) {
|
|
const cls = line.match(/^\+/) ? 'diff-added' : line.match(/^-/) ? 'diff-removed' : 'diff-context';
|
|
html += `<div class="${cls}">${escapeHtml(replaceTabs(line))}</div>`;
|
|
}
|
|
html += '</div>';
|
|
} else if (result) {
|
|
const output = getResultText().trim();
|
|
if (output) html += `<div class="tool-output"><pre>${escapeHtml(output)}</pre></div>`;
|
|
}
|
|
break;
|
|
}
|
|
case 'ls': {
|
|
const dirPath = str(args.path);
|
|
const limit = args.limit;
|
|
|
|
let pathHtml = dirPath === null ? invalidArg : escapeHtml(shortenPath(dirPath || '.'));
|
|
if (limit !== undefined) {
|
|
pathHtml += ` <span class="line-count">(limit ${escapeHtml(String(limit))})</span>`;
|
|
}
|
|
|
|
html += `<div class="tool-header"><span class="tool-name">ls</span> <span class="tool-path">${pathHtml}</span></div>`;
|
|
if (result) {
|
|
const output = getResultText().trim();
|
|
if (output) html += formatExpandableOutput(output, 20);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
// Check for pre-rendered custom tool HTML
|
|
const rendered = renderedTools?.[call.id];
|
|
if (rendered?.callHtml || rendered?.resultHtmlCollapsed || rendered?.resultHtmlExpanded) {
|
|
// Custom tool with pre-rendered HTML from TUI renderer
|
|
if (rendered.callHtml) {
|
|
html += `<div class="tool-header ansi-rendered">${rendered.callHtml}</div>`;
|
|
} else {
|
|
html += `<div class="tool-header"><span class="tool-name">${escapeHtml(name)}</span></div>`;
|
|
}
|
|
|
|
if (rendered.resultHtmlCollapsed && rendered.resultHtmlExpanded && rendered.resultHtmlCollapsed !== rendered.resultHtmlExpanded) {
|
|
// Both collapsed and expanded differ - render expandable section
|
|
html += `<div class="tool-output expandable ansi-rendered" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
|
|
<div class="output-preview">${rendered.resultHtmlCollapsed}</div>
|
|
<div class="output-full">${rendered.resultHtmlExpanded}</div>
|
|
</div>`;
|
|
} else if (rendered.resultHtmlExpanded) {
|
|
// Only expanded exists (or collapsed is identical) - show directly
|
|
html += `<div class="tool-output ansi-rendered">${rendered.resultHtmlExpanded}</div>`;
|
|
} else if (result) {
|
|
// No pre-rendered result HTML - fallback to JSON
|
|
const output = getResultText();
|
|
if (output) html += formatExpandableOutput(output, 10);
|
|
}
|
|
} else {
|
|
// Fallback to JSON display (existing behavior)
|
|
html += `<div class="tool-header"><span class="tool-name">${escapeHtml(name)}</span></div>`;
|
|
html += `<div class="tool-output"><pre>${escapeHtml(JSON.stringify(args, null, 2))}</pre></div>`;
|
|
if (result) {
|
|
const output = getResultText();
|
|
if (output) html += formatExpandableOutput(output, 10);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
html += '</div>';
|
|
return html;
|
|
}
|
|
|
|
/**
|
|
* Download the session data as a JSONL file.
|
|
* Reconstructs the original format: header line + entry lines.
|
|
*/
|
|
window.downloadSessionJson = function() {
|
|
// Build JSONL content: header first, then all entries
|
|
const lines = [];
|
|
if (header) {
|
|
lines.push(JSON.stringify({ type: 'header', ...header }));
|
|
}
|
|
for (const entry of entries) {
|
|
lines.push(JSON.stringify(entry));
|
|
}
|
|
const jsonlContent = lines.join('\n');
|
|
|
|
// Create download
|
|
const blob = new Blob([jsonlContent], { type: 'application/x-ndjson' });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = `${header?.id || 'session'}.jsonl`;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
/**
|
|
* Build a shareable URL for a specific message.
|
|
* URL format: base?gistId&leafId=<leafId>&targetId=<entryId>
|
|
*/
|
|
function buildShareUrl(entryId) {
|
|
// Check for injected base URL (used when loaded in iframe via srcdoc)
|
|
const baseUrlMeta = document.querySelector('meta[name="pi-share-base-url"]');
|
|
const baseUrl = baseUrlMeta ? baseUrlMeta.content : window.location.href.split('?')[0];
|
|
|
|
const url = new URL(window.location.href);
|
|
// Find the gist ID (first query param without value, e.g., ?abc123)
|
|
const gistId = Array.from(url.searchParams.keys()).find(k => !url.searchParams.get(k));
|
|
|
|
// Build the share URL
|
|
const params = new URLSearchParams();
|
|
params.set('leafId', currentLeafId);
|
|
params.set('targetId', entryId);
|
|
|
|
// If we have an injected base URL (iframe context), use it directly
|
|
if (baseUrlMeta) {
|
|
return `${baseUrl}&${params.toString()}`;
|
|
}
|
|
|
|
// Otherwise build from current location (direct file access)
|
|
url.search = gistId ? `?${gistId}&${params.toString()}` : `?${params.toString()}`;
|
|
return url.toString();
|
|
}
|
|
|
|
/**
|
|
* Copy text to clipboard with visual feedback.
|
|
* Uses navigator.clipboard with fallback to execCommand for HTTP contexts.
|
|
*/
|
|
async function copyToClipboard(text, button) {
|
|
let success = false;
|
|
try {
|
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
await navigator.clipboard.writeText(text);
|
|
success = true;
|
|
}
|
|
} catch (err) {
|
|
// Clipboard API failed, try fallback
|
|
}
|
|
|
|
// Fallback for HTTP or when Clipboard API is unavailable
|
|
if (!success) {
|
|
try {
|
|
const textarea = document.createElement('textarea');
|
|
textarea.value = text;
|
|
textarea.style.position = 'fixed';
|
|
textarea.style.opacity = '0';
|
|
document.body.appendChild(textarea);
|
|
textarea.select();
|
|
success = document.execCommand('copy');
|
|
document.body.removeChild(textarea);
|
|
} catch (err) {
|
|
console.error('Failed to copy:', err);
|
|
}
|
|
}
|
|
|
|
if (success && button) {
|
|
const originalHtml = button.innerHTML;
|
|
button.innerHTML = '✓';
|
|
button.classList.add('copied');
|
|
setTimeout(() => {
|
|
button.innerHTML = originalHtml;
|
|
button.classList.remove('copied');
|
|
}, 1500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render the copy-link button HTML for a message.
|
|
*/
|
|
function renderCopyLinkButton(entryId) {
|
|
return `<button class="copy-link-btn" data-entry-id="${escapeHtml(entryId)}" title="Copy link to this message">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
|
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
|
</svg>
|
|
</button>`;
|
|
}
|
|
|
|
function renderEntry(entry) {
|
|
const ts = formatTimestamp(entry.timestamp);
|
|
const tsHtml = ts ? `<div class="message-timestamp">${ts}</div>` : '';
|
|
const entryDomId = `entry-${escapeHtml(entry.id)}`;
|
|
const copyBtnHtml = renderCopyLinkButton(entry.id);
|
|
|
|
if (entry.type === 'message') {
|
|
const msg = entry.message;
|
|
|
|
if (msg.role === 'user') {
|
|
const content = msg.content;
|
|
const text = typeof content === 'string' ? content :
|
|
content.filter(c => c.type === 'text').map(c => c.text).join('\n');
|
|
const skillBlock = parseSkillBlock(text);
|
|
|
|
if (skillBlock) {
|
|
// Collect images from content array
|
|
const images = Array.isArray(content) ? content.filter(c => c.type === 'image') : [];
|
|
const hasUserContent = skillBlock.userMessage || images.length > 0;
|
|
let html = `<div class="skill-user-entry" id="${entryDomId}">${copyBtnHtml}${tsHtml}`;
|
|
|
|
// Skill invocation (collapsed by default, click to expand)
|
|
html += `<div class="skill-invocation" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
|
|
<div class="skill-invocation-label">[skill] ${escapeHtml(skillBlock.name)}</div>
|
|
<div class="skill-invocation-collapsed">${escapeHtml(skillBlock.name)} (click to expand)</div>
|
|
<div class="skill-invocation-content markdown-content">${safeMarkedParse(skillBlock.content)}</div>
|
|
</div>`;
|
|
|
|
// User message (separate block if present)
|
|
if (hasUserContent) {
|
|
html += '<div class="user-message">';
|
|
if (images.length > 0) {
|
|
html += '<div class="message-images">';
|
|
for (const img of images) {
|
|
html += `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${escapeHtml(img.data || '')}" class="message-image" />`;
|
|
}
|
|
html += '</div>';
|
|
}
|
|
if (skillBlock.userMessage) {
|
|
html += `<div class="markdown-content">${safeMarkedParse(skillBlock.userMessage)}</div>`;
|
|
}
|
|
html += '</div>';
|
|
}
|
|
|
|
html += '</div>';
|
|
return html;
|
|
}
|
|
|
|
// No skill block - normal user message
|
|
let html = `<div class="user-message" id="${entryDomId}">${copyBtnHtml}${tsHtml}`;
|
|
|
|
if (Array.isArray(content)) {
|
|
const images = content.filter(c => c.type === 'image');
|
|
if (images.length > 0) {
|
|
html += '<div class="message-images">';
|
|
for (const img of images) {
|
|
html += `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${escapeHtml(img.data || '')}" class="message-image" />`;
|
|
}
|
|
html += '</div>';
|
|
}
|
|
}
|
|
|
|
if (text.trim()) {
|
|
html += `<div class="markdown-content">${safeMarkedParse(text)}</div>`;
|
|
}
|
|
html += '</div>';
|
|
return html;
|
|
}
|
|
|
|
if (msg.role === 'assistant') {
|
|
let html = `<div class="assistant-message" id="${entryDomId}">${copyBtnHtml}${tsHtml}`;
|
|
|
|
for (const block of msg.content) {
|
|
if (block.type === 'text' && block.text.trim()) {
|
|
html += `<div class="assistant-text markdown-content">${safeMarkedParse(block.text)}</div>`;
|
|
} else if (block.type === 'thinking' && block.thinking.trim()) {
|
|
html += `<div class="thinking-block">
|
|
<div class="thinking-text">${escapeHtml(block.thinking)}</div>
|
|
<div class="thinking-collapsed">Thinking ...</div>
|
|
</div>`;
|
|
}
|
|
}
|
|
|
|
for (const block of msg.content) {
|
|
if (block.type === 'toolCall') {
|
|
html += renderToolCall(block);
|
|
}
|
|
}
|
|
|
|
if (msg.stopReason === 'aborted') {
|
|
html += '<div class="error-text">Aborted</div>';
|
|
} else if (msg.stopReason === 'error') {
|
|
html += `<div class="error-text">Error: ${escapeHtml(msg.errorMessage || 'Unknown error')}</div>`;
|
|
}
|
|
|
|
html += '</div>';
|
|
return html;
|
|
}
|
|
|
|
if (msg.role === 'bashExecution') {
|
|
const isError = msg.cancelled || (msg.exitCode !== 0 && msg.exitCode !== null);
|
|
let html = `<div class="tool-execution ${isError ? 'error' : 'success'}" id="${entryDomId}">${tsHtml}`;
|
|
html += `<div class="tool-command">$ ${escapeHtml(msg.command)}</div>`;
|
|
if (msg.output) html += formatExpandableOutput(msg.output, 10);
|
|
if (msg.cancelled) {
|
|
html += '<div style="color: var(--warning)">(cancelled)</div>';
|
|
} else if (msg.exitCode !== 0 && msg.exitCode !== null) {
|
|
html += `<div style="color: var(--error)">(exit ${msg.exitCode})</div>`;
|
|
}
|
|
html += '</div>';
|
|
return html;
|
|
}
|
|
|
|
if (msg.role === 'toolResult') return '';
|
|
}
|
|
|
|
if (entry.type === 'model_change') {
|
|
return `<div class="model-change" id="${entryDomId}">${tsHtml}Switched to model: <span class="model-name">${escapeHtml(entry.provider)}/${escapeHtml(entry.modelId)}</span></div>`;
|
|
}
|
|
|
|
if (entry.type === 'compaction') {
|
|
return `<div class="compaction" id="${entryDomId}" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
|
|
<div class="compaction-label">[compaction]</div>
|
|
<div class="compaction-collapsed">Compacted from ${entry.tokensBefore.toLocaleString()} tokens</div>
|
|
<div class="compaction-content"><strong>Compacted from ${entry.tokensBefore.toLocaleString()} tokens</strong>\n\n${escapeHtml(entry.summary)}</div>
|
|
</div>`;
|
|
}
|
|
|
|
if (entry.type === 'branch_summary') {
|
|
return `<div class="branch-summary" id="${entryDomId}">${tsHtml}
|
|
<div class="branch-summary-header">Branch Summary</div>
|
|
<div class="markdown-content">${safeMarkedParse(entry.summary)}</div>
|
|
</div>`;
|
|
}
|
|
|
|
if (entry.type === 'custom_message' && entry.display) {
|
|
return `<div class="hook-message" id="${entryDomId}">${tsHtml}
|
|
<div class="hook-type">[${escapeHtml(entry.customType)}]</div>
|
|
<div class="markdown-content">${safeMarkedParse(typeof entry.content === 'string' ? entry.content : JSON.stringify(entry.content))}</div>
|
|
</div>`;
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
// ============================================================
|
|
// HEADER / STATS
|
|
// ============================================================
|
|
|
|
function computeStats(entryList) {
|
|
let userMessages = 0, assistantMessages = 0, toolResults = 0;
|
|
let customMessages = 0, compactions = 0, branchSummaries = 0, toolCalls = 0;
|
|
const tokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
const cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
const models = new Set();
|
|
|
|
for (const entry of entryList) {
|
|
if (entry.type === 'message') {
|
|
const msg = entry.message;
|
|
if (msg.role === 'user') userMessages++;
|
|
if (msg.role === 'assistant') {
|
|
assistantMessages++;
|
|
if (msg.model) models.add(msg.provider ? `${msg.provider}/${msg.model}` : msg.model);
|
|
if (msg.usage) {
|
|
tokens.input += msg.usage.input || 0;
|
|
tokens.output += msg.usage.output || 0;
|
|
tokens.cacheRead += msg.usage.cacheRead || 0;
|
|
tokens.cacheWrite += msg.usage.cacheWrite || 0;
|
|
if (msg.usage.cost) {
|
|
cost.input += msg.usage.cost.input || 0;
|
|
cost.output += msg.usage.cost.output || 0;
|
|
cost.cacheRead += msg.usage.cost.cacheRead || 0;
|
|
cost.cacheWrite += msg.usage.cost.cacheWrite || 0;
|
|
}
|
|
}
|
|
toolCalls += msg.content.filter(c => c.type === 'toolCall').length;
|
|
}
|
|
if (msg.role === 'toolResult') toolResults++;
|
|
} else if (entry.type === 'compaction') {
|
|
compactions++;
|
|
} else if (entry.type === 'branch_summary') {
|
|
branchSummaries++;
|
|
} else if (entry.type === 'custom_message') {
|
|
customMessages++;
|
|
}
|
|
}
|
|
|
|
return { userMessages, assistantMessages, toolResults, customMessages, compactions, branchSummaries, toolCalls, tokens, cost, models: Array.from(models) };
|
|
}
|
|
|
|
const globalStats = computeStats(entries);
|
|
|
|
function renderHeader() {
|
|
const totalCost = globalStats.cost.input + globalStats.cost.output + globalStats.cost.cacheRead + globalStats.cost.cacheWrite;
|
|
|
|
const tokenParts = [];
|
|
if (globalStats.tokens.input) tokenParts.push(`↑${formatTokens(globalStats.tokens.input)}`);
|
|
if (globalStats.tokens.output) tokenParts.push(`↓${formatTokens(globalStats.tokens.output)}`);
|
|
if (globalStats.tokens.cacheRead) tokenParts.push(`R${formatTokens(globalStats.tokens.cacheRead)}`);
|
|
if (globalStats.tokens.cacheWrite) tokenParts.push(`W${formatTokens(globalStats.tokens.cacheWrite)}`);
|
|
|
|
const msgParts = [];
|
|
if (globalStats.userMessages) msgParts.push(`${globalStats.userMessages} user`);
|
|
if (globalStats.assistantMessages) msgParts.push(`${globalStats.assistantMessages} assistant`);
|
|
if (globalStats.toolResults) msgParts.push(`${globalStats.toolResults} tool results`);
|
|
if (globalStats.customMessages) msgParts.push(`${globalStats.customMessages} custom`);
|
|
if (globalStats.compactions) msgParts.push(`${globalStats.compactions} compactions`);
|
|
if (globalStats.branchSummaries) msgParts.push(`${globalStats.branchSummaries} branch summaries`);
|
|
|
|
let html = `
|
|
<div class="header">
|
|
<h1>Session: ${escapeHtml(header?.id || 'unknown')}</h1>
|
|
<div class="help-bar">
|
|
<span class="help-hint">T toggle thinking · O toggle tools</span>
|
|
<div class="help-actions">
|
|
<button type="button" class="header-toggle-btn" data-action="toggle-thinking" title="Toggle thinking (T)">Toggle thinking</button>
|
|
<button type="button" class="header-toggle-btn" data-action="toggle-tools" title="Toggle tools (O)">Toggle tools</button>
|
|
<button type="button" class="download-json-btn" onclick="downloadSessionJson()" title="Download session as JSONL">↓ JSONL</button>
|
|
</div>
|
|
</div>
|
|
<div class="header-info">
|
|
<div class="info-item"><span class="info-label">Date:</span><span class="info-value">${header?.timestamp ? new Date(header.timestamp).toLocaleString() : 'unknown'}</span></div>
|
|
<div class="info-item"><span class="info-label">Models:</span><span class="info-value">${escapeHtml(globalStats.models.join(', ') || 'unknown')}</span></div>
|
|
<div class="info-item"><span class="info-label">Messages:</span><span class="info-value">${msgParts.join(', ') || '0'}</span></div>
|
|
<div class="info-item"><span class="info-label">Tool Calls:</span><span class="info-value">${globalStats.toolCalls}</span></div>
|
|
<div class="info-item"><span class="info-label">Tokens:</span><span class="info-value">${tokenParts.join(' ') || '0'}</span></div>
|
|
<div class="info-item"><span class="info-label">Cost:</span><span class="info-value">${totalCost.toFixed(3)}</span></div>
|
|
</div>
|
|
</div>`;
|
|
|
|
// Render system prompt (user's base prompt, applies to all providers)
|
|
if (systemPrompt) {
|
|
const lines = systemPrompt.split('\n');
|
|
const previewLines = 10;
|
|
if (lines.length > previewLines) {
|
|
const preview = lines.slice(0, previewLines).join('\n');
|
|
const remaining = lines.length - previewLines;
|
|
html += `<div class="system-prompt expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
|
|
<div class="system-prompt-header">System Prompt</div>
|
|
<div class="system-prompt-preview">${escapeHtml(preview)}</div>
|
|
<div class="system-prompt-expand-hint">... (${remaining} more lines, click to expand)</div>
|
|
<div class="system-prompt-full">${escapeHtml(systemPrompt)}</div>
|
|
</div>`;
|
|
} else {
|
|
html += `<div class="system-prompt">
|
|
<div class="system-prompt-header">System Prompt</div>
|
|
<div class="system-prompt-full" style="display: block">${escapeHtml(systemPrompt)}</div>
|
|
</div>`;
|
|
}
|
|
}
|
|
|
|
if (tools && tools.length > 0) {
|
|
html += `<div class="tools-list">
|
|
<div class="tools-header">Available Tools</div>
|
|
<div class="tools-content">
|
|
${tools.map(t => {
|
|
const hasParams = t.parameters && typeof t.parameters === 'object' && t.parameters.properties && Object.keys(t.parameters.properties).length > 0;
|
|
if (!hasParams) {
|
|
return `<div class="tool-item"><span class="tool-item-name">${escapeHtml(t.name)}</span> - <span class="tool-item-desc">${escapeHtml(t.description)}</span></div>`;
|
|
}
|
|
const params = t.parameters;
|
|
const properties = params.properties;
|
|
const required = params.required || [];
|
|
let paramsHtml = '';
|
|
for (const [name, prop] of Object.entries(properties)) {
|
|
const isRequired = required.includes(name);
|
|
const typeStr = prop.type || 'any';
|
|
const reqLabel = isRequired ? '<span class="tool-param-required">required</span>' : '<span class="tool-param-optional">optional</span>';
|
|
paramsHtml += `<div class="tool-param"><span class="tool-param-name">${escapeHtml(name)}</span> <span class="tool-param-type">${escapeHtml(typeStr)}</span> ${reqLabel}`;
|
|
if (prop.description) {
|
|
paramsHtml += `<div class="tool-param-desc">${escapeHtml(prop.description)}</div>`;
|
|
}
|
|
paramsHtml += `</div>`;
|
|
}
|
|
return `<div class="tool-item" onclick="if(window.getSelection().toString())return;this.classList.toggle('params-expanded')"><span class="tool-item-name">${escapeHtml(t.name)}</span> - <span class="tool-item-desc">${escapeHtml(t.description)}</span> <span class="tool-params-hint"></span><div class="tool-params-content">${paramsHtml}</div></div>`;
|
|
}).join('')}
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
return html;
|
|
}
|
|
|
|
// ============================================================
|
|
// NAVIGATION
|
|
// ============================================================
|
|
|
|
// Cache for rendered entry DOM nodes
|
|
const entryCache = new Map();
|
|
|
|
function getScrollTargetElementId(entryId) {
|
|
const entry = byId.get(entryId);
|
|
if (entry?.type === 'message' && entry.message.role === 'toolResult' && entry.message.toolCallId) {
|
|
// getElementById() matches the parsed DOM id attribute, whose HTML entities
|
|
// were already resolved from the escaped id rendered by renderToolCall().
|
|
return `tool-call-${entry.message.toolCallId}`;
|
|
}
|
|
return `entry-${entryId}`;
|
|
}
|
|
|
|
function renderEntryToNode(entry) {
|
|
// Check cache first
|
|
if (entryCache.has(entry.id)) {
|
|
return entryCache.get(entry.id).cloneNode(true);
|
|
}
|
|
|
|
// Render to HTML string, then parse to node
|
|
const html = renderEntry(entry);
|
|
if (!html) return null;
|
|
|
|
const template = document.createElement('template');
|
|
template.innerHTML = html;
|
|
const node = template.content.firstElementChild;
|
|
|
|
// Cache the node
|
|
if (node) {
|
|
entryCache.set(entry.id, node.cloneNode(true));
|
|
}
|
|
return node;
|
|
}
|
|
|
|
function navigateTo(targetId, scrollMode = 'target', scrollToEntryId = null) {
|
|
currentLeafId = targetId;
|
|
currentTargetId = scrollToEntryId || targetId;
|
|
const path = getPath(targetId);
|
|
|
|
renderTree();
|
|
|
|
document.getElementById('header-container').innerHTML = renderHeader();
|
|
attachHeaderHandlers();
|
|
|
|
// Build messages using cached DOM nodes
|
|
const messagesEl = document.getElementById('messages');
|
|
const fragment = document.createDocumentFragment();
|
|
|
|
for (const entry of path) {
|
|
const node = renderEntryToNode(entry);
|
|
if (node) {
|
|
fragment.appendChild(node);
|
|
}
|
|
}
|
|
|
|
messagesEl.innerHTML = '';
|
|
messagesEl.appendChild(fragment);
|
|
|
|
// Attach click handlers for copy-link buttons
|
|
messagesEl.querySelectorAll('.copy-link-btn').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
const entryId = btn.dataset.entryId;
|
|
const shareUrl = buildShareUrl(entryId);
|
|
copyToClipboard(shareUrl, btn);
|
|
});
|
|
});
|
|
|
|
// Use setTimeout(0) to ensure DOM is fully laid out before scrolling
|
|
setTimeout(() => {
|
|
const content = document.getElementById('content');
|
|
if (scrollMode === 'bottom') {
|
|
content.scrollTop = content.scrollHeight;
|
|
} else if (scrollMode === 'target') {
|
|
// If scrollToEntryId is provided, scroll to that specific entry.
|
|
// Tool result entries are rendered inside their assistant tool-call block,
|
|
// so route them to the visible tool-call element instead.
|
|
const scrollTargetId = scrollToEntryId || targetId;
|
|
const targetEl = document.getElementById(getScrollTargetElementId(scrollTargetId)) ||
|
|
document.getElementById(`entry-${scrollTargetId}`);
|
|
if (targetEl) {
|
|
targetEl.scrollIntoView({ block: 'center' });
|
|
// Briefly highlight the target message
|
|
if (scrollToEntryId) {
|
|
targetEl.classList.add('highlight');
|
|
setTimeout(() => targetEl.classList.remove('highlight'), 2000);
|
|
}
|
|
}
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
// ============================================================
|
|
// INITIALIZATION
|
|
// ============================================================
|
|
|
|
// Configure marked with syntax highlighting and TUI-compatible HTML handling
|
|
const strictStrikethroughRegex = /^(~~)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/;
|
|
|
|
marked.use({
|
|
breaks: true,
|
|
gfm: true,
|
|
tokenizer: {
|
|
// Treat HTML-like input as plain text so tags are shown verbatim,
|
|
// matching the TUI markdown renderer.
|
|
html() {
|
|
return undefined;
|
|
},
|
|
tag() {
|
|
return undefined;
|
|
},
|
|
del(src) {
|
|
const match = strictStrikethroughRegex.exec(src);
|
|
if (!match) return undefined;
|
|
return {
|
|
type: 'del',
|
|
raw: match[0],
|
|
text: match[2],
|
|
tokens: this.lexer.inlineTokens(match[2])
|
|
};
|
|
}
|
|
},
|
|
renderer: {
|
|
// Sanitize link URLs with a scheme allow-list. Browsers strip C0
|
|
// controls from schemes, so strip them before checking and emitting.
|
|
link(token) {
|
|
const href = sanitizeMarkdownUrl(token.href);
|
|
if (href === null) {
|
|
return this.parser.parseInline(token.tokens);
|
|
}
|
|
let out = '<a href="' + escapeHtml(href) + '"';
|
|
if (token.title) {
|
|
out += ' title="' + escapeHtml(token.title) + '"';
|
|
}
|
|
out += '>' + this.parser.parseInline(token.tokens) + '</a>';
|
|
return out;
|
|
},
|
|
// Sanitize image src URLs with the same scheme allow-list.
|
|
image(token) {
|
|
const href = sanitizeMarkdownUrl(token.href);
|
|
if (href === null) {
|
|
return escapeHtml(token.text || '');
|
|
}
|
|
let out = '<img src="' + escapeHtml(href) + '" alt="' + escapeHtml(token.text || '') + '"';
|
|
if (token.title) {
|
|
out += ' title="' + escapeHtml(token.title) + '"';
|
|
}
|
|
out += '>';
|
|
return out;
|
|
},
|
|
// Code blocks: syntax highlight, no HTML escaping
|
|
code(token) {
|
|
const code = token.text;
|
|
const lang = token.lang;
|
|
let highlighted;
|
|
if (lang && hljs.getLanguage(lang)) {
|
|
try {
|
|
highlighted = hljs.highlight(code, { language: lang }).value;
|
|
} catch {
|
|
highlighted = escapeHtml(code);
|
|
}
|
|
} else {
|
|
// Auto-detect language if not specified
|
|
try {
|
|
highlighted = hljs.highlightAuto(code).value;
|
|
} catch {
|
|
highlighted = escapeHtml(code);
|
|
}
|
|
}
|
|
return `<pre><code class="hljs">${highlighted}</code></pre>`;
|
|
},
|
|
// Inline code: escape HTML
|
|
codespan(token) {
|
|
return `<code>${escapeHtml(token.text)}</code>`;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Simple marked parse (escaping handled in renderers)
|
|
function safeMarkedParse(text) {
|
|
return marked.parse(text);
|
|
}
|
|
|
|
// Search input
|
|
const searchInput = document.getElementById('tree-search');
|
|
searchInput.addEventListener('input', (e) => {
|
|
searchQuery = e.target.value;
|
|
forceTreeRerender();
|
|
});
|
|
|
|
// Filter buttons
|
|
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
|
|
btn.classList.add('active');
|
|
filterMode = btn.dataset.filter;
|
|
forceTreeRerender();
|
|
});
|
|
});
|
|
|
|
// Sidebar toggle
|
|
const sidebar = document.getElementById('sidebar');
|
|
const overlay = document.getElementById('sidebar-overlay');
|
|
const hamburger = document.getElementById('hamburger');
|
|
const sidebarResizer = document.getElementById('sidebar-resizer');
|
|
const SIDEBAR_WIDTH_STORAGE_KEY = 'pi-share:v1:sidebar-width';
|
|
const MIN_CONTENT_WIDTH = 320;
|
|
|
|
function isMobileLayout() {
|
|
return window.matchMedia('(max-width: 900px)').matches;
|
|
}
|
|
|
|
function getSidebarBounds() {
|
|
const rootStyles = getComputedStyle(document.documentElement);
|
|
const minWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-min-width')) || 240;
|
|
const maxWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-max-width')) || 720;
|
|
const viewportMaxWidth = window.innerWidth - MIN_CONTENT_WIDTH;
|
|
return {
|
|
minWidth,
|
|
maxWidth: Math.max(minWidth, Math.min(maxWidth, viewportMaxWidth))
|
|
};
|
|
}
|
|
|
|
function clampSidebarWidth(width) {
|
|
const { minWidth, maxWidth } = getSidebarBounds();
|
|
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
}
|
|
|
|
function applySidebarWidth(width) {
|
|
document.documentElement.style.setProperty('--sidebar-width', `${Math.round(clampSidebarWidth(width))}px`);
|
|
}
|
|
|
|
function loadSidebarWidth() {
|
|
try {
|
|
const raw = localStorage.getItem(SIDEBAR_WIDTH_STORAGE_KEY);
|
|
if (raw === null) return null;
|
|
const width = Number(raw);
|
|
return Number.isFinite(width) ? width : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function saveSidebarWidth(width) {
|
|
try {
|
|
localStorage.setItem(SIDEBAR_WIDTH_STORAGE_KEY, String(Math.round(clampSidebarWidth(width))));
|
|
} catch {
|
|
// Ignore storage failures (e.g. private browsing restrictions)
|
|
}
|
|
}
|
|
|
|
function setupSidebarResize() {
|
|
const savedWidth = loadSidebarWidth();
|
|
if (savedWidth !== null) {
|
|
applySidebarWidth(savedWidth);
|
|
}
|
|
|
|
if (!sidebarResizer) return;
|
|
|
|
let cleanupDrag = null;
|
|
|
|
const stopDrag = (pointerId) => {
|
|
if (cleanupDrag) {
|
|
cleanupDrag(pointerId);
|
|
cleanupDrag = null;
|
|
}
|
|
};
|
|
|
|
sidebarResizer.addEventListener('pointerdown', (e) => {
|
|
if (isMobileLayout()) return;
|
|
|
|
e.preventDefault();
|
|
const startX = e.clientX;
|
|
const startWidth = sidebar.getBoundingClientRect().width;
|
|
document.body.classList.add('sidebar-resizing');
|
|
sidebarResizer.setPointerCapture?.(e.pointerId);
|
|
|
|
const onPointerMove = (event) => {
|
|
applySidebarWidth(startWidth + (event.clientX - startX));
|
|
};
|
|
|
|
cleanupDrag = (pointerIdToRelease) => {
|
|
document.body.classList.remove('sidebar-resizing');
|
|
sidebarResizer.releasePointerCapture?.(pointerIdToRelease);
|
|
window.removeEventListener('pointermove', onPointerMove);
|
|
window.removeEventListener('pointerup', onPointerUp);
|
|
window.removeEventListener('pointercancel', onPointerCancel);
|
|
saveSidebarWidth(sidebar.getBoundingClientRect().width);
|
|
};
|
|
|
|
const onPointerUp = (event) => stopDrag(event.pointerId);
|
|
const onPointerCancel = (event) => stopDrag(event.pointerId);
|
|
|
|
window.addEventListener('pointermove', onPointerMove);
|
|
window.addEventListener('pointerup', onPointerUp);
|
|
window.addEventListener('pointercancel', onPointerCancel);
|
|
});
|
|
|
|
sidebarResizer.addEventListener('dblclick', () => {
|
|
if (isMobileLayout()) return;
|
|
applySidebarWidth(400);
|
|
saveSidebarWidth(400);
|
|
});
|
|
|
|
window.addEventListener('resize', () => {
|
|
if (isMobileLayout()) return;
|
|
applySidebarWidth(sidebar.getBoundingClientRect().width);
|
|
});
|
|
}
|
|
|
|
setupSidebarResize();
|
|
|
|
hamburger.addEventListener('click', () => {
|
|
sidebar.classList.add('open');
|
|
overlay.classList.add('open');
|
|
hamburger.style.display = 'none';
|
|
});
|
|
|
|
const closeSidebar = () => {
|
|
sidebar.classList.remove('open');
|
|
overlay.classList.remove('open');
|
|
hamburger.style.display = '';
|
|
};
|
|
|
|
overlay.addEventListener('click', closeSidebar);
|
|
document.getElementById('sidebar-close').addEventListener('click', closeSidebar);
|
|
|
|
// Toggle states
|
|
let thinkingExpanded = true;
|
|
let toolOutputsExpanded = false;
|
|
|
|
const toggleThinking = () => {
|
|
thinkingExpanded = !thinkingExpanded;
|
|
document.querySelectorAll('.thinking-text').forEach(el => {
|
|
el.style.display = thinkingExpanded ? '' : 'none';
|
|
});
|
|
document.querySelectorAll('.thinking-collapsed').forEach(el => {
|
|
el.style.display = thinkingExpanded ? 'none' : 'block';
|
|
});
|
|
};
|
|
|
|
const toggleToolOutputs = () => {
|
|
toolOutputsExpanded = !toolOutputsExpanded;
|
|
document.querySelectorAll('.tool-output.expandable').forEach(el => {
|
|
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
});
|
|
document.querySelectorAll('.compaction').forEach(el => {
|
|
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
});
|
|
document.querySelectorAll('.skill-invocation').forEach(el => {
|
|
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
});
|
|
};
|
|
|
|
const attachHeaderHandlers = () => {
|
|
document.querySelector('[data-action="toggle-thinking"]')?.addEventListener('click', toggleThinking);
|
|
document.querySelector('[data-action="toggle-tools"]')?.addEventListener('click', toggleToolOutputs);
|
|
};
|
|
|
|
const isEditableTarget = (element) => {
|
|
if (!element) return false;
|
|
const tagName = element.tagName;
|
|
if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT' || tagName === 'BUTTON') {
|
|
return true;
|
|
}
|
|
return element.isContentEditable || Boolean(element.closest?.('[contenteditable="true"]'));
|
|
};
|
|
|
|
// Keyboard shortcuts
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') {
|
|
searchInput.value = '';
|
|
searchQuery = '';
|
|
navigateTo(leafId, 'bottom');
|
|
}
|
|
|
|
if (isEditableTarget(document.activeElement)) {
|
|
return;
|
|
}
|
|
|
|
const key = e.key.toLowerCase();
|
|
if (key === 't') {
|
|
e.preventDefault();
|
|
toggleThinking();
|
|
} else if (key === 'o') {
|
|
e.preventDefault();
|
|
toggleToolOutputs();
|
|
}
|
|
});
|
|
|
|
// Initial render
|
|
// If URL has targetId, scroll to that specific message; otherwise stay at top
|
|
if (leafId) {
|
|
if (urlTargetId && byId.has(urlTargetId)) {
|
|
// Deep link: navigate to leaf and scroll to target message
|
|
navigateTo(leafId, 'target', urlTargetId);
|
|
} else {
|
|
navigateTo(leafId, 'none');
|
|
}
|
|
} else if (entries.length > 0) {
|
|
// Fallback: use last entry if no leafId
|
|
navigateTo(entries[entries.length - 1].id, 'none');
|
|
}
|
|
})();
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|