@dollhousemcp/mcp-server 2.0.10 → 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-dollhouse/portDiscovery.d.ts +23 -0
- package/dist/auto-dollhouse/portDiscovery.d.ts.map +1 -0
- package/dist/auto-dollhouse/portDiscovery.js +77 -0
- package/dist/cli/console-token.d.ts +18 -0
- package/dist/cli/console-token.d.ts.map +1 -0
- package/dist/cli/console-token.js +187 -0
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -5
- package/dist/web/console/consoleToken.d.ts +403 -0
- package/dist/web/console/consoleToken.d.ts.map +1 -0
- package/dist/web/console/consoleToken.js +930 -0
- package/dist/web/middleware/authMiddleware.d.ts +64 -0
- package/dist/web/middleware/authMiddleware.d.ts.map +1 -0
- package/dist/web/middleware/authMiddleware.js +174 -0
- package/dist/web/routes/consoleRouteHelpers.d.ts +33 -0
- package/dist/web/routes/consoleRouteHelpers.d.ts.map +1 -0
- package/dist/web/routes/consoleRouteHelpers.js +60 -0
- package/dist/web/routes/tokenRoutes.d.ts +37 -0
- package/dist/web/routes/tokenRoutes.d.ts.map +1 -0
- package/dist/web/routes/tokenRoutes.js +95 -0
- package/dist/web/routes/totpRoutes.d.ts +45 -0
- package/dist/web/routes/totpRoutes.d.ts.map +1 -0
- package/dist/web/routes/totpRoutes.js +187 -0
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/constants/version.d.ts +0 -3
- package/dist/constants/version.d.ts.map +0 -1
- package/dist/constants/version.js +0 -4
- package/dist/logging/sinks/SSELogSink.d.ts +0 -35
- package/dist/logging/sinks/SSELogSink.d.ts.map +0 -1
- package/dist/logging/sinks/SSELogSink.js +0 -181
- package/dist/logging/viewer/viewerHtml.d.ts +0 -8
- package/dist/logging/viewer/viewerHtml.d.ts.map +0 -1
- package/dist/logging/viewer/viewerHtml.js +0 -204
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Embedded HTML template for the DollhouseMCP Log Viewer.
|
|
3
|
-
*
|
|
4
|
-
* Returns a self-contained vanilla JS/CSS page that connects to the
|
|
5
|
-
* SSELogSink's /logs/stream endpoint via EventSource. See docs/LOGGING-DESIGN.md §4.6.
|
|
6
|
-
*/
|
|
7
|
-
export function getViewerHtml(port) {
|
|
8
|
-
return /* html */ `<!DOCTYPE html>
|
|
9
|
-
<html lang="en">
|
|
10
|
-
<head>
|
|
11
|
-
<meta charset="utf-8">
|
|
12
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
13
|
-
<title>DollhouseMCP Log Viewer</title>
|
|
14
|
-
<style>
|
|
15
|
-
*{box-sizing:border-box;margin:0;padding:0}
|
|
16
|
-
body{background:#1a1a2e;color:#e0e0e0;font-family:'Cascadia Code','Fira Code',monospace;font-size:13px}
|
|
17
|
-
#controls{display:flex;gap:8px;padding:8px 12px;background:#16213e;border-bottom:1px solid #0f3460;align-items:center;flex-wrap:wrap}
|
|
18
|
-
#controls label{color:#94a3b8;font-size:12px}
|
|
19
|
-
#controls select,#controls input{background:#1a1a2e;color:#e0e0e0;border:1px solid #0f3460;border-radius:4px;padding:4px 8px;font-family:inherit;font-size:12px}
|
|
20
|
-
#controls select:focus,#controls input:focus{outline:none;border-color:#e94560}
|
|
21
|
-
button{background:#0f3460;color:#e0e0e0;border:1px solid #0f3460;border-radius:4px;padding:4px 12px;cursor:pointer;font-family:inherit;font-size:12px}
|
|
22
|
-
button:hover{background:#e94560;border-color:#e94560}
|
|
23
|
-
#status{margin-left:auto;font-size:11px;padding:2px 8px;border-radius:10px}
|
|
24
|
-
.connected{background:#064e3b;color:#6ee7b7}
|
|
25
|
-
.disconnected{background:#7f1d1d;color:#fca5a5}
|
|
26
|
-
.paused{background:#78350f;color:#fcd34d}
|
|
27
|
-
#log{overflow-y:auto;height:calc(100vh - 44px);padding:8px 12px}
|
|
28
|
-
.entry{padding:2px 0;white-space:pre-wrap;word-break:break-word;border-bottom:1px solid #1e293b}
|
|
29
|
-
.entry:hover{background:#16213e}
|
|
30
|
-
.lvl-error{color:#f87171}
|
|
31
|
-
.lvl-warn{color:#fbbf24}
|
|
32
|
-
.lvl-info{color:#60a5fa}
|
|
33
|
-
.lvl-debug{color:#9ca3af}
|
|
34
|
-
.ts{color:#64748b}
|
|
35
|
-
.cat{color:#a78bfa}
|
|
36
|
-
.src{color:#2dd4bf}
|
|
37
|
-
.cid{color:#f472b6;font-size:11px;display:inline-block;width:72px;text-align:right;margin-right:4px}
|
|
38
|
-
#search{margin-left:4px}
|
|
39
|
-
</style>
|
|
40
|
-
</head>
|
|
41
|
-
<body>
|
|
42
|
-
<div id="controls">
|
|
43
|
-
<label>Category
|
|
44
|
-
<select id="fCategory">
|
|
45
|
-
<option value="">all</option>
|
|
46
|
-
<option value="application">application</option>
|
|
47
|
-
<option value="security">security</option>
|
|
48
|
-
<option value="performance">performance</option>
|
|
49
|
-
<option value="telemetry">telemetry</option>
|
|
50
|
-
</select>
|
|
51
|
-
</label>
|
|
52
|
-
<label>Level
|
|
53
|
-
<select id="fLevel">
|
|
54
|
-
<option value="">all</option>
|
|
55
|
-
<option value="debug">debug</option>
|
|
56
|
-
<option value="info">info</option>
|
|
57
|
-
<option value="warn">warn</option>
|
|
58
|
-
<option value="error">error</option>
|
|
59
|
-
</select>
|
|
60
|
-
</label>
|
|
61
|
-
<label>Source <input id="fSource" placeholder="substring" size="14"></label>
|
|
62
|
-
<label>RequestId <input id="fCorrelationId" placeholder="correlationId" size="20"></label>
|
|
63
|
-
<label>Search <input id="search" placeholder="message filter" size="18"></label>
|
|
64
|
-
<button id="btnPause">Pause</button>
|
|
65
|
-
<button id="btnClear">Clear</button>
|
|
66
|
-
<span id="status" class="disconnected">disconnected</span>
|
|
67
|
-
</div>
|
|
68
|
-
<div id="log"></div>
|
|
69
|
-
<script>
|
|
70
|
-
(function(){
|
|
71
|
-
var BASE = 'http://127.0.0.1:${port}';
|
|
72
|
-
var MAX_ENTRIES = 1000;
|
|
73
|
-
var log = document.getElementById('log');
|
|
74
|
-
var status = document.getElementById('status');
|
|
75
|
-
var fCategory = document.getElementById('fCategory');
|
|
76
|
-
var fLevel = document.getElementById('fLevel');
|
|
77
|
-
var fSource = document.getElementById('fSource');
|
|
78
|
-
var fCorrelationId = document.getElementById('fCorrelationId');
|
|
79
|
-
var searchBox = document.getElementById('search');
|
|
80
|
-
var btnPause = document.getElementById('btnPause');
|
|
81
|
-
var btnClear = document.getElementById('btnClear');
|
|
82
|
-
var es = null;
|
|
83
|
-
var paused = false;
|
|
84
|
-
var buffer = [];
|
|
85
|
-
|
|
86
|
-
function escHtml(s){
|
|
87
|
-
var d = document.createElement('div');
|
|
88
|
-
d.appendChild(document.createTextNode(s));
|
|
89
|
-
return d.innerHTML;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function setStatus(s, cls){
|
|
93
|
-
status.textContent = s;
|
|
94
|
-
status.className = cls;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
var LEVEL_ORDER = {debug:0, info:1, warn:2, error:3};
|
|
100
|
-
|
|
101
|
-
function matchesFilters(entry){
|
|
102
|
-
var cat = fCategory.value;
|
|
103
|
-
if(cat && entry.category !== cat) return false;
|
|
104
|
-
var lvl = fLevel.value;
|
|
105
|
-
if(lvl && (LEVEL_ORDER[entry.level]||0) < (LEVEL_ORDER[lvl]||0)) return false;
|
|
106
|
-
var src = fSource.value.toLowerCase();
|
|
107
|
-
if(src && (!entry.source || entry.source.toLowerCase().indexOf(src) === -1)) return false;
|
|
108
|
-
var cid = fCorrelationId.value;
|
|
109
|
-
if(cid && entry.correlationId !== cid) return false;
|
|
110
|
-
var needle = searchBox.value.toLowerCase();
|
|
111
|
-
if(needle && (!entry.message || entry.message.toLowerCase().indexOf(needle) === -1)) return false;
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function refilter(){
|
|
116
|
-
var els = log.children;
|
|
117
|
-
for(var i = 0; i < els.length; i++){
|
|
118
|
-
var data = els[i]._entryData;
|
|
119
|
-
if(data){
|
|
120
|
-
els[i].style.display = matchesFilters(data) ? '' : 'none';
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function addEntry(entry){
|
|
126
|
-
if(!matchesFilters(entry)) var hidden = true;
|
|
127
|
-
|
|
128
|
-
var el = document.createElement('div');
|
|
129
|
-
el.className = 'entry lvl-' + entry.level;
|
|
130
|
-
el._entryData = entry;
|
|
131
|
-
if(hidden) el.style.display = 'none';
|
|
132
|
-
var ts = entry.timestamp ? entry.timestamp.slice(11, 23) : '';
|
|
133
|
-
var cid = entry.correlationId ? entry.correlationId.slice(-8) : '';
|
|
134
|
-
el.innerHTML = '<span class="ts">' + escHtml(ts) + '</span> '
|
|
135
|
-
+ '<span class="cid">' + escHtml(cid) + '</span> '
|
|
136
|
-
+ '<span class="cat">[' + escHtml(entry.category) + ']</span> '
|
|
137
|
-
+ '<span class="src">' + escHtml(entry.source) + '</span> '
|
|
138
|
-
+ escHtml(entry.message);
|
|
139
|
-
log.appendChild(el);
|
|
140
|
-
|
|
141
|
-
while(log.children.length > MAX_ENTRIES){
|
|
142
|
-
log.removeChild(log.firstChild);
|
|
143
|
-
}
|
|
144
|
-
if(!hidden) log.scrollTop = log.scrollHeight;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function connect(){
|
|
148
|
-
if(es){ es.close(); }
|
|
149
|
-
es = new EventSource(BASE + '/logs/stream');
|
|
150
|
-
es.onopen = function(){ setStatus('connected', 'connected'); };
|
|
151
|
-
es.onmessage = function(e){
|
|
152
|
-
try{
|
|
153
|
-
var entry = JSON.parse(e.data);
|
|
154
|
-
if(paused){ buffer.push(entry); }
|
|
155
|
-
else { addEntry(entry); }
|
|
156
|
-
}catch(err){}
|
|
157
|
-
};
|
|
158
|
-
es.onerror = function(){ setStatus('disconnected', 'disconnected'); };
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
var filterTimer = null;
|
|
162
|
-
function onFilterChange(){
|
|
163
|
-
clearTimeout(filterTimer);
|
|
164
|
-
filterTimer = setTimeout(refilter, 50);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
fCategory.addEventListener('change', onFilterChange);
|
|
168
|
-
fLevel.addEventListener('change', onFilterChange);
|
|
169
|
-
fSource.addEventListener('input', function(){
|
|
170
|
-
clearTimeout(filterTimer);
|
|
171
|
-
filterTimer = setTimeout(refilter, 400);
|
|
172
|
-
});
|
|
173
|
-
fCorrelationId.addEventListener('input', function(){
|
|
174
|
-
clearTimeout(filterTimer);
|
|
175
|
-
filterTimer = setTimeout(refilter, 400);
|
|
176
|
-
});
|
|
177
|
-
searchBox.addEventListener('input', function(){
|
|
178
|
-
clearTimeout(filterTimer);
|
|
179
|
-
filterTimer = setTimeout(refilter, 400);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
btnPause.addEventListener('click', function(){
|
|
183
|
-
paused = !paused;
|
|
184
|
-
btnPause.textContent = paused ? 'Resume' : 'Pause';
|
|
185
|
-
if(paused){
|
|
186
|
-
setStatus('paused', 'paused');
|
|
187
|
-
} else {
|
|
188
|
-
setStatus('connected', 'connected');
|
|
189
|
-
buffer.forEach(addEntry);
|
|
190
|
-
buffer = [];
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
btnClear.addEventListener('click', function(){
|
|
195
|
-
log.innerHTML = '';
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
connect();
|
|
199
|
-
})();
|
|
200
|
-
</script>
|
|
201
|
-
</body>
|
|
202
|
-
</html>`;
|
|
203
|
-
}
|
|
204
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VySHRtbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sb2dnaW5nL3ZpZXdlci92aWV3ZXJIdG1sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFZO0lBQ3hDLE9BQU8sVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7aUNBK0RhLElBQUk7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBbUk3QixDQUFDO0FBQ1QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRW1iZWRkZWQgSFRNTCB0ZW1wbGF0ZSBmb3IgdGhlIERvbGxob3VzZU1DUCBMb2cgVmlld2VyLlxuICpcbiAqIFJldHVybnMgYSBzZWxmLWNvbnRhaW5lZCB2YW5pbGxhIEpTL0NTUyBwYWdlIHRoYXQgY29ubmVjdHMgdG8gdGhlXG4gKiBTU0VMb2dTaW5rJ3MgL2xvZ3Mvc3RyZWFtIGVuZHBvaW50IHZpYSBFdmVudFNvdXJjZS4gU2VlIGRvY3MvTE9HR0lORy1ERVNJR04ubWQgwqc0LjYuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZpZXdlckh0bWwocG9ydDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIC8qIGh0bWwgKi8gYDwhRE9DVFlQRSBodG1sPlxuPGh0bWwgbGFuZz1cImVuXCI+XG48aGVhZD5cbjxtZXRhIGNoYXJzZXQ9XCJ1dGYtOFwiPlxuPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCxpbml0aWFsLXNjYWxlPTFcIj5cbjx0aXRsZT5Eb2xsaG91c2VNQ1AgTG9nIFZpZXdlcjwvdGl0bGU+XG48c3R5bGU+XG4qe2JveC1zaXppbmc6Ym9yZGVyLWJveDttYXJnaW46MDtwYWRkaW5nOjB9XG5ib2R5e2JhY2tncm91bmQ6IzFhMWEyZTtjb2xvcjojZTBlMGUwO2ZvbnQtZmFtaWx5OidDYXNjYWRpYSBDb2RlJywnRmlyYSBDb2RlJyxtb25vc3BhY2U7Zm9udC1zaXplOjEzcHh9XG4jY29udHJvbHN7ZGlzcGxheTpmbGV4O2dhcDo4cHg7cGFkZGluZzo4cHggMTJweDtiYWNrZ3JvdW5kOiMxNjIxM2U7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgIzBmMzQ2MDthbGlnbi1pdGVtczpjZW50ZXI7ZmxleC13cmFwOndyYXB9XG4jY29udHJvbHMgbGFiZWx7Y29sb3I6Izk0YTNiODtmb250LXNpemU6MTJweH1cbiNjb250cm9scyBzZWxlY3QsI2NvbnRyb2xzIGlucHV0e2JhY2tncm91bmQ6IzFhMWEyZTtjb2xvcjojZTBlMGUwO2JvcmRlcjoxcHggc29saWQgIzBmMzQ2MDtib3JkZXItcmFkaXVzOjRweDtwYWRkaW5nOjRweCA4cHg7Zm9udC1mYW1pbHk6aW5oZXJpdDtmb250LXNpemU6MTJweH1cbiNjb250cm9scyBzZWxlY3Q6Zm9jdXMsI2NvbnRyb2xzIGlucHV0OmZvY3Vze291dGxpbmU6bm9uZTtib3JkZXItY29sb3I6I2U5NDU2MH1cbmJ1dHRvbntiYWNrZ3JvdW5kOiMwZjM0NjA7Y29sb3I6I2UwZTBlMDtib3JkZXI6MXB4IHNvbGlkICMwZjM0NjA7Ym9yZGVyLXJhZGl1czo0cHg7cGFkZGluZzo0cHggMTJweDtjdXJzb3I6cG9pbnRlcjtmb250LWZhbWlseTppbmhlcml0O2ZvbnQtc2l6ZToxMnB4fVxuYnV0dG9uOmhvdmVye2JhY2tncm91bmQ6I2U5NDU2MDtib3JkZXItY29sb3I6I2U5NDU2MH1cbiNzdGF0dXN7bWFyZ2luLWxlZnQ6YXV0bztmb250LXNpemU6MTFweDtwYWRkaW5nOjJweCA4cHg7Ym9yZGVyLXJhZGl1czoxMHB4fVxuLmNvbm5lY3RlZHtiYWNrZ3JvdW5kOiMwNjRlM2I7Y29sb3I6IzZlZTdiN31cbi5kaXNjb25uZWN0ZWR7YmFja2dyb3VuZDojN2YxZDFkO2NvbG9yOiNmY2E1YTV9XG4ucGF1c2Vke2JhY2tncm91bmQ6Izc4MzUwZjtjb2xvcjojZmNkMzRkfVxuI2xvZ3tvdmVyZmxvdy15OmF1dG87aGVpZ2h0OmNhbGMoMTAwdmggLSA0NHB4KTtwYWRkaW5nOjhweCAxMnB4fVxuLmVudHJ5e3BhZGRpbmc6MnB4IDA7d2hpdGUtc3BhY2U6cHJlLXdyYXA7d29yZC1icmVhazpicmVhay13b3JkO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICMxZTI5M2J9XG4uZW50cnk6aG92ZXJ7YmFja2dyb3VuZDojMTYyMTNlfVxuLmx2bC1lcnJvcntjb2xvcjojZjg3MTcxfVxuLmx2bC13YXJue2NvbG9yOiNmYmJmMjR9XG4ubHZsLWluZm97Y29sb3I6IzYwYTVmYX1cbi5sdmwtZGVidWd7Y29sb3I6IzljYTNhZn1cbi50c3tjb2xvcjojNjQ3NDhifVxuLmNhdHtjb2xvcjojYTc4YmZhfVxuLnNyY3tjb2xvcjojMmRkNGJmfVxuLmNpZHtjb2xvcjojZjQ3MmI2O2ZvbnQtc2l6ZToxMXB4O2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjcycHg7dGV4dC1hbGlnbjpyaWdodDttYXJnaW4tcmlnaHQ6NHB4fVxuI3NlYXJjaHttYXJnaW4tbGVmdDo0cHh9XG48L3N0eWxlPlxuPC9oZWFkPlxuPGJvZHk+XG48ZGl2IGlkPVwiY29udHJvbHNcIj5cbiAgPGxhYmVsPkNhdGVnb3J5XG4gICAgPHNlbGVjdCBpZD1cImZDYXRlZ29yeVwiPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPmFsbDwvb3B0aW9uPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cImFwcGxpY2F0aW9uXCI+YXBwbGljYXRpb248L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9XCJzZWN1cml0eVwiPnNlY3VyaXR5PC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwicGVyZm9ybWFuY2VcIj5wZXJmb3JtYW5jZTwvb3B0aW9uPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cInRlbGVtZXRyeVwiPnRlbGVtZXRyeTwvb3B0aW9uPlxuICAgIDwvc2VsZWN0PlxuICA8L2xhYmVsPlxuICA8bGFiZWw+TGV2ZWxcbiAgICA8c2VsZWN0IGlkPVwiZkxldmVsXCI+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+YWxsPC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwiZGVidWdcIj5kZWJ1Zzwvb3B0aW9uPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cImluZm9cIj5pbmZvPC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwid2FyblwiPndhcm48L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9XCJlcnJvclwiPmVycm9yPC9vcHRpb24+XG4gICAgPC9zZWxlY3Q+XG4gIDwvbGFiZWw+XG4gIDxsYWJlbD5Tb3VyY2UgPGlucHV0IGlkPVwiZlNvdXJjZVwiIHBsYWNlaG9sZGVyPVwic3Vic3RyaW5nXCIgc2l6ZT1cIjE0XCI+PC9sYWJlbD5cbiAgPGxhYmVsPlJlcXVlc3RJZCA8aW5wdXQgaWQ9XCJmQ29ycmVsYXRpb25JZFwiIHBsYWNlaG9sZGVyPVwiY29ycmVsYXRpb25JZFwiIHNpemU9XCIyMFwiPjwvbGFiZWw+XG4gIDxsYWJlbD5TZWFyY2ggPGlucHV0IGlkPVwic2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJtZXNzYWdlIGZpbHRlclwiIHNpemU9XCIxOFwiPjwvbGFiZWw+XG4gIDxidXR0b24gaWQ9XCJidG5QYXVzZVwiPlBhdXNlPC9idXR0b24+XG4gIDxidXR0b24gaWQ9XCJidG5DbGVhclwiPkNsZWFyPC9idXR0b24+XG4gIDxzcGFuIGlkPVwic3RhdHVzXCIgY2xhc3M9XCJkaXNjb25uZWN0ZWRcIj5kaXNjb25uZWN0ZWQ8L3NwYW4+XG48L2Rpdj5cbjxkaXYgaWQ9XCJsb2dcIj48L2Rpdj5cbjxzY3JpcHQ+XG4oZnVuY3Rpb24oKXtcbiAgdmFyIEJBU0UgPSAnaHR0cDovLzEyNy4wLjAuMToke3BvcnR9JztcbiAgdmFyIE1BWF9FTlRSSUVTID0gMTAwMDtcbiAgdmFyIGxvZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2cnKTtcbiAgdmFyIHN0YXR1cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0dXMnKTtcbiAgdmFyIGZDYXRlZ29yeSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmQ2F0ZWdvcnknKTtcbiAgdmFyIGZMZXZlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmTGV2ZWwnKTtcbiAgdmFyIGZTb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZlNvdXJjZScpO1xuICB2YXIgZkNvcnJlbGF0aW9uSWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZkNvcnJlbGF0aW9uSWQnKTtcbiAgdmFyIHNlYXJjaEJveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWFyY2gnKTtcbiAgdmFyIGJ0blBhdXNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0blBhdXNlJyk7XG4gIHZhciBidG5DbGVhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdidG5DbGVhcicpO1xuICB2YXIgZXMgPSBudWxsO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG4gIHZhciBidWZmZXIgPSBbXTtcblxuICBmdW5jdGlvbiBlc2NIdG1sKHMpe1xuICAgIHZhciBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzKSk7XG4gICAgcmV0dXJuIGQuaW5uZXJIVE1MO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0U3RhdHVzKHMsIGNscyl7XG4gICAgc3RhdHVzLnRleHRDb250ZW50ID0gcztcbiAgICBzdGF0dXMuY2xhc3NOYW1lID0gY2xzO1xuICB9XG5cblxuXG4gIHZhciBMRVZFTF9PUkRFUiA9IHtkZWJ1ZzowLCBpbmZvOjEsIHdhcm46MiwgZXJyb3I6M307XG5cbiAgZnVuY3Rpb24gbWF0Y2hlc0ZpbHRlcnMoZW50cnkpe1xuICAgIHZhciBjYXQgPSBmQ2F0ZWdvcnkudmFsdWU7XG4gICAgaWYoY2F0ICYmIGVudHJ5LmNhdGVnb3J5ICE9PSBjYXQpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgbHZsID0gZkxldmVsLnZhbHVlO1xuICAgIGlmKGx2bCAmJiAoTEVWRUxfT1JERVJbZW50cnkubGV2ZWxdfHwwKSA8IChMRVZFTF9PUkRFUltsdmxdfHwwKSkgcmV0dXJuIGZhbHNlO1xuICAgIHZhciBzcmMgPSBmU291cmNlLnZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYoc3JjICYmICghZW50cnkuc291cmNlIHx8IGVudHJ5LnNvdXJjZS50b0xvd2VyQ2FzZSgpLmluZGV4T2Yoc3JjKSA9PT0gLTEpKSByZXR1cm4gZmFsc2U7XG4gICAgdmFyIGNpZCA9IGZDb3JyZWxhdGlvbklkLnZhbHVlO1xuICAgIGlmKGNpZCAmJiBlbnRyeS5jb3JyZWxhdGlvbklkICE9PSBjaWQpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgbmVlZGxlID0gc2VhcmNoQm94LnZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYobmVlZGxlICYmICghZW50cnkubWVzc2FnZSB8fCBlbnRyeS5tZXNzYWdlLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihuZWVkbGUpID09PSAtMSkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlZmlsdGVyKCl7XG4gICAgdmFyIGVscyA9IGxvZy5jaGlsZHJlbjtcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgZWxzLmxlbmd0aDsgaSsrKXtcbiAgICAgIHZhciBkYXRhID0gZWxzW2ldLl9lbnRyeURhdGE7XG4gICAgICBpZihkYXRhKXtcbiAgICAgICAgZWxzW2ldLnN0eWxlLmRpc3BsYXkgPSBtYXRjaGVzRmlsdGVycyhkYXRhKSA/ICcnIDogJ25vbmUnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEVudHJ5KGVudHJ5KXtcbiAgICBpZighbWF0Y2hlc0ZpbHRlcnMoZW50cnkpKSB2YXIgaGlkZGVuID0gdHJ1ZTtcblxuICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGVsLmNsYXNzTmFtZSA9ICdlbnRyeSBsdmwtJyArIGVudHJ5LmxldmVsO1xuICAgIGVsLl9lbnRyeURhdGEgPSBlbnRyeTtcbiAgICBpZihoaWRkZW4pIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgdmFyIHRzID0gZW50cnkudGltZXN0YW1wID8gZW50cnkudGltZXN0YW1wLnNsaWNlKDExLCAyMykgOiAnJztcbiAgICB2YXIgY2lkID0gZW50cnkuY29ycmVsYXRpb25JZCA/IGVudHJ5LmNvcnJlbGF0aW9uSWQuc2xpY2UoLTgpIDogJyc7XG4gICAgZWwuaW5uZXJIVE1MID0gJzxzcGFuIGNsYXNzPVwidHNcIj4nICsgZXNjSHRtbCh0cykgKyAnPC9zcGFuPiAnXG4gICAgICArICc8c3BhbiBjbGFzcz1cImNpZFwiPicgKyBlc2NIdG1sKGNpZCkgKyAnPC9zcGFuPiAnXG4gICAgICArICc8c3BhbiBjbGFzcz1cImNhdFwiPlsnICsgZXNjSHRtbChlbnRyeS5jYXRlZ29yeSkgKyAnXTwvc3Bhbj4gJ1xuICAgICAgKyAnPHNwYW4gY2xhc3M9XCJzcmNcIj4nICsgZXNjSHRtbChlbnRyeS5zb3VyY2UpICsgJzwvc3Bhbj4gJ1xuICAgICAgKyBlc2NIdG1sKGVudHJ5Lm1lc3NhZ2UpO1xuICAgIGxvZy5hcHBlbmRDaGlsZChlbCk7XG5cbiAgICB3aGlsZShsb2cuY2hpbGRyZW4ubGVuZ3RoID4gTUFYX0VOVFJJRVMpe1xuICAgICAgbG9nLnJlbW92ZUNoaWxkKGxvZy5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgaWYoIWhpZGRlbikgbG9nLnNjcm9sbFRvcCA9IGxvZy5zY3JvbGxIZWlnaHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjb25uZWN0KCl7XG4gICAgaWYoZXMpeyBlcy5jbG9zZSgpOyB9XG4gICAgZXMgPSBuZXcgRXZlbnRTb3VyY2UoQkFTRSArICcvbG9ncy9zdHJlYW0nKTtcbiAgICBlcy5vbm9wZW4gPSBmdW5jdGlvbigpeyBzZXRTdGF0dXMoJ2Nvbm5lY3RlZCcsICdjb25uZWN0ZWQnKTsgfTtcbiAgICBlcy5vbm1lc3NhZ2UgPSBmdW5jdGlvbihlKXtcbiAgICAgIHRyeXtcbiAgICAgICAgdmFyIGVudHJ5ID0gSlNPTi5wYXJzZShlLmRhdGEpO1xuICAgICAgICBpZihwYXVzZWQpeyBidWZmZXIucHVzaChlbnRyeSk7IH1cbiAgICAgICAgZWxzZSB7IGFkZEVudHJ5KGVudHJ5KTsgfVxuICAgICAgfWNhdGNoKGVycil7fVxuICAgIH07XG4gICAgZXMub25lcnJvciA9IGZ1bmN0aW9uKCl7IHNldFN0YXR1cygnZGlzY29ubmVjdGVkJywgJ2Rpc2Nvbm5lY3RlZCcpOyB9O1xuICB9XG5cbiAgdmFyIGZpbHRlclRpbWVyID0gbnVsbDtcbiAgZnVuY3Rpb24gb25GaWx0ZXJDaGFuZ2UoKXtcbiAgICBjbGVhclRpbWVvdXQoZmlsdGVyVGltZXIpO1xuICAgIGZpbHRlclRpbWVyID0gc2V0VGltZW91dChyZWZpbHRlciwgNTApO1xuICB9XG5cbiAgZkNhdGVnb3J5LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIG9uRmlsdGVyQ2hhbmdlKTtcbiAgZkxldmVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIG9uRmlsdGVyQ2hhbmdlKTtcbiAgZlNvdXJjZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKCl7XG4gICAgY2xlYXJUaW1lb3V0KGZpbHRlclRpbWVyKTtcbiAgICBmaWx0ZXJUaW1lciA9IHNldFRpbWVvdXQocmVmaWx0ZXIsIDQwMCk7XG4gIH0pO1xuICBmQ29ycmVsYXRpb25JZC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKCl7XG4gICAgY2xlYXJUaW1lb3V0KGZpbHRlclRpbWVyKTtcbiAgICBmaWx0ZXJUaW1lciA9IHNldFRpbWVvdXQocmVmaWx0ZXIsIDQwMCk7XG4gIH0pO1xuICBzZWFyY2hCb3guYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmdW5jdGlvbigpe1xuICAgIGNsZWFyVGltZW91dChmaWx0ZXJUaW1lcik7XG4gICAgZmlsdGVyVGltZXIgPSBzZXRUaW1lb3V0KHJlZmlsdGVyLCA0MDApO1xuICB9KTtcblxuICBidG5QYXVzZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7XG4gICAgcGF1c2VkID0gIXBhdXNlZDtcbiAgICBidG5QYXVzZS50ZXh0Q29udGVudCA9IHBhdXNlZCA/ICdSZXN1bWUnIDogJ1BhdXNlJztcbiAgICBpZihwYXVzZWQpe1xuICAgICAgc2V0U3RhdHVzKCdwYXVzZWQnLCAncGF1c2VkJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldFN0YXR1cygnY29ubmVjdGVkJywgJ2Nvbm5lY3RlZCcpO1xuICAgICAgYnVmZmVyLmZvckVhY2goYWRkRW50cnkpO1xuICAgICAgYnVmZmVyID0gW107XG4gICAgfVxuICB9KTtcblxuICBidG5DbGVhci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7XG4gICAgbG9nLmlubmVySFRNTCA9ICcnO1xuICB9KTtcblxuICBjb25uZWN0KCk7XG59KSgpO1xuPC9zY3JpcHQ+XG48L2JvZHk+XG48L2h0bWw+YDtcbn1cbiJdfQ==
|