punkweb-bb 0.2.2__py3-none-any.whl → 0.3.0__py3-none-any.whl
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.
- punkweb_bb/__pycache__/admin.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/admin_forms.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/forms.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/settings.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/sitemap.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/tests.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/urls.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/utils.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/views.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/widgets.cpython-311.pyc +0 -0
- punkweb_bb/admin.py +0 -4
- punkweb_bb/admin_forms.py +6 -5
- punkweb_bb/forms.py +13 -5
- punkweb_bb/migrations/0005_alter_thread_options.py +24 -0
- punkweb_bb/migrations/0006_remove_boardprofile__signature_rendered_and_more.py +60 -0
- punkweb_bb/migrations/__pycache__/0005_alter_thread_options.cpython-311.pyc +0 -0
- punkweb_bb/migrations/__pycache__/0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
- punkweb_bb/models.py +12 -9
- punkweb_bb/settings.py +1 -0
- punkweb_bb/static/punkweb_bb/css/thread.css +45 -28
- punkweb_bb/static/punkweb_bb/editor/markdown-editor.js +23 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.eslintrc.json +15 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.gitignore +108 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.prettierrc.json +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/LICENSE +21 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/README.md +240 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/babel.config.json +14 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/blank.html +18 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/demo.html +126 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.css +231 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.js +3086 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.css +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.tiny.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/_config.yml +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/_layouts/default.html +50 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/index.md +174 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/globals.d.ts +172 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/gulpfile.mjs +226 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/block.test.js +696 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/commandbar.test.js +84 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/inline.test.js +486 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/interaction.test.js +31 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/setup.test.js +164 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/config.js +2 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/server.js +9 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/setup.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/test-helpers.js +98 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest-puppeteer.config.js +8 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest.config.js +13 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/package-lock.json +16295 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/package.json +72 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/TinyMDE.js +1926 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/TinyMDECommandBar.js +256 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/commandbar.css +72 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/editor.css +157 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/index.css +3 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/grammar.js +300 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/html/blank.html +18 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/html/demo.html +126 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/index.js +4 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/blockquote.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/bold.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/clear_formatting.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/code.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/h1.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/h2.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/hr.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/image.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/italic.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/link.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/ol.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/strikethrough.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/svg.js +17 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/ul.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/tiny.js +3 -0
- punkweb_bb/templates/punkweb_bb/base_delete_modal.html +13 -0
- punkweb_bb/templates/punkweb_bb/index.html +2 -2
- punkweb_bb/templates/punkweb_bb/members.html +3 -1
- punkweb_bb/templates/punkweb_bb/partials/category_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/post_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/shout_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/subcategory_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/thread_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/thread_move.html +24 -0
- punkweb_bb/templates/punkweb_bb/profile.html +8 -4
- punkweb_bb/templates/punkweb_bb/shoutbox/shout_list.html +3 -3
- punkweb_bb/templates/punkweb_bb/subcategory.html +1 -1
- punkweb_bb/templates/punkweb_bb/thread.html +89 -71
- punkweb_bb/templates/punkweb_bb/widgets/markdown-editor.html +3 -0
- punkweb_bb/templatetags/__pycache__/markdown.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/render.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/shoutbox_bbcode.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/shoutbox_render.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/styled_group_name.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/render.py +48 -0
- punkweb_bb/templatetags/shoutbox_render.py +22 -0
- punkweb_bb/templatetags/styled_group_name.py +2 -2
- punkweb_bb/tests.py +3 -3
- punkweb_bb/urls.py +1 -0
- punkweb_bb/utils.py +23 -7
- punkweb_bb/views.py +36 -7
- punkweb_bb/widgets.py +20 -0
- {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/METADATA +56 -41
- {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/RECORD +109 -41
- punkweb_bb/templatetags/shoutbox_bbcode.py +0 -14
- {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/LICENSE +0 -0
- {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/WHEEL +0 -0
- {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,3086 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TinyMDE = {}));
|
|
5
|
+
})(this, (function (exports) { 'use strict';
|
|
6
|
+
|
|
7
|
+
const svg = {
|
|
8
|
+
blockquote: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="m228-240 92-160q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 23-5.5 42.5T458-480L320-240h-92Zm360 0 92-160q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 23-5.5 42.5T818-480L680-240h-92ZM320-500q25 0 42.5-17.5T380-560q0-25-17.5-42.5T320-620q-25 0-42.5 17.5T260-560q0 25 17.5 42.5T320-500Zm360 0q25 0 42.5-17.5T740-560q0-25-17.5-42.5T680-620q-25 0-42.5 17.5T620-560q0 25 17.5 42.5T680-500Zm0-60Zm-360 0Z"/></svg>`,
|
|
9
|
+
bold: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M272-200v-560h221q65 0 120 40t55 111q0 51-23 78.5T602-491q25 11 55.5 41t30.5 90q0 89-65 124.5T501-200H272Zm121-112h104q48 0 58.5-24.5T566-372q0-11-10.5-35.5T494-432H393v120Zm0-228h93q33 0 48-17t15-38q0-24-17-39t-44-15h-95v109Z"/></svg>`,
|
|
10
|
+
clear_formatting: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="m528-546-93-93-121-121h486v120H568l-40 94ZM792-56 460-388l-80 188H249l119-280L56-792l56-56 736 736-56 56Z"/></svg>`,
|
|
11
|
+
code: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M320-240 80-480l240-240 57 57-184 184 183 183-56 56Zm320 0-57-57 184-184-183-183 56-56 240 240-240 240Z"/></svg>`,
|
|
12
|
+
h1: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M200-280v-400h80v160h160v-160h80v400h-80v-160H280v160h-80Zm480 0v-320h-80v-80h160v400h-80Z"/></svg>`,
|
|
13
|
+
h2: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M120-280v-400h80v160h160v-160h80v400h-80v-160H200v160h-80Zm400 0v-160q0-33 23.5-56.5T600-520h160v-80H520v-80h240q33 0 56.5 23.5T840-600v80q0 33-23.5 56.5T760-440H600v80h240v80H520Z"/></svg>`,
|
|
14
|
+
hr: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M160-440v-80h640v80H160Z"/></svg>`,
|
|
15
|
+
image: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"/></svg>`,
|
|
16
|
+
italic: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M200-200v-100h160l120-360H320v-100h400v100H580L460-300h140v100H200Z"/></svg>`,
|
|
17
|
+
link: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M440-280H280q-83 0-141.5-58.5T80-480q0-83 58.5-141.5T280-680h160v80H280q-50 0-85 35t-35 85q0 50 35 85t85 35h160v80ZM320-440v-80h320v80H320Zm200 160v-80h160q50 0 85-35t35-85q0-50-35-85t-85-35H520v-80h160q83 0 141.5 58.5T880-480q0 83-58.5 141.5T680-280H520Z"/></svg>`,
|
|
18
|
+
ol: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M120-80v-60h100v-30h-60v-60h60v-30H120v-60h120q17 0 28.5 11.5T280-280v40q0 17-11.5 28.5T240-200q17 0 28.5 11.5T280-160v40q0 17-11.5 28.5T240-80H120Zm0-280v-110q0-17 11.5-28.5T160-510h60v-30H120v-60h120q17 0 28.5 11.5T280-560v70q0 17-11.5 28.5T240-450h-60v30h100v60H120Zm60-280v-180h-60v-60h120v240h-60Zm180 440v-80h480v80H360Zm0-240v-80h480v80H360Zm0-240v-80h480v80H360Z"/></svg>`,
|
|
19
|
+
strikethrough: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M80-400v-80h800v80H80Zm340-160v-120H200v-120h560v120H540v120H420Zm0 400v-160h120v160H420Z"/></svg>`,
|
|
20
|
+
ul: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M360-200v-80h480v80H360Zm0-240v-80h480v80H360Zm0-240v-80h480v80H360ZM200-160q-33 0-56.5-23.5T120-240q0-33 23.5-56.5T200-320q33 0 56.5 23.5T280-240q0 33-23.5 56.5T200-160Zm0-240q-33 0-56.5-23.5T120-480q0-33 23.5-56.5T200-560q33 0 56.5 23.5T280-480q0 33-23.5 56.5T200-400Zm0-240q-33 0-56.5-23.5T120-720q0-33 23.5-56.5T200-800q33 0 56.5 23.5T280-720q0 33-23.5 56.5T200-640Z"/></svg>`
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(typeof navigator !== "undefined" ? navigator.platform : "");
|
|
24
|
+
const DefaultCommands = {
|
|
25
|
+
'bold': {
|
|
26
|
+
name: 'bold',
|
|
27
|
+
action: 'bold',
|
|
28
|
+
innerHTML: svg.bold,
|
|
29
|
+
title: 'Bold',
|
|
30
|
+
hotkey: 'Mod-B'
|
|
31
|
+
},
|
|
32
|
+
'italic': {
|
|
33
|
+
name: 'italic',
|
|
34
|
+
action: 'italic',
|
|
35
|
+
innerHTML: svg.italic,
|
|
36
|
+
title: 'Italic',
|
|
37
|
+
hotkey: 'Mod-I'
|
|
38
|
+
},
|
|
39
|
+
'strikethrough': {
|
|
40
|
+
name: 'strikethrough',
|
|
41
|
+
action: 'strikethrough',
|
|
42
|
+
innerHTML: svg.strikethrough,
|
|
43
|
+
title: 'Strikethrough',
|
|
44
|
+
hotkey: 'Mod2-Shift-5'
|
|
45
|
+
},
|
|
46
|
+
'code': {
|
|
47
|
+
name: 'code',
|
|
48
|
+
action: 'code',
|
|
49
|
+
innerHTML: svg.code,
|
|
50
|
+
title: 'Format as code'
|
|
51
|
+
},
|
|
52
|
+
'h1': {
|
|
53
|
+
name: 'h1',
|
|
54
|
+
action: 'h1',
|
|
55
|
+
innerHTML: svg.h1,
|
|
56
|
+
title: 'Level 1 heading',
|
|
57
|
+
hotkey: 'Mod-Shift-1'
|
|
58
|
+
},
|
|
59
|
+
'h2': {
|
|
60
|
+
name: 'h2',
|
|
61
|
+
action: 'h2',
|
|
62
|
+
innerHTML: svg.h2,
|
|
63
|
+
title: 'Level 2 heading',
|
|
64
|
+
hotkey: 'Mod-Shift-2'
|
|
65
|
+
},
|
|
66
|
+
'ul': {
|
|
67
|
+
name: 'ul',
|
|
68
|
+
action: 'ul',
|
|
69
|
+
innerHTML: svg.ul,
|
|
70
|
+
title: 'Bulleted list'
|
|
71
|
+
},
|
|
72
|
+
'ol': {
|
|
73
|
+
name: 'ol',
|
|
74
|
+
action: 'ol',
|
|
75
|
+
innerHTML: svg.ol,
|
|
76
|
+
title: 'Numbered list'
|
|
77
|
+
},
|
|
78
|
+
'blockquote': {
|
|
79
|
+
name: 'blockquote',
|
|
80
|
+
action: 'blockquote',
|
|
81
|
+
innerHTML: svg.blockquote,
|
|
82
|
+
title: 'Quote',
|
|
83
|
+
hotkey: 'Mod2-Shift-Q'
|
|
84
|
+
},
|
|
85
|
+
'insertLink': {
|
|
86
|
+
name: 'insertLink',
|
|
87
|
+
action: editor => {
|
|
88
|
+
if (editor.isInlineFormattingAllowed()) editor.wrapSelection('[', ']()');
|
|
89
|
+
},
|
|
90
|
+
enabled: (editor, focus, anchor) => editor.isInlineFormattingAllowed(focus, anchor) ? false : null,
|
|
91
|
+
innerHTML: svg.link,
|
|
92
|
+
title: 'Insert link',
|
|
93
|
+
hotkey: 'Mod-K'
|
|
94
|
+
},
|
|
95
|
+
'insertImage': {
|
|
96
|
+
name: 'insertImage',
|
|
97
|
+
action: editor => {
|
|
98
|
+
if (editor.isInlineFormattingAllowed()) editor.wrapSelection('![', ']()');
|
|
99
|
+
},
|
|
100
|
+
enabled: (editor, focus, anchor) => editor.isInlineFormattingAllowed(focus, anchor) ? false : null,
|
|
101
|
+
innerHTML: svg.image,
|
|
102
|
+
title: 'Insert image',
|
|
103
|
+
hotkey: 'Mod2-Shift-I'
|
|
104
|
+
},
|
|
105
|
+
'hr': {
|
|
106
|
+
name: 'hr',
|
|
107
|
+
action: editor => editor.paste('\n***\n'),
|
|
108
|
+
enabled: () => false,
|
|
109
|
+
innerHTML: svg.hr,
|
|
110
|
+
title: 'Insert horizontal line',
|
|
111
|
+
hotkey: 'Mod2-Shift-L'
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
class CommandBar {
|
|
115
|
+
constructor(props) {
|
|
116
|
+
this.e = null;
|
|
117
|
+
this.editor = null;
|
|
118
|
+
this.commands = [];
|
|
119
|
+
this.buttons = {};
|
|
120
|
+
this.state = {};
|
|
121
|
+
this.hotkeys = [];
|
|
122
|
+
let element = props.element;
|
|
123
|
+
if (element && !element.tagName) {
|
|
124
|
+
element = document.getElementById(props.element);
|
|
125
|
+
}
|
|
126
|
+
if (!element) {
|
|
127
|
+
element = document.body;
|
|
128
|
+
}
|
|
129
|
+
this.createCommandBarElement(element, props.commands || ['bold', 'italic', 'strikethrough', '|', 'code', '|', 'h1', 'h2', '|', 'ul', 'ol', '|', 'blockquote', 'hr', '|', 'insertLink', 'insertImage']);
|
|
130
|
+
document.addEventListener('keydown', e => this.handleKeydown(e));
|
|
131
|
+
if (props.editor) this.setEditor(props.editor);
|
|
132
|
+
}
|
|
133
|
+
createCommandBarElement(parentElement, commands) {
|
|
134
|
+
this.e = document.createElement('div');
|
|
135
|
+
this.e.className = 'TMCommandBar';
|
|
136
|
+
for (let command of commands) {
|
|
137
|
+
if (command == '|') {
|
|
138
|
+
let el = document.createElement('div');
|
|
139
|
+
el.className = 'TMCommandDivider';
|
|
140
|
+
this.e.appendChild(el);
|
|
141
|
+
} else {
|
|
142
|
+
let commandName;
|
|
143
|
+
if (typeof command == "string") {
|
|
144
|
+
// Reference to default command
|
|
145
|
+
|
|
146
|
+
if (DefaultCommands[command]) {
|
|
147
|
+
commandName = command;
|
|
148
|
+
this.commands[commandName] = DefaultCommands[commandName];
|
|
149
|
+
} else {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
} else if (typeof command == "object" && command.name) {
|
|
153
|
+
commandName = command.name;
|
|
154
|
+
this.commands[commandName] = {};
|
|
155
|
+
if (DefaultCommands[commandName]) Object.assign(this.commands[commandName], DefaultCommands[commandName]);
|
|
156
|
+
Object.assign(this.commands[commandName], command);
|
|
157
|
+
} else {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
let title = this.commands[commandName].title || commandName;
|
|
161
|
+
if (this.commands[commandName].hotkey) {
|
|
162
|
+
const keys = this.commands[commandName].hotkey.split('-');
|
|
163
|
+
// construct modifiers
|
|
164
|
+
let modifiers = [];
|
|
165
|
+
let modifierexplanation = [];
|
|
166
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
167
|
+
switch (keys[i]) {
|
|
168
|
+
case 'Ctrl':
|
|
169
|
+
modifiers.push('ctrlKey');
|
|
170
|
+
modifierexplanation.push('Ctrl');
|
|
171
|
+
break;
|
|
172
|
+
case 'Cmd':
|
|
173
|
+
modifiers.push('metaKey');
|
|
174
|
+
modifierexplanation.push('⌘');
|
|
175
|
+
break;
|
|
176
|
+
case 'Alt':
|
|
177
|
+
modifiers.push('altKey');
|
|
178
|
+
modifierexplanation.push('Alt');
|
|
179
|
+
break;
|
|
180
|
+
case 'Option':
|
|
181
|
+
modifiers.push('altKey');
|
|
182
|
+
modifierexplanation.push('⌥');
|
|
183
|
+
break;
|
|
184
|
+
case 'Win':
|
|
185
|
+
modifiers.push('metaKey');
|
|
186
|
+
modifierexplanation.push('⊞ Win');
|
|
187
|
+
break;
|
|
188
|
+
case 'Shift':
|
|
189
|
+
modifiers.push('shiftKey');
|
|
190
|
+
modifierexplanation.push('⇧');
|
|
191
|
+
break;
|
|
192
|
+
case 'Mod':
|
|
193
|
+
// Mod is a convenience mechanism: Ctrl on Windows, Cmd on Mac
|
|
194
|
+
if (isMacLike) {
|
|
195
|
+
modifiers.push('metaKey');
|
|
196
|
+
modifierexplanation.push('⌘');
|
|
197
|
+
} else {
|
|
198
|
+
modifiers.push('ctrlKey');
|
|
199
|
+
modifierexplanation.push('Ctrl');
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
case 'Mod2':
|
|
203
|
+
modifiers.push('altKey');
|
|
204
|
+
if (isMacLike) modifierexplanation.push('⌥');else modifierexplanation.push('Alt');
|
|
205
|
+
break;
|
|
206
|
+
// Mod2 is a convenience mechanism: Alt on Windows, Option on Mac
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
modifierexplanation.push(keys[keys.length - 1]);
|
|
211
|
+
let hotkey = {
|
|
212
|
+
modifiers: modifiers,
|
|
213
|
+
command: commandName
|
|
214
|
+
};
|
|
215
|
+
// TODO Right now this is working only for letters and numbers
|
|
216
|
+
if (keys[keys.length - 1].match(/^[0-9]$/)) {
|
|
217
|
+
hotkey.code = `Digit${keys[keys.length - 1]}`;
|
|
218
|
+
} else {
|
|
219
|
+
hotkey.key = keys[keys.length - 1].toLowerCase();
|
|
220
|
+
}
|
|
221
|
+
this.hotkeys.push(hotkey);
|
|
222
|
+
title = title.concat(` (${modifierexplanation.join('+')})`);
|
|
223
|
+
}
|
|
224
|
+
this.buttons[commandName] = document.createElement('div');
|
|
225
|
+
this.buttons[commandName].className = 'TMCommandButton TMCommandButton_Disabled';
|
|
226
|
+
this.buttons[commandName].title = title;
|
|
227
|
+
this.buttons[commandName].innerHTML = this.commands[commandName].innerHTML;
|
|
228
|
+
this.buttons[commandName].addEventListener('mousedown', e => this.handleClick(commandName, e));
|
|
229
|
+
this.e.appendChild(this.buttons[commandName]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
parentElement.appendChild(this.e);
|
|
233
|
+
}
|
|
234
|
+
handleClick(commandName, event) {
|
|
235
|
+
if (!this.editor) return;
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
if (typeof this.commands[commandName].action == "string") {
|
|
238
|
+
if (this.state[commandName] === false) this.editor.setCommandState(commandName, true);else this.editor.setCommandState(commandName, false);
|
|
239
|
+
} else if (typeof this.commands[commandName].action == "function") {
|
|
240
|
+
this.commands[commandName].action(this.editor);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
setEditor(editor) {
|
|
244
|
+
this.editor = editor;
|
|
245
|
+
editor.addEventListener('selection', e => this.handleSelection(e));
|
|
246
|
+
}
|
|
247
|
+
handleSelection(event) {
|
|
248
|
+
if (event.commandState) {
|
|
249
|
+
for (let command in this.commands) {
|
|
250
|
+
if (event.commandState[command] === undefined) {
|
|
251
|
+
if (this.commands[command].enabled) this.state[command] = this.commands[command].enabled(this.editor, event.focus, event.anchor);else this.state[command] = event.focus ? false : null;
|
|
252
|
+
} else {
|
|
253
|
+
this.state[command] = event.commandState[command];
|
|
254
|
+
}
|
|
255
|
+
if (this.state[command] === true) {
|
|
256
|
+
this.buttons[command].className = 'TMCommandButton TMCommandButton_Active';
|
|
257
|
+
} else if (this.state[command] === false) {
|
|
258
|
+
this.buttons[command].className = 'TMCommandButton TMCommandButton_Inactive';
|
|
259
|
+
} else {
|
|
260
|
+
this.buttons[command].className = 'TMCommandButton TMCommandButton_Disabled';
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
handleKeydown(event) {
|
|
266
|
+
outer: for (let hotkey of this.hotkeys) {
|
|
267
|
+
if (hotkey.key && event.key.toLowerCase() == hotkey.key || hotkey.code && event.code == hotkey.code) {
|
|
268
|
+
// Key matches hotkey. Look for any required modifier that wasn't pressed
|
|
269
|
+
for (let modifier of hotkey.modifiers) {
|
|
270
|
+
if (!event[modifier]) continue outer;
|
|
271
|
+
}
|
|
272
|
+
// Everything matches.
|
|
273
|
+
this.handleClick(hotkey.command, event);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
281
|
+
|
|
282
|
+
var check = function (it) {
|
|
283
|
+
return it && it.Math === Math && it;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
|
|
287
|
+
var global$b =
|
|
288
|
+
// eslint-disable-next-line es/no-global-this -- safe
|
|
289
|
+
check(typeof globalThis == 'object' && globalThis) || check(typeof window == 'object' && window) ||
|
|
290
|
+
// eslint-disable-next-line no-restricted-globals -- safe
|
|
291
|
+
check(typeof self == 'object' && self) || check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
|
|
292
|
+
// eslint-disable-next-line no-new-func -- fallback
|
|
293
|
+
function () {
|
|
294
|
+
return this;
|
|
295
|
+
}() || commonjsGlobal || Function('return this')();
|
|
296
|
+
|
|
297
|
+
var fails$7 = function (exec) {
|
|
298
|
+
try {
|
|
299
|
+
return !!exec();
|
|
300
|
+
} catch (error) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
var fails$6 = fails$7;
|
|
306
|
+
|
|
307
|
+
// Detect IE8's incomplete defineProperty implementation
|
|
308
|
+
var descriptors = !fails$6(function () {
|
|
309
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
310
|
+
return Object.defineProperty({}, 1, {
|
|
311
|
+
get: function () {
|
|
312
|
+
return 7;
|
|
313
|
+
}
|
|
314
|
+
})[1] !== 7;
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
var makeBuiltInExports = {};
|
|
318
|
+
var makeBuiltIn$2 = {
|
|
319
|
+
get exports(){ return makeBuiltInExports; },
|
|
320
|
+
set exports(v){ makeBuiltInExports = v; },
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
var fails$5 = fails$7;
|
|
324
|
+
var functionBindNative = !fails$5(function () {
|
|
325
|
+
// eslint-disable-next-line es/no-function-prototype-bind -- safe
|
|
326
|
+
var test = function () {/* empty */}.bind();
|
|
327
|
+
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
328
|
+
return typeof test != 'function' || test.hasOwnProperty('prototype');
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
var NATIVE_BIND$1 = functionBindNative;
|
|
332
|
+
var FunctionPrototype$1 = Function.prototype;
|
|
333
|
+
var call$3 = FunctionPrototype$1.call;
|
|
334
|
+
var uncurryThisWithBind = NATIVE_BIND$1 && FunctionPrototype$1.bind.bind(call$3, call$3);
|
|
335
|
+
var functionUncurryThis = NATIVE_BIND$1 ? uncurryThisWithBind : function (fn) {
|
|
336
|
+
return function () {
|
|
337
|
+
return call$3.apply(fn, arguments);
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
var documentAll$2 = typeof document == 'object' && document.all;
|
|
342
|
+
|
|
343
|
+
// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
|
|
344
|
+
// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing
|
|
345
|
+
var IS_HTMLDDA = typeof documentAll$2 == 'undefined' && documentAll$2 !== undefined;
|
|
346
|
+
var documentAll_1 = {
|
|
347
|
+
all: documentAll$2,
|
|
348
|
+
IS_HTMLDDA: IS_HTMLDDA
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
var $documentAll$1 = documentAll_1;
|
|
352
|
+
var documentAll$1 = $documentAll$1.all;
|
|
353
|
+
|
|
354
|
+
// `IsCallable` abstract operation
|
|
355
|
+
// https://tc39.es/ecma262/#sec-iscallable
|
|
356
|
+
var isCallable$8 = $documentAll$1.IS_HTMLDDA ? function (argument) {
|
|
357
|
+
return typeof argument == 'function' || argument === documentAll$1;
|
|
358
|
+
} : function (argument) {
|
|
359
|
+
return typeof argument == 'function';
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// we can't use just `it == null` since of `document.all` special case
|
|
363
|
+
// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec
|
|
364
|
+
var isNullOrUndefined$2 = function (it) {
|
|
365
|
+
return it === null || it === undefined;
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
var isNullOrUndefined$1 = isNullOrUndefined$2;
|
|
369
|
+
var $TypeError$5 = TypeError;
|
|
370
|
+
|
|
371
|
+
// `RequireObjectCoercible` abstract operation
|
|
372
|
+
// https://tc39.es/ecma262/#sec-requireobjectcoercible
|
|
373
|
+
var requireObjectCoercible$1 = function (it) {
|
|
374
|
+
if (isNullOrUndefined$1(it)) throw new $TypeError$5("Can't call method on " + it);
|
|
375
|
+
return it;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
var requireObjectCoercible = requireObjectCoercible$1;
|
|
379
|
+
var $Object$1 = Object;
|
|
380
|
+
|
|
381
|
+
// `ToObject` abstract operation
|
|
382
|
+
// https://tc39.es/ecma262/#sec-toobject
|
|
383
|
+
var toObject$1 = function (argument) {
|
|
384
|
+
return $Object$1(requireObjectCoercible(argument));
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
var uncurryThis$4 = functionUncurryThis;
|
|
388
|
+
var toObject = toObject$1;
|
|
389
|
+
var hasOwnProperty = uncurryThis$4({}.hasOwnProperty);
|
|
390
|
+
|
|
391
|
+
// `HasOwnProperty` abstract operation
|
|
392
|
+
// https://tc39.es/ecma262/#sec-hasownproperty
|
|
393
|
+
// eslint-disable-next-line es/no-object-hasown -- safe
|
|
394
|
+
var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) {
|
|
395
|
+
return hasOwnProperty(toObject(it), key);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
var DESCRIPTORS$6 = descriptors;
|
|
399
|
+
var hasOwn$3 = hasOwnProperty_1;
|
|
400
|
+
var FunctionPrototype = Function.prototype;
|
|
401
|
+
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
|
|
402
|
+
var getDescriptor = DESCRIPTORS$6 && Object.getOwnPropertyDescriptor;
|
|
403
|
+
var EXISTS$1 = hasOwn$3(FunctionPrototype, 'name');
|
|
404
|
+
// additional protection from minified / mangled / dropped function names
|
|
405
|
+
var PROPER = EXISTS$1 && function something() {/* empty */}.name === 'something';
|
|
406
|
+
var CONFIGURABLE$1 = EXISTS$1 && (!DESCRIPTORS$6 || DESCRIPTORS$6 && getDescriptor(FunctionPrototype, 'name').configurable);
|
|
407
|
+
var functionName = {
|
|
408
|
+
EXISTS: EXISTS$1,
|
|
409
|
+
PROPER: PROPER,
|
|
410
|
+
CONFIGURABLE: CONFIGURABLE$1
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
var global$a = global$b;
|
|
414
|
+
|
|
415
|
+
// eslint-disable-next-line es/no-object-defineproperty -- safe
|
|
416
|
+
var defineProperty$2 = Object.defineProperty;
|
|
417
|
+
var defineGlobalProperty$1 = function (key, value) {
|
|
418
|
+
try {
|
|
419
|
+
defineProperty$2(global$a, key, {
|
|
420
|
+
value: value,
|
|
421
|
+
configurable: true,
|
|
422
|
+
writable: true
|
|
423
|
+
});
|
|
424
|
+
} catch (error) {
|
|
425
|
+
global$a[key] = value;
|
|
426
|
+
}
|
|
427
|
+
return value;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
var global$9 = global$b;
|
|
431
|
+
var defineGlobalProperty = defineGlobalProperty$1;
|
|
432
|
+
var SHARED = '__core-js_shared__';
|
|
433
|
+
var store$3 = global$9[SHARED] || defineGlobalProperty(SHARED, {});
|
|
434
|
+
var sharedStore = store$3;
|
|
435
|
+
|
|
436
|
+
var uncurryThis$3 = functionUncurryThis;
|
|
437
|
+
var isCallable$7 = isCallable$8;
|
|
438
|
+
var store$2 = sharedStore;
|
|
439
|
+
var functionToString = uncurryThis$3(Function.toString);
|
|
440
|
+
|
|
441
|
+
// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper
|
|
442
|
+
if (!isCallable$7(store$2.inspectSource)) {
|
|
443
|
+
store$2.inspectSource = function (it) {
|
|
444
|
+
return functionToString(it);
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
var inspectSource$1 = store$2.inspectSource;
|
|
448
|
+
|
|
449
|
+
var global$8 = global$b;
|
|
450
|
+
var isCallable$6 = isCallable$8;
|
|
451
|
+
var WeakMap$1 = global$8.WeakMap;
|
|
452
|
+
var weakMapBasicDetection = isCallable$6(WeakMap$1) && /native code/.test(String(WeakMap$1));
|
|
453
|
+
|
|
454
|
+
var isCallable$5 = isCallable$8;
|
|
455
|
+
var $documentAll = documentAll_1;
|
|
456
|
+
var documentAll = $documentAll.all;
|
|
457
|
+
var isObject$5 = $documentAll.IS_HTMLDDA ? function (it) {
|
|
458
|
+
return typeof it == 'object' ? it !== null : isCallable$5(it) || it === documentAll;
|
|
459
|
+
} : function (it) {
|
|
460
|
+
return typeof it == 'object' ? it !== null : isCallable$5(it);
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
var objectDefineProperty = {};
|
|
464
|
+
|
|
465
|
+
var global$7 = global$b;
|
|
466
|
+
var isObject$4 = isObject$5;
|
|
467
|
+
var document$1 = global$7.document;
|
|
468
|
+
// typeof document.createElement is 'object' in old IE
|
|
469
|
+
var EXISTS = isObject$4(document$1) && isObject$4(document$1.createElement);
|
|
470
|
+
var documentCreateElement = function (it) {
|
|
471
|
+
return EXISTS ? document$1.createElement(it) : {};
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
var DESCRIPTORS$5 = descriptors;
|
|
475
|
+
var fails$4 = fails$7;
|
|
476
|
+
var createElement = documentCreateElement;
|
|
477
|
+
|
|
478
|
+
// Thanks to IE8 for its funny defineProperty
|
|
479
|
+
var ie8DomDefine = !DESCRIPTORS$5 && !fails$4(function () {
|
|
480
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
481
|
+
return Object.defineProperty(createElement('div'), 'a', {
|
|
482
|
+
get: function () {
|
|
483
|
+
return 7;
|
|
484
|
+
}
|
|
485
|
+
}).a !== 7;
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
var DESCRIPTORS$4 = descriptors;
|
|
489
|
+
var fails$3 = fails$7;
|
|
490
|
+
|
|
491
|
+
// V8 ~ Chrome 36-
|
|
492
|
+
// https://bugs.chromium.org/p/v8/issues/detail?id=3334
|
|
493
|
+
var v8PrototypeDefineBug = DESCRIPTORS$4 && fails$3(function () {
|
|
494
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
495
|
+
return Object.defineProperty(function () {/* empty */}, 'prototype', {
|
|
496
|
+
value: 42,
|
|
497
|
+
writable: false
|
|
498
|
+
}).prototype !== 42;
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
var isObject$3 = isObject$5;
|
|
502
|
+
var $String$3 = String;
|
|
503
|
+
var $TypeError$4 = TypeError;
|
|
504
|
+
|
|
505
|
+
// `Assert: Type(argument) is Object`
|
|
506
|
+
var anObject$2 = function (argument) {
|
|
507
|
+
if (isObject$3(argument)) return argument;
|
|
508
|
+
throw new $TypeError$4($String$3(argument) + ' is not an object');
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
var NATIVE_BIND = functionBindNative;
|
|
512
|
+
var call$2 = Function.prototype.call;
|
|
513
|
+
var functionCall = NATIVE_BIND ? call$2.bind(call$2) : function () {
|
|
514
|
+
return call$2.apply(call$2, arguments);
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
var global$6 = global$b;
|
|
518
|
+
var isCallable$4 = isCallable$8;
|
|
519
|
+
var aFunction = function (argument) {
|
|
520
|
+
return isCallable$4(argument) ? argument : undefined;
|
|
521
|
+
};
|
|
522
|
+
var getBuiltIn$1 = function (namespace, method) {
|
|
523
|
+
return arguments.length < 2 ? aFunction(global$6[namespace]) : global$6[namespace] && global$6[namespace][method];
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
var uncurryThis$2 = functionUncurryThis;
|
|
527
|
+
var objectIsPrototypeOf = uncurryThis$2({}.isPrototypeOf);
|
|
528
|
+
|
|
529
|
+
var engineUserAgent = typeof navigator != 'undefined' && String(navigator.userAgent) || '';
|
|
530
|
+
|
|
531
|
+
var global$5 = global$b;
|
|
532
|
+
var userAgent = engineUserAgent;
|
|
533
|
+
var process = global$5.process;
|
|
534
|
+
var Deno = global$5.Deno;
|
|
535
|
+
var versions = process && process.versions || Deno && Deno.version;
|
|
536
|
+
var v8 = versions && versions.v8;
|
|
537
|
+
var match, version;
|
|
538
|
+
if (v8) {
|
|
539
|
+
match = v8.split('.');
|
|
540
|
+
// in old Chrome, versions of V8 isn't V8 = Chrome / 10
|
|
541
|
+
// but their correct versions are not interesting for us
|
|
542
|
+
version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
|
|
546
|
+
// so check `userAgent` even if `.v8` exists, but 0
|
|
547
|
+
if (!version && userAgent) {
|
|
548
|
+
match = userAgent.match(/Edge\/(\d+)/);
|
|
549
|
+
if (!match || match[1] >= 74) {
|
|
550
|
+
match = userAgent.match(/Chrome\/(\d+)/);
|
|
551
|
+
if (match) version = +match[1];
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
var engineV8Version = version;
|
|
555
|
+
|
|
556
|
+
/* eslint-disable es/no-symbol -- required for testing */
|
|
557
|
+
var V8_VERSION = engineV8Version;
|
|
558
|
+
var fails$2 = fails$7;
|
|
559
|
+
var global$4 = global$b;
|
|
560
|
+
var $String$2 = global$4.String;
|
|
561
|
+
|
|
562
|
+
// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
|
|
563
|
+
var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$2(function () {
|
|
564
|
+
var symbol = Symbol('symbol detection');
|
|
565
|
+
// Chrome 38 Symbol has incorrect toString conversion
|
|
566
|
+
// `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
|
|
567
|
+
// nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
|
|
568
|
+
// of course, fail.
|
|
569
|
+
return !$String$2(symbol) || !(Object(symbol) instanceof Symbol) ||
|
|
570
|
+
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
|
|
571
|
+
!Symbol.sham && V8_VERSION && V8_VERSION < 41;
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
/* eslint-disable es/no-symbol -- required for testing */
|
|
575
|
+
var NATIVE_SYMBOL$1 = symbolConstructorDetection;
|
|
576
|
+
var useSymbolAsUid = NATIVE_SYMBOL$1 && !Symbol.sham && typeof Symbol.iterator == 'symbol';
|
|
577
|
+
|
|
578
|
+
var getBuiltIn = getBuiltIn$1;
|
|
579
|
+
var isCallable$3 = isCallable$8;
|
|
580
|
+
var isPrototypeOf = objectIsPrototypeOf;
|
|
581
|
+
var USE_SYMBOL_AS_UID$1 = useSymbolAsUid;
|
|
582
|
+
var $Object = Object;
|
|
583
|
+
var isSymbol$2 = USE_SYMBOL_AS_UID$1 ? function (it) {
|
|
584
|
+
return typeof it == 'symbol';
|
|
585
|
+
} : function (it) {
|
|
586
|
+
var $Symbol = getBuiltIn('Symbol');
|
|
587
|
+
return isCallable$3($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
var $String$1 = String;
|
|
591
|
+
var tryToString$1 = function (argument) {
|
|
592
|
+
try {
|
|
593
|
+
return $String$1(argument);
|
|
594
|
+
} catch (error) {
|
|
595
|
+
return 'Object';
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
var isCallable$2 = isCallable$8;
|
|
600
|
+
var tryToString = tryToString$1;
|
|
601
|
+
var $TypeError$3 = TypeError;
|
|
602
|
+
|
|
603
|
+
// `Assert: IsCallable(argument) is true`
|
|
604
|
+
var aCallable$1 = function (argument) {
|
|
605
|
+
if (isCallable$2(argument)) return argument;
|
|
606
|
+
throw new $TypeError$3(tryToString(argument) + ' is not a function');
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
var aCallable = aCallable$1;
|
|
610
|
+
var isNullOrUndefined = isNullOrUndefined$2;
|
|
611
|
+
|
|
612
|
+
// `GetMethod` abstract operation
|
|
613
|
+
// https://tc39.es/ecma262/#sec-getmethod
|
|
614
|
+
var getMethod$1 = function (V, P) {
|
|
615
|
+
var func = V[P];
|
|
616
|
+
return isNullOrUndefined(func) ? undefined : aCallable(func);
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
var call$1 = functionCall;
|
|
620
|
+
var isCallable$1 = isCallable$8;
|
|
621
|
+
var isObject$2 = isObject$5;
|
|
622
|
+
var $TypeError$2 = TypeError;
|
|
623
|
+
|
|
624
|
+
// `OrdinaryToPrimitive` abstract operation
|
|
625
|
+
// https://tc39.es/ecma262/#sec-ordinarytoprimitive
|
|
626
|
+
var ordinaryToPrimitive$1 = function (input, pref) {
|
|
627
|
+
var fn, val;
|
|
628
|
+
if (pref === 'string' && isCallable$1(fn = input.toString) && !isObject$2(val = call$1(fn, input))) return val;
|
|
629
|
+
if (isCallable$1(fn = input.valueOf) && !isObject$2(val = call$1(fn, input))) return val;
|
|
630
|
+
if (pref !== 'string' && isCallable$1(fn = input.toString) && !isObject$2(val = call$1(fn, input))) return val;
|
|
631
|
+
throw new $TypeError$2("Can't convert object to primitive value");
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
var sharedExports = {};
|
|
635
|
+
var shared$3 = {
|
|
636
|
+
get exports(){ return sharedExports; },
|
|
637
|
+
set exports(v){ sharedExports = v; },
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
var store$1 = sharedStore;
|
|
641
|
+
(shared$3.exports = function (key, value) {
|
|
642
|
+
return store$1[key] || (store$1[key] = value !== undefined ? value : {});
|
|
643
|
+
})('versions', []).push({
|
|
644
|
+
version: '3.33.0',
|
|
645
|
+
mode: 'global',
|
|
646
|
+
copyright: '© 2014-2023 Denis Pushkarev (zloirock.ru)',
|
|
647
|
+
license: 'https://github.com/zloirock/core-js/blob/v3.33.0/LICENSE',
|
|
648
|
+
source: 'https://github.com/zloirock/core-js'
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
var uncurryThis$1 = functionUncurryThis;
|
|
652
|
+
var id = 0;
|
|
653
|
+
var postfix = Math.random();
|
|
654
|
+
var toString = uncurryThis$1(1.0.toString);
|
|
655
|
+
var uid$2 = function (key) {
|
|
656
|
+
return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
var global$3 = global$b;
|
|
660
|
+
var shared$2 = sharedExports;
|
|
661
|
+
var hasOwn$2 = hasOwnProperty_1;
|
|
662
|
+
var uid$1 = uid$2;
|
|
663
|
+
var NATIVE_SYMBOL = symbolConstructorDetection;
|
|
664
|
+
var USE_SYMBOL_AS_UID = useSymbolAsUid;
|
|
665
|
+
var Symbol$1 = global$3.Symbol;
|
|
666
|
+
var WellKnownSymbolsStore = shared$2('wks');
|
|
667
|
+
var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1['for'] || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$1;
|
|
668
|
+
var wellKnownSymbol$1 = function (name) {
|
|
669
|
+
if (!hasOwn$2(WellKnownSymbolsStore, name)) {
|
|
670
|
+
WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol('Symbol.' + name);
|
|
671
|
+
}
|
|
672
|
+
return WellKnownSymbolsStore[name];
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
var call = functionCall;
|
|
676
|
+
var isObject$1 = isObject$5;
|
|
677
|
+
var isSymbol$1 = isSymbol$2;
|
|
678
|
+
var getMethod = getMethod$1;
|
|
679
|
+
var ordinaryToPrimitive = ordinaryToPrimitive$1;
|
|
680
|
+
var wellKnownSymbol = wellKnownSymbol$1;
|
|
681
|
+
var $TypeError$1 = TypeError;
|
|
682
|
+
var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
|
|
683
|
+
|
|
684
|
+
// `ToPrimitive` abstract operation
|
|
685
|
+
// https://tc39.es/ecma262/#sec-toprimitive
|
|
686
|
+
var toPrimitive$1 = function (input, pref) {
|
|
687
|
+
if (!isObject$1(input) || isSymbol$1(input)) return input;
|
|
688
|
+
var exoticToPrim = getMethod(input, TO_PRIMITIVE);
|
|
689
|
+
var result;
|
|
690
|
+
if (exoticToPrim) {
|
|
691
|
+
if (pref === undefined) pref = 'default';
|
|
692
|
+
result = call(exoticToPrim, input, pref);
|
|
693
|
+
if (!isObject$1(result) || isSymbol$1(result)) return result;
|
|
694
|
+
throw new $TypeError$1("Can't convert object to primitive value");
|
|
695
|
+
}
|
|
696
|
+
if (pref === undefined) pref = 'number';
|
|
697
|
+
return ordinaryToPrimitive(input, pref);
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
var toPrimitive = toPrimitive$1;
|
|
701
|
+
var isSymbol = isSymbol$2;
|
|
702
|
+
|
|
703
|
+
// `ToPropertyKey` abstract operation
|
|
704
|
+
// https://tc39.es/ecma262/#sec-topropertykey
|
|
705
|
+
var toPropertyKey$1 = function (argument) {
|
|
706
|
+
var key = toPrimitive(argument, 'string');
|
|
707
|
+
return isSymbol(key) ? key : key + '';
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
var DESCRIPTORS$3 = descriptors;
|
|
711
|
+
var IE8_DOM_DEFINE = ie8DomDefine;
|
|
712
|
+
var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug;
|
|
713
|
+
var anObject$1 = anObject$2;
|
|
714
|
+
var toPropertyKey = toPropertyKey$1;
|
|
715
|
+
var $TypeError = TypeError;
|
|
716
|
+
// eslint-disable-next-line es/no-object-defineproperty -- safe
|
|
717
|
+
var $defineProperty = Object.defineProperty;
|
|
718
|
+
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
|
|
719
|
+
var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
720
|
+
var ENUMERABLE = 'enumerable';
|
|
721
|
+
var CONFIGURABLE = 'configurable';
|
|
722
|
+
var WRITABLE = 'writable';
|
|
723
|
+
|
|
724
|
+
// `Object.defineProperty` method
|
|
725
|
+
// https://tc39.es/ecma262/#sec-object.defineproperty
|
|
726
|
+
objectDefineProperty.f = DESCRIPTORS$3 ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {
|
|
727
|
+
anObject$1(O);
|
|
728
|
+
P = toPropertyKey(P);
|
|
729
|
+
anObject$1(Attributes);
|
|
730
|
+
if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {
|
|
731
|
+
var current = $getOwnPropertyDescriptor(O, P);
|
|
732
|
+
if (current && current[WRITABLE]) {
|
|
733
|
+
O[P] = Attributes.value;
|
|
734
|
+
Attributes = {
|
|
735
|
+
configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],
|
|
736
|
+
enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],
|
|
737
|
+
writable: false
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return $defineProperty(O, P, Attributes);
|
|
742
|
+
} : $defineProperty : function defineProperty(O, P, Attributes) {
|
|
743
|
+
anObject$1(O);
|
|
744
|
+
P = toPropertyKey(P);
|
|
745
|
+
anObject$1(Attributes);
|
|
746
|
+
if (IE8_DOM_DEFINE) try {
|
|
747
|
+
return $defineProperty(O, P, Attributes);
|
|
748
|
+
} catch (error) {/* empty */}
|
|
749
|
+
if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');
|
|
750
|
+
if ('value' in Attributes) O[P] = Attributes.value;
|
|
751
|
+
return O;
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
var createPropertyDescriptor$1 = function (bitmap, value) {
|
|
755
|
+
return {
|
|
756
|
+
enumerable: !(bitmap & 1),
|
|
757
|
+
configurable: !(bitmap & 2),
|
|
758
|
+
writable: !(bitmap & 4),
|
|
759
|
+
value: value
|
|
760
|
+
};
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
var DESCRIPTORS$2 = descriptors;
|
|
764
|
+
var definePropertyModule = objectDefineProperty;
|
|
765
|
+
var createPropertyDescriptor = createPropertyDescriptor$1;
|
|
766
|
+
var createNonEnumerableProperty$1 = DESCRIPTORS$2 ? function (object, key, value) {
|
|
767
|
+
return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
|
|
768
|
+
} : function (object, key, value) {
|
|
769
|
+
object[key] = value;
|
|
770
|
+
return object;
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
var shared$1 = sharedExports;
|
|
774
|
+
var uid = uid$2;
|
|
775
|
+
var keys = shared$1('keys');
|
|
776
|
+
var sharedKey$1 = function (key) {
|
|
777
|
+
return keys[key] || (keys[key] = uid(key));
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
var NATIVE_WEAK_MAP = weakMapBasicDetection;
|
|
781
|
+
var global$2 = global$b;
|
|
782
|
+
var isObject = isObject$5;
|
|
783
|
+
var createNonEnumerableProperty = createNonEnumerableProperty$1;
|
|
784
|
+
var hasOwn$1 = hasOwnProperty_1;
|
|
785
|
+
var shared = sharedStore;
|
|
786
|
+
var sharedKey = sharedKey$1;
|
|
787
|
+
var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
|
|
788
|
+
var TypeError$1 = global$2.TypeError;
|
|
789
|
+
var WeakMap = global$2.WeakMap;
|
|
790
|
+
var set, get, has;
|
|
791
|
+
var enforce = function (it) {
|
|
792
|
+
return has(it) ? get(it) : set(it, {});
|
|
793
|
+
};
|
|
794
|
+
var getterFor = function (TYPE) {
|
|
795
|
+
return function (it) {
|
|
796
|
+
var state;
|
|
797
|
+
if (!isObject(it) || (state = get(it)).type !== TYPE) {
|
|
798
|
+
throw new TypeError$1('Incompatible receiver, ' + TYPE + ' required');
|
|
799
|
+
}
|
|
800
|
+
return state;
|
|
801
|
+
};
|
|
802
|
+
};
|
|
803
|
+
if (NATIVE_WEAK_MAP || shared.state) {
|
|
804
|
+
var store = shared.state || (shared.state = new WeakMap());
|
|
805
|
+
/* eslint-disable no-self-assign -- prototype methods protection */
|
|
806
|
+
store.get = store.get;
|
|
807
|
+
store.has = store.has;
|
|
808
|
+
store.set = store.set;
|
|
809
|
+
/* eslint-enable no-self-assign -- prototype methods protection */
|
|
810
|
+
set = function (it, metadata) {
|
|
811
|
+
if (store.has(it)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED);
|
|
812
|
+
metadata.facade = it;
|
|
813
|
+
store.set(it, metadata);
|
|
814
|
+
return metadata;
|
|
815
|
+
};
|
|
816
|
+
get = function (it) {
|
|
817
|
+
return store.get(it) || {};
|
|
818
|
+
};
|
|
819
|
+
has = function (it) {
|
|
820
|
+
return store.has(it);
|
|
821
|
+
};
|
|
822
|
+
} else {
|
|
823
|
+
var STATE = sharedKey('state');
|
|
824
|
+
set = function (it, metadata) {
|
|
825
|
+
if (hasOwn$1(it, STATE)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED);
|
|
826
|
+
metadata.facade = it;
|
|
827
|
+
createNonEnumerableProperty(it, STATE, metadata);
|
|
828
|
+
return metadata;
|
|
829
|
+
};
|
|
830
|
+
get = function (it) {
|
|
831
|
+
return hasOwn$1(it, STATE) ? it[STATE] : {};
|
|
832
|
+
};
|
|
833
|
+
has = function (it) {
|
|
834
|
+
return hasOwn$1(it, STATE);
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
var internalState = {
|
|
838
|
+
set: set,
|
|
839
|
+
get: get,
|
|
840
|
+
has: has,
|
|
841
|
+
enforce: enforce,
|
|
842
|
+
getterFor: getterFor
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
var uncurryThis = functionUncurryThis;
|
|
846
|
+
var fails$1 = fails$7;
|
|
847
|
+
var isCallable = isCallable$8;
|
|
848
|
+
var hasOwn = hasOwnProperty_1;
|
|
849
|
+
var DESCRIPTORS$1 = descriptors;
|
|
850
|
+
var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE;
|
|
851
|
+
var inspectSource = inspectSource$1;
|
|
852
|
+
var InternalStateModule = internalState;
|
|
853
|
+
var enforceInternalState = InternalStateModule.enforce;
|
|
854
|
+
var getInternalState = InternalStateModule.get;
|
|
855
|
+
var $String = String;
|
|
856
|
+
// eslint-disable-next-line es/no-object-defineproperty -- safe
|
|
857
|
+
var defineProperty$1 = Object.defineProperty;
|
|
858
|
+
var stringSlice = uncurryThis(''.slice);
|
|
859
|
+
var replace = uncurryThis(''.replace);
|
|
860
|
+
var join = uncurryThis([].join);
|
|
861
|
+
var CONFIGURABLE_LENGTH = DESCRIPTORS$1 && !fails$1(function () {
|
|
862
|
+
return defineProperty$1(function () {/* empty */}, 'length', {
|
|
863
|
+
value: 8
|
|
864
|
+
}).length !== 8;
|
|
865
|
+
});
|
|
866
|
+
var TEMPLATE = String(String).split('String');
|
|
867
|
+
var makeBuiltIn$1 = makeBuiltIn$2.exports = function (value, name, options) {
|
|
868
|
+
if (stringSlice($String(name), 0, 7) === 'Symbol(') {
|
|
869
|
+
name = '[' + replace($String(name), /^Symbol\(([^)]*)\)/, '$1') + ']';
|
|
870
|
+
}
|
|
871
|
+
if (options && options.getter) name = 'get ' + name;
|
|
872
|
+
if (options && options.setter) name = 'set ' + name;
|
|
873
|
+
if (!hasOwn(value, 'name') || CONFIGURABLE_FUNCTION_NAME && value.name !== name) {
|
|
874
|
+
if (DESCRIPTORS$1) defineProperty$1(value, 'name', {
|
|
875
|
+
value: name,
|
|
876
|
+
configurable: true
|
|
877
|
+
});else value.name = name;
|
|
878
|
+
}
|
|
879
|
+
if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {
|
|
880
|
+
defineProperty$1(value, 'length', {
|
|
881
|
+
value: options.arity
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
try {
|
|
885
|
+
if (options && hasOwn(options, 'constructor') && options.constructor) {
|
|
886
|
+
if (DESCRIPTORS$1) defineProperty$1(value, 'prototype', {
|
|
887
|
+
writable: false
|
|
888
|
+
});
|
|
889
|
+
// in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable
|
|
890
|
+
} else if (value.prototype) value.prototype = undefined;
|
|
891
|
+
} catch (error) {/* empty */}
|
|
892
|
+
var state = enforceInternalState(value);
|
|
893
|
+
if (!hasOwn(state, 'source')) {
|
|
894
|
+
state.source = join(TEMPLATE, typeof name == 'string' ? name : '');
|
|
895
|
+
}
|
|
896
|
+
return value;
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
|
|
900
|
+
// eslint-disable-next-line no-extend-native -- required
|
|
901
|
+
Function.prototype.toString = makeBuiltIn$1(function toString() {
|
|
902
|
+
return isCallable(this) && getInternalState(this).source || inspectSource(this);
|
|
903
|
+
}, 'toString');
|
|
904
|
+
|
|
905
|
+
var makeBuiltIn = makeBuiltInExports;
|
|
906
|
+
var defineProperty = objectDefineProperty;
|
|
907
|
+
var defineBuiltInAccessor$1 = function (target, name, descriptor) {
|
|
908
|
+
if (descriptor.get) makeBuiltIn(descriptor.get, name, {
|
|
909
|
+
getter: true
|
|
910
|
+
});
|
|
911
|
+
if (descriptor.set) makeBuiltIn(descriptor.set, name, {
|
|
912
|
+
setter: true
|
|
913
|
+
});
|
|
914
|
+
return defineProperty.f(target, name, descriptor);
|
|
915
|
+
};
|
|
916
|
+
|
|
917
|
+
var anObject = anObject$2;
|
|
918
|
+
|
|
919
|
+
// `RegExp.prototype.flags` getter implementation
|
|
920
|
+
// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
|
|
921
|
+
var regexpFlags = function () {
|
|
922
|
+
var that = anObject(this);
|
|
923
|
+
var result = '';
|
|
924
|
+
if (that.hasIndices) result += 'd';
|
|
925
|
+
if (that.global) result += 'g';
|
|
926
|
+
if (that.ignoreCase) result += 'i';
|
|
927
|
+
if (that.multiline) result += 'm';
|
|
928
|
+
if (that.dotAll) result += 's';
|
|
929
|
+
if (that.unicode) result += 'u';
|
|
930
|
+
if (that.unicodeSets) result += 'v';
|
|
931
|
+
if (that.sticky) result += 'y';
|
|
932
|
+
return result;
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
var global$1 = global$b;
|
|
936
|
+
var DESCRIPTORS = descriptors;
|
|
937
|
+
var defineBuiltInAccessor = defineBuiltInAccessor$1;
|
|
938
|
+
var regExpFlags = regexpFlags;
|
|
939
|
+
var fails = fails$7;
|
|
940
|
+
|
|
941
|
+
// babel-minify and Closure Compiler transpiles RegExp('.', 'd') -> /./d and it causes SyntaxError
|
|
942
|
+
var RegExp$1 = global$1.RegExp;
|
|
943
|
+
var RegExpPrototype = RegExp$1.prototype;
|
|
944
|
+
var FORCED = DESCRIPTORS && fails(function () {
|
|
945
|
+
var INDICES_SUPPORT = true;
|
|
946
|
+
try {
|
|
947
|
+
RegExp$1('.', 'd');
|
|
948
|
+
} catch (error) {
|
|
949
|
+
INDICES_SUPPORT = false;
|
|
950
|
+
}
|
|
951
|
+
var O = {};
|
|
952
|
+
// modern V8 bug
|
|
953
|
+
var calls = '';
|
|
954
|
+
var expected = INDICES_SUPPORT ? 'dgimsy' : 'gimsy';
|
|
955
|
+
var addGetter = function (key, chr) {
|
|
956
|
+
// eslint-disable-next-line es/no-object-defineproperty -- safe
|
|
957
|
+
Object.defineProperty(O, key, {
|
|
958
|
+
get: function () {
|
|
959
|
+
calls += chr;
|
|
960
|
+
return true;
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
};
|
|
964
|
+
var pairs = {
|
|
965
|
+
dotAll: 's',
|
|
966
|
+
global: 'g',
|
|
967
|
+
ignoreCase: 'i',
|
|
968
|
+
multiline: 'm',
|
|
969
|
+
sticky: 'y'
|
|
970
|
+
};
|
|
971
|
+
if (INDICES_SUPPORT) pairs.hasIndices = 'd';
|
|
972
|
+
for (var key in pairs) addGetter(key, pairs[key]);
|
|
973
|
+
|
|
974
|
+
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
|
|
975
|
+
var result = Object.getOwnPropertyDescriptor(RegExpPrototype, 'flags').get.call(O);
|
|
976
|
+
return result !== expected || calls !== expected;
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
// `RegExp.prototype.flags` getter
|
|
980
|
+
// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
|
|
981
|
+
if (FORCED) defineBuiltInAccessor(RegExpPrototype, 'flags', {
|
|
982
|
+
configurable: true,
|
|
983
|
+
get: regExpFlags
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
// const replacements = {
|
|
987
|
+
// ASCIIPunctuation: '!"#$%&\'()*+,\\-./:;<=>?@\\[\\]^_`{|}~',
|
|
988
|
+
// TriggerChars: '`_\*\[\]\(\)',
|
|
989
|
+
// Scheme: `[A-Za-z][A-Za-z0-9\+\.\-]{1,31}`,
|
|
990
|
+
// 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])?)*`, // From CommonMark spec
|
|
991
|
+
|
|
992
|
+
// }
|
|
993
|
+
const replacements = {
|
|
994
|
+
ASCIIPunctuation: /[!"#$%&'()*+,\-./:;<=>?@[\]^_`{|}~\\]/,
|
|
995
|
+
NotTriggerChar: /[^`_*[\]()<>!~]/,
|
|
996
|
+
Scheme: /[A-Za-z][A-Za-z0-9+.-]{1,31}/,
|
|
997
|
+
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])?)*/,
|
|
998
|
+
// From CommonMark spec
|
|
999
|
+
HTMLOpenTag: /<HTMLTagName(?:HTMLAttribute)*\s*\/?>/,
|
|
1000
|
+
HTMLCloseTag: /<\/HTMLTagName\s*>/,
|
|
1001
|
+
HTMLTagName: /[A-Za-z][A-Za-z0-9-]*/,
|
|
1002
|
+
HTMLComment: /<!--(?:[^>-]|(?:[^>-](?:[^-]|-[^-])*[^-]))-->/,
|
|
1003
|
+
HTMLPI: /<\?(?:|.|(?:[^?]|\?[^>])*)\?>/,
|
|
1004
|
+
HTMLDeclaration: /<![A-Z]+\s[^>]*>/,
|
|
1005
|
+
HTMLCDATA: /<!\[CDATA\[.*?\]\]>/,
|
|
1006
|
+
HTMLAttribute: /\s+[A-Za-z_:][A-Za-z0-9_.:-]*(?:HTMLAttValue)?/,
|
|
1007
|
+
HTMLAttValue: /\s*=\s*(?:(?:'[^']*')|(?:"[^"]*")|(?:[^\s"'=<>`]+))/,
|
|
1008
|
+
KnownTag: /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|h1|h2|h3|h4|h5|h6|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul/
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
// From CommonMark.js.
|
|
1012
|
+
const punctuationLeading = new RegExp(/^(?:[!"#$%&'()*+,\-./:;<=>?@[\]\\^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B])/);
|
|
1013
|
+
const punctuationTrailing = new RegExp(/(?:[!"#$%&'()*+,\-./:;<=>?@[\]\\^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B])$/);
|
|
1014
|
+
|
|
1015
|
+
// export const inlineTriggerChars = new RegExp(`[${replacements.TriggerChars}]`);
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* This is CommonMark's block grammar, but we're ignoring nested blocks here.
|
|
1019
|
+
*/
|
|
1020
|
+
const lineGrammar = {
|
|
1021
|
+
TMH1: {
|
|
1022
|
+
regexp: /^( {0,3}#\s)(.*?)((?:\s+#+\s*)?)$/,
|
|
1023
|
+
replacement: '<span class="TMMark TMMark_TMH1">$1</span>$$2<span class="TMMark TMMark_TMH1">$3</span>'
|
|
1024
|
+
},
|
|
1025
|
+
TMH2: {
|
|
1026
|
+
regexp: /^( {0,3}##\s)(.*?)((?:\s+#+\s*)?)$/,
|
|
1027
|
+
replacement: '<span class="TMMark TMMark_TMH2">$1</span>$$2<span class="TMMark TMMark_TMH2">$3</span>'
|
|
1028
|
+
},
|
|
1029
|
+
TMH3: {
|
|
1030
|
+
regexp: /^( {0,3}###\s)(.*?)((?:\s+#+\s*)?)$/,
|
|
1031
|
+
replacement: '<span class="TMMark TMMark_TMH3">$1</span>$$2<span class="TMMark TMMark_TMH3">$3</span>'
|
|
1032
|
+
},
|
|
1033
|
+
TMH4: {
|
|
1034
|
+
regexp: /^( {0,3}####\s)(.*?)((?:\s+#+\s*)?)$/,
|
|
1035
|
+
replacement: '<span class="TMMark TMMark_TMH4">$1</span>$$2<span class="TMMark TMMark_TMH4">$3</span>'
|
|
1036
|
+
},
|
|
1037
|
+
TMH5: {
|
|
1038
|
+
regexp: /^( {0,3}#####\s)(.*?)((?:\s+#+\s*)?)$/,
|
|
1039
|
+
replacement: '<span class="TMMark TMMark_TMH5">$1</span>$$2<span class="TMMark TMMark_TMH5">$3</span>'
|
|
1040
|
+
},
|
|
1041
|
+
TMH6: {
|
|
1042
|
+
regexp: /^( {0,3}######\s)(.*?)((?:\s+#+\s*)?)$/,
|
|
1043
|
+
replacement: '<span class="TMMark TMMark_TMH6">$1</span>$$2<span class="TMMark TMMark_TMH6">$3</span>'
|
|
1044
|
+
},
|
|
1045
|
+
TMBlockquote: {
|
|
1046
|
+
regexp: /^( {0,3}>[ ]?)(.*)$/,
|
|
1047
|
+
replacement: '<span class="TMMark TMMark_TMBlockquote">$1</span>$$2'
|
|
1048
|
+
},
|
|
1049
|
+
TMCodeFenceBacktickOpen: {
|
|
1050
|
+
regexp: /^( {0,3}(?<seq>````*)\s*)([^`]*?)(\s*)$/,
|
|
1051
|
+
replacement: '<span class="TMMark TMMark_TMCodeFenceBacktick">$1</span><span class="TMInfoString">$3</span>$4'
|
|
1052
|
+
},
|
|
1053
|
+
TMCodeFenceTildeOpen: {
|
|
1054
|
+
regexp: /^( {0,3}(?<seq>~~~~*)\s*)(.*?)(\s*)$/,
|
|
1055
|
+
replacement: '<span class="TMMark TMMark_TMCodeFenceTilde">$1</span><span class="TMInfoString">$3</span>$4'
|
|
1056
|
+
},
|
|
1057
|
+
TMCodeFenceBacktickClose: {
|
|
1058
|
+
regexp: /^( {0,3}(?<seq>````*))(\s*)$/,
|
|
1059
|
+
replacement: '<span class="TMMark TMMark_TMCodeFenceBacktick">$1</span>$3'
|
|
1060
|
+
},
|
|
1061
|
+
TMCodeFenceTildeClose: {
|
|
1062
|
+
regexp: /^( {0,3}(?<seq>~~~~*))(\s*)$/,
|
|
1063
|
+
replacement: '<span class="TMMark TMMark_TMCodeFenceTilde">$1</span>$3'
|
|
1064
|
+
},
|
|
1065
|
+
TMBlankLine: {
|
|
1066
|
+
regexp: /^([ \t]*)$/,
|
|
1067
|
+
replacement: '$0'
|
|
1068
|
+
},
|
|
1069
|
+
TMSetextH1Marker: {
|
|
1070
|
+
regexp: /^ {0,3}=+\s*$/,
|
|
1071
|
+
replacement: '<span class="TMMark TMMark_TMSetextH1Marker">$0</span>'
|
|
1072
|
+
},
|
|
1073
|
+
TMSetextH2Marker: {
|
|
1074
|
+
regexp: /^ {0,3}-+\s*$/,
|
|
1075
|
+
replacement: '<span class="TMMark TMMark_TMSetextH1Marker">$0</span>'
|
|
1076
|
+
},
|
|
1077
|
+
TMHR: {
|
|
1078
|
+
regexp: /^( {0,3}(\*[ \t]*\*[ \t]*\*[ \t*]*)|(-[ \t]*-[ \t]*-[ \t-]*)|(_[ \t]*_[ \t]*_[ \t_]*))$/,
|
|
1079
|
+
replacement: '<span class="TMMark TMMark_TMHR">$0</span>'
|
|
1080
|
+
},
|
|
1081
|
+
TMUL: {
|
|
1082
|
+
regexp: /^( {0,3}[+*-] {1,4})(.*)$/,
|
|
1083
|
+
replacement: '<span class="TMMark TMMark_TMUL">$1</span>$$2'
|
|
1084
|
+
},
|
|
1085
|
+
TMOL: {
|
|
1086
|
+
regexp: /^( {0,3}\d{1,9}[.)] {1,4})(.*)$/,
|
|
1087
|
+
replacement: '<span class="TMMark TMMark_TMOL">$1</span>$$2'
|
|
1088
|
+
},
|
|
1089
|
+
// TODO: This is currently preventing sublists (and any content within list items, really) from working
|
|
1090
|
+
TMIndentedCode: {
|
|
1091
|
+
regexp: /^( {4}|\t)(.*)$/,
|
|
1092
|
+
replacement: '<span class="TMMark TMMark_TMIndentedCode">$1</span>$2'
|
|
1093
|
+
},
|
|
1094
|
+
TMLinkReferenceDefinition: {
|
|
1095
|
+
// TODO: Link destination can't include unbalanced parantheses, but we just ignore that here
|
|
1096
|
+
regexp: /^( {0,3}\[\s*)([^\s\]](?:[^\]]|\\\])*?)(\s*\]:\s*)((?:[^\s<>]+)|(?:<(?:[^<>\\]|\\.)*>))?(\s*)((?:\((?:[^()\\]|\\.)*\))|(?:"(?:[^"\\]|\\.)*")|(?:'(?:[^'\\]|\\.)*'))?(\s*)$/,
|
|
1097
|
+
replacement: '<span class="TMMark TMMark_TMLinkReferenceDefinition">$1</span><span class="TMLinkLabel TMLinkLabel_Definition">$2</span><span class="TMMark TMMark_TMLinkReferenceDefinition">$3</span><span class="TMLinkDestination">$4</span>$5<span class="TMLinkTitle">$6</span>$7',
|
|
1098
|
+
labelPlaceholder: 2 // this defines which placeholder in the above regex is the link "label"
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* HTML blocks have multiple different classes of opener and closer. This array defines all the cases
|
|
1104
|
+
*/
|
|
1105
|
+
var htmlBlockGrammar = [{
|
|
1106
|
+
start: /^ {0,3}<(?:script|pre|style)(?:\s|>|$)/i,
|
|
1107
|
+
end: /(?:<\/script>|<\/pre>|<\/style>)/i,
|
|
1108
|
+
paraInterrupt: true
|
|
1109
|
+
}, {
|
|
1110
|
+
start: /^ {0,3}<!--/,
|
|
1111
|
+
end: /-->/,
|
|
1112
|
+
paraInterrupt: true
|
|
1113
|
+
}, {
|
|
1114
|
+
start: /^ {0,3}<\?/,
|
|
1115
|
+
end: /\?>/,
|
|
1116
|
+
paraInterrupt: true
|
|
1117
|
+
}, {
|
|
1118
|
+
start: /^ {0,3}<![A-Z]/,
|
|
1119
|
+
end: />/,
|
|
1120
|
+
paraInterrupt: true
|
|
1121
|
+
}, {
|
|
1122
|
+
start: /^ {0,3}<!\[CDATA\[/,
|
|
1123
|
+
end: /\]\]>/,
|
|
1124
|
+
paraInterrupt: true
|
|
1125
|
+
}, {
|
|
1126
|
+
start: /^ {0,3}(?:<|<\/)(?:KnownTag)(?:\s|>|\/>|$)/i,
|
|
1127
|
+
end: false,
|
|
1128
|
+
paraInterrupt: true
|
|
1129
|
+
}, {
|
|
1130
|
+
start: /^ {0,3}(?:HTMLOpenTag|HTMLCloseTag)\s*$/,
|
|
1131
|
+
end: false,
|
|
1132
|
+
paraInterrupt: false
|
|
1133
|
+
}];
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Structure of the object:
|
|
1137
|
+
* Top level entries are rules, each consisting of a regular expressions (in string format) as well as a replacement.
|
|
1138
|
+
* In the regular expressions, replacements from the object 'replacements' will be processed before compiling into the property regexp.
|
|
1139
|
+
*/
|
|
1140
|
+
var inlineGrammar = {
|
|
1141
|
+
escape: {
|
|
1142
|
+
regexp: /^\\(ASCIIPunctuation)/,
|
|
1143
|
+
replacement: '<span class="TMMark TMMark_TMEscape">\\</span>$1'
|
|
1144
|
+
},
|
|
1145
|
+
code: {
|
|
1146
|
+
regexp: /^(`+)((?:[^`])|(?:[^`].*?[^`]))(\1)/,
|
|
1147
|
+
replacement: '<span class="TMMark TMMark_TMCode">$1</span><code class="TMCode">$2</code><span class="TMMark TMMark_TMCode">$3</span>'
|
|
1148
|
+
},
|
|
1149
|
+
autolink: {
|
|
1150
|
+
regexp: /^<((?:Scheme:[^\s<>]*)|(?:Email))>/,
|
|
1151
|
+
replacement: '<span class="TMMark TMMark_TMAutolink"><</span><span class="TMAutolink">$1</span><span class="TMMark TMMark_TMAutolink">></span>'
|
|
1152
|
+
},
|
|
1153
|
+
html: {
|
|
1154
|
+
regexp: /^((?:HTMLOpenTag)|(?:HTMLCloseTag)|(?:HTMLComment)|(?:HTMLPI)|(?:HTMLDeclaration)|(?:HTMLCDATA))/,
|
|
1155
|
+
replacement: '<span class="TMHTML">$1</span>'
|
|
1156
|
+
},
|
|
1157
|
+
linkOpen: {
|
|
1158
|
+
regexp: /^\[/,
|
|
1159
|
+
replacement: ''
|
|
1160
|
+
},
|
|
1161
|
+
imageOpen: {
|
|
1162
|
+
regexp: /^!\[/,
|
|
1163
|
+
replacement: ''
|
|
1164
|
+
},
|
|
1165
|
+
linkLabel: {
|
|
1166
|
+
regexp: /^(\[\s*)([^\]]*?)(\s*\])/,
|
|
1167
|
+
replacement: '',
|
|
1168
|
+
labelPlaceholder: 2
|
|
1169
|
+
},
|
|
1170
|
+
default: {
|
|
1171
|
+
regexp: /^(.|(?:NotTriggerChar+))/,
|
|
1172
|
+
replacement: '$1'
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
// Process replacements in regexps
|
|
1177
|
+
const replacementRegexp = new RegExp(Object.keys(replacements).join('|'));
|
|
1178
|
+
|
|
1179
|
+
// Inline
|
|
1180
|
+
const inlineRules = [...Object.keys(inlineGrammar)];
|
|
1181
|
+
for (let rule of inlineRules) {
|
|
1182
|
+
let re = inlineGrammar[rule].regexp.source;
|
|
1183
|
+
// Replace while there is something to replace. This means it also works over multiple levels (replacements containing replacements)
|
|
1184
|
+
while (re.match(replacementRegexp)) {
|
|
1185
|
+
re = re.replace(replacementRegexp, string => {
|
|
1186
|
+
return replacements[string].source;
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
inlineGrammar[rule].regexp = new RegExp(re, inlineGrammar[rule].regexp.flags);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// HTML Block (only opening rule is processed currently)
|
|
1193
|
+
for (let rule of htmlBlockGrammar) {
|
|
1194
|
+
let re = rule.start.source;
|
|
1195
|
+
// Replace while there is something to replace. This means it also works over multiple levels (replacements containing replacements)
|
|
1196
|
+
while (re.match(replacementRegexp)) {
|
|
1197
|
+
re = re.replace(replacementRegexp, string => {
|
|
1198
|
+
return replacements[string].source;
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
rule.start = new RegExp(re, rule.start.flags);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/**
|
|
1205
|
+
* Escapes HTML special characters (<, >, and &) in the string.
|
|
1206
|
+
* @param {string} string The raw string to be escaped
|
|
1207
|
+
* @returns {string} The string, ready to be used in HTML
|
|
1208
|
+
*/
|
|
1209
|
+
function htmlescape(string) {
|
|
1210
|
+
return (string ? string : '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Contains the commands that can be sent to the editor. Contains objects with a name representing the name of the command.
|
|
1214
|
+
* Each of the objects contains the following keys:
|
|
1215
|
+
*
|
|
1216
|
+
* - type: Can be either inline (for inline formatting) or line (for block / line formatting).
|
|
1217
|
+
* - className: Used to determine whether the command is active at a given position.
|
|
1218
|
+
* For line formatting, this looks at the class of the line element. For inline elements, tries to find an enclosing element with that class.
|
|
1219
|
+
* - set / unset: Contain instructions how to set and unset the command. For line type commands, both consist of a pattern and replacement that
|
|
1220
|
+
* will be applied to each line (using String.replace). For inline type commands, the set object contains a pre and post string which will
|
|
1221
|
+
* be inserted before and after the selection. The unset object contains a prePattern and a postPattern. Both should be regular expressions and
|
|
1222
|
+
* they will be applied to the portion of the line before and after the selection (using String.replace, with an empty replacement string).
|
|
1223
|
+
*/
|
|
1224
|
+
const commands = {
|
|
1225
|
+
// Replacements for unset for inline commands are '' by default
|
|
1226
|
+
bold: {
|
|
1227
|
+
type: 'inline',
|
|
1228
|
+
className: 'TMStrong',
|
|
1229
|
+
set: {
|
|
1230
|
+
pre: '**',
|
|
1231
|
+
post: '**'
|
|
1232
|
+
},
|
|
1233
|
+
unset: {
|
|
1234
|
+
prePattern: /(?:\*\*|__)$/,
|
|
1235
|
+
postPattern: /^(?:\*\*|__)/
|
|
1236
|
+
}
|
|
1237
|
+
},
|
|
1238
|
+
italic: {
|
|
1239
|
+
type: 'inline',
|
|
1240
|
+
className: 'TMEm',
|
|
1241
|
+
set: {
|
|
1242
|
+
pre: '*',
|
|
1243
|
+
post: '*'
|
|
1244
|
+
},
|
|
1245
|
+
unset: {
|
|
1246
|
+
prePattern: /(?:\*|_)$/,
|
|
1247
|
+
postPattern: /^(?:\*|_)/
|
|
1248
|
+
}
|
|
1249
|
+
},
|
|
1250
|
+
code: {
|
|
1251
|
+
type: 'inline',
|
|
1252
|
+
className: 'TMCode',
|
|
1253
|
+
set: {
|
|
1254
|
+
pre: '`',
|
|
1255
|
+
post: '`'
|
|
1256
|
+
},
|
|
1257
|
+
unset: {
|
|
1258
|
+
prePattern: /`+$/,
|
|
1259
|
+
postPattern: /^`+/
|
|
1260
|
+
} // FIXME this doesn't ensure balanced backticks right now
|
|
1261
|
+
},
|
|
1262
|
+
|
|
1263
|
+
strikethrough: {
|
|
1264
|
+
type: 'inline',
|
|
1265
|
+
className: 'TMStrikethrough',
|
|
1266
|
+
set: {
|
|
1267
|
+
pre: '~~',
|
|
1268
|
+
post: '~~'
|
|
1269
|
+
},
|
|
1270
|
+
unset: {
|
|
1271
|
+
prePattern: /~~$/,
|
|
1272
|
+
postPattern: /^~~/
|
|
1273
|
+
}
|
|
1274
|
+
},
|
|
1275
|
+
h1: {
|
|
1276
|
+
type: 'line',
|
|
1277
|
+
className: 'TMH1',
|
|
1278
|
+
set: {
|
|
1279
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1280
|
+
replacement: '# $2'
|
|
1281
|
+
},
|
|
1282
|
+
unset: {
|
|
1283
|
+
pattern: /^( {0,3}#\s+)(.*?)((?:\s+#+\s*)?)$/,
|
|
1284
|
+
replacement: '$2'
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
h2: {
|
|
1288
|
+
type: 'line',
|
|
1289
|
+
className: 'TMH2',
|
|
1290
|
+
set: {
|
|
1291
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1292
|
+
replacement: '## $2'
|
|
1293
|
+
},
|
|
1294
|
+
unset: {
|
|
1295
|
+
pattern: /^( {0,3}##\s+)(.*?)((?:\s+#+\s*)?)$/,
|
|
1296
|
+
replacement: '$2'
|
|
1297
|
+
}
|
|
1298
|
+
},
|
|
1299
|
+
h3: {
|
|
1300
|
+
type: 'line',
|
|
1301
|
+
className: 'TMH3',
|
|
1302
|
+
set: {
|
|
1303
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1304
|
+
replacement: '### $2'
|
|
1305
|
+
},
|
|
1306
|
+
unset: {
|
|
1307
|
+
pattern: /^( {0,3}###\s+)(.*?)((?:\s+#+\s*)?)$/,
|
|
1308
|
+
replacement: '$2'
|
|
1309
|
+
}
|
|
1310
|
+
},
|
|
1311
|
+
h4: {
|
|
1312
|
+
type: 'line',
|
|
1313
|
+
className: 'TMH4',
|
|
1314
|
+
set: {
|
|
1315
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1316
|
+
replacement: '#### $2'
|
|
1317
|
+
},
|
|
1318
|
+
unset: {
|
|
1319
|
+
pattern: /^( {0,3}####\s+)(.*?)((?:\s+#+\s*)?)$/,
|
|
1320
|
+
replacement: '$2'
|
|
1321
|
+
}
|
|
1322
|
+
},
|
|
1323
|
+
h5: {
|
|
1324
|
+
type: 'line',
|
|
1325
|
+
className: 'TMH5',
|
|
1326
|
+
set: {
|
|
1327
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1328
|
+
replacement: '##### $2'
|
|
1329
|
+
},
|
|
1330
|
+
unset: {
|
|
1331
|
+
pattern: /^( {0,3}#####\s+)(.*?)((?:\s+#+\s*)?)$/,
|
|
1332
|
+
replacement: '$2'
|
|
1333
|
+
}
|
|
1334
|
+
},
|
|
1335
|
+
h6: {
|
|
1336
|
+
type: 'line',
|
|
1337
|
+
className: 'TMH6',
|
|
1338
|
+
set: {
|
|
1339
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1340
|
+
replacement: '###### $2'
|
|
1341
|
+
},
|
|
1342
|
+
unset: {
|
|
1343
|
+
pattern: /^( {0,3}######\s+)(.*?)((?:\s+#+\s*)?)$/,
|
|
1344
|
+
replacement: '$2'
|
|
1345
|
+
}
|
|
1346
|
+
},
|
|
1347
|
+
ul: {
|
|
1348
|
+
type: 'line',
|
|
1349
|
+
className: 'TMUL',
|
|
1350
|
+
set: {
|
|
1351
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1352
|
+
replacement: '- $2'
|
|
1353
|
+
},
|
|
1354
|
+
unset: {
|
|
1355
|
+
pattern: /^( {0,3}[+*-] {1,4})(.*)$/,
|
|
1356
|
+
replacement: '$2'
|
|
1357
|
+
}
|
|
1358
|
+
},
|
|
1359
|
+
ol: {
|
|
1360
|
+
type: 'line',
|
|
1361
|
+
className: 'TMOL',
|
|
1362
|
+
set: {
|
|
1363
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1364
|
+
replacement: '$#. $2'
|
|
1365
|
+
},
|
|
1366
|
+
unset: {
|
|
1367
|
+
pattern: /^( {0,3}\d{1,9}[.)] {1,4})(.*)$/,
|
|
1368
|
+
replacement: '$2'
|
|
1369
|
+
}
|
|
1370
|
+
},
|
|
1371
|
+
blockquote: {
|
|
1372
|
+
type: 'line',
|
|
1373
|
+
className: 'TMBlockquote',
|
|
1374
|
+
set: {
|
|
1375
|
+
pattern: /^( {0,3}(?:(?:#+|[0-9]{1,9}[).]|[>\-*+])\s+)?)(.*)$/,
|
|
1376
|
+
replacement: '> $2'
|
|
1377
|
+
},
|
|
1378
|
+
unset: {
|
|
1379
|
+
pattern: /^( {0,3}>[ ]?)(.*)$/,
|
|
1380
|
+
replacement: '$2'
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
|
|
1385
|
+
class Editor {
|
|
1386
|
+
constructor() {
|
|
1387
|
+
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1388
|
+
this.e = null;
|
|
1389
|
+
this.textarea = null;
|
|
1390
|
+
this.lines = [];
|
|
1391
|
+
this.lineElements = [];
|
|
1392
|
+
this.lineTypes = [];
|
|
1393
|
+
this.lineCaptures = [];
|
|
1394
|
+
this.lineReplacements = [];
|
|
1395
|
+
this.linkLabels = [];
|
|
1396
|
+
this.lineDirty = [];
|
|
1397
|
+
this.lastCommandState = null;
|
|
1398
|
+
this.listeners = {
|
|
1399
|
+
change: [],
|
|
1400
|
+
selection: []
|
|
1401
|
+
};
|
|
1402
|
+
let element = props.element;
|
|
1403
|
+
this.textarea = props.textarea;
|
|
1404
|
+
if (this.textarea) {
|
|
1405
|
+
if (!this.textarea.tagName) {
|
|
1406
|
+
this.textarea = document.getElementById(this.textarea);
|
|
1407
|
+
}
|
|
1408
|
+
if (!element) element = this.textarea;
|
|
1409
|
+
}
|
|
1410
|
+
if (element && !element.tagName) {
|
|
1411
|
+
element = document.getElementById(props.element);
|
|
1412
|
+
}
|
|
1413
|
+
if (!element) {
|
|
1414
|
+
element = document.getElementsByTagName("body")[0];
|
|
1415
|
+
}
|
|
1416
|
+
if (element.tagName == "TEXTAREA") {
|
|
1417
|
+
this.textarea = element;
|
|
1418
|
+
element = this.textarea.parentNode;
|
|
1419
|
+
}
|
|
1420
|
+
if (this.textarea) {
|
|
1421
|
+
this.textarea.style.display = "none";
|
|
1422
|
+
}
|
|
1423
|
+
this.createEditorElement(element);
|
|
1424
|
+
// TODO Placeholder for empty content
|
|
1425
|
+
this.setContent(props.content || (this.textarea ? this.textarea.value : "# Hello TinyMDE!\nEdit **here**"));
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
/**
|
|
1429
|
+
* Creates the editor element inside the target element of the DOM tree
|
|
1430
|
+
* @param element The target element of the DOM tree
|
|
1431
|
+
*/
|
|
1432
|
+
createEditorElement(element) {
|
|
1433
|
+
this.e = document.createElement("div");
|
|
1434
|
+
this.e.className = "TinyMDE";
|
|
1435
|
+
this.e.contentEditable = true;
|
|
1436
|
+
// The following is important for formatting purposes, but also since otherwise the browser replaces subsequent spaces with
|
|
1437
|
+
// That breaks a lot of stuff, so we do this here and not in CSS—therefore, you don't have to remember to put this in the CSS file
|
|
1438
|
+
this.e.style.whiteSpace = "pre-wrap";
|
|
1439
|
+
// Avoid formatting (B / I / U) popping up on iOS
|
|
1440
|
+
this.e.style.webkitUserModify = "read-write-plaintext-only";
|
|
1441
|
+
if (this.textarea && this.textarea.parentNode == element && this.textarea.nextSibling) {
|
|
1442
|
+
element.insertBefore(this.e, this.textarea.nextSibling);
|
|
1443
|
+
} else {
|
|
1444
|
+
element.appendChild(this.e);
|
|
1445
|
+
}
|
|
1446
|
+
this.e.addEventListener("input", e => this.handleInputEvent(e));
|
|
1447
|
+
this.e.addEventListener("compositionend", e => this.handleInputEvent(e));
|
|
1448
|
+
document.addEventListener("selectionchange", e => this.handleSelectionChangeEvent(e));
|
|
1449
|
+
this.e.addEventListener("paste", e => this.handlePaste(e));
|
|
1450
|
+
this.lineElements = this.e.childNodes; // this will automatically update
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
/**
|
|
1454
|
+
* Sets the editor content.
|
|
1455
|
+
* @param {string} content The new Markdown content
|
|
1456
|
+
*/
|
|
1457
|
+
setContent(content) {
|
|
1458
|
+
// Delete any existing content
|
|
1459
|
+
while (this.e.firstChild) {
|
|
1460
|
+
this.e.removeChild(this.e.firstChild);
|
|
1461
|
+
}
|
|
1462
|
+
this.lines = content.split(/(?:\r\n|\r|\n)/);
|
|
1463
|
+
this.lineDirty = [];
|
|
1464
|
+
for (let lineNum = 0; lineNum < this.lines.length; lineNum++) {
|
|
1465
|
+
let le = document.createElement("div");
|
|
1466
|
+
this.e.appendChild(le);
|
|
1467
|
+
this.lineDirty.push(true);
|
|
1468
|
+
}
|
|
1469
|
+
this.lineTypes = new Array(this.lines.length);
|
|
1470
|
+
this.updateFormatting();
|
|
1471
|
+
this.fireChange();
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
/**
|
|
1475
|
+
* Gets the editor content as a Markdown string.
|
|
1476
|
+
* @returns {string} The editor content as a markdown string
|
|
1477
|
+
*/
|
|
1478
|
+
getContent() {
|
|
1479
|
+
return this.lines.join("\n");
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
/**
|
|
1483
|
+
* This is the main method to update the formatting (from this.lines to HTML output)
|
|
1484
|
+
*/
|
|
1485
|
+
updateFormatting() {
|
|
1486
|
+
// First, parse line types. This will update this.lineTypes, this.lineReplacements, and this.lineCaptures
|
|
1487
|
+
// We don't apply the formatting yet
|
|
1488
|
+
this.updateLineTypes();
|
|
1489
|
+
// Collect any valid link labels from link reference definitions—we need that for formatting to determine what's a valid link
|
|
1490
|
+
this.updateLinkLabels();
|
|
1491
|
+
// Now, apply the formatting
|
|
1492
|
+
this.applyLineTypes();
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
/**
|
|
1496
|
+
* Updates this.linkLabels: For every link reference definition (line type TMLinkReferenceDefinition), we collect the label
|
|
1497
|
+
*/
|
|
1498
|
+
updateLinkLabels() {
|
|
1499
|
+
this.linkLabels = [];
|
|
1500
|
+
for (let l = 0; l < this.lines.length; l++) {
|
|
1501
|
+
if (this.lineTypes[l] == "TMLinkReferenceDefinition") {
|
|
1502
|
+
this.linkLabels.push(this.lineCaptures[l][lineGrammar.TMLinkReferenceDefinition.labelPlaceholder]);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
/**
|
|
1508
|
+
* Helper function to replace placeholders from a RegExp capture. The replacement string can contain regular dollar placeholders (e.g., $1),
|
|
1509
|
+
* which are interpreted like in String.replace(), but also double dollar placeholders ($$1). In the case of double dollar placeholders,
|
|
1510
|
+
* Markdown inline grammar is applied on the content of the captured subgroup, i.e., $$1 processes inline Markdown grammar in the content of the
|
|
1511
|
+
* first captured subgroup, and replaces `$$1` with the result.
|
|
1512
|
+
*
|
|
1513
|
+
* @param {string} replacement The replacement string, including placeholders.
|
|
1514
|
+
* @param capture The result of a RegExp.exec() call
|
|
1515
|
+
* @returns The replacement string, with placeholders replaced from the capture result.
|
|
1516
|
+
*/
|
|
1517
|
+
replace(replacement, capture) {
|
|
1518
|
+
return replacement.replace(/(\${1,2})([0-9])/g, (str, p1, p2) => {
|
|
1519
|
+
if (p1 == "$") return htmlescape(capture[p2]);else return `<span class="TMInlineFormatted">${this.processInlineStyles(capture[p2])}</span>`;
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Applies the line types (from this.lineTypes as well as the capture result in this.lineReplacements and this.lineCaptures)
|
|
1525
|
+
* and processes inline formatting for all lines.
|
|
1526
|
+
*/
|
|
1527
|
+
applyLineTypes() {
|
|
1528
|
+
for (let lineNum = 0; lineNum < this.lines.length; lineNum++) {
|
|
1529
|
+
if (this.lineDirty[lineNum]) {
|
|
1530
|
+
let contentHTML = this.replace(this.lineReplacements[lineNum], this.lineCaptures[lineNum]);
|
|
1531
|
+
// this.lineHTML[lineNum] = (contentHTML == '' ? '<br />' : contentHTML); // Prevent empty elements which can't be selected etc.
|
|
1532
|
+
this.lineElements[lineNum].className = this.lineTypes[lineNum];
|
|
1533
|
+
this.lineElements[lineNum].removeAttribute("style");
|
|
1534
|
+
this.lineElements[lineNum].innerHTML = contentHTML == "" ? "<br />" : contentHTML; // Prevent empty elements which can't be selected etc.
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
this.lineElements[lineNum].dataset.lineNum = lineNum;
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
/**
|
|
1542
|
+
* Determines line types for all lines based on the line / block grammar. Captures the results of the respective line
|
|
1543
|
+
* grammar regular expressions.
|
|
1544
|
+
* Updates this.lineTypes, this.lineCaptures, and this.lineReplacements.
|
|
1545
|
+
*/
|
|
1546
|
+
updateLineTypes() {
|
|
1547
|
+
let codeBlockType = false;
|
|
1548
|
+
let codeBlockSeqLength = 0;
|
|
1549
|
+
let htmlBlock = false;
|
|
1550
|
+
for (let lineNum = 0; lineNum < this.lines.length; lineNum++) {
|
|
1551
|
+
let lineType = "TMPara";
|
|
1552
|
+
let lineCapture = [this.lines[lineNum]];
|
|
1553
|
+
let lineReplacement = "$$0"; // Default replacement for paragraph: Inline format the entire line
|
|
1554
|
+
|
|
1555
|
+
// Check ongoing code blocks
|
|
1556
|
+
// if (lineNum > 0 && (this.lineTypes[lineNum - 1] == 'TMCodeFenceBacktickOpen' || this.lineTypes[lineNum - 1] == 'TMFencedCodeBacktick')) {
|
|
1557
|
+
if (codeBlockType == "TMCodeFenceBacktickOpen") {
|
|
1558
|
+
// We're in a backtick-fenced code block, check if the current line closes it
|
|
1559
|
+
let capture = lineGrammar.TMCodeFenceBacktickClose.regexp.exec(this.lines[lineNum]);
|
|
1560
|
+
if (capture && capture.groups["seq"].length >= codeBlockSeqLength) {
|
|
1561
|
+
lineType = "TMCodeFenceBacktickClose";
|
|
1562
|
+
lineReplacement = lineGrammar.TMCodeFenceBacktickClose.replacement;
|
|
1563
|
+
lineCapture = capture;
|
|
1564
|
+
codeBlockType = false;
|
|
1565
|
+
} else {
|
|
1566
|
+
lineType = "TMFencedCodeBacktick";
|
|
1567
|
+
lineReplacement = '<span class="TMFencedCode">$0<br /></span>';
|
|
1568
|
+
lineCapture = [this.lines[lineNum]];
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
// if (lineNum > 0 && (this.lineTypes[lineNum - 1] == 'TMCodeFenceTildeOpen' || this.lineTypes[lineNum - 1] == 'TMFencedCodeTilde')) {
|
|
1572
|
+
else if (codeBlockType == "TMCodeFenceTildeOpen") {
|
|
1573
|
+
// We're in a tilde-fenced code block
|
|
1574
|
+
let capture = lineGrammar.TMCodeFenceTildeClose.regexp.exec(this.lines[lineNum]);
|
|
1575
|
+
if (capture && capture.groups["seq"].length >= codeBlockSeqLength) {
|
|
1576
|
+
lineType = "TMCodeFenceTildeClose";
|
|
1577
|
+
lineReplacement = lineGrammar.TMCodeFenceTildeClose.replacement;
|
|
1578
|
+
lineCapture = capture;
|
|
1579
|
+
codeBlockType = false;
|
|
1580
|
+
} else {
|
|
1581
|
+
lineType = "TMFencedCodeTilde";
|
|
1582
|
+
lineReplacement = '<span class="TMFencedCode">$0<br /></span>';
|
|
1583
|
+
lineCapture = [this.lines[lineNum]];
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
// Check HTML block types
|
|
1588
|
+
if (lineType == "TMPara" && htmlBlock === false) {
|
|
1589
|
+
for (let htmlBlockType of htmlBlockGrammar) {
|
|
1590
|
+
if (this.lines[lineNum].match(htmlBlockType.start)) {
|
|
1591
|
+
// Matching start condition. Check if this tag can start here (not all start conditions allow breaking a paragraph).
|
|
1592
|
+
if (htmlBlockType.paraInterrupt || lineNum == 0 || !(this.lineTypes[lineNum - 1] == "TMPara" || this.lineTypes[lineNum - 1] == "TMUL" || this.lineTypes[lineNum - 1] == "TMOL" || this.lineTypes[lineNum - 1] == "TMBlockquote")) {
|
|
1593
|
+
htmlBlock = htmlBlockType;
|
|
1594
|
+
break;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
if (htmlBlock !== false) {
|
|
1600
|
+
lineType = "TMHTMLBlock";
|
|
1601
|
+
lineReplacement = '<span class="TMHTMLContent">$0<br /></span>'; // No formatting in TMHTMLBlock
|
|
1602
|
+
lineCapture = [this.lines[lineNum]]; // This should already be set but better safe than sorry
|
|
1603
|
+
|
|
1604
|
+
// Check if HTML block should be closed
|
|
1605
|
+
if (htmlBlock.end) {
|
|
1606
|
+
// Specific end condition
|
|
1607
|
+
if (this.lines[lineNum].match(htmlBlock.end)) {
|
|
1608
|
+
htmlBlock = false;
|
|
1609
|
+
}
|
|
1610
|
+
} else {
|
|
1611
|
+
// No specific end condition, ends with blank line
|
|
1612
|
+
if (lineNum == this.lines.length - 1 || this.lines[lineNum + 1].match(lineGrammar.TMBlankLine.regexp)) {
|
|
1613
|
+
htmlBlock = false;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
// Check all regexps if we haven't applied one of the code block types
|
|
1619
|
+
if (lineType == "TMPara") {
|
|
1620
|
+
for (let type in lineGrammar) {
|
|
1621
|
+
if (lineGrammar[type].regexp) {
|
|
1622
|
+
let capture = lineGrammar[type].regexp.exec(this.lines[lineNum]);
|
|
1623
|
+
if (capture) {
|
|
1624
|
+
lineType = type;
|
|
1625
|
+
lineReplacement = lineGrammar[type].replacement;
|
|
1626
|
+
lineCapture = capture;
|
|
1627
|
+
break;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
// If we've opened a code block, remember that
|
|
1634
|
+
if (lineType == "TMCodeFenceBacktickOpen" || lineType == "TMCodeFenceTildeOpen") {
|
|
1635
|
+
codeBlockType = lineType;
|
|
1636
|
+
codeBlockSeqLength = lineCapture.groups["seq"].length;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
// Link reference definition and indented code can't interrupt a paragraph
|
|
1640
|
+
if ((lineType == "TMIndentedCode" || lineType == "TMLinkReferenceDefinition") && lineNum > 0 && (this.lineTypes[lineNum - 1] == "TMPara" || this.lineTypes[lineNum - 1] == "TMUL" || this.lineTypes[lineNum - 1] == "TMOL" || this.lineTypes[lineNum - 1] == "TMBlockquote")) {
|
|
1641
|
+
// Fall back to TMPara
|
|
1642
|
+
lineType = "TMPara";
|
|
1643
|
+
lineCapture = [this.lines[lineNum]];
|
|
1644
|
+
lineReplacement = "$$0";
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
// Setext H2 markers that can also be interpreted as an empty list item should be regarded as such (as per CommonMark spec)
|
|
1648
|
+
if (lineType == "TMSetextH2Marker") {
|
|
1649
|
+
let capture = lineGrammar.TMUL.regexp.exec(this.lines[lineNum]);
|
|
1650
|
+
if (capture) {
|
|
1651
|
+
lineType = "TMUL";
|
|
1652
|
+
lineReplacement = lineGrammar.TMUL.replacement;
|
|
1653
|
+
lineCapture = capture;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
// Setext headings are only valid if preceded by a paragraph (and if so, they change the type of the previous paragraph)
|
|
1658
|
+
if (lineType == "TMSetextH1Marker" || lineType == "TMSetextH2Marker") {
|
|
1659
|
+
if (lineNum == 0 || this.lineTypes[lineNum - 1] != "TMPara") {
|
|
1660
|
+
// Setext marker is invalid. However, a H2 marker might still be a valid HR, so let's check that
|
|
1661
|
+
let capture = lineGrammar.TMHR.regexp.exec(this.lines[lineNum]);
|
|
1662
|
+
if (capture) {
|
|
1663
|
+
// Valid HR
|
|
1664
|
+
lineType = "TMHR";
|
|
1665
|
+
lineCapture = capture;
|
|
1666
|
+
lineReplacement = lineGrammar.TMHR.replacement;
|
|
1667
|
+
} else {
|
|
1668
|
+
// Not valid HR, format as TMPara
|
|
1669
|
+
lineType = "TMPara";
|
|
1670
|
+
lineCapture = [this.lines[lineNum]];
|
|
1671
|
+
lineReplacement = "$$0";
|
|
1672
|
+
}
|
|
1673
|
+
} else {
|
|
1674
|
+
// Valid setext marker. Change types of preceding para lines
|
|
1675
|
+
let headingLine = lineNum - 1;
|
|
1676
|
+
const headingLineType = lineType == "TMSetextH1Marker" ? "TMSetextH1" : "TMSetextH2";
|
|
1677
|
+
do {
|
|
1678
|
+
if (this.lineTypes[headingLineType] != headingLineType) {
|
|
1679
|
+
this.lineTypes[headingLine] = headingLineType;
|
|
1680
|
+
this.lineDirty[headingLineType] = true;
|
|
1681
|
+
}
|
|
1682
|
+
this.lineReplacements[headingLine] = "$$0";
|
|
1683
|
+
this.lineCaptures[headingLine] = [this.lines[headingLine]];
|
|
1684
|
+
headingLine--;
|
|
1685
|
+
} while (headingLine >= 0 && this.lineTypes[headingLine] == "TMPara");
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
// Lastly, save the line style to be applied later
|
|
1689
|
+
if (this.lineTypes[lineNum] != lineType) {
|
|
1690
|
+
this.lineTypes[lineNum] = lineType;
|
|
1691
|
+
this.lineDirty[lineNum] = true;
|
|
1692
|
+
}
|
|
1693
|
+
this.lineReplacements[lineNum] = lineReplacement;
|
|
1694
|
+
this.lineCaptures[lineNum] = lineCapture;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
/**
|
|
1699
|
+
* Updates all line contents from the HTML, then re-applies formatting.
|
|
1700
|
+
*/
|
|
1701
|
+
updateLineContentsAndFormatting() {
|
|
1702
|
+
this.clearDirtyFlag();
|
|
1703
|
+
this.updateLineContents();
|
|
1704
|
+
this.updateFormatting();
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/**
|
|
1708
|
+
* Attempts to parse a link or image at the current position. This assumes that the opening [ or ![ has already been matched.
|
|
1709
|
+
* Returns false if this is not a valid link, image. See below for more information
|
|
1710
|
+
* @param {string} originalString The original string, starting at the opening marker ([ or ![)
|
|
1711
|
+
* @param {boolean} isImage Whether or not this is an image (opener == ![)
|
|
1712
|
+
* @returns false if not a valid link / image.
|
|
1713
|
+
* Otherwise returns an object with two properties: output is the string to be included in the processed output,
|
|
1714
|
+
* charCount is the number of input characters (from originalString) consumed.
|
|
1715
|
+
*/
|
|
1716
|
+
parseLinkOrImage(originalString, isImage) {
|
|
1717
|
+
// Skip the opening bracket
|
|
1718
|
+
let textOffset = isImage ? 2 : 1;
|
|
1719
|
+
let opener = originalString.substr(0, textOffset);
|
|
1720
|
+
let type = isImage ? "TMImage" : "TMLink";
|
|
1721
|
+
let currentOffset = textOffset;
|
|
1722
|
+
let bracketLevel = 1;
|
|
1723
|
+
let linkText = false;
|
|
1724
|
+
let linkRef = false;
|
|
1725
|
+
let linkLabel = [];
|
|
1726
|
+
let linkDetails = []; // If matched, this will be an array: [whitespace + link destination delimiter, link destination, link destination delimiter, whitespace, link title delimiter, link title, link title delimiter + whitespace]. All can be empty strings.
|
|
1727
|
+
|
|
1728
|
+
textOuter: while (currentOffset < originalString.length && linkText === false /* empty string is okay */) {
|
|
1729
|
+
let string = originalString.substr(currentOffset);
|
|
1730
|
+
|
|
1731
|
+
// Capture any escapes and code blocks at current position, they bind more strongly than links
|
|
1732
|
+
// We don't have to actually process them here, that'll be done later in case the link / image is valid, but we need to skip over them.
|
|
1733
|
+
for (let rule of ["escape", "code", "autolink", "html"]) {
|
|
1734
|
+
let cap = inlineGrammar[rule].regexp.exec(string);
|
|
1735
|
+
if (cap) {
|
|
1736
|
+
currentOffset += cap[0].length;
|
|
1737
|
+
continue textOuter;
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
// Check for image. It's okay for an image to be included in a link or image
|
|
1742
|
+
if (string.match(inlineGrammar.imageOpen.regexp)) {
|
|
1743
|
+
// Opening image. It's okay if this is a matching pair of brackets
|
|
1744
|
+
bracketLevel++;
|
|
1745
|
+
currentOffset += 2;
|
|
1746
|
+
continue textOuter;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
// Check for link (not an image because that would have been captured and skipped over above)
|
|
1750
|
+
if (string.match(inlineGrammar.linkOpen.regexp)) {
|
|
1751
|
+
// Opening bracket. Two things to do:
|
|
1752
|
+
// 1) it's okay if this part of a pair of brackets.
|
|
1753
|
+
// 2) If we are currently trying to parse a link, this nested bracket musn't start a valid link (no nested links allowed)
|
|
1754
|
+
bracketLevel++;
|
|
1755
|
+
// if (bracketLevel >= 2) return false; // Nested unescaped brackets, this doesn't qualify as a link / image
|
|
1756
|
+
if (!isImage) {
|
|
1757
|
+
if (this.parseLinkOrImage(string, false)) {
|
|
1758
|
+
// Valid link inside this possible link, which makes this link invalid (inner links beat outer ones)
|
|
1759
|
+
return false;
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
currentOffset += 1;
|
|
1763
|
+
continue textOuter;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// Check for closing bracket
|
|
1767
|
+
if (string.match(/^\]/)) {
|
|
1768
|
+
bracketLevel--;
|
|
1769
|
+
if (bracketLevel == 0) {
|
|
1770
|
+
// Found matching bracket and haven't found anything disqualifying this as link / image.
|
|
1771
|
+
linkText = originalString.substr(textOffset, currentOffset - textOffset);
|
|
1772
|
+
currentOffset++;
|
|
1773
|
+
continue textOuter;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
// Nothing matches, proceed to next char
|
|
1778
|
+
currentOffset++;
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
// Did we find a link text (i.e., find a matching closing bracket?)
|
|
1782
|
+
if (linkText === false) return false; // Nope
|
|
1783
|
+
|
|
1784
|
+
// So far, so good. We've got a valid link text. Let's see what type of link this is
|
|
1785
|
+
let nextChar = currentOffset < originalString.length ? originalString.substr(currentOffset, 1) : "";
|
|
1786
|
+
|
|
1787
|
+
// REFERENCE LINKS
|
|
1788
|
+
if (nextChar == "[") {
|
|
1789
|
+
let string = originalString.substr(currentOffset);
|
|
1790
|
+
let cap = inlineGrammar.linkLabel.regexp.exec(string);
|
|
1791
|
+
if (cap) {
|
|
1792
|
+
// Valid link label
|
|
1793
|
+
currentOffset += cap[0].length;
|
|
1794
|
+
linkLabel.push(cap[1], cap[2], cap[3]);
|
|
1795
|
+
if (cap[inlineGrammar.linkLabel.labelPlaceholder]) {
|
|
1796
|
+
// Full reference link
|
|
1797
|
+
linkRef = cap[inlineGrammar.linkLabel.labelPlaceholder];
|
|
1798
|
+
} else {
|
|
1799
|
+
// Collapsed reference link
|
|
1800
|
+
linkRef = linkText.trim();
|
|
1801
|
+
}
|
|
1802
|
+
} else {
|
|
1803
|
+
// Not a valid link label
|
|
1804
|
+
return false;
|
|
1805
|
+
}
|
|
1806
|
+
} else if (nextChar != "(") {
|
|
1807
|
+
// Shortcut ref link
|
|
1808
|
+
linkRef = linkText.trim();
|
|
1809
|
+
|
|
1810
|
+
// INLINE LINKS
|
|
1811
|
+
} else {
|
|
1812
|
+
// nextChar == '('
|
|
1813
|
+
|
|
1814
|
+
// Potential inline link
|
|
1815
|
+
currentOffset++;
|
|
1816
|
+
let parenthesisLevel = 1;
|
|
1817
|
+
inlineOuter: while (currentOffset < originalString.length && parenthesisLevel > 0) {
|
|
1818
|
+
let string = originalString.substr(currentOffset);
|
|
1819
|
+
|
|
1820
|
+
// Process whitespace
|
|
1821
|
+
let cap = /^\s+/.exec(string);
|
|
1822
|
+
if (cap) {
|
|
1823
|
+
switch (linkDetails.length) {
|
|
1824
|
+
case 0:
|
|
1825
|
+
linkDetails.push(cap[0]);
|
|
1826
|
+
break;
|
|
1827
|
+
// Opening whitespace
|
|
1828
|
+
case 1:
|
|
1829
|
+
linkDetails.push(cap[0]);
|
|
1830
|
+
break;
|
|
1831
|
+
// Open destination, but not a destination yet; desination opened with <
|
|
1832
|
+
case 2:
|
|
1833
|
+
// Open destination with content in it. Whitespace only allowed if opened by angle bracket, otherwise this closes the destination
|
|
1834
|
+
if (linkDetails[0].match(/</)) {
|
|
1835
|
+
linkDetails[1] = linkDetails[1].concat(cap[0]);
|
|
1836
|
+
} else {
|
|
1837
|
+
if (parenthesisLevel != 1) return false; // Unbalanced parenthesis
|
|
1838
|
+
linkDetails.push(""); // Empty end delimiter for destination
|
|
1839
|
+
linkDetails.push(cap[0]); // Whitespace in between destination and title
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
break;
|
|
1843
|
+
case 3:
|
|
1844
|
+
linkDetails.push(cap[0]);
|
|
1845
|
+
break;
|
|
1846
|
+
// Whitespace between destination and title
|
|
1847
|
+
case 4:
|
|
1848
|
+
return false;
|
|
1849
|
+
// This should never happen (no opener for title yet, but more whitespace to capture)
|
|
1850
|
+
case 5:
|
|
1851
|
+
linkDetails.push("");
|
|
1852
|
+
// Whitespace at beginning of title, push empty title and continue
|
|
1853
|
+
case 6:
|
|
1854
|
+
linkDetails[5] = linkDetails[5].concat(cap[0]);
|
|
1855
|
+
break;
|
|
1856
|
+
// Whitespace in title
|
|
1857
|
+
case 7:
|
|
1858
|
+
linkDetails[6] = linkDetails[6].concat(cap[0]);
|
|
1859
|
+
break;
|
|
1860
|
+
// Whitespace after closing delimiter
|
|
1861
|
+
default:
|
|
1862
|
+
return false;
|
|
1863
|
+
// We should never get here
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
currentOffset += cap[0].length;
|
|
1867
|
+
continue inlineOuter;
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
// Process backslash escapes
|
|
1871
|
+
cap = inlineGrammar.escape.regexp.exec(string);
|
|
1872
|
+
if (cap) {
|
|
1873
|
+
switch (linkDetails.length) {
|
|
1874
|
+
case 0:
|
|
1875
|
+
linkDetails.push("");
|
|
1876
|
+
// this opens the link destination, add empty opening delimiter and proceed to next case
|
|
1877
|
+
case 1:
|
|
1878
|
+
linkDetails.push(cap[0]);
|
|
1879
|
+
break;
|
|
1880
|
+
// This opens the link destination, append it
|
|
1881
|
+
case 2:
|
|
1882
|
+
linkDetails[1] = linkDetails[1].concat(cap[0]);
|
|
1883
|
+
break;
|
|
1884
|
+
// Part of the link destination
|
|
1885
|
+
case 3:
|
|
1886
|
+
return false;
|
|
1887
|
+
// Lacking opening delimiter for link title
|
|
1888
|
+
case 4:
|
|
1889
|
+
return false;
|
|
1890
|
+
// Lcaking opening delimiter for link title
|
|
1891
|
+
case 5:
|
|
1892
|
+
linkDetails.push("");
|
|
1893
|
+
// This opens the link title
|
|
1894
|
+
case 6:
|
|
1895
|
+
linkDetails[5] = linkDetails[5].concat(cap[0]);
|
|
1896
|
+
break;
|
|
1897
|
+
// Part of the link title
|
|
1898
|
+
default:
|
|
1899
|
+
return false;
|
|
1900
|
+
// After link title was closed, without closing parenthesis
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
currentOffset += cap[0].length;
|
|
1904
|
+
continue inlineOuter;
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
// Process opening angle bracket as deilimiter of destination
|
|
1908
|
+
if (linkDetails.length < 2 && string.match(/^</)) {
|
|
1909
|
+
if (linkDetails.length == 0) linkDetails.push("");
|
|
1910
|
+
linkDetails[0] = linkDetails[0].concat("<");
|
|
1911
|
+
currentOffset++;
|
|
1912
|
+
continue inlineOuter;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
// Process closing angle bracket as delimiter of destination
|
|
1916
|
+
if ((linkDetails.length == 1 || linkDetails.length == 2) && string.match(/^>/)) {
|
|
1917
|
+
if (linkDetails.length == 1) linkDetails.push(""); // Empty link destination
|
|
1918
|
+
linkDetails.push(">");
|
|
1919
|
+
currentOffset++;
|
|
1920
|
+
continue inlineOuter;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
// Process non-parenthesis delimiter for title.
|
|
1924
|
+
cap = /^["']/.exec(string);
|
|
1925
|
+
// For this to be a valid opener, we have to either have no destination, only whitespace so far,
|
|
1926
|
+
// or a destination with trailing whitespace.
|
|
1927
|
+
if (cap && (linkDetails.length == 0 || linkDetails.length == 1 || linkDetails.length == 4)) {
|
|
1928
|
+
while (linkDetails.length < 4) linkDetails.push("");
|
|
1929
|
+
linkDetails.push(cap[0]);
|
|
1930
|
+
currentOffset++;
|
|
1931
|
+
continue inlineOuter;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
// For this to be a valid closer, we have to have an opener and some or no title, and this has to match the opener
|
|
1935
|
+
if (cap && (linkDetails.length == 5 || linkDetails.length == 6) && linkDetails[4] == cap[0]) {
|
|
1936
|
+
if (linkDetails.length == 5) linkDetails.push(""); // Empty link title
|
|
1937
|
+
linkDetails.push(cap[0]);
|
|
1938
|
+
currentOffset++;
|
|
1939
|
+
continue inlineOuter;
|
|
1940
|
+
}
|
|
1941
|
+
// Other cases (linkDetails.length == 2, 3, 7) will be handled with the "default" case below.
|
|
1942
|
+
|
|
1943
|
+
// Process opening parenthesis
|
|
1944
|
+
if (string.match(/^\(/)) {
|
|
1945
|
+
switch (linkDetails.length) {
|
|
1946
|
+
case 0:
|
|
1947
|
+
linkDetails.push("");
|
|
1948
|
+
// this opens the link destination, add empty opening delimiter and proceed to next case
|
|
1949
|
+
case 1:
|
|
1950
|
+
linkDetails.push("");
|
|
1951
|
+
// This opens the link destination
|
|
1952
|
+
case 2:
|
|
1953
|
+
// Part of the link destination
|
|
1954
|
+
linkDetails[1] = linkDetails[1].concat("(");
|
|
1955
|
+
if (!linkDetails[0].match(/<$/)) parenthesisLevel++;
|
|
1956
|
+
break;
|
|
1957
|
+
case 3:
|
|
1958
|
+
linkDetails.push("");
|
|
1959
|
+
// opening delimiter for link title
|
|
1960
|
+
case 4:
|
|
1961
|
+
linkDetails.push("(");
|
|
1962
|
+
break;
|
|
1963
|
+
// opening delimiter for link title
|
|
1964
|
+
case 5:
|
|
1965
|
+
linkDetails.push("");
|
|
1966
|
+
// opens the link title, add empty title content and proceed to next case
|
|
1967
|
+
case 6:
|
|
1968
|
+
// Part of the link title. Un-escaped parenthesis only allowed in " or ' delimited title
|
|
1969
|
+
if (linkDetails[4] == "(") return false;
|
|
1970
|
+
linkDetails[5] = linkDetails[5].concat("(");
|
|
1971
|
+
break;
|
|
1972
|
+
default:
|
|
1973
|
+
return false;
|
|
1974
|
+
// After link title was closed, without closing parenthesis
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
currentOffset++;
|
|
1978
|
+
continue inlineOuter;
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
// Process closing parenthesis
|
|
1982
|
+
if (string.match(/^\)/)) {
|
|
1983
|
+
if (linkDetails.length <= 2) {
|
|
1984
|
+
// We are inside the link destination. Parentheses have to be matched if not in angle brackets
|
|
1985
|
+
while (linkDetails.length < 2) linkDetails.push("");
|
|
1986
|
+
if (!linkDetails[0].match(/<$/)) parenthesisLevel--;
|
|
1987
|
+
if (parenthesisLevel > 0) {
|
|
1988
|
+
linkDetails[1] = linkDetails[1].concat(")");
|
|
1989
|
+
}
|
|
1990
|
+
} else if (linkDetails.length == 5 || linkDetails.length == 6) {
|
|
1991
|
+
// We are inside the link title.
|
|
1992
|
+
if (linkDetails[4] == "(") {
|
|
1993
|
+
// This closes the link title
|
|
1994
|
+
if (linkDetails.length == 5) linkDetails.push("");
|
|
1995
|
+
linkDetails.push(")");
|
|
1996
|
+
} else {
|
|
1997
|
+
// Just regular ol' content
|
|
1998
|
+
if (linkDetails.length == 5) linkDetails.push(")");else linkDetails[5] = linkDetails[5].concat(")");
|
|
1999
|
+
}
|
|
2000
|
+
} else {
|
|
2001
|
+
parenthesisLevel--; // This should decrease it from 1 to 0...
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
if (parenthesisLevel == 0) {
|
|
2005
|
+
// No invalid condition, let's make sure the linkDetails array is complete
|
|
2006
|
+
while (linkDetails.length < 7) linkDetails.push("");
|
|
2007
|
+
}
|
|
2008
|
+
currentOffset++;
|
|
2009
|
+
continue inlineOuter;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
// Any old character
|
|
2013
|
+
cap = /^./.exec(string);
|
|
2014
|
+
if (cap) {
|
|
2015
|
+
switch (linkDetails.length) {
|
|
2016
|
+
case 0:
|
|
2017
|
+
linkDetails.push("");
|
|
2018
|
+
// this opens the link destination, add empty opening delimiter and proceed to next case
|
|
2019
|
+
case 1:
|
|
2020
|
+
linkDetails.push(cap[0]);
|
|
2021
|
+
break;
|
|
2022
|
+
// This opens the link destination, append it
|
|
2023
|
+
case 2:
|
|
2024
|
+
linkDetails[1] = linkDetails[1].concat(cap[0]);
|
|
2025
|
+
break;
|
|
2026
|
+
// Part of the link destination
|
|
2027
|
+
case 3:
|
|
2028
|
+
return false;
|
|
2029
|
+
// Lacking opening delimiter for link title
|
|
2030
|
+
case 4:
|
|
2031
|
+
return false;
|
|
2032
|
+
// Lcaking opening delimiter for link title
|
|
2033
|
+
case 5:
|
|
2034
|
+
linkDetails.push("");
|
|
2035
|
+
// This opens the link title
|
|
2036
|
+
case 6:
|
|
2037
|
+
linkDetails[5] = linkDetails[5].concat(cap[0]);
|
|
2038
|
+
break;
|
|
2039
|
+
// Part of the link title
|
|
2040
|
+
default:
|
|
2041
|
+
return false;
|
|
2042
|
+
// After link title was closed, without closing parenthesis
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
currentOffset += cap[0].length;
|
|
2046
|
+
continue inlineOuter;
|
|
2047
|
+
}
|
|
2048
|
+
throw "Infinite loop"; // we should never get here since the last test matches any character
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
if (parenthesisLevel > 0) return false; // Parenthes(es) not closed
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
if (linkRef !== false) {
|
|
2055
|
+
// Ref link; check that linkRef is valid
|
|
2056
|
+
let valid = false;
|
|
2057
|
+
for (let label of this.linkLabels) {
|
|
2058
|
+
if (label == linkRef) {
|
|
2059
|
+
valid = true;
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
let label = valid ? "TMLinkLabel TMLinkLabel_Valid" : "TMLinkLabel TMLinkLabel_Invalid";
|
|
2064
|
+
let output = `<span class="TMMark TMMark_${type}">${opener}</span><span class="${type} ${linkLabel.length < 3 || !linkLabel[1] ? label : ""}">${this.processInlineStyles(linkText)}</span><span class="TMMark TMMark_${type}">]</span>`;
|
|
2065
|
+
if (linkLabel.length >= 3) {
|
|
2066
|
+
output = output.concat(`<span class="TMMark TMMark_${type}">${linkLabel[0]}</span>`, `<span class="${label}">${linkLabel[1]}</span>`, `<span class="TMMark TMMark_${type}">${linkLabel[2]}</span>`);
|
|
2067
|
+
}
|
|
2068
|
+
return {
|
|
2069
|
+
output: output,
|
|
2070
|
+
charCount: currentOffset
|
|
2071
|
+
};
|
|
2072
|
+
} else if (linkDetails) {
|
|
2073
|
+
// Inline link
|
|
2074
|
+
|
|
2075
|
+
// This should never happen, but better safe than sorry.
|
|
2076
|
+
while (linkDetails.length < 7) {
|
|
2077
|
+
linkDetails.push("");
|
|
2078
|
+
}
|
|
2079
|
+
return {
|
|
2080
|
+
output: `<span class="TMMark TMMark_${type}">${opener}</span><span class="${type}">${this.processInlineStyles(linkText)}</span><span class="TMMark TMMark_${type}">](${linkDetails[0]}</span><span class="${type}Destination">${linkDetails[1]}</span><span class="TMMark TMMark_${type}">${linkDetails[2]}${linkDetails[3]}${linkDetails[4]}</span><span class="${type}Title">${linkDetails[5]}</span><span class="TMMark TMMark_${type}">${linkDetails[6]})</span>`,
|
|
2081
|
+
charCount: currentOffset
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
return false;
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
/**
|
|
2088
|
+
* Formats a markdown string as HTML, using Markdown inline formatting.
|
|
2089
|
+
* @param {string} originalString The input (markdown inline formatted) string
|
|
2090
|
+
* @returns {string} The HTML formatted output
|
|
2091
|
+
*/
|
|
2092
|
+
processInlineStyles(originalString) {
|
|
2093
|
+
let processed = "";
|
|
2094
|
+
let stack = []; // Stack is an array of objects of the format: {delimiter, delimString, count, output}
|
|
2095
|
+
let offset = 0;
|
|
2096
|
+
let string = originalString;
|
|
2097
|
+
outer: while (string) {
|
|
2098
|
+
// Process simple rules (non-delimiter)
|
|
2099
|
+
for (let rule of ["escape", "code", "autolink", "html"]) {
|
|
2100
|
+
let cap = inlineGrammar[rule].regexp.exec(string);
|
|
2101
|
+
if (cap) {
|
|
2102
|
+
string = string.substr(cap[0].length);
|
|
2103
|
+
offset += cap[0].length;
|
|
2104
|
+
processed += inlineGrammar[rule].replacement
|
|
2105
|
+
// .replace(/\$\$([1-9])/g, (str, p1) => processInlineStyles(cap[p1])) // todo recursive calling
|
|
2106
|
+
.replace(/\$([1-9])/g, (str, p1) => htmlescape(cap[p1]));
|
|
2107
|
+
continue outer;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
// Check for links / images
|
|
2112
|
+
let potentialLink = string.match(inlineGrammar.linkOpen.regexp);
|
|
2113
|
+
let potentialImage = string.match(inlineGrammar.imageOpen.regexp);
|
|
2114
|
+
if (potentialImage || potentialLink) {
|
|
2115
|
+
let result = this.parseLinkOrImage(string, potentialImage);
|
|
2116
|
+
if (result) {
|
|
2117
|
+
processed = `${processed}${result.output}`;
|
|
2118
|
+
string = string.substr(result.charCount);
|
|
2119
|
+
offset += result.charCount;
|
|
2120
|
+
continue outer;
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
// Check for em / strong delimiters
|
|
2125
|
+
let cap = /(^\*+)|(^_+)/.exec(string);
|
|
2126
|
+
if (cap) {
|
|
2127
|
+
let delimCount = cap[0].length;
|
|
2128
|
+
const delimString = cap[0];
|
|
2129
|
+
const currentDelimiter = cap[0][0]; // This should be * or _
|
|
2130
|
+
|
|
2131
|
+
string = string.substr(cap[0].length);
|
|
2132
|
+
|
|
2133
|
+
// We have a delimiter run. Let's check if it can open or close an emphasis.
|
|
2134
|
+
|
|
2135
|
+
const preceding = offset > 0 ? originalString.substr(0, offset) : " "; // beginning and end of line count as whitespace
|
|
2136
|
+
const following = offset + cap[0].length < originalString.length ? string : " ";
|
|
2137
|
+
const punctuationFollows = following.match(punctuationLeading);
|
|
2138
|
+
const punctuationPrecedes = preceding.match(punctuationTrailing);
|
|
2139
|
+
const whitespaceFollows = following.match(/^\s/);
|
|
2140
|
+
const whitespacePrecedes = preceding.match(/\s$/);
|
|
2141
|
+
|
|
2142
|
+
// These are the rules for right-flanking and left-flanking delimiter runs as per CommonMark spec
|
|
2143
|
+
let canOpen = !whitespaceFollows && (!punctuationFollows || !!whitespacePrecedes || !!punctuationPrecedes);
|
|
2144
|
+
let canClose = !whitespacePrecedes && (!punctuationPrecedes || !!whitespaceFollows || !!punctuationFollows);
|
|
2145
|
+
|
|
2146
|
+
// Underscores have more detailed rules than just being part of left- or right-flanking run:
|
|
2147
|
+
if (currentDelimiter == "_" && canOpen && canClose) {
|
|
2148
|
+
canOpen = punctuationPrecedes;
|
|
2149
|
+
canClose = punctuationFollows;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
// If the delimiter can close, check the stack if there's something it can close
|
|
2153
|
+
if (canClose) {
|
|
2154
|
+
let stackPointer = stack.length - 1;
|
|
2155
|
+
// See if we can find a matching opening delimiter, move down through the stack
|
|
2156
|
+
while (delimCount && stackPointer >= 0) {
|
|
2157
|
+
if (stack[stackPointer].delimiter == currentDelimiter) {
|
|
2158
|
+
// We found a matching delimiter, let's construct the formatted string
|
|
2159
|
+
|
|
2160
|
+
// Firstly, if we skipped any stack levels, pop them immediately (non-matching delimiters)
|
|
2161
|
+
while (stackPointer < stack.length - 1) {
|
|
2162
|
+
const entry = stack.pop();
|
|
2163
|
+
processed = `${entry.output}${entry.delimString.substr(0, entry.count)}${processed}`;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
// Then, format the string
|
|
2167
|
+
if (delimCount >= 2 && stack[stackPointer].count >= 2) {
|
|
2168
|
+
// Strong
|
|
2169
|
+
processed = `<span class="TMMark">${currentDelimiter}${currentDelimiter}</span><strong class="TMStrong">${processed}</strong><span class="TMMark">${currentDelimiter}${currentDelimiter}</span>`;
|
|
2170
|
+
delimCount -= 2;
|
|
2171
|
+
stack[stackPointer].count -= 2;
|
|
2172
|
+
} else {
|
|
2173
|
+
// Em
|
|
2174
|
+
processed = `<span class="TMMark">${currentDelimiter}</span><em class="TMEm">${processed}</em><span class="TMMark">${currentDelimiter}</span>`;
|
|
2175
|
+
delimCount -= 1;
|
|
2176
|
+
stack[stackPointer].count -= 1;
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
// If that stack level is empty now, pop it
|
|
2180
|
+
if (stack[stackPointer].count == 0) {
|
|
2181
|
+
let entry = stack.pop();
|
|
2182
|
+
processed = `${entry.output}${processed}`;
|
|
2183
|
+
stackPointer--;
|
|
2184
|
+
}
|
|
2185
|
+
} else {
|
|
2186
|
+
// This stack level's delimiter type doesn't match the current delimiter type
|
|
2187
|
+
// Go down one level in the stack
|
|
2188
|
+
stackPointer--;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
// If there are still delimiters left, and the delimiter run can open, push it on the stack
|
|
2193
|
+
if (delimCount && canOpen) {
|
|
2194
|
+
stack.push({
|
|
2195
|
+
delimiter: currentDelimiter,
|
|
2196
|
+
delimString: delimString,
|
|
2197
|
+
count: delimCount,
|
|
2198
|
+
output: processed
|
|
2199
|
+
});
|
|
2200
|
+
processed = ""; // Current formatted output has been pushed on the stack and will be prepended when the stack gets popped
|
|
2201
|
+
delimCount = 0;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
// Any delimiters that are left (closing unmatched) are appended to the output.
|
|
2205
|
+
if (delimCount) {
|
|
2206
|
+
processed = `${processed}${delimString.substr(0, delimCount)}`;
|
|
2207
|
+
}
|
|
2208
|
+
offset += cap[0].length;
|
|
2209
|
+
continue outer;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
// Check for strikethrough delimiter
|
|
2213
|
+
cap = /^~~/.exec(string);
|
|
2214
|
+
if (cap) {
|
|
2215
|
+
let consumed = false;
|
|
2216
|
+
let stackPointer = stack.length - 1;
|
|
2217
|
+
// See if we can find a matching opening delimiter, move down through the stack
|
|
2218
|
+
while (!consumed && stackPointer >= 0) {
|
|
2219
|
+
if (stack[stackPointer].delimiter == "~") {
|
|
2220
|
+
// We found a matching delimiter, let's construct the formatted string
|
|
2221
|
+
|
|
2222
|
+
// Firstly, if we skipped any stack levels, pop them immediately (non-matching delimiters)
|
|
2223
|
+
while (stackPointer < stack.length - 1) {
|
|
2224
|
+
const entry = stack.pop();
|
|
2225
|
+
processed = `${entry.output}${entry.delimString.substr(0, entry.count)}${processed}`;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
// Then, format the string
|
|
2229
|
+
processed = `<span class="TMMark">~~</span><del class="TMStrikethrough">${processed}</del><span class="TMMark">~~</span>`;
|
|
2230
|
+
let entry = stack.pop();
|
|
2231
|
+
processed = `${entry.output}${processed}`;
|
|
2232
|
+
consumed = true;
|
|
2233
|
+
} else {
|
|
2234
|
+
// This stack level's delimiter type doesn't match the current delimiter type
|
|
2235
|
+
// Go down one level in the stack
|
|
2236
|
+
stackPointer--;
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
// If there are still delimiters left, and the delimiter run can open, push it on the stack
|
|
2241
|
+
if (!consumed) {
|
|
2242
|
+
stack.push({
|
|
2243
|
+
delimiter: "~",
|
|
2244
|
+
delimString: "~~",
|
|
2245
|
+
count: 2,
|
|
2246
|
+
output: processed
|
|
2247
|
+
});
|
|
2248
|
+
processed = ""; // Current formatted output has been pushed on the stack and will be prepended when the stack gets popped
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
offset += cap[0].length;
|
|
2252
|
+
string = string.substr(cap[0].length);
|
|
2253
|
+
continue outer;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// Process 'default' rule
|
|
2257
|
+
cap = inlineGrammar.default.regexp.exec(string);
|
|
2258
|
+
if (cap) {
|
|
2259
|
+
string = string.substr(cap[0].length);
|
|
2260
|
+
offset += cap[0].length;
|
|
2261
|
+
processed += inlineGrammar.default.replacement.replace(/\$([1-9])/g, (str, p1) => htmlescape(cap[p1]));
|
|
2262
|
+
continue outer;
|
|
2263
|
+
}
|
|
2264
|
+
throw "Infinite loop!";
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
// Empty the stack, any opening delimiters are unused
|
|
2268
|
+
while (stack.length) {
|
|
2269
|
+
const entry = stack.pop();
|
|
2270
|
+
processed = `${entry.output}${entry.delimString.substr(0, entry.count)}${processed}`;
|
|
2271
|
+
}
|
|
2272
|
+
return processed;
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
/**
|
|
2276
|
+
* Clears the line dirty flag (resets it to an array of false)
|
|
2277
|
+
*/
|
|
2278
|
+
clearDirtyFlag() {
|
|
2279
|
+
this.lineDirty = new Array(this.lines.length);
|
|
2280
|
+
for (let i = 0; i < this.lineDirty.length; i++) {
|
|
2281
|
+
this.lineDirty[i] = false;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
/**
|
|
2286
|
+
* Updates the class properties (lines, lineElements) from the DOM.
|
|
2287
|
+
* @returns true if contents changed
|
|
2288
|
+
*/
|
|
2289
|
+
updateLineContents() {
|
|
2290
|
+
// this.lineDirty = [];
|
|
2291
|
+
// Check if we have changed anything about the number of lines (inserted or deleted a paragraph)
|
|
2292
|
+
// < 0 means line(s) removed; > 0 means line(s) added
|
|
2293
|
+
let lineDelta = this.e.childElementCount - this.lines.length;
|
|
2294
|
+
if (lineDelta) {
|
|
2295
|
+
// yup. Let's try how much we can salvage (find out which lines from beginning and end were unchanged)
|
|
2296
|
+
// Find lines from the beginning that haven't changed...
|
|
2297
|
+
let firstChangedLine = 0;
|
|
2298
|
+
while (firstChangedLine <= this.lines.length && firstChangedLine <= this.lineElements.length && this.lineElements[firstChangedLine] &&
|
|
2299
|
+
// Check that the line element hasn't been deleted
|
|
2300
|
+
this.lines[firstChangedLine] == this.lineElements[firstChangedLine].textContent) {
|
|
2301
|
+
firstChangedLine++;
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
// End also from the end
|
|
2305
|
+
let lastChangedLine = -1;
|
|
2306
|
+
while (-lastChangedLine < this.lines.length && -lastChangedLine < this.lineElements.length && this.lines[this.lines.length + lastChangedLine] == this.lineElements[this.lineElements.length + lastChangedLine].textContent) {
|
|
2307
|
+
lastChangedLine--;
|
|
2308
|
+
}
|
|
2309
|
+
let linesToDelete = this.lines.length + lastChangedLine + 1 - firstChangedLine;
|
|
2310
|
+
if (linesToDelete < -lineDelta) linesToDelete = -lineDelta;
|
|
2311
|
+
if (linesToDelete < 0) linesToDelete = 0;
|
|
2312
|
+
let linesToAdd = [];
|
|
2313
|
+
for (let l = 0; l < linesToDelete + lineDelta; l++) {
|
|
2314
|
+
linesToAdd.push(this.lineElements[firstChangedLine + l].textContent);
|
|
2315
|
+
}
|
|
2316
|
+
this.spliceLines(firstChangedLine, linesToDelete, linesToAdd, false);
|
|
2317
|
+
} else {
|
|
2318
|
+
// No lines added or removed
|
|
2319
|
+
for (let line = 0; line < this.lineElements.length; line++) {
|
|
2320
|
+
let e = this.lineElements[line];
|
|
2321
|
+
let ct = e.textContent;
|
|
2322
|
+
if (this.lines[line] !== ct) {
|
|
2323
|
+
// Line changed, update it
|
|
2324
|
+
this.lines[line] = ct;
|
|
2325
|
+
this.lineDirty[line] = true;
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
/**
|
|
2332
|
+
* Processes a new paragraph.
|
|
2333
|
+
* @param sel The current selection
|
|
2334
|
+
*/
|
|
2335
|
+
processNewParagraph(sel) {
|
|
2336
|
+
if (!sel) return;
|
|
2337
|
+
|
|
2338
|
+
// Update lines from content
|
|
2339
|
+
this.updateLineContents();
|
|
2340
|
+
let continuableType = false;
|
|
2341
|
+
// Let's see if we need to continue a list
|
|
2342
|
+
|
|
2343
|
+
let checkLine = sel.col > 0 ? sel.row : sel.row - 1;
|
|
2344
|
+
switch (this.lineTypes[checkLine]) {
|
|
2345
|
+
case "TMUL":
|
|
2346
|
+
continuableType = "TMUL";
|
|
2347
|
+
break;
|
|
2348
|
+
case "TMOL":
|
|
2349
|
+
continuableType = "TMOL";
|
|
2350
|
+
break;
|
|
2351
|
+
case "TMIndentedCode":
|
|
2352
|
+
continuableType = "TMIndentedCode";
|
|
2353
|
+
break;
|
|
2354
|
+
}
|
|
2355
|
+
let lines = this.lines[sel.row].replace(/\n\n$/, "\n").split(/(?:\r\n|\n|\r)/);
|
|
2356
|
+
if (lines.length == 1) {
|
|
2357
|
+
// No new line
|
|
2358
|
+
this.updateFormatting();
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2361
|
+
this.spliceLines(sel.row, 1, lines, true);
|
|
2362
|
+
sel.row++;
|
|
2363
|
+
sel.col = 0;
|
|
2364
|
+
if (continuableType) {
|
|
2365
|
+
// Check if the previous line was non-empty
|
|
2366
|
+
let capture = lineGrammar[continuableType].regexp.exec(this.lines[sel.row - 1]);
|
|
2367
|
+
if (capture) {
|
|
2368
|
+
// Convention: capture[1] is the line type marker, capture[2] is the content
|
|
2369
|
+
if (capture[2]) {
|
|
2370
|
+
// Previous line has content, continue the continuable type
|
|
2371
|
+
|
|
2372
|
+
// Hack for OL: increment number
|
|
2373
|
+
if (continuableType == "TMOL") {
|
|
2374
|
+
capture[1] = capture[1].replace(/\d{1,9}/, result => {
|
|
2375
|
+
return parseInt(result[0]) + 1;
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
this.lines[sel.row] = `${capture[1]}${this.lines[sel.row]}`;
|
|
2379
|
+
this.lineDirty[sel.row] = true;
|
|
2380
|
+
sel.col = capture[1].length;
|
|
2381
|
+
} else {
|
|
2382
|
+
// Previous line has no content, remove the continuable type from the previous row
|
|
2383
|
+
this.lines[sel.row - 1] = "";
|
|
2384
|
+
this.lineDirty[sel.row - 1] = true;
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
this.updateFormatting();
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
// /**
|
|
2392
|
+
// * Processes a "delete" input action.
|
|
2393
|
+
// * @param {object} focus The selection
|
|
2394
|
+
// * @param {boolean} forward If true, performs a forward delete, otherwise performs a backward delete
|
|
2395
|
+
// */
|
|
2396
|
+
// processDelete(focus, forward) {
|
|
2397
|
+
// if (!focus) return;
|
|
2398
|
+
// let anchor = this.getSelection(true);
|
|
2399
|
+
// // Do we have a non-empty selection?
|
|
2400
|
+
// if (focus.col != anchor.col || focus.row != anchor.row) {
|
|
2401
|
+
// // non-empty. direction doesn't matter.
|
|
2402
|
+
// this.paste('', anchor, focus);
|
|
2403
|
+
// } else {
|
|
2404
|
+
// if (forward) {
|
|
2405
|
+
// if (focus.col < this.lines[focus.row].length) this.paste('', {row: focus.row, col: focus.col + 1}, focus);
|
|
2406
|
+
// else if (focus.col < this.lines.length) this.paste('', {row: focus.row + 1, col: 0}, focus);
|
|
2407
|
+
// // Otherwise, we're at the very end and can't delete forward
|
|
2408
|
+
// } else {
|
|
2409
|
+
// if (focus.col > 0) this.paste('', {row: focus.row, col: focus.col - 1}, focus);
|
|
2410
|
+
// else if (focus.row > 0) this.paste('', {row: focus.row - 1, col: this.lines[focus.row - 1].length - 1}, focus);
|
|
2411
|
+
// // Otherwise, we're at the very beginning and can't delete backwards
|
|
2412
|
+
// }
|
|
2413
|
+
// }
|
|
2414
|
+
|
|
2415
|
+
// }
|
|
2416
|
+
|
|
2417
|
+
/**
|
|
2418
|
+
* Gets the current position of the selection counted by row and column of the editor Markdown content (as opposed to the position in the DOM).
|
|
2419
|
+
*
|
|
2420
|
+
* @param {boolean} getAnchor if set to true, gets the selection anchor (start point of the selection), otherwise gets the focus (end point).
|
|
2421
|
+
* @return {object} An object representing the selection, with properties col and row.
|
|
2422
|
+
*/
|
|
2423
|
+
getSelection() {
|
|
2424
|
+
let getAnchor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
2425
|
+
const selection = window.getSelection();
|
|
2426
|
+
let startNode = getAnchor ? selection.anchorNode : selection.focusNode;
|
|
2427
|
+
if (!startNode) return null;
|
|
2428
|
+
let offset = getAnchor ? selection.anchorOffset : selection.focusOffset;
|
|
2429
|
+
if (startNode == this.e) {
|
|
2430
|
+
if (offset < this.lines.length) return {
|
|
2431
|
+
row: offset,
|
|
2432
|
+
col: 0
|
|
2433
|
+
};
|
|
2434
|
+
return {
|
|
2435
|
+
row: offset - 1,
|
|
2436
|
+
col: this.lines[offset - 1].length
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2439
|
+
let col = this.computeColumn(startNode, offset);
|
|
2440
|
+
if (col === null) return null; // We are outside of the editor
|
|
2441
|
+
|
|
2442
|
+
// Find the row node
|
|
2443
|
+
let node = startNode;
|
|
2444
|
+
while (node.parentElement != this.e) {
|
|
2445
|
+
node = node.parentElement;
|
|
2446
|
+
}
|
|
2447
|
+
let row = 0;
|
|
2448
|
+
// Check if we can read a line number from the data-line-num attribute.
|
|
2449
|
+
// The last condition is a security measure since inserting a new paragraph copies the previous rows' line number
|
|
2450
|
+
if (node.dataset && node.dataset.lineNum && (!node.previousSibling || node.previousSibling.dataset.lineNum != node.dataset.lineNum)) {
|
|
2451
|
+
row = parseInt(node.dataset.lineNum);
|
|
2452
|
+
} else {
|
|
2453
|
+
while (node.previousSibling) {
|
|
2454
|
+
row++;
|
|
2455
|
+
node = node.previousSibling;
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
return {
|
|
2459
|
+
row: row,
|
|
2460
|
+
col: col,
|
|
2461
|
+
node: startNode
|
|
2462
|
+
};
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
/**
|
|
2466
|
+
* Computes a column within an editor line from a node and offset within that node.
|
|
2467
|
+
* @param {Node} startNode The node
|
|
2468
|
+
* @param {int} offset THe selection
|
|
2469
|
+
* @returns {int} the column, or null if the node is not inside the editor
|
|
2470
|
+
*/
|
|
2471
|
+
computeColumn(startNode, offset) {
|
|
2472
|
+
let node = startNode;
|
|
2473
|
+
let col;
|
|
2474
|
+
// First, make sure we're actually in the editor.
|
|
2475
|
+
while (node && node.parentNode != this.e) {
|
|
2476
|
+
node = node.parentNode;
|
|
2477
|
+
}
|
|
2478
|
+
if (node == null) return null;
|
|
2479
|
+
|
|
2480
|
+
// There are two ways that offset can be defined:
|
|
2481
|
+
// - Either, the node is a text node, in which case it is the offset within the text
|
|
2482
|
+
// - Or, the node is an element with child notes, in which case the offset refers to the
|
|
2483
|
+
// child node after which the selection is located
|
|
2484
|
+
if (startNode.nodeType === Node.TEXT_NODE || offset === 0) {
|
|
2485
|
+
// In the case that the node is non-text node but the offset is 0,
|
|
2486
|
+
// The selection is at the beginning of that element so we
|
|
2487
|
+
// can simply use the same approach as if it were at the beginning
|
|
2488
|
+
// of a text node.
|
|
2489
|
+
col = offset;
|
|
2490
|
+
node = startNode;
|
|
2491
|
+
} else if (offset > 0) {
|
|
2492
|
+
node = startNode.childNodes[offset - 1];
|
|
2493
|
+
col = node.textContent.length;
|
|
2494
|
+
}
|
|
2495
|
+
while (node.parentNode != this.e) {
|
|
2496
|
+
if (node.previousSibling) {
|
|
2497
|
+
node = node.previousSibling;
|
|
2498
|
+
col += node.textContent.length;
|
|
2499
|
+
} else {
|
|
2500
|
+
node = node.parentNode;
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
return col;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
/**
|
|
2507
|
+
* Computes DOM node and offset within that node from a position expressed as row and column.
|
|
2508
|
+
* @param {int} row Row (line number)
|
|
2509
|
+
* @param {int} col Column
|
|
2510
|
+
* @returns An object with two properties: node and offset. offset may be null;
|
|
2511
|
+
*/
|
|
2512
|
+
computeNodeAndOffset(row, col) {
|
|
2513
|
+
let bindRight = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
2514
|
+
if (row >= this.lineElements.length) {
|
|
2515
|
+
// Selection past the end of text, set selection to end of text
|
|
2516
|
+
row = this.lineElements.length - 1;
|
|
2517
|
+
col = this.lines[row].length;
|
|
2518
|
+
}
|
|
2519
|
+
if (col > this.lines[row].length) {
|
|
2520
|
+
col = this.lines[row].length;
|
|
2521
|
+
}
|
|
2522
|
+
const parentNode = this.lineElements[row];
|
|
2523
|
+
let node = parentNode.firstChild;
|
|
2524
|
+
let childrenComplete = false;
|
|
2525
|
+
// default return value
|
|
2526
|
+
let rv = {
|
|
2527
|
+
node: parentNode.firstChild ? parentNode.firstChild : parentNode,
|
|
2528
|
+
offset: 0
|
|
2529
|
+
};
|
|
2530
|
+
while (node != parentNode) {
|
|
2531
|
+
if (!childrenComplete && node.nodeType === Node.TEXT_NODE) {
|
|
2532
|
+
if (node.nodeValue.length >= col) {
|
|
2533
|
+
if (bindRight && node.nodeValue.length == col) {
|
|
2534
|
+
// Selection is at the end of this text node, but we are binding right (prefer an offset of 0 in the next text node)
|
|
2535
|
+
// Remember return value in case we don't find another text node
|
|
2536
|
+
rv = {
|
|
2537
|
+
node: node,
|
|
2538
|
+
offset: col
|
|
2539
|
+
};
|
|
2540
|
+
col = 0;
|
|
2541
|
+
} else {
|
|
2542
|
+
return {
|
|
2543
|
+
node: node,
|
|
2544
|
+
offset: col
|
|
2545
|
+
};
|
|
2546
|
+
}
|
|
2547
|
+
} else {
|
|
2548
|
+
col -= node.nodeValue.length;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
if (!childrenComplete && node.firstChild) {
|
|
2552
|
+
node = node.firstChild;
|
|
2553
|
+
} else if (node.nextSibling) {
|
|
2554
|
+
childrenComplete = false;
|
|
2555
|
+
node = node.nextSibling;
|
|
2556
|
+
} else {
|
|
2557
|
+
childrenComplete = true;
|
|
2558
|
+
node = node.parentNode;
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
// Either, the position was invalid and we just return the default return value
|
|
2563
|
+
// Or we are binding right and the selection is at the end of the line
|
|
2564
|
+
return rv;
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
/**
|
|
2568
|
+
* Sets the selection based on rows and columns within the editor Markdown content.
|
|
2569
|
+
* @param {object} focus Object representing the selection, needs to have properties row and col.
|
|
2570
|
+
* @param anchor Anchor of the selection. If not given, assumes the current anchor.
|
|
2571
|
+
*/
|
|
2572
|
+
setSelection(focus) {
|
|
2573
|
+
let anchor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
2574
|
+
if (!focus) return;
|
|
2575
|
+
let range = document.createRange();
|
|
2576
|
+
let {
|
|
2577
|
+
node: focusNode,
|
|
2578
|
+
offset: focusOffset
|
|
2579
|
+
} = this.computeNodeAndOffset(focus.row, focus.col, anchor && anchor.row == focus.row && anchor.col > focus.col); // Bind selection right if anchor is in the same row and behind the focus
|
|
2580
|
+
let anchorNode = null,
|
|
2581
|
+
anchorOffset = null;
|
|
2582
|
+
if (anchor && (anchor.row != focus.row || anchor.col != focus.col)) {
|
|
2583
|
+
let {
|
|
2584
|
+
node,
|
|
2585
|
+
offset
|
|
2586
|
+
} = this.computeNodeAndOffset(anchor.row, anchor.col, focus.row == anchor.row && focus.col > anchor.col);
|
|
2587
|
+
anchorNode = node;
|
|
2588
|
+
anchorOffset = offset;
|
|
2589
|
+
}
|
|
2590
|
+
if (anchorNode) range.setStart(anchorNode, anchorOffset);else range.setStart(focusNode, focusOffset);
|
|
2591
|
+
range.setEnd(focusNode, focusOffset);
|
|
2592
|
+
let windowSelection = window.getSelection();
|
|
2593
|
+
windowSelection.removeAllRanges();
|
|
2594
|
+
windowSelection.addRange(range);
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
/**
|
|
2598
|
+
* Event handler for input events
|
|
2599
|
+
*/
|
|
2600
|
+
handleInputEvent(event) {
|
|
2601
|
+
// For composition input, we are only updating the text after we have received
|
|
2602
|
+
// a compositionend event, so we return upon insertCompositionText.
|
|
2603
|
+
// Otherwise, the DOM changes break the text input.
|
|
2604
|
+
if (event.inputType == "insertCompositionText") return;
|
|
2605
|
+
let focus = this.getSelection();
|
|
2606
|
+
if ((event.inputType == "insertParagraph" || event.inputType == "insertLineBreak") && focus) {
|
|
2607
|
+
this.clearDirtyFlag();
|
|
2608
|
+
this.processNewParagraph(focus);
|
|
2609
|
+
} else {
|
|
2610
|
+
if (!this.e.firstChild) {
|
|
2611
|
+
this.e.innerHTML = '<div class="TMBlankLine"><br></div>';
|
|
2612
|
+
} else {
|
|
2613
|
+
this.fixNodeHierarchy();
|
|
2614
|
+
}
|
|
2615
|
+
this.updateLineContentsAndFormatting();
|
|
2616
|
+
}
|
|
2617
|
+
if (focus) {
|
|
2618
|
+
this.setSelection(focus);
|
|
2619
|
+
}
|
|
2620
|
+
this.fireChange();
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
/**
|
|
2624
|
+
* Fixes the node hierarchy – makes sure that each line is in a div, and there are no nested divs
|
|
2625
|
+
*/
|
|
2626
|
+
fixNodeHierarchy() {
|
|
2627
|
+
const originalChildren = Array.from(this.e.childNodes);
|
|
2628
|
+
const replaceChild = function (child) {
|
|
2629
|
+
const parent = child.parentElement;
|
|
2630
|
+
const nextSibling = child.nextSibling;
|
|
2631
|
+
parent.removeChild(child);
|
|
2632
|
+
for (var _len = arguments.length, newChildren = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
2633
|
+
newChildren[_key - 1] = arguments[_key];
|
|
2634
|
+
}
|
|
2635
|
+
newChildren.forEach(newChild => nextSibling ? parent.insertBefore(newChild, nextSibling) : parent.appendChild(newChild));
|
|
2636
|
+
};
|
|
2637
|
+
originalChildren.forEach(child => {
|
|
2638
|
+
if (child.nodeType !== Node.ELEMENT_NODE || child.tagName !== "DIV") {
|
|
2639
|
+
// Found a child node that's either not an element or not a div. Wrap it in a div.
|
|
2640
|
+
const divWrapper = document.createElement("div");
|
|
2641
|
+
replaceChild(child, divWrapper);
|
|
2642
|
+
divWrapper.appendChild(child);
|
|
2643
|
+
} else if (child.childNodes.length == 0) {
|
|
2644
|
+
// Empty div child node, include at least a <br />
|
|
2645
|
+
child.appendChild(document.createElement("br"));
|
|
2646
|
+
} else {
|
|
2647
|
+
const grandChildren = Array.from(child.childNodes);
|
|
2648
|
+
if (grandChildren.some(grandChild => grandChild.nodeType === Node.ELEMENT_NODE && grandChild.tagName === "DIV")) {
|
|
2649
|
+
return replaceChild(child, grandChildren);
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
|
|
2655
|
+
/**
|
|
2656
|
+
* Event handler for "selectionchange" events.
|
|
2657
|
+
*/
|
|
2658
|
+
handleSelectionChangeEvent() {
|
|
2659
|
+
this.fireSelection();
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
/**
|
|
2663
|
+
* Convenience function to "splice" new lines into the arrays this.lines, this.lineDirty, this.lineTypes, and the DOM elements
|
|
2664
|
+
* underneath the editor element.
|
|
2665
|
+
* This method is essentially Array.splice, only that the third parameter takes an un-spread array (and the forth parameter)
|
|
2666
|
+
* determines whether the DOM should also be adjusted.
|
|
2667
|
+
*
|
|
2668
|
+
* @param {int} startLine Position at which to start changing the array of lines
|
|
2669
|
+
* @param {int} linesToDelete Number of lines to delete
|
|
2670
|
+
* @param {array} linesToInsert Array of strings representing the lines to be inserted
|
|
2671
|
+
* @param {boolean} adjustLineElements If true, then <div> elements are also inserted in the DOM at the respective position
|
|
2672
|
+
*/
|
|
2673
|
+
spliceLines(startLine) {
|
|
2674
|
+
let linesToDelete = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
2675
|
+
let linesToInsert = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
2676
|
+
let adjustLineElements = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
|
2677
|
+
if (adjustLineElements) {
|
|
2678
|
+
for (let i = 0; i < linesToDelete; i++) {
|
|
2679
|
+
this.e.removeChild(this.e.childNodes[startLine]);
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
let insertedBlank = [];
|
|
2683
|
+
let insertedDirty = [];
|
|
2684
|
+
for (let i = 0; i < linesToInsert.length; i++) {
|
|
2685
|
+
insertedBlank.push("");
|
|
2686
|
+
insertedDirty.push(true);
|
|
2687
|
+
if (adjustLineElements) {
|
|
2688
|
+
if (this.e.childNodes[startLine]) this.e.insertBefore(document.createElement("div"), this.e.childNodes[startLine]);else this.e.appendChild(document.createElement("div"));
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
this.lines.splice(startLine, linesToDelete, ...linesToInsert);
|
|
2692
|
+
this.lineTypes.splice(startLine, linesToDelete, ...insertedBlank);
|
|
2693
|
+
this.lineDirty.splice(startLine, linesToDelete, ...insertedDirty);
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2696
|
+
/**
|
|
2697
|
+
* Event handler for the "paste" event
|
|
2698
|
+
*/
|
|
2699
|
+
handlePaste(event) {
|
|
2700
|
+
event.preventDefault();
|
|
2701
|
+
|
|
2702
|
+
// get text representation of clipboard
|
|
2703
|
+
let text = (event.originalEvent || event).clipboardData.getData("text/plain");
|
|
2704
|
+
|
|
2705
|
+
// insert text manually
|
|
2706
|
+
this.paste(text);
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
/**
|
|
2710
|
+
* Pastes the text at the current selection (or at the end, if no current selection)
|
|
2711
|
+
* @param {string} text
|
|
2712
|
+
*/
|
|
2713
|
+
paste(text) {
|
|
2714
|
+
let anchor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
2715
|
+
let focus = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
2716
|
+
if (!anchor) anchor = this.getSelection(true);
|
|
2717
|
+
if (!focus) focus = this.getSelection(false);
|
|
2718
|
+
let beginning, end;
|
|
2719
|
+
if (!focus) {
|
|
2720
|
+
focus = {
|
|
2721
|
+
row: this.lines.length - 1,
|
|
2722
|
+
col: this.lines[this.lines.length - 1].length
|
|
2723
|
+
}; // Insert at end
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
if (!anchor) {
|
|
2727
|
+
anchor = focus;
|
|
2728
|
+
}
|
|
2729
|
+
if (anchor.row < focus.row || anchor.row == focus.row && anchor.col <= focus.col) {
|
|
2730
|
+
beginning = anchor;
|
|
2731
|
+
end = focus;
|
|
2732
|
+
} else {
|
|
2733
|
+
beginning = focus;
|
|
2734
|
+
end = anchor;
|
|
2735
|
+
}
|
|
2736
|
+
let insertedLines = text.split(/(?:\r\n|\r|\n)/);
|
|
2737
|
+
let lineBefore = this.lines[beginning.row].substr(0, beginning.col);
|
|
2738
|
+
let lineEnd = this.lines[end.row].substr(end.col);
|
|
2739
|
+
insertedLines[0] = lineBefore.concat(insertedLines[0]);
|
|
2740
|
+
let endColPos = insertedLines[insertedLines.length - 1].length;
|
|
2741
|
+
insertedLines[insertedLines.length - 1] = insertedLines[insertedLines.length - 1].concat(lineEnd);
|
|
2742
|
+
this.spliceLines(beginning.row, 1 + end.row - beginning.row, insertedLines);
|
|
2743
|
+
focus.row = beginning.row + insertedLines.length - 1;
|
|
2744
|
+
focus.col = endColPos;
|
|
2745
|
+
this.updateFormatting();
|
|
2746
|
+
this.setSelection(focus);
|
|
2747
|
+
this.fireChange();
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
/**
|
|
2751
|
+
* Computes the (lowest in the DOM tree) common ancestor of two DOM nodes.
|
|
2752
|
+
* @param {Node} node1 the first node
|
|
2753
|
+
* @param {Node} node2 the second node
|
|
2754
|
+
* @returns {Node} The commen ancestor node, or null if there is no common ancestor
|
|
2755
|
+
*/
|
|
2756
|
+
computeCommonAncestor(node1, node2) {
|
|
2757
|
+
if (!node1 || !node2) return null;
|
|
2758
|
+
if (node1 == node2) return node1;
|
|
2759
|
+
const ancestry = node => {
|
|
2760
|
+
let ancestry = [];
|
|
2761
|
+
while (node) {
|
|
2762
|
+
ancestry.unshift(node);
|
|
2763
|
+
node = node.parentNode;
|
|
2764
|
+
}
|
|
2765
|
+
return ancestry;
|
|
2766
|
+
};
|
|
2767
|
+
const ancestry1 = ancestry(node1);
|
|
2768
|
+
const ancestry2 = ancestry(node2);
|
|
2769
|
+
if (ancestry1[0] != ancestry2[0]) return null;
|
|
2770
|
+
let i;
|
|
2771
|
+
for (i = 0; ancestry1[i] == ancestry2[i]; i++);
|
|
2772
|
+
return ancestry1[i - 1];
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
/**
|
|
2776
|
+
* Finds the (lowest in the DOM tree) enclosing DOM node with a given class.
|
|
2777
|
+
* @param {object} focus The focus selection object
|
|
2778
|
+
* @param {object} anchor The anchor selection object
|
|
2779
|
+
* @param {string} className The class name to find
|
|
2780
|
+
* @returns {Node} The enclosing DOM node with the respective class (inside the editor), if there is one; null otherwise.
|
|
2781
|
+
*/
|
|
2782
|
+
computeEnclosingMarkupNode(focus, anchor, className) {
|
|
2783
|
+
let node = null;
|
|
2784
|
+
if (!focus) return null;
|
|
2785
|
+
if (!anchor) {
|
|
2786
|
+
node = focus.node;
|
|
2787
|
+
} else {
|
|
2788
|
+
if (focus.row != anchor.row) return null;
|
|
2789
|
+
node = this.computeCommonAncestor(focus.node, anchor.node);
|
|
2790
|
+
}
|
|
2791
|
+
if (!node) return null;
|
|
2792
|
+
while (node != this.e) {
|
|
2793
|
+
if (node.className && node.className.includes(className)) return node;
|
|
2794
|
+
node = node.parentNode;
|
|
2795
|
+
}
|
|
2796
|
+
// Ascended all the way to the editor element
|
|
2797
|
+
return null;
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
/**
|
|
2801
|
+
* Returns the state (true / false) of all commands.
|
|
2802
|
+
* @param focus Focus of the selection. If not given, assumes the current focus.
|
|
2803
|
+
* @param anchor Anchor of the selection. If not given, assumes the current anchor.
|
|
2804
|
+
*/
|
|
2805
|
+
getCommandState() {
|
|
2806
|
+
let focus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
2807
|
+
let anchor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
2808
|
+
let commandState = {};
|
|
2809
|
+
if (!focus) focus = this.getSelection(false);
|
|
2810
|
+
if (!anchor) anchor = this.getSelection(true);
|
|
2811
|
+
if (!focus) {
|
|
2812
|
+
for (let cmd in commands) {
|
|
2813
|
+
commandState[cmd] = null;
|
|
2814
|
+
}
|
|
2815
|
+
return commandState;
|
|
2816
|
+
}
|
|
2817
|
+
if (!anchor) anchor = focus;
|
|
2818
|
+
let start, end;
|
|
2819
|
+
if (anchor.row < focus.row || anchor.row == focus.row && anchor.col < focus.col) {
|
|
2820
|
+
start = anchor;
|
|
2821
|
+
end = focus;
|
|
2822
|
+
} else {
|
|
2823
|
+
start = focus;
|
|
2824
|
+
end = anchor;
|
|
2825
|
+
}
|
|
2826
|
+
if (end.row > start.row && end.col == 0) {
|
|
2827
|
+
end.row--;
|
|
2828
|
+
end.col = this.lines[end.row].length; // Selection to beginning of next line is said to end at the beginning of the last line
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
for (let cmd in commands) {
|
|
2832
|
+
if (commands[cmd].type == "inline") {
|
|
2833
|
+
if (!focus || focus.row != anchor.row || !this.isInlineFormattingAllowed(focus, anchor)) {
|
|
2834
|
+
commandState[cmd] = null;
|
|
2835
|
+
} else {
|
|
2836
|
+
// The command state is true if there is a respective enclosing markup node (e.g., the selection is enclosed in a <b>..</b>) ...
|
|
2837
|
+
commandState[cmd] = !!this.computeEnclosingMarkupNode(focus, anchor, commands[cmd].className) ||
|
|
2838
|
+
// ... or if it's an empty string preceded by and followed by formatting markers, e.g. **|** where | is the cursor
|
|
2839
|
+
focus.col == anchor.col && !!this.lines[focus.row].substr(0, focus.col).match(commands[cmd].unset.prePattern) && !!this.lines[focus.row].substr(focus.col).match(commands[cmd].unset.postPattern);
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2842
|
+
if (commands[cmd].type == "line") {
|
|
2843
|
+
if (!focus) {
|
|
2844
|
+
commandState[cmd] = null;
|
|
2845
|
+
} else {
|
|
2846
|
+
let state = this.lineTypes[start.row] == commands[cmd].className;
|
|
2847
|
+
for (let line = start.row; line <= end.row; line++) {
|
|
2848
|
+
if (this.lineTypes[line] == commands[cmd].className != state) {
|
|
2849
|
+
state = null;
|
|
2850
|
+
break;
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
commandState[cmd] = state;
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
return commandState;
|
|
2858
|
+
}
|
|
2859
|
+
|
|
2860
|
+
/**
|
|
2861
|
+
* Sets a command state
|
|
2862
|
+
* @param {string} command
|
|
2863
|
+
* @param {boolean} state
|
|
2864
|
+
*/
|
|
2865
|
+
setCommandState(command, state) {
|
|
2866
|
+
if (commands[command].type == "inline") {
|
|
2867
|
+
let anchor = this.getSelection(true);
|
|
2868
|
+
let focus = this.getSelection(false);
|
|
2869
|
+
if (!anchor) anchor = focus;
|
|
2870
|
+
if (!anchor) return;
|
|
2871
|
+
if (anchor.row != focus.row) return;
|
|
2872
|
+
if (!this.isInlineFormattingAllowed(focus, anchor)) return;
|
|
2873
|
+
let markupNode = this.computeEnclosingMarkupNode(focus, anchor, commands[command].className);
|
|
2874
|
+
this.clearDirtyFlag();
|
|
2875
|
+
|
|
2876
|
+
// First case: There's an enclosing markup node, remove the markers around that markup node
|
|
2877
|
+
if (markupNode) {
|
|
2878
|
+
this.lineDirty[focus.row] = true;
|
|
2879
|
+
const startCol = this.computeColumn(markupNode, 0);
|
|
2880
|
+
const len = markupNode.textContent.length;
|
|
2881
|
+
const left = this.lines[focus.row].substr(0, startCol).replace(commands[command].unset.prePattern, "");
|
|
2882
|
+
const mid = this.lines[focus.row].substr(startCol, len);
|
|
2883
|
+
const right = this.lines[focus.row].substr(startCol + len).replace(commands[command].unset.postPattern, "");
|
|
2884
|
+
this.lines[focus.row] = left.concat(mid, right);
|
|
2885
|
+
anchor.col = left.length;
|
|
2886
|
+
focus.col = anchor.col + len;
|
|
2887
|
+
this.updateFormatting();
|
|
2888
|
+
this.setSelection(focus, anchor);
|
|
2889
|
+
this.fireChange();
|
|
2890
|
+
|
|
2891
|
+
// Second case: Empty selection with surrounding formatting markers, remove those
|
|
2892
|
+
} else if (focus.col == anchor.col && !!this.lines[focus.row].substr(0, focus.col).match(commands[command].unset.prePattern) && !!this.lines[focus.row].substr(focus.col).match(commands[command].unset.postPattern)) {
|
|
2893
|
+
this.lineDirty[focus.row] = true;
|
|
2894
|
+
const left = this.lines[focus.row].substr(0, focus.col).replace(commands[command].unset.prePattern, "");
|
|
2895
|
+
const right = this.lines[focus.row].substr(focus.col).replace(commands[command].unset.postPattern, "");
|
|
2896
|
+
this.lines[focus.row] = left.concat(right);
|
|
2897
|
+
focus.col = anchor.col = left.length;
|
|
2898
|
+
this.updateFormatting();
|
|
2899
|
+
this.setSelection(focus, anchor);
|
|
2900
|
+
this.fireChange();
|
|
2901
|
+
|
|
2902
|
+
// Not currently formatted, insert formatting markers
|
|
2903
|
+
} else {
|
|
2904
|
+
// Trim any spaces from the selection
|
|
2905
|
+
let {
|
|
2906
|
+
startCol,
|
|
2907
|
+
endCol
|
|
2908
|
+
} = focus.col < anchor.col ? {
|
|
2909
|
+
startCol: focus.col,
|
|
2910
|
+
endCol: anchor.col
|
|
2911
|
+
} : {
|
|
2912
|
+
startCol: anchor.col,
|
|
2913
|
+
endCol: focus.col
|
|
2914
|
+
};
|
|
2915
|
+
let match = this.lines[focus.row].substr(startCol, endCol - startCol).match(/^(?<leading>\s*).*\S(?<trailing>\s*)$/);
|
|
2916
|
+
if (match) {
|
|
2917
|
+
startCol += match.groups.leading.length;
|
|
2918
|
+
endCol -= match.groups.trailing.length;
|
|
2919
|
+
}
|
|
2920
|
+
focus.col = startCol;
|
|
2921
|
+
anchor.col = endCol;
|
|
2922
|
+
|
|
2923
|
+
// Just insert markup before and after and hope for the best.
|
|
2924
|
+
this.wrapSelection(commands[command].set.pre, commands[command].set.post, focus, anchor);
|
|
2925
|
+
this.fireChange();
|
|
2926
|
+
// TODO clean this up so that markup remains properly nested
|
|
2927
|
+
}
|
|
2928
|
+
} else if (commands[command].type == "line") {
|
|
2929
|
+
let anchor = this.getSelection(true);
|
|
2930
|
+
let focus = this.getSelection(false);
|
|
2931
|
+
if (!anchor) anchor = focus;
|
|
2932
|
+
if (!focus) return;
|
|
2933
|
+
this.clearDirtyFlag();
|
|
2934
|
+
let start = anchor.row > focus.row ? focus : anchor;
|
|
2935
|
+
let end = anchor.row > focus.row ? anchor : focus;
|
|
2936
|
+
if (end.row > start.row && end.col == 0) {
|
|
2937
|
+
end.row--;
|
|
2938
|
+
}
|
|
2939
|
+
for (let line = start.row; line <= end.row; line++) {
|
|
2940
|
+
if (state && this.lineTypes[line] != commands[command].className) {
|
|
2941
|
+
this.lines[line] = this.lines[line].replace(commands[command].set.pattern, commands[command].set.replacement.replace("$#", line - start.row + 1));
|
|
2942
|
+
this.lineDirty[line] = true;
|
|
2943
|
+
}
|
|
2944
|
+
if (!state && this.lineTypes[line] == commands[command].className) {
|
|
2945
|
+
this.lines[line] = this.lines[line].replace(commands[command].unset.pattern, commands[command].unset.replacement);
|
|
2946
|
+
this.lineDirty[line] = true;
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
this.updateFormatting();
|
|
2950
|
+
this.setSelection({
|
|
2951
|
+
row: end.row,
|
|
2952
|
+
col: this.lines[end.row].length
|
|
2953
|
+
}, {
|
|
2954
|
+
row: start.row,
|
|
2955
|
+
col: 0
|
|
2956
|
+
});
|
|
2957
|
+
this.fireChange();
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
/**
|
|
2962
|
+
* Returns whether or not inline formatting is allowed at the current focus
|
|
2963
|
+
* @param {object} focus The current focus
|
|
2964
|
+
*/
|
|
2965
|
+
isInlineFormattingAllowed() {
|
|
2966
|
+
// TODO Remove parameters from all calls
|
|
2967
|
+
const sel = window.getSelection();
|
|
2968
|
+
if (!sel || !sel.focusNode || !sel.anchorNode) return false;
|
|
2969
|
+
|
|
2970
|
+
// Check if we can find a common ancestor with the class `TMInlineFormatted`
|
|
2971
|
+
|
|
2972
|
+
// Special case: Empty selection right before `TMInlineFormatted`
|
|
2973
|
+
if (sel.isCollapsed && sel.focusNode.nodeType == 3 && sel.focusOffset == sel.focusNode.nodeValue.length) {
|
|
2974
|
+
let node;
|
|
2975
|
+
for (node = sel.focusNode; node && node.nextSibling == null; node = node.parentNode);
|
|
2976
|
+
if (node && node.nextSibling.className && node.nextSibling.className.includes("TMInlineFormatted")) return true;
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
// Look for a common ancestor
|
|
2980
|
+
let ancestor = this.computeCommonAncestor(sel.focusNode, sel.anchorNode);
|
|
2981
|
+
if (!ancestor) return false;
|
|
2982
|
+
|
|
2983
|
+
// Check if there's an ancestor of class 'TMInlineFormatted' or 'TMBlankLine'
|
|
2984
|
+
while (ancestor && ancestor != this.e) {
|
|
2985
|
+
if (ancestor.className && (ancestor.className.includes("TMInlineFormatted") || ancestor.className.includes("TMBlankLine"))) return true;
|
|
2986
|
+
ancestor = ancestor.parentNode;
|
|
2987
|
+
}
|
|
2988
|
+
return false;
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
/**
|
|
2992
|
+
* Wraps the current selection in the strings pre and post. If the selection is not on one line, returns.
|
|
2993
|
+
* @param {string} pre The string to insert before the selection.
|
|
2994
|
+
* @param {string} post The string to insert after the selection.
|
|
2995
|
+
* @param {object} focus The current selection focus. If null, selection will be computed.
|
|
2996
|
+
* @param {object} anchor The current selection focus. If null, selection will be computed.
|
|
2997
|
+
*/
|
|
2998
|
+
wrapSelection(pre, post) {
|
|
2999
|
+
let focus = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
3000
|
+
let anchor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
3001
|
+
if (!focus) focus = this.getSelection(false);
|
|
3002
|
+
if (!anchor) anchor = this.getSelection(true);
|
|
3003
|
+
if (!focus || !anchor || focus.row != anchor.row) return;
|
|
3004
|
+
this.lineDirty[focus.row] = true;
|
|
3005
|
+
const startCol = focus.col < anchor.col ? focus.col : anchor.col;
|
|
3006
|
+
const endCol = focus.col < anchor.col ? anchor.col : focus.col;
|
|
3007
|
+
const left = this.lines[focus.row].substr(0, startCol).concat(pre);
|
|
3008
|
+
const mid = endCol == startCol ? "" : this.lines[focus.row].substr(startCol, endCol - startCol);
|
|
3009
|
+
const right = post.concat(this.lines[focus.row].substr(endCol));
|
|
3010
|
+
this.lines[focus.row] = left.concat(mid, right);
|
|
3011
|
+
anchor.col = left.length;
|
|
3012
|
+
focus.col = anchor.col + mid.length;
|
|
3013
|
+
this.updateFormatting();
|
|
3014
|
+
this.setSelection(focus, anchor);
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
/**
|
|
3018
|
+
* Toggles the command state for a command (true <-> false)
|
|
3019
|
+
* @param {string} command The editor command
|
|
3020
|
+
*/
|
|
3021
|
+
toggleCommandState(command) {
|
|
3022
|
+
if (!this.lastCommandState) this.lastCommandState = this.getCommandState();
|
|
3023
|
+
this.setCommandState(command, !this.lastCommandState[command]);
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
/**
|
|
3027
|
+
* Fires a change event. Updates the linked textarea and notifies any event listeners.
|
|
3028
|
+
*/
|
|
3029
|
+
fireChange() {
|
|
3030
|
+
if (!this.textarea && !this.listeners.change.length) return;
|
|
3031
|
+
const content = this.getContent();
|
|
3032
|
+
if (this.textarea) this.textarea.value = content;
|
|
3033
|
+
for (let listener of this.listeners.change) {
|
|
3034
|
+
listener({
|
|
3035
|
+
content: content,
|
|
3036
|
+
linesDirty: this.linesDirty
|
|
3037
|
+
});
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
/**
|
|
3042
|
+
* Fires a "selection changed" event.
|
|
3043
|
+
*/
|
|
3044
|
+
fireSelection() {
|
|
3045
|
+
if (this.listeners.selection && this.listeners.selection.length) {
|
|
3046
|
+
let focus = this.getSelection(false);
|
|
3047
|
+
let anchor = this.getSelection(true);
|
|
3048
|
+
let commandState = this.getCommandState(focus, anchor);
|
|
3049
|
+
if (this.lastCommandState) {
|
|
3050
|
+
Object.assign(this.lastCommandState, commandState);
|
|
3051
|
+
} else {
|
|
3052
|
+
this.lastCommandState = Object.assign({}, commandState);
|
|
3053
|
+
}
|
|
3054
|
+
for (let listener of this.listeners.selection) {
|
|
3055
|
+
listener({
|
|
3056
|
+
focus: focus,
|
|
3057
|
+
anchor: anchor,
|
|
3058
|
+
commandState: this.lastCommandState
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
/**
|
|
3065
|
+
* Adds an event listener.
|
|
3066
|
+
* @param {string} type The type of event to listen to. Can be 'change' or 'selection'
|
|
3067
|
+
* @param {*} listener Function of the type (event) => {} to be called when the event occurs.
|
|
3068
|
+
*/
|
|
3069
|
+
addEventListener(type, listener) {
|
|
3070
|
+
if (type.match(/^(?:change|input)$/i)) {
|
|
3071
|
+
this.listeners.change.push(listener);
|
|
3072
|
+
}
|
|
3073
|
+
if (type.match(/^(?:selection|selectionchange)$/i)) {
|
|
3074
|
+
this.listeners.selection.push(listener);
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
exports.CommandBar = CommandBar;
|
|
3080
|
+
exports.Editor = Editor;
|
|
3081
|
+
|
|
3082
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3083
|
+
|
|
3084
|
+
}));
|
|
3085
|
+
|
|
3086
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbInNyYy9zdmcvc3ZnLmpzIiwic3JjL1RpbnlNREVDb21tYW5kQmFyLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2dsb2JhbC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mYWlscy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9kZXNjcmlwdG9ycy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mdW5jdGlvbi1iaW5kLW5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mdW5jdGlvbi11bmN1cnJ5LXRoaXMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZG9jdW1lbnQtYWxsLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2lzLWNhbGxhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2lzLW51bGwtb3ItdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3JlcXVpcmUtb2JqZWN0LWNvZXJjaWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy90by1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaGFzLW93bi1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mdW5jdGlvbi1uYW1lLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2RlZmluZS1nbG9iYWwtcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2hhcmVkLXN0b3JlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2luc3BlY3Qtc291cmNlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3dlYWstbWFwLWJhc2ljLWRldGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZG9jdW1lbnQtY3JlYXRlLWVsZW1lbnQuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaWU4LWRvbS1kZWZpbmUuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdjgtcHJvdG90eXBlLWRlZmluZS1idWcuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYW4tb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2Z1bmN0aW9uLWNhbGwuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZ2V0LWJ1aWx0LWluLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL29iamVjdC1pcy1wcm90b3R5cGUtb2YuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZW5naW5lLXVzZXItYWdlbnQuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZW5naW5lLXY4LXZlcnNpb24uanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3ltYm9sLWNvbnN0cnVjdG9yLWRldGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy91c2Utc3ltYm9sLWFzLXVpZC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pcy1zeW1ib2wuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdHJ5LXRvLXN0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9hLWNhbGxhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2dldC1tZXRob2QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb3JkaW5hcnktdG8tcHJpbWl0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3NoYXJlZC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy91aWQuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tcHJpbWl0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3RvLXByb3BlcnR5LWtleS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3QtZGVmaW5lLXByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2NyZWF0ZS1wcm9wZXJ0eS1kZXNjcmlwdG9yLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2NyZWF0ZS1ub24tZW51bWVyYWJsZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9zaGFyZWQta2V5LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2ludGVybmFsLXN0YXRlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL21ha2UtYnVpbHQtaW4uanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZGVmaW5lLWJ1aWx0LWluLWFjY2Vzc29yLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3JlZ2V4cC1mbGFncy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLmZsYWdzLmpzIiwic3JjL2dyYW1tYXIuanMiLCJzcmMvVGlueU1ERS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBzdmcgPSB7XG4gIGJsb2NrcXVvdGU6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwibTIyOC0yNDAgOTItMTYwcS02NiAwLTExMy00N3QtNDctMTEzcTAtNjYgNDctMTEzdDExMy00N3E2NiAwIDExMyA0N3Q0NyAxMTNxMCAyMy01LjUgNDIuNVQ0NTgtNDgwTDMyMC0yNDBoLTkyWm0zNjAgMCA5Mi0xNjBxLTY2IDAtMTEzLTQ3dC00Ny0xMTNxMC02NiA0Ny0xMTN0MTEzLTQ3cTY2IDAgMTEzIDQ3dDQ3IDExM3EwIDIzLTUuNSA0Mi41VDgxOC00ODBMNjgwLTI0MGgtOTJaTTMyMC01MDBxMjUgMCA0Mi41LTE3LjVUMzgwLTU2MHEwLTI1LTE3LjUtNDIuNVQzMjAtNjIwcS0yNSAwLTQyLjUgMTcuNVQyNjAtNTYwcTAgMjUgMTcuNSA0Mi41VDMyMC01MDBabTM2MCAwcTI1IDAgNDIuNS0xNy41VDc0MC01NjBxMC0yNS0xNy41LTQyLjVUNjgwLTYyMHEtMjUgMC00Mi41IDE3LjVUNjIwLTU2MHEwIDI1IDE3LjUgNDIuNVQ2ODAtNTAwWm0wLTYwWm0tMzYwIDBaXCIvPjwvc3ZnPmAsXG4gIGJvbGQ6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwiTTI3Mi0yMDB2LTU2MGgyMjFxNjUgMCAxMjAgNDB0NTUgMTExcTAgNTEtMjMgNzguNVQ2MDItNDkxcTI1IDExIDU1LjUgNDF0MzAuNSA5MHEwIDg5LTY1IDEyNC41VDUwMS0yMDBIMjcyWm0xMjEtMTEyaDEwNHE0OCAwIDU4LjUtMjQuNVQ1NjYtMzcycTAtMTEtMTAuNS0zNS41VDQ5NC00MzJIMzkzdjEyMFptMC0yMjhoOTNxMzMgMCA0OC0xN3QxNS0zOHEwLTI0LTE3LTM5dC00NC0xNWgtOTV2MTA5WlwiLz48L3N2Zz5gLFxuICBjbGVhcl9mb3JtYXR0aW5nOiBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgaGVpZ2h0PVwiMjRweFwiIHZpZXdCb3g9XCIwIC05NjAgOTYwIDk2MFwiIHdpZHRoPVwiMjRweFwiIGZpbGw9XCIjNWY2MzY4XCI+PHBhdGggZD1cIm01MjgtNTQ2LTkzLTkzLTEyMS0xMjFoNDg2djEyMEg1NjhsLTQwIDk0Wk03OTItNTYgNDYwLTM4OGwtODAgMTg4SDI0OWwxMTktMjgwTDU2LTc5Mmw1Ni01NiA3MzYgNzM2LTU2IDU2WlwiLz48L3N2Zz5gLFxuICBjb2RlOiBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgaGVpZ2h0PVwiMjRweFwiIHZpZXdCb3g9XCIwIC05NjAgOTYwIDk2MFwiIHdpZHRoPVwiMjRweFwiIGZpbGw9XCIjNWY2MzY4XCI+PHBhdGggZD1cIk0zMjAtMjQwIDgwLTQ4MGwyNDAtMjQwIDU3IDU3LTE4NCAxODQgMTgzIDE4My01NiA1NlptMzIwIDAtNTctNTcgMTg0LTE4NC0xODMtMTgzIDU2LTU2IDI0MCAyNDAtMjQwIDI0MFpcIi8+PC9zdmc+YCxcbiAgaDE6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwiTTIwMC0yODB2LTQwMGg4MHYxNjBoMTYwdi0xNjBoODB2NDAwaC04MHYtMTYwSDI4MHYxNjBoLTgwWm00ODAgMHYtMzIwaC04MHYtODBoMTYwdjQwMGgtODBaXCIvPjwvc3ZnPmAsXG4gIGgyOiBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgaGVpZ2h0PVwiMjRweFwiIHZpZXdCb3g9XCIwIC05NjAgOTYwIDk2MFwiIHdpZHRoPVwiMjRweFwiIGZpbGw9XCIjNWY2MzY4XCI+PHBhdGggZD1cIk0xMjAtMjgwdi00MDBoODB2MTYwaDE2MHYtMTYwaDgwdjQwMGgtODB2LTE2MEgyMDB2MTYwaC04MFptNDAwIDB2LTE2MHEwLTMzIDIzLjUtNTYuNVQ2MDAtNTIwaDE2MHYtODBINTIwdi04MGgyNDBxMzMgMCA1Ni41IDIzLjVUODQwLTYwMHY4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtNDQwSDYwMHY4MGgyNDB2ODBINTIwWlwiLz48L3N2Zz5gLFxuICBocjogYDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGhlaWdodD1cIjI0cHhcIiB2aWV3Qm94PVwiMCAtOTYwIDk2MCA5NjBcIiB3aWR0aD1cIjI0cHhcIiBmaWxsPVwiIzVmNjM2OFwiPjxwYXRoIGQ9XCJNMTYwLTQ0MHYtODBoNjQwdjgwSDE2MFpcIi8+PC9zdmc+YCxcbiAgaW1hZ2U6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwiTTIwMC0xMjBxLTMzIDAtNTYuNS0yMy41VDEyMC0yMDB2LTU2MHEwLTMzIDIzLjUtNTYuNVQyMDAtODQwaDU2MHEzMyAwIDU2LjUgMjMuNVQ4NDAtNzYwdjU2MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDIwMFptMC04MGg1NjB2LTU2MEgyMDB2NTYwWm00MC04MGg0ODBMNTcwLTQ4MCA0NTAtMzIwbC05MC0xMjAtMTIwIDE2MFptLTQwIDgwdi01NjAgNTYwWlwiLz48L3N2Zz5gLFxuICBpdGFsaWM6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwiTTIwMC0yMDB2LTEwMGgxNjBsMTIwLTM2MEgzMjB2LTEwMGg0MDB2MTAwSDU4MEw0NjAtMzAwaDE0MHYxMDBIMjAwWlwiLz48L3N2Zz5gLFxuICBsaW5rOiBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgaGVpZ2h0PVwiMjRweFwiIHZpZXdCb3g9XCIwIC05NjAgOTYwIDk2MFwiIHdpZHRoPVwiMjRweFwiIGZpbGw9XCIjNWY2MzY4XCI+PHBhdGggZD1cIk00NDAtMjgwSDI4MHEtODMgMC0xNDEuNS01OC41VDgwLTQ4MHEwLTgzIDU4LjUtMTQxLjVUMjgwLTY4MGgxNjB2ODBIMjgwcS01MCAwLTg1IDM1dC0zNSA4NXEwIDUwIDM1IDg1dDg1IDM1aDE2MHY4MFpNMzIwLTQ0MHYtODBoMzIwdjgwSDMyMFptMjAwIDE2MHYtODBoMTYwcTUwIDAgODUtMzV0MzUtODVxMC01MC0zNS04NXQtODUtMzVINTIwdi04MGgxNjBxODMgMCAxNDEuNSA1OC41VDg4MC00ODBxMCA4My01OC41IDE0MS41VDY4MC0yODBINTIwWlwiLz48L3N2Zz5gLFxuICBvbDogYDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGhlaWdodD1cIjI0cHhcIiB2aWV3Qm94PVwiMCAtOTYwIDk2MCA5NjBcIiB3aWR0aD1cIjI0cHhcIiBmaWxsPVwiIzVmNjM2OFwiPjxwYXRoIGQ9XCJNMTIwLTgwdi02MGgxMDB2LTMwaC02MHYtNjBoNjB2LTMwSDEyMHYtNjBoMTIwcTE3IDAgMjguNSAxMS41VDI4MC0yODB2NDBxMCAxNy0xMS41IDI4LjVUMjQwLTIwMHExNyAwIDI4LjUgMTEuNVQyODAtMTYwdjQwcTAgMTctMTEuNSAyOC41VDI0MC04MEgxMjBabTAtMjgwdi0xMTBxMC0xNyAxMS41LTI4LjVUMTYwLTUxMGg2MHYtMzBIMTIwdi02MGgxMjBxMTcgMCAyOC41IDExLjVUMjgwLTU2MHY3MHEwIDE3LTExLjUgMjguNVQyNDAtNDUwaC02MHYzMGgxMDB2NjBIMTIwWm02MC0yODB2LTE4MGgtNjB2LTYwaDEyMHYyNDBoLTYwWm0xODAgNDQwdi04MGg0ODB2ODBIMzYwWm0wLTI0MHYtODBoNDgwdjgwSDM2MFptMC0yNDB2LTgwaDQ4MHY4MEgzNjBaXCIvPjwvc3ZnPmAsXG4gIHN0cmlrZXRocm91Z2g6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwiTTgwLTQwMHYtODBoODAwdjgwSDgwWm0zNDAtMTYwdi0xMjBIMjAwdi0xMjBoNTYwdjEyMEg1NDB2MTIwSDQyMFptMCA0MDB2LTE2MGgxMjB2MTYwSDQyMFpcIi8+PC9zdmc+YCxcbiAgdWw6IGA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgLTk2MCA5NjAgOTYwXCIgd2lkdGg9XCIyNHB4XCIgZmlsbD1cIiM1ZjYzNjhcIj48cGF0aCBkPVwiTTM2MC0yMDB2LTgwaDQ4MHY4MEgzNjBabTAtMjQwdi04MGg0ODB2ODBIMzYwWm0wLTI0MHYtODBoNDgwdjgwSDM2MFpNMjAwLTE2MHEtMzMgMC01Ni41LTIzLjVUMTIwLTI0MHEwLTMzIDIzLjUtNTYuNVQyMDAtMzIwcTMzIDAgNTYuNSAyMy41VDI4MC0yNDBxMCAzMy0yMy41IDU2LjVUMjAwLTE2MFptMC0yNDBxLTMzIDAtNTYuNS0yMy41VDEyMC00ODBxMC0zMyAyMy41LTU2LjVUMjAwLTU2MHEzMyAwIDU2LjUgMjMuNVQyODAtNDgwcTAgMzMtMjMuNSA1Ni41VDIwMC00MDBabTAtMjQwcS0zMyAwLTU2LjUtMjMuNVQxMjAtNzIwcTAtMzMgMjMuNS01Ni41VDIwMC04MDBxMzMgMCA1Ni41IDIzLjVUMjgwLTcyMHEwIDMzLTIzLjUgNTYuNVQyMDAtNjQwWlwiLz48L3N2Zz5gXG59O1xuXG5leHBvcnQgZGVmYXVsdCBzdmc7IiwiaW1wb3J0IHN2ZyBmcm9tICcuL3N2Zy9zdmcnO1xuXG5jb25zdCBpc01hY0xpa2UgPSAvKE1hY3xpUGhvbmV8aVBvZHxpUGFkKS9pLnRlc3QodHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIiA/IG5hdmlnYXRvci5wbGF0Zm9ybSA6IFwiXCIpO1xuXG5jb25zdCBEZWZhdWx0Q29tbWFuZHMgPSB7XG4gICdib2xkJzoge1xuICAgIG5hbWU6ICdib2xkJyxcbiAgICBhY3Rpb246ICdib2xkJyxcbiAgICBpbm5lckhUTUw6IHN2Zy5ib2xkLFxuICAgIHRpdGxlOiAnQm9sZCcsXG4gICAgaG90a2V5OiAnTW9kLUInLFxuICB9LFxuICAnaXRhbGljJzoge1xuICAgIG5hbWU6ICdpdGFsaWMnLFxuICAgIGFjdGlvbjogJ2l0YWxpYycsXG4gICAgaW5uZXJIVE1MOiBzdmcuaXRhbGljLFxuICAgIHRpdGxlOiAnSXRhbGljJyxcbiAgICBob3RrZXk6ICdNb2QtSScsXG4gIH0sXG4gICdzdHJpa2V0aHJvdWdoJzoge1xuICAgIG5hbWU6ICdzdHJpa2V0aHJvdWdoJyxcbiAgICBhY3Rpb246ICdzdHJpa2V0aHJvdWdoJyxcbiAgICBpbm5lckhUTUw6IHN2Zy5zdHJpa2V0aHJvdWdoLFxuICAgIHRpdGxlOiAnU3RyaWtldGhyb3VnaCcsXG4gICAgaG90a2V5OiAnTW9kMi1TaGlmdC01JyxcbiAgfSxcbiAgJ2NvZGUnOiB7XG4gICAgbmFtZTogJ2NvZGUnLFxuICAgIGFjdGlvbjogJ2NvZGUnLFxuICAgIGlubmVySFRNTDogc3ZnLmNvZGUsXG4gICAgdGl0bGU6ICdGb3JtYXQgYXMgY29kZScsXG4gIH0sXG4gICdoMSc6IHtcbiAgICBuYW1lOiAnaDEnLFxuICAgIGFjdGlvbjogJ2gxJyxcbiAgICBpbm5lckhUTUw6IHN2Zy5oMSxcbiAgICB0aXRsZTogJ0xldmVsIDEgaGVhZGluZycsXG4gICAgaG90a2V5OiAnTW9kLVNoaWZ0LTEnLFxuICB9LFxuICAnaDInOiB7XG4gICAgbmFtZTogJ2gyJyxcbiAgICBhY3Rpb246ICdoMicsXG4gICAgaW5uZXJIVE1MOiBzdmcuaDIsXG4gICAgdGl0bGU6ICdMZXZlbCAyIGhlYWRpbmcnLFxuICAgIGhvdGtleTogJ01vZC1TaGlmdC0yJyxcbiAgfSxcbiAgJ3VsJzoge1xuICAgIG5hbWU6ICd1bCcsXG4gICAgYWN0aW9uOiAndWwnLFxuICAgIGlubmVySFRNTDogc3ZnLnVsLFxuICAgIHRpdGxlOiAnQnVsbGV0ZWQgbGlzdCcsXG4gIH0sXG4gICdvbCc6IHtcbiAgICBuYW1lOiAnb2wnLFxuICAgIGFjdGlvbjogJ29sJyxcbiAgICBpbm5lckhUTUw6IHN2Zy5vbCxcbiAgICB0aXRsZTogJ051bWJlcmVkIGxpc3QnLFxuICB9LFxuICAnYmxvY2txdW90ZSc6IHtcbiAgICBuYW1lOiAnYmxvY2txdW90ZScsXG4gICAgYWN0aW9uOiAnYmxvY2txdW90ZScsXG4gICAgaW5uZXJIVE1MOiBzdmcuYmxvY2txdW90ZSxcbiAgICB0aXRsZTogJ1F1b3RlJyxcbiAgICBob3RrZXk6ICdNb2QyLVNoaWZ0LVEnLFxuICB9LFxuICAnaW5zZXJ0TGluayc6IHtcbiAgICBuYW1lOiAnaW5zZXJ0TGluaycsXG4gICAgYWN0aW9uOiAoZWRpdG9yKSA9PiB7aWYgKGVkaXRvci5pc0lubGluZUZvcm1hdHRpbmdBbGxvd2VkKCkpIGVkaXRvci53cmFwU2VsZWN0aW9uKCdbJywgJ10oKScpfSxcbiAgICBlbmFibGVkOiAoZWRpdG9yLCBmb2N1cywgYW5jaG9yKSA9PiBlZGl0b3IuaXNJbmxpbmVGb3JtYXR0aW5nQWxsb3dlZChmb2N1cywgYW5jaG9yKSA/IGZhbHNlIDogbnVsbCxcbiAgICBpbm5lckhUTUw6IHN2Zy5saW5rLFxuICAgIHRpdGxlOiAnSW5zZXJ0IGxpbmsnLFxuICAgIGhvdGtleTogJ01vZC1LJyxcbiAgfSxcbiAgJ2luc2VydEltYWdlJzoge1xuICAgIG5hbWU6ICdpbnNlcnRJbWFnZScsXG4gICAgYWN0aW9uOiAoZWRpdG9yKSA9PiB7aWYgKGVkaXRvci5pc0lubGluZUZvcm1hdHRpbmdBbGxvd2VkKCkpIGVkaXRvci53cmFwU2VsZWN0aW9uKCchWycsICddKCknKX0sXG4gICAgZW5hYmxlZDogKGVkaXRvciwgZm9jdXMsIGFuY2hvcikgPT4gZWRpdG9yLmlzSW5saW5lRm9ybWF0dGluZ0FsbG93ZWQoZm9jdXMsIGFuY2hvcikgPyBmYWxzZSA6IG51bGwsXG4gICAgaW5uZXJIVE1MOiBzdmcuaW1hZ2UsXG4gICAgdGl0bGU6ICdJbnNlcnQgaW1hZ2UnLFxuICAgIGhvdGtleTogJ01vZDItU2hpZnQtSScsXG4gIH0sXG4gICdocic6IHtcbiAgICBuYW1lOiAnaHInLFxuICAgIGFjdGlvbjogKGVkaXRvcikgPT4gZWRpdG9yLnBhc3RlKCdcXG4qKipcXG4nKSxcbiAgICBlbmFibGVkOiAoKSA9PiBmYWxzZSxcbiAgICBpbm5lckhUTUw6IHN2Zy5ocixcbiAgICB0aXRsZTogJ0luc2VydCBob3Jpem9udGFsIGxpbmUnLFxuICAgIGhvdGtleTogJ01vZDItU2hpZnQtTCdcbiAgfVxufVxuXG5cbmNsYXNzIENvbW1hbmRCYXIge1xuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIHRoaXMuZSA9IG51bGw7XG4gICAgdGhpcy5lZGl0b3IgPSBudWxsO1xuICAgIHRoaXMuY29tbWFuZHMgPSBbXTtcbiAgICB0aGlzLmJ1dHRvbnMgPSB7fTtcbiAgICB0aGlzLnN0YXRlID0ge307XG4gICAgdGhpcy5ob3RrZXlzID0gW107XG5cbiAgICBsZXQgZWxlbWVudCA9IHByb3BzLmVsZW1lbnQ7XG4gICAgaWYgKGVsZW1lbnQgJiYgIWVsZW1lbnQudGFnTmFtZSkge1xuICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHByb3BzLmVsZW1lbnQpO1xuICAgIH1cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5ib2R5OyBcbiAgICB9XG4gICAgdGhpcy5jcmVhdGVDb21tYW5kQmFyRWxlbWVudChlbGVtZW50LCBwcm9wcy5jb21tYW5kcyB8fCBbJ2JvbGQnLCAnaXRhbGljJywgJ3N0cmlrZXRocm91Z2gnLCAnfCcsICdjb2RlJywgJ3wnLCAnaDEnLCAnaDInLCAnfCcsICd1bCcsICdvbCcsICd8JywgJ2Jsb2NrcXVvdGUnLCAnaHInLCAnfCcsICdpbnNlcnRMaW5rJywgJ2luc2VydEltYWdlJ10pO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZSkgPT4gdGhpcy5oYW5kbGVLZXlkb3duKGUpKTtcbiAgICBpZiAocHJvcHMuZWRpdG9yKSB0aGlzLnNldEVkaXRvcihwcm9wcy5lZGl0b3IpO1xuICB9XG5cbiAgY3JlYXRlQ29tbWFuZEJhckVsZW1lbnQocGFyZW50RWxlbWVudCwgY29tbWFuZHMpIHtcbiAgICB0aGlzLmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmUuY2xhc3NOYW1lID0gJ1RNQ29tbWFuZEJhcic7XG5cbiAgICBmb3IgKGxldCBjb21tYW5kIG9mIGNvbW1hbmRzKSB7XG4gICAgICBpZiAoY29tbWFuZCA9PSAnfCcpIHtcbiAgICAgICAgbGV0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGVsLmNsYXNzTmFtZSA9ICdUTUNvbW1hbmREaXZpZGVyJztcbiAgICAgICAgdGhpcy5lLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBjb21tYW5kTmFtZTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb21tYW5kID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAvLyBSZWZlcmVuY2UgdG8gZGVmYXVsdCBjb21tYW5kXG5cbiAgICAgICAgICBpZiAoRGVmYXVsdENvbW1hbmRzW2NvbW1hbmRdKSB7XG4gICAgICAgICAgICBjb21tYW5kTmFtZSA9IGNvbW1hbmQ7XG4gICAgICAgICAgICB0aGlzLmNvbW1hbmRzW2NvbW1hbmROYW1lXSA9IERlZmF1bHRDb21tYW5kc1tjb21tYW5kTmFtZV07XG5cbiAgICAgICAgICAgIFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbW1hbmQgPT0gXCJvYmplY3RcIiAmJiBjb21tYW5kLm5hbWUpIHtcbiAgICAgICAgICBjb21tYW5kTmFtZSA9IGNvbW1hbmQubmFtZTtcbiAgICAgICAgICB0aGlzLmNvbW1hbmRzW2NvbW1hbmROYW1lXSA9IHt9OyBcbiAgICAgICAgICBpZiAoRGVmYXVsdENvbW1hbmRzW2NvbW1hbmROYW1lXSkgT2JqZWN0LmFzc2lnbih0aGlzLmNvbW1hbmRzW2NvbW1hbmROYW1lXSwgRGVmYXVsdENvbW1hbmRzW2NvbW1hbmROYW1lXSk7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLmNvbW1hbmRzW2NvbW1hbmROYW1lXSwgY29tbWFuZCk7XG4gICAgICAgIFxuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdGl0bGUgPSB0aGlzLmNvbW1hbmRzW2NvbW1hbmROYW1lXS50aXRsZSB8fCBjb21tYW5kTmFtZTtcblxuICAgICAgICBpZiAodGhpcy5jb21tYW5kc1tjb21tYW5kTmFtZV0uaG90a2V5KSB7XG4gICAgICAgICAgY29uc3Qga2V5cyA9IHRoaXMuY29tbWFuZHNbY29tbWFuZE5hbWVdLmhvdGtleS5zcGxpdCgnLScpO1xuICAgICAgICAgIC8vIGNvbnN0cnVjdCBtb2RpZmllcnNcbiAgICAgICAgICBsZXQgbW9kaWZpZXJzID0gW107XG4gICAgICAgICAgbGV0IG1vZGlmaWVyZXhwbGFuYXRpb24gPSBbXTtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGtleXNbaV0pIHtcbiAgICAgICAgICAgICAgY2FzZSAnQ3RybCc6IG1vZGlmaWVycy5wdXNoKCdjdHJsS2V5Jyk7IG1vZGlmaWVyZXhwbGFuYXRpb24ucHVzaCgnQ3RybCcpOyBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAnQ21kJzogbW9kaWZpZXJzLnB1c2goJ21ldGFLZXknKTsgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKCfijJgnKTsgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ0FsdCc6IG1vZGlmaWVycy5wdXNoKCdhbHRLZXknKTsgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKCdBbHQnKTsgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ09wdGlvbic6IG1vZGlmaWVycy5wdXNoKCdhbHRLZXknKTsgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKCfijKUnKTsgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ1dpbic6IG1vZGlmaWVycy5wdXNoKCdtZXRhS2V5Jyk7IG1vZGlmaWVyZXhwbGFuYXRpb24ucHVzaCgn4oqeIFdpbicpOyBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlICdTaGlmdCc6ICBtb2RpZmllcnMucHVzaCgnc2hpZnRLZXknKTsgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKCfih6cnKTsgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSAnTW9kJzogLy8gTW9kIGlzIGEgY29udmVuaWVuY2UgbWVjaGFuaXNtOiBDdHJsIG9uIFdpbmRvd3MsIENtZCBvbiBNYWNcbiAgICAgICAgICAgICAgICBpZiAoaXNNYWNMaWtlKSB7bW9kaWZpZXJzLnB1c2goJ21ldGFLZXknKTsgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKCfijJgnKTt9IFxuICAgICAgICAgICAgICAgIGVsc2Uge21vZGlmaWVycy5wdXNoKCdjdHJsS2V5Jyk7IG1vZGlmaWVyZXhwbGFuYXRpb24ucHVzaCgnQ3RybCcpO30gXG4gICAgICAgICAgICAgICAgYnJlYWs7IFxuICAgICAgICAgICAgICBjYXNlICdNb2QyJzogXG4gICAgICAgICAgICAgICAgbW9kaWZpZXJzLnB1c2goJ2FsdEtleScpOyBcbiAgICAgICAgICAgICAgICBpZiAoaXNNYWNMaWtlKSBtb2RpZmllcmV4cGxhbmF0aW9uLnB1c2goJ+KMpScpO1xuICAgICAgICAgICAgICAgIGVsc2UgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKCdBbHQnKTtcbiAgICAgICAgICAgICAgICBicmVhazsgLy8gTW9kMiBpcyBhIGNvbnZlbmllbmNlIG1lY2hhbmlzbTogQWx0IG9uIFdpbmRvd3MsIE9wdGlvbiBvbiBNYWNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbW9kaWZpZXJleHBsYW5hdGlvbi5wdXNoKGtleXNba2V5cy5sZW5ndGggLSAxXSk7XG4gICAgICAgICAgbGV0IGhvdGtleSA9IHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgbW9kaWZpZXJzOiBtb2RpZmllcnMsXG4gICAgICAgICAgICBjb21tYW5kOiBjb21tYW5kTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIFRPRE8gUmlnaHQgbm93IHRoaXMgaXMgd29ya2luZyBvbmx5IGZvciBsZXR0ZXJzIGFuZCBudW1iZXJzXG4gICAgICAgICAgaWYgKGtleXNba2V5cy5sZW5ndGggLSAxXS5tYXRjaCgvXlswLTldJC8pKSB7XG4gICAgICAgICAgICBob3RrZXkuY29kZSA9IGBEaWdpdCR7a2V5c1trZXlzLmxlbmd0aCAtIDFdfWA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhvdGtleS5rZXkgPSBrZXlzW2tleXMubGVuZ3RoIC0gMV0udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5ob3RrZXlzLnB1c2goaG90a2V5KTtcbiAgICAgICAgICB0aXRsZSA9IHRpdGxlLmNvbmNhdChgICgke21vZGlmaWVyZXhwbGFuYXRpb24uam9pbignKycpfSlgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYnV0dG9uc1tjb21tYW5kTmFtZV0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdGhpcy5idXR0b25zW2NvbW1hbmROYW1lXS5jbGFzc05hbWUgPSAnVE1Db21tYW5kQnV0dG9uIFRNQ29tbWFuZEJ1dHRvbl9EaXNhYmxlZCc7XG4gICAgICAgIHRoaXMuYnV0dG9uc1tjb21tYW5kTmFtZV0udGl0bGUgPSB0aXRsZTtcbiAgICAgICAgdGhpcy5idXR0b25zW2NvbW1hbmROYW1lXS5pbm5lckhUTUwgPSB0aGlzLmNvbW1hbmRzW2NvbW1hbmROYW1lXS5pbm5lckhUTUw7XG5cbiAgICAgICAgdGhpcy5idXR0b25zW2NvbW1hbmROYW1lXS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCAoZSkgPT4gdGhpcy5oYW5kbGVDbGljayhjb21tYW5kTmFtZSwgZSkpO1xuICAgICAgICB0aGlzLmUuYXBwZW5kQ2hpbGQodGhpcy5idXR0b25zW2NvbW1hbmROYW1lXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lKTtcbiAgfVxuXG4gIGhhbmRsZUNsaWNrKGNvbW1hbmROYW1lLCBldmVudCkge1xuICAgIGlmICghdGhpcy5lZGl0b3IpIHJldHVybjtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmICh0eXBlb2YgdGhpcy5jb21tYW5kc1tjb21tYW5kTmFtZV0uYWN0aW9uID09IFwic3RyaW5nXCIpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlW2NvbW1hbmROYW1lXSA9PT0gZmFsc2UpIHRoaXMuZWRpdG9yLnNldENvbW1hbmRTdGF0ZShjb21tYW5kTmFtZSwgdHJ1ZSk7XG4gICAgICBlbHNlIHRoaXMuZWRpdG9yLnNldENvbW1hbmRTdGF0ZShjb21tYW5kTmFtZSwgZmFsc2UpOyAgXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5jb21tYW5kc1tjb21tYW5kTmFtZV0uYWN0aW9uID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5jb21tYW5kc1tjb21tYW5kTmFtZV0uYWN0aW9uKHRoaXMuZWRpdG9yKTtcbiAgICB9XG4gIH1cblxuICBzZXRFZGl0b3IoZWRpdG9yKSB7XG4gICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7XG4gICAgZWRpdG9yLmFkZEV2ZW50TGlzdGVuZXIoJ3NlbGVjdGlvbicsIChlKSA9PiB0aGlzLmhhbmRsZVNlbGVjdGlvbihlKSk7XG4gIH1cblxuICBoYW5kbGVTZWxlY3Rpb24oZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQuY29tbWFuZFN0YXRlKSB7XG4gICAgICBmb3IgKGxldCBjb21tYW5kIGluIHRoaXMuY29tbWFuZHMpIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvbW1hbmRTdGF0ZVtjb21tYW5kXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29tbWFuZHNbY29tbWFuZF0uZW5hYmxlZCkgdGhpcy5zdGF0ZVtjb21tYW5kXSA9IHRoaXMuY29tbWFuZHNbY29tbWFuZF0uZW5hYmxlZCh0aGlzLmVkaXRvciwgZXZlbnQuZm9jdXMsIGV2ZW50LmFuY2hvcik7XG4gICAgICAgICAgZWxzZSB0aGlzLnN0YXRlW2NvbW1hbmRdID0gZXZlbnQuZm9jdXMgPyBmYWxzZSA6IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdGF0ZVtjb21tYW5kXSA9IGV2ZW50LmNvbW1hbmRTdGF0ZVtjb21tYW5kXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlW2NvbW1hbmRdID09PSB0cnVlKSB7XG4gICAgICAgICAgdGhpcy5idXR0b25zW2NvbW1hbmRdLmNsYXNzTmFtZSA9ICdUTUNvbW1hbmRCdXR0b24gVE1Db21tYW5kQnV0dG9uX0FjdGl2ZSc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZVtjb21tYW5kXSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICB0aGlzLmJ1dHRvbnNbY29tbWFuZF0uY2xhc3NOYW1lID0gJ1RNQ29tbWFuZEJ1dHRvbiBUTUNvbW1hbmRCdXR0b25fSW5hY3RpdmUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYnV0dG9uc1tjb21tYW5kXS5jbGFzc05hbWUgPSAgJ1RNQ29tbWFuZEJ1dHRvbiBUTUNvbW1hbmRCdXR0b25fRGlzYWJsZWQnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlS2V5ZG93bihldmVudCkge1xuICAgIG91dGVyOiBmb3IgKGxldCBob3RrZXkgb2YgdGhpcy5ob3RrZXlzKSB7XG4gICAgICBpZiAoKGhvdGtleS5rZXkgJiYgZXZlbnQua2V5LnRvTG93ZXJDYXNlKCkgPT0gaG90a2V5LmtleSkgfHwgKGhvdGtleS5jb2RlICYmIGV2ZW50LmNvZGUgPT0gaG90a2V5LmNvZGUpKSB7XG4gICAgICAgIC8vIEtleSBtYXRjaGVzIGhvdGtleS4gTG9vayBmb3IgYW55IHJlcXVpcmVkIG1vZGlmaWVyIHRoYXQgd2Fzbid0IHByZXNzZWRcbiAgICAgICAgZm9yIChsZXQgbW9kaWZpZXIgb2YgaG90a2V5Lm1vZGlmaWVycykge1xuICAgICAgICAgIGlmICghZXZlbnRbbW9kaWZpZXJdKSBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBFdmVyeXRoaW5nIG1hdGNoZXMuXG4gICAgICAgIHRoaXMuaGFuZGxlQ2xpY2soaG90a2V5LmNvbW1hbmQsIGV2ZW50KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb21tYW5kQmFyOyIsIid1c2Ugc3RyaWN0JztcbnZhciBjaGVjayA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgJiYgaXQuTWF0aCA9PT0gTWF0aCAmJiBpdDtcbn07XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG5tb2R1bGUuZXhwb3J0cyA9XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1nbG9iYWwtdGhpcyAtLSBzYWZlXG4gIGNoZWNrKHR5cGVvZiBnbG9iYWxUaGlzID09ICdvYmplY3QnICYmIGdsb2JhbFRoaXMpIHx8XG4gIGNoZWNrKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgd2luZG93KSB8fFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzIC0tIHNhZmVcbiAgY2hlY2sodHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZikgfHxcbiAgY2hlY2sodHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwpIHx8XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuYyAtLSBmYWxsYmFja1xuICAoZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSkoKSB8fCB0aGlzIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG4iLCIndXNlIHN0cmljdCc7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuICEhZXhlYygpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG5cbi8vIERldGVjdCBJRTgncyBpbmNvbXBsZXRlIGRlZmluZVByb3BlcnR5IGltcGxlbWVudGF0aW9uXG5tb2R1bGUuZXhwb3J0cyA9ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1vYmplY3QtZGVmaW5lcHJvcGVydHkgLS0gcmVxdWlyZWQgZm9yIHRlc3RpbmdcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgMSwgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSlbMV0gIT09IDc7XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mYWlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1mdW5jdGlvbi1wcm90b3R5cGUtYmluZCAtLSBzYWZlXG4gIHZhciB0ZXN0ID0gKGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSkuYmluZCgpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zIC0tIHNhZmVcbiAgcmV0dXJuIHR5cGVvZiB0ZXN0ICE9ICdmdW5jdGlvbicgfHwgdGVzdC5oYXNPd25Qcm9wZXJ0eSgncHJvdG90eXBlJyk7XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBOQVRJVkVfQklORCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mdW5jdGlvbi1iaW5kLW5hdGl2ZScpO1xuXG52YXIgRnVuY3Rpb25Qcm90b3R5cGUgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG52YXIgY2FsbCA9IEZ1bmN0aW9uUHJvdG90eXBlLmNhbGw7XG52YXIgdW5jdXJyeVRoaXNXaXRoQmluZCA9IE5BVElWRV9CSU5EICYmIEZ1bmN0aW9uUHJvdG90eXBlLmJpbmQuYmluZChjYWxsLCBjYWxsKTtcblxubW9kdWxlLmV4cG9ydHMgPSBOQVRJVkVfQklORCA/IHVuY3VycnlUaGlzV2l0aEJpbmQgOiBmdW5jdGlvbiAoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY2FsbC5hcHBseShmbiwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZG9jdW1lbnRBbGwgPSB0eXBlb2YgZG9jdW1lbnQgPT0gJ29iamVjdCcgJiYgZG9jdW1lbnQuYWxsO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLUlzSFRNTEREQS1pbnRlcm5hbC1zbG90XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdW5pY29ybi9uby10eXBlb2YtdW5kZWZpbmVkIC0tIHJlcXVpcmVkIGZvciB0ZXN0aW5nXG52YXIgSVNfSFRNTEREQSA9IHR5cGVvZiBkb2N1bWVudEFsbCA9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudEFsbCAhPT0gdW5kZWZpbmVkO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWxsOiBkb2N1bWVudEFsbCxcbiAgSVNfSFRNTEREQTogSVNfSFRNTEREQVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZG9jdW1lbnRBbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZG9jdW1lbnQtYWxsJyk7XG5cbnZhciBkb2N1bWVudEFsbCA9ICRkb2N1bWVudEFsbC5hbGw7XG5cbi8vIGBJc0NhbGxhYmxlYCBhYnN0cmFjdCBvcGVyYXRpb25cbi8vIGh0dHBzOi8vdGMzOS5lcy9lY21hMjYyLyNzZWMtaXNjYWxsYWJsZVxubW9kdWxlLmV4cG9ydHMgPSAkZG9jdW1lbnRBbGwuSVNfSFRNTEREQSA/IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICByZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09ICdmdW5jdGlvbicgfHwgYXJndW1lbnQgPT09IGRvY3VtZW50QWxsO1xufSA6IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICByZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09ICdmdW5jdGlvbic7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gd2UgY2FuJ3QgdXNlIGp1c3QgYGl0ID09IG51bGxgIHNpbmNlIG9mIGBkb2N1bWVudC5hbGxgIHNwZWNpYWwgY2FzZVxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1Jc0hUTUxEREEtaW50ZXJuYWwtc2xvdC1hZWNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCA9PT0gbnVsbCB8fCBpdCA9PT0gdW5kZWZpbmVkO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBpc051bGxPclVuZGVmaW5lZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1udWxsLW9yLXVuZGVmaW5lZCcpO1xuXG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxuLy8gYFJlcXVpcmVPYmplY3RDb2VyY2libGVgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1yZXF1aXJlb2JqZWN0Y29lcmNpYmxlXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXNOdWxsT3JVbmRlZmluZWQoaXQpKSB0aHJvdyBuZXcgJFR5cGVFcnJvcihcIkNhbid0IGNhbGwgbWV0aG9kIG9uIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHJlcXVpcmVPYmplY3RDb2VyY2libGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlJyk7XG5cbnZhciAkT2JqZWN0ID0gT2JqZWN0O1xuXG4vLyBgVG9PYmplY3RgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy10b29iamVjdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgcmV0dXJuICRPYmplY3QocmVxdWlyZU9iamVjdENvZXJjaWJsZShhcmd1bWVudCkpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciB1bmN1cnJ5VGhpcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mdW5jdGlvbi11bmN1cnJ5LXRoaXMnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1vYmplY3QnKTtcblxudmFyIGhhc093blByb3BlcnR5ID0gdW5jdXJyeVRoaXMoe30uaGFzT3duUHJvcGVydHkpO1xuXG4vLyBgSGFzT3duUHJvcGVydHlgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1oYXNvd25wcm9wZXJ0eVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVzL25vLW9iamVjdC1oYXNvd24gLS0gc2FmZVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaGFzT3duIHx8IGZ1bmN0aW9uIGhhc093bihpdCwga2V5KSB7XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eSh0b09iamVjdChpdCksIGtleSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgaGFzT3duID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2hhcy1vd24tcHJvcGVydHknKTtcblxudmFyIEZ1bmN0aW9uUHJvdG90eXBlID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVzL25vLW9iamVjdC1nZXRvd25wcm9wZXJ0eWRlc2NyaXB0b3IgLS0gc2FmZVxudmFyIGdldERlc2NyaXB0b3IgPSBERVNDUklQVE9SUyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuXG52YXIgRVhJU1RTID0gaGFzT3duKEZ1bmN0aW9uUHJvdG90eXBlLCAnbmFtZScpO1xuLy8gYWRkaXRpb25hbCBwcm90ZWN0aW9uIGZyb20gbWluaWZpZWQgLyBtYW5nbGVkIC8gZHJvcHBlZCBmdW5jdGlvbiBuYW1lc1xudmFyIFBST1BFUiA9IEVYSVNUUyAmJiAoZnVuY3Rpb24gc29tZXRoaW5nKCkgeyAvKiBlbXB0eSAqLyB9KS5uYW1lID09PSAnc29tZXRoaW5nJztcbnZhciBDT05GSUdVUkFCTEUgPSBFWElTVFMgJiYgKCFERVNDUklQVE9SUyB8fCAoREVTQ1JJUFRPUlMgJiYgZ2V0RGVzY3JpcHRvcihGdW5jdGlvblByb3RvdHlwZSwgJ25hbWUnKS5jb25maWd1cmFibGUpKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEVYSVNUUzogRVhJU1RTLFxuICBQUk9QRVI6IFBST1BFUixcbiAgQ09ORklHVVJBQkxFOiBDT05GSUdVUkFCTEVcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXMvbm8tb2JqZWN0LWRlZmluZXByb3BlcnR5IC0tIHNhZmVcbnZhciBkZWZpbmVQcm9wZXJ0eSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICB0cnkge1xuICAgIGRlZmluZVByb3BlcnR5KGdsb2JhbCwga2V5LCB7IHZhbHVlOiB2YWx1ZSwgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBnbG9iYWxba2V5XSA9IHZhbHVlO1xuICB9IHJldHVybiB2YWx1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xudmFyIGRlZmluZUdsb2JhbFByb3BlcnR5ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2RlZmluZS1nbG9iYWwtcHJvcGVydHknKTtcblxudmFyIFNIQVJFRCA9ICdfX2NvcmUtanNfc2hhcmVkX18nO1xudmFyIHN0b3JlID0gZ2xvYmFsW1NIQVJFRF0gfHwgZGVmaW5lR2xvYmFsUHJvcGVydHkoU0hBUkVELCB7fSk7XG5cbm1vZHVsZS5leHBvcnRzID0gc3RvcmU7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgdW5jdXJyeVRoaXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZnVuY3Rpb24tdW5jdXJyeS10aGlzJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1jYWxsYWJsZScpO1xudmFyIHN0b3JlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NoYXJlZC1zdG9yZScpO1xuXG52YXIgZnVuY3Rpb25Ub1N0cmluZyA9IHVuY3VycnlUaGlzKEZ1bmN0aW9uLnRvU3RyaW5nKTtcblxuLy8gdGhpcyBoZWxwZXIgYnJva2VuIGluIGBjb3JlLWpzQDMuNC4xLTMuNC40YCwgc28gd2UgY2FuJ3QgdXNlIGBzaGFyZWRgIGhlbHBlclxuaWYgKCFpc0NhbGxhYmxlKHN0b3JlLmluc3BlY3RTb3VyY2UpKSB7XG4gIHN0b3JlLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gZnVuY3Rpb25Ub1N0cmluZyhpdCk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RvcmUuaW5zcGVjdFNvdXJjZTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1jYWxsYWJsZScpO1xuXG52YXIgV2Vha01hcCA9IGdsb2JhbC5XZWFrTWFwO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQ2FsbGFibGUoV2Vha01hcCkgJiYgL25hdGl2ZSBjb2RlLy50ZXN0KFN0cmluZyhXZWFrTWFwKSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1jYWxsYWJsZScpO1xudmFyICRkb2N1bWVudEFsbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kb2N1bWVudC1hbGwnKTtcblxudmFyIGRvY3VtZW50QWxsID0gJGRvY3VtZW50QWxsLmFsbDtcblxubW9kdWxlLmV4cG9ydHMgPSAkZG9jdW1lbnRBbGwuSVNfSFRNTEREQSA/IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09ICdvYmplY3QnID8gaXQgIT09IG51bGwgOiBpc0NhbGxhYmxlKGl0KSB8fCBpdCA9PT0gZG9jdW1lbnRBbGw7XG59IDogZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IGlzQ2FsbGFibGUoaXQpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtb2JqZWN0Jyk7XG5cbnZhciBkb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudDtcbi8vIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnIGluIG9sZCBJRVxudmFyIEVYSVNUUyA9IGlzT2JqZWN0KGRvY3VtZW50KSAmJiBpc09iamVjdChkb2N1bWVudC5jcmVhdGVFbGVtZW50KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIEVYSVNUUyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaXQpIDoge307XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZmFpbHMnKTtcbnZhciBjcmVhdGVFbGVtZW50ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2RvY3VtZW50LWNyZWF0ZS1lbGVtZW50Jyk7XG5cbi8vIFRoYW5rcyB0byBJRTggZm9yIGl0cyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhREVTQ1JJUFRPUlMgJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVzL25vLW9iamVjdC1kZWZpbmVwcm9wZXJ0eSAtLSByZXF1aXJlZCBmb3IgdGVzdGluZ1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGNyZWF0ZUVsZW1lbnQoJ2RpdicpLCAnYScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH1cbiAgfSkuYSAhPT0gNztcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZmFpbHMnKTtcblxuLy8gVjggfiBDaHJvbWUgMzYtXG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMzM0XG5tb2R1bGUuZXhwb3J0cyA9IERFU0NSSVBUT1JTICYmIGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVzL25vLW9iamVjdC1kZWZpbmVwcm9wZXJ0eSAtLSByZXF1aXJlZCBmb3IgdGVzdGluZ1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSwgJ3Byb3RvdHlwZScsIHtcbiAgICB2YWx1ZTogNDIsXG4gICAgd3JpdGFibGU6IGZhbHNlXG4gIH0pLnByb3RvdHlwZSAhPT0gNDI7XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1vYmplY3QnKTtcblxudmFyICRTdHJpbmcgPSBTdHJpbmc7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxuLy8gYEFzc2VydDogVHlwZShhcmd1bWVudCkgaXMgT2JqZWN0YFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgaWYgKGlzT2JqZWN0KGFyZ3VtZW50KSkgcmV0dXJuIGFyZ3VtZW50O1xuICB0aHJvdyBuZXcgJFR5cGVFcnJvcigkU3RyaW5nKGFyZ3VtZW50KSArICcgaXMgbm90IGFuIG9iamVjdCcpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBOQVRJVkVfQklORCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mdW5jdGlvbi1iaW5kLW5hdGl2ZScpO1xuXG52YXIgY2FsbCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE5BVElWRV9CSU5EID8gY2FsbC5iaW5kKGNhbGwpIDogZnVuY3Rpb24gKCkge1xuICByZXR1cm4gY2FsbC5hcHBseShjYWxsLCBhcmd1bWVudHMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1jYWxsYWJsZScpO1xuXG52YXIgYUZ1bmN0aW9uID0gZnVuY3Rpb24gKGFyZ3VtZW50KSB7XG4gIHJldHVybiBpc0NhbGxhYmxlKGFyZ3VtZW50KSA/IGFyZ3VtZW50IDogdW5kZWZpbmVkO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZXNwYWNlLCBtZXRob2QpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPCAyID8gYUZ1bmN0aW9uKGdsb2JhbFtuYW1lc3BhY2VdKSA6IGdsb2JhbFtuYW1lc3BhY2VdICYmIGdsb2JhbFtuYW1lc3BhY2VdW21ldGhvZF07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHVuY3VycnlUaGlzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Z1bmN0aW9uLXVuY3VycnktdGhpcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHVuY3VycnlUaGlzKHt9LmlzUHJvdG90eXBlT2YpO1xuIiwiJ3VzZSBzdHJpY3QnO1xubW9kdWxlLmV4cG9ydHMgPSB0eXBlb2YgbmF2aWdhdG9yICE9ICd1bmRlZmluZWQnICYmIFN0cmluZyhuYXZpZ2F0b3IudXNlckFnZW50KSB8fCAnJztcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgdXNlckFnZW50ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2VuZ2luZS11c2VyLWFnZW50Jyk7XG5cbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgRGVubyA9IGdsb2JhbC5EZW5vO1xudmFyIHZlcnNpb25zID0gcHJvY2VzcyAmJiBwcm9jZXNzLnZlcnNpb25zIHx8IERlbm8gJiYgRGVuby52ZXJzaW9uO1xudmFyIHY4ID0gdmVyc2lvbnMgJiYgdmVyc2lvbnMudjg7XG52YXIgbWF0Y2gsIHZlcnNpb247XG5cbmlmICh2OCkge1xuICBtYXRjaCA9IHY4LnNwbGl0KCcuJyk7XG4gIC8vIGluIG9sZCBDaHJvbWUsIHZlcnNpb25zIG9mIFY4IGlzbid0IFY4ID0gQ2hyb21lIC8gMTBcbiAgLy8gYnV0IHRoZWlyIGNvcnJlY3QgdmVyc2lvbnMgYXJlIG5vdCBpbnRlcmVzdGluZyBmb3IgdXNcbiAgdmVyc2lvbiA9IG1hdGNoWzBdID4gMCAmJiBtYXRjaFswXSA8IDQgPyAxIDogKyhtYXRjaFswXSArIG1hdGNoWzFdKTtcbn1cblxuLy8gQnJvd3NlckZTIE5vZGVKUyBgcHJvY2Vzc2AgcG9seWZpbGwgaW5jb3JyZWN0bHkgc2V0IGAudjhgIHRvIGAwLjBgXG4vLyBzbyBjaGVjayBgdXNlckFnZW50YCBldmVuIGlmIGAudjhgIGV4aXN0cywgYnV0IDBcbmlmICghdmVyc2lvbiAmJiB1c2VyQWdlbnQpIHtcbiAgbWF0Y2ggPSB1c2VyQWdlbnQubWF0Y2goL0VkZ2VcXC8oXFxkKykvKTtcbiAgaWYgKCFtYXRjaCB8fCBtYXRjaFsxXSA+PSA3NCkge1xuICAgIG1hdGNoID0gdXNlckFnZW50Lm1hdGNoKC9DaHJvbWVcXC8oXFxkKykvKTtcbiAgICBpZiAobWF0Y2gpIHZlcnNpb24gPSArbWF0Y2hbMV07XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB2ZXJzaW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLyogZXNsaW50LWRpc2FibGUgZXMvbm8tc3ltYm9sIC0tIHJlcXVpcmVkIGZvciB0ZXN0aW5nICovXG52YXIgVjhfVkVSU0lPTiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9lbmdpbmUtdjgtdmVyc2lvbicpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xuXG52YXIgJFN0cmluZyA9IGdsb2JhbC5TdHJpbmc7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1vYmplY3QtZ2V0b3ducHJvcGVydHlzeW1ib2xzIC0tIHJlcXVpcmVkIGZvciB0ZXN0aW5nXG5tb2R1bGUuZXhwb3J0cyA9ICEhT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAmJiAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICB2YXIgc3ltYm9sID0gU3ltYm9sKCdzeW1ib2wgZGV0ZWN0aW9uJyk7XG4gIC8vIENocm9tZSAzOCBTeW1ib2wgaGFzIGluY29ycmVjdCB0b1N0cmluZyBjb252ZXJzaW9uXG4gIC8vIGBnZXQtb3duLXByb3BlcnR5LXN5bWJvbHNgIHBvbHlmaWxsIHN5bWJvbHMgY29udmVydGVkIHRvIG9iamVjdCBhcmUgbm90IFN5bWJvbCBpbnN0YW5jZXNcbiAgLy8gbmI6IERvIG5vdCBjYWxsIGBTdHJpbmdgIGRpcmVjdGx5IHRvIGF2b2lkIHRoaXMgYmVpbmcgb3B0aW1pemVkIG91dCB0byBgc3ltYm9sKycnYCB3aGljaCB3aWxsLFxuICAvLyBvZiBjb3Vyc2UsIGZhaWwuXG4gIHJldHVybiAhJFN0cmluZyhzeW1ib2wpIHx8ICEoT2JqZWN0KHN5bWJvbCkgaW5zdGFuY2VvZiBTeW1ib2wpIHx8XG4gICAgLy8gQ2hyb21lIDM4LTQwIHN5bWJvbHMgYXJlIG5vdCBpbmhlcml0ZWQgZnJvbSBET00gY29sbGVjdGlvbnMgcHJvdG90eXBlcyB0byBpbnN0YW5jZXNcbiAgICAhU3ltYm9sLnNoYW0gJiYgVjhfVkVSU0lPTiAmJiBWOF9WRVJTSU9OIDwgNDE7XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8qIGVzbGludC1kaXNhYmxlIGVzL25vLXN5bWJvbCAtLSByZXF1aXJlZCBmb3IgdGVzdGluZyAqL1xudmFyIE5BVElWRV9TWU1CT0wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc3ltYm9sLWNvbnN0cnVjdG9yLWRldGVjdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE5BVElWRV9TWU1CT0xcbiAgJiYgIVN5bWJvbC5zaGFtXG4gICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT0gJ3N5bWJvbCc7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2V0QnVpbHRJbiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nZXQtYnVpbHQtaW4nKTtcbnZhciBpc0NhbGxhYmxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLWNhbGxhYmxlJyk7XG52YXIgaXNQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtaXMtcHJvdG90eXBlLW9mJyk7XG52YXIgVVNFX1NZTUJPTF9BU19VSUQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdXNlLXN5bWJvbC1hcy11aWQnKTtcblxudmFyICRPYmplY3QgPSBPYmplY3Q7XG5cbm1vZHVsZS5leHBvcnRzID0gVVNFX1NZTUJPTF9BU19VSUQgPyBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJztcbn0gOiBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyICRTeW1ib2wgPSBnZXRCdWlsdEluKCdTeW1ib2wnKTtcbiAgcmV0dXJuIGlzQ2FsbGFibGUoJFN5bWJvbCkgJiYgaXNQcm90b3R5cGVPZigkU3ltYm9sLnByb3RvdHlwZSwgJE9iamVjdChpdCkpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkU3RyaW5nID0gU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICB0cnkge1xuICAgIHJldHVybiAkU3RyaW5nKGFyZ3VtZW50KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gJ09iamVjdCc7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1jYWxsYWJsZScpO1xudmFyIHRyeVRvU3RyaW5nID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RyeS10by1zdHJpbmcnKTtcblxudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGBBc3NlcnQ6IElzQ2FsbGFibGUoYXJndW1lbnQpIGlzIHRydWVgXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICBpZiAoaXNDYWxsYWJsZShhcmd1bWVudCkpIHJldHVybiBhcmd1bWVudDtcbiAgdGhyb3cgbmV3ICRUeXBlRXJyb3IodHJ5VG9TdHJpbmcoYXJndW1lbnQpICsgJyBpcyBub3QgYSBmdW5jdGlvbicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhQ2FsbGFibGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYS1jYWxsYWJsZScpO1xudmFyIGlzTnVsbE9yVW5kZWZpbmVkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW51bGwtb3ItdW5kZWZpbmVkJyk7XG5cbi8vIGBHZXRNZXRob2RgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1nZXRtZXRob2Rcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFYsIFApIHtcbiAgdmFyIGZ1bmMgPSBWW1BdO1xuICByZXR1cm4gaXNOdWxsT3JVbmRlZmluZWQoZnVuYykgPyB1bmRlZmluZWQgOiBhQ2FsbGFibGUoZnVuYyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZnVuY3Rpb24tY2FsbCcpO1xudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtY2FsbGFibGUnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1vYmplY3QnKTtcblxudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGBPcmRpbmFyeVRvUHJpbWl0aXZlYCBhYnN0cmFjdCBvcGVyYXRpb25cbi8vIGh0dHBzOi8vdGMzOS5lcy9lY21hMjYyLyNzZWMtb3JkaW5hcnl0b3ByaW1pdGl2ZVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaW5wdXQsIHByZWYpIHtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmIChwcmVmID09PSAnc3RyaW5nJyAmJiBpc0NhbGxhYmxlKGZuID0gaW5wdXQudG9TdHJpbmcpICYmICFpc09iamVjdCh2YWwgPSBjYWxsKGZuLCBpbnB1dCkpKSByZXR1cm4gdmFsO1xuICBpZiAoaXNDYWxsYWJsZShmbiA9IGlucHV0LnZhbHVlT2YpICYmICFpc09iamVjdCh2YWwgPSBjYWxsKGZuLCBpbnB1dCkpKSByZXR1cm4gdmFsO1xuICBpZiAocHJlZiAhPT0gJ3N0cmluZycgJiYgaXNDYWxsYWJsZShmbiA9IGlucHV0LnRvU3RyaW5nKSAmJiAhaXNPYmplY3QodmFsID0gY2FsbChmbiwgaW5wdXQpKSkgcmV0dXJuIHZhbDtcbiAgdGhyb3cgbmV3ICRUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIElTX1BVUkUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtcHVyZScpO1xudmFyIHN0b3JlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NoYXJlZC1zdG9yZScpO1xuXG4obW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICByZXR1cm4gc3RvcmVba2V5XSB8fCAoc3RvcmVba2V5XSA9IHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHt9KTtcbn0pKCd2ZXJzaW9ucycsIFtdKS5wdXNoKHtcbiAgdmVyc2lvbjogJzMuMzMuMCcsXG4gIG1vZGU6IElTX1BVUkUgPyAncHVyZScgOiAnZ2xvYmFsJyxcbiAgY29weXJpZ2h0OiAnwqkgMjAxNC0yMDIzIERlbmlzIFB1c2hrYXJldiAoemxvaXJvY2sucnUpJyxcbiAgbGljZW5zZTogJ2h0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2Jsb2IvdjMuMzMuMC9MSUNFTlNFJyxcbiAgc291cmNlOiAnaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciB1bmN1cnJ5VGhpcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mdW5jdGlvbi11bmN1cnJ5LXRoaXMnKTtcblxudmFyIGlkID0gMDtcbnZhciBwb3N0Zml4ID0gTWF0aC5yYW5kb20oKTtcbnZhciB0b1N0cmluZyA9IHVuY3VycnlUaGlzKDEuMC50b1N0cmluZyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICByZXR1cm4gJ1N5bWJvbCgnICsgKGtleSA9PT0gdW5kZWZpbmVkID8gJycgOiBrZXkpICsgJylfJyArIHRvU3RyaW5nKCsraWQgKyBwb3N0Zml4LCAzNik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbnZhciBzaGFyZWQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2hhcmVkJyk7XG52YXIgaGFzT3duID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2hhcy1vd24tcHJvcGVydHknKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdWlkJyk7XG52YXIgTkFUSVZFX1NZTUJPTCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zeW1ib2wtY29uc3RydWN0b3ItZGV0ZWN0aW9uJyk7XG52YXIgVVNFX1NZTUJPTF9BU19VSUQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdXNlLXN5bWJvbC1hcy11aWQnKTtcblxudmFyIFN5bWJvbCA9IGdsb2JhbC5TeW1ib2w7XG52YXIgV2VsbEtub3duU3ltYm9sc1N0b3JlID0gc2hhcmVkKCd3a3MnKTtcbnZhciBjcmVhdGVXZWxsS25vd25TeW1ib2wgPSBVU0VfU1lNQk9MX0FTX1VJRCA/IFN5bWJvbFsnZm9yJ10gfHwgU3ltYm9sIDogU3ltYm9sICYmIFN5bWJvbC53aXRob3V0U2V0dGVyIHx8IHVpZDtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSkge1xuICBpZiAoIWhhc093bihXZWxsS25vd25TeW1ib2xzU3RvcmUsIG5hbWUpKSB7XG4gICAgV2VsbEtub3duU3ltYm9sc1N0b3JlW25hbWVdID0gTkFUSVZFX1NZTUJPTCAmJiBoYXNPd24oU3ltYm9sLCBuYW1lKVxuICAgICAgPyBTeW1ib2xbbmFtZV1cbiAgICAgIDogY3JlYXRlV2VsbEtub3duU3ltYm9sKCdTeW1ib2wuJyArIG5hbWUpO1xuICB9IHJldHVybiBXZWxsS25vd25TeW1ib2xzU3RvcmVbbmFtZV07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZnVuY3Rpb24tY2FsbCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xudmFyIGlzU3ltYm9sID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLXN5bWJvbCcpO1xudmFyIGdldE1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nZXQtbWV0aG9kJyk7XG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vcmRpbmFyeS10by1wcmltaXRpdmUnKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG52YXIgVE9fUFJJTUlUSVZFID0gd2VsbEtub3duU3ltYm9sKCd0b1ByaW1pdGl2ZScpO1xuXG4vLyBgVG9QcmltaXRpdmVgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy10b3ByaW1pdGl2ZVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaW5wdXQsIHByZWYpIHtcbiAgaWYgKCFpc09iamVjdChpbnB1dCkgfHwgaXNTeW1ib2woaW5wdXQpKSByZXR1cm4gaW5wdXQ7XG4gIHZhciBleG90aWNUb1ByaW0gPSBnZXRNZXRob2QoaW5wdXQsIFRPX1BSSU1JVElWRSk7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChleG90aWNUb1ByaW0pIHtcbiAgICBpZiAocHJlZiA9PT0gdW5kZWZpbmVkKSBwcmVmID0gJ2RlZmF1bHQnO1xuICAgIHJlc3VsdCA9IGNhbGwoZXhvdGljVG9QcmltLCBpbnB1dCwgcHJlZik7XG4gICAgaWYgKCFpc09iamVjdChyZXN1bHQpIHx8IGlzU3ltYm9sKHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG4gICAgdGhyb3cgbmV3ICRUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG4gIH1cbiAgaWYgKHByZWYgPT09IHVuZGVmaW5lZCkgcHJlZiA9ICdudW1iZXInO1xuICByZXR1cm4gb3JkaW5hcnlUb1ByaW1pdGl2ZShpbnB1dCwgcHJlZik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLXByaW1pdGl2ZScpO1xudmFyIGlzU3ltYm9sID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLXN5bWJvbCcpO1xuXG4vLyBgVG9Qcm9wZXJ0eUtleWAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLXRvcHJvcGVydHlrZXlcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFyZ3VtZW50KSB7XG4gIHZhciBrZXkgPSB0b1ByaW1pdGl2ZShhcmd1bWVudCwgJ3N0cmluZycpO1xuICByZXR1cm4gaXNTeW1ib2woa2V5KSA/IGtleSA6IGtleSArICcnO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kZXNjcmlwdG9ycycpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2llOC1kb20tZGVmaW5lJyk7XG52YXIgVjhfUFJPVE9UWVBFX0RFRklORV9CVUcgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdjgtcHJvdG90eXBlLWRlZmluZS1idWcnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hbi1vYmplY3QnKTtcbnZhciB0b1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLXByb3BlcnR5LWtleScpO1xuXG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1vYmplY3QtZGVmaW5lcHJvcGVydHkgLS0gc2FmZVxudmFyICRkZWZpbmVQcm9wZXJ0eSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1vYmplY3QtZ2V0b3ducHJvcGVydHlkZXNjcmlwdG9yIC0tIHNhZmVcbnZhciAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbnZhciBFTlVNRVJBQkxFID0gJ2VudW1lcmFibGUnO1xudmFyIENPTkZJR1VSQUJMRSA9ICdjb25maWd1cmFibGUnO1xudmFyIFdSSVRBQkxFID0gJ3dyaXRhYmxlJztcblxuLy8gYE9iamVjdC5kZWZpbmVQcm9wZXJ0eWAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLW9iamVjdC5kZWZpbmVwcm9wZXJ0eVxuZXhwb3J0cy5mID0gREVTQ1JJUFRPUlMgPyBWOF9QUk9UT1RZUEVfREVGSU5FX0JVRyA/IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1Byb3BlcnR5S2V5KFApO1xuICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcbiAgaWYgKHR5cGVvZiBPID09PSAnZnVuY3Rpb24nICYmIFAgPT09ICdwcm90b3R5cGUnICYmICd2YWx1ZScgaW4gQXR0cmlidXRlcyAmJiBXUklUQUJMRSBpbiBBdHRyaWJ1dGVzICYmICFBdHRyaWJ1dGVzW1dSSVRBQkxFXSkge1xuICAgIHZhciBjdXJyZW50ID0gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKTtcbiAgICBpZiAoY3VycmVudCAmJiBjdXJyZW50W1dSSVRBQkxFXSkge1xuICAgICAgT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gICAgICBBdHRyaWJ1dGVzID0ge1xuICAgICAgICBjb25maWd1cmFibGU6IENPTkZJR1VSQUJMRSBpbiBBdHRyaWJ1dGVzID8gQXR0cmlidXRlc1tDT05GSUdVUkFCTEVdIDogY3VycmVudFtDT05GSUdVUkFCTEVdLFxuICAgICAgICBlbnVtZXJhYmxlOiBFTlVNRVJBQkxFIGluIEF0dHJpYnV0ZXMgPyBBdHRyaWJ1dGVzW0VOVU1FUkFCTEVdIDogY3VycmVudFtFTlVNRVJBQkxFXSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlXG4gICAgICB9O1xuICAgIH1cbiAgfSByZXR1cm4gJGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpO1xufSA6ICRkZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1Byb3BlcnR5S2V5KFApO1xuICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcbiAgaWYgKElFOF9ET01fREVGSU5FKSB0cnkge1xuICAgIHJldHVybiAkZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7IC8qIGVtcHR5ICovIH1cbiAgaWYgKCdnZXQnIGluIEF0dHJpYnV0ZXMgfHwgJ3NldCcgaW4gQXR0cmlidXRlcykgdGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkJyk7XG4gIGlmICgndmFsdWUnIGluIEF0dHJpYnV0ZXMpIE9bUF0gPSBBdHRyaWJ1dGVzLnZhbHVlO1xuICByZXR1cm4gTztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChiaXRtYXAsIHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgZW51bWVyYWJsZTogIShiaXRtYXAgJiAxKSxcbiAgICBjb25maWd1cmFibGU6ICEoYml0bWFwICYgMiksXG4gICAgd3JpdGFibGU6ICEoYml0bWFwICYgNCksXG4gICAgdmFsdWU6IHZhbHVlXG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgZGVmaW5lUHJvcGVydHlNb2R1bGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWRlZmluZS1wcm9wZXJ0eScpO1xudmFyIGNyZWF0ZVByb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtcHJvcGVydHktZGVzY3JpcHRvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IERFU0NSSVBUT1JTID8gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICByZXR1cm4gZGVmaW5lUHJvcGVydHlNb2R1bGUuZihvYmplY3QsIGtleSwgY3JlYXRlUHJvcGVydHlEZXNjcmlwdG9yKDEsIHZhbHVlKSk7XG59IDogZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBzaGFyZWQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2hhcmVkJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3VpZCcpO1xuXG52YXIga2V5cyA9IHNoYXJlZCgna2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIGtleXNba2V5XSB8fCAoa2V5c1trZXldID0gdWlkKGtleSkpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBOQVRJVkVfV0VBS19NQVAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2Vhay1tYXAtYmFzaWMtZGV0ZWN0aW9uJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xudmFyIGNyZWF0ZU5vbkVudW1lcmFibGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtbm9uLWVudW1lcmFibGUtcHJvcGVydHknKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGFzLW93bi1wcm9wZXJ0eScpO1xudmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zaGFyZWQtc3RvcmUnKTtcbnZhciBzaGFyZWRLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2hhcmVkLWtleScpO1xudmFyIGhpZGRlbktleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZGVuLWtleXMnKTtcblxudmFyIE9CSkVDVF9BTFJFQURZX0lOSVRJQUxJWkVEID0gJ09iamVjdCBhbHJlYWR5IGluaXRpYWxpemVkJztcbnZhciBUeXBlRXJyb3IgPSBnbG9iYWwuVHlwZUVycm9yO1xudmFyIFdlYWtNYXAgPSBnbG9iYWwuV2Vha01hcDtcbnZhciBzZXQsIGdldCwgaGFzO1xuXG52YXIgZW5mb3JjZSA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaGFzKGl0KSA/IGdldChpdCkgOiBzZXQoaXQsIHt9KTtcbn07XG5cbnZhciBnZXR0ZXJGb3IgPSBmdW5jdGlvbiAoVFlQRSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGl0KSB7XG4gICAgdmFyIHN0YXRlO1xuICAgIGlmICghaXNPYmplY3QoaXQpIHx8IChzdGF0ZSA9IGdldChpdCkpLnR5cGUgIT09IFRZUEUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0luY29tcGF0aWJsZSByZWNlaXZlciwgJyArIFRZUEUgKyAnIHJlcXVpcmVkJyk7XG4gICAgfSByZXR1cm4gc3RhdGU7XG4gIH07XG59O1xuXG5pZiAoTkFUSVZFX1dFQUtfTUFQIHx8IHNoYXJlZC5zdGF0ZSkge1xuICB2YXIgc3RvcmUgPSBzaGFyZWQuc3RhdGUgfHwgKHNoYXJlZC5zdGF0ZSA9IG5ldyBXZWFrTWFwKCkpO1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby1zZWxmLWFzc2lnbiAtLSBwcm90b3R5cGUgbWV0aG9kcyBwcm90ZWN0aW9uICovXG4gIHN0b3JlLmdldCA9IHN0b3JlLmdldDtcbiAgc3RvcmUuaGFzID0gc3RvcmUuaGFzO1xuICBzdG9yZS5zZXQgPSBzdG9yZS5zZXQ7XG4gIC8qIGVzbGludC1lbmFibGUgbm8tc2VsZi1hc3NpZ24gLS0gcHJvdG90eXBlIG1ldGhvZHMgcHJvdGVjdGlvbiAqL1xuICBzZXQgPSBmdW5jdGlvbiAoaXQsIG1ldGFkYXRhKSB7XG4gICAgaWYgKHN0b3JlLmhhcyhpdCkpIHRocm93IG5ldyBUeXBlRXJyb3IoT0JKRUNUX0FMUkVBRFlfSU5JVElBTElaRUQpO1xuICAgIG1ldGFkYXRhLmZhY2FkZSA9IGl0O1xuICAgIHN0b3JlLnNldChpdCwgbWV0YWRhdGEpO1xuICAgIHJldHVybiBtZXRhZGF0YTtcbiAgfTtcbiAgZ2V0ID0gZnVuY3Rpb24gKGl0KSB7XG4gICAgcmV0dXJuIHN0b3JlLmdldChpdCkgfHwge307XG4gIH07XG4gIGhhcyA9IGZ1bmN0aW9uIChpdCkge1xuICAgIHJldHVybiBzdG9yZS5oYXMoaXQpO1xuICB9O1xufSBlbHNlIHtcbiAgdmFyIFNUQVRFID0gc2hhcmVkS2V5KCdzdGF0ZScpO1xuICBoaWRkZW5LZXlzW1NUQVRFXSA9IHRydWU7XG4gIHNldCA9IGZ1bmN0aW9uIChpdCwgbWV0YWRhdGEpIHtcbiAgICBpZiAoaGFzT3duKGl0LCBTVEFURSkpIHRocm93IG5ldyBUeXBlRXJyb3IoT0JKRUNUX0FMUkVBRFlfSU5JVElBTElaRUQpO1xuICAgIG1ldGFkYXRhLmZhY2FkZSA9IGl0O1xuICAgIGNyZWF0ZU5vbkVudW1lcmFibGVQcm9wZXJ0eShpdCwgU1RBVEUsIG1ldGFkYXRhKTtcbiAgICByZXR1cm4gbWV0YWRhdGE7XG4gIH07XG4gIGdldCA9IGZ1bmN0aW9uIChpdCkge1xuICAgIHJldHVybiBoYXNPd24oaXQsIFNUQVRFKSA/IGl0W1NUQVRFXSA6IHt9O1xuICB9O1xuICBoYXMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gaGFzT3duKGl0LCBTVEFURSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXQ6IHNldCxcbiAgZ2V0OiBnZXQsXG4gIGhhczogaGFzLFxuICBlbmZvcmNlOiBlbmZvcmNlLFxuICBnZXR0ZXJGb3I6IGdldHRlckZvclxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciB1bmN1cnJ5VGhpcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mdW5jdGlvbi11bmN1cnJ5LXRoaXMnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mYWlscycpO1xudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtY2FsbGFibGUnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGFzLW93bi1wcm9wZXJ0eScpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgQ09ORklHVVJBQkxFX0ZVTkNUSU9OX05BTUUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZnVuY3Rpb24tbmFtZScpLkNPTkZJR1VSQUJMRTtcbnZhciBpbnNwZWN0U291cmNlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2luc3BlY3Qtc291cmNlJyk7XG52YXIgSW50ZXJuYWxTdGF0ZU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pbnRlcm5hbC1zdGF0ZScpO1xuXG52YXIgZW5mb3JjZUludGVybmFsU3RhdGUgPSBJbnRlcm5hbFN0YXRlTW9kdWxlLmVuZm9yY2U7XG52YXIgZ2V0SW50ZXJuYWxTdGF0ZSA9IEludGVybmFsU3RhdGVNb2R1bGUuZ2V0O1xudmFyICRTdHJpbmcgPSBTdHJpbmc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXMvbm8tb2JqZWN0LWRlZmluZXByb3BlcnR5IC0tIHNhZmVcbnZhciBkZWZpbmVQcm9wZXJ0eSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcbnZhciBzdHJpbmdTbGljZSA9IHVuY3VycnlUaGlzKCcnLnNsaWNlKTtcbnZhciByZXBsYWNlID0gdW5jdXJyeVRoaXMoJycucmVwbGFjZSk7XG52YXIgam9pbiA9IHVuY3VycnlUaGlzKFtdLmpvaW4pO1xuXG52YXIgQ09ORklHVVJBQkxFX0xFTkdUSCA9IERFU0NSSVBUT1JTICYmICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBkZWZpbmVQcm9wZXJ0eShmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0sICdsZW5ndGgnLCB7IHZhbHVlOiA4IH0pLmxlbmd0aCAhPT0gODtcbn0pO1xuXG52YXIgVEVNUExBVEUgPSBTdHJpbmcoU3RyaW5nKS5zcGxpdCgnU3RyaW5nJyk7XG5cbnZhciBtYWtlQnVpbHRJbiA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHZhbHVlLCBuYW1lLCBvcHRpb25zKSB7XG4gIGlmIChzdHJpbmdTbGljZSgkU3RyaW5nKG5hbWUpLCAwLCA3KSA9PT0gJ1N5bWJvbCgnKSB7XG4gICAgbmFtZSA9ICdbJyArIHJlcGxhY2UoJFN0cmluZyhuYW1lKSwgL15TeW1ib2xcXCgoW14pXSopXFwpLywgJyQxJykgKyAnXSc7XG4gIH1cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5nZXR0ZXIpIG5hbWUgPSAnZ2V0ICcgKyBuYW1lO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnNldHRlcikgbmFtZSA9ICdzZXQgJyArIG5hbWU7XG4gIGlmICghaGFzT3duKHZhbHVlLCAnbmFtZScpIHx8IChDT05GSUdVUkFCTEVfRlVOQ1RJT05fTkFNRSAmJiB2YWx1ZS5uYW1lICE9PSBuYW1lKSkge1xuICAgIGlmIChERVNDUklQVE9SUykgZGVmaW5lUHJvcGVydHkodmFsdWUsICduYW1lJywgeyB2YWx1ZTogbmFtZSwgY29uZmlndXJhYmxlOiB0cnVlIH0pO1xuICAgIGVsc2UgdmFsdWUubmFtZSA9IG5hbWU7XG4gIH1cbiAgaWYgKENPTkZJR1VSQUJMRV9MRU5HVEggJiYgb3B0aW9ucyAmJiBoYXNPd24ob3B0aW9ucywgJ2FyaXR5JykgJiYgdmFsdWUubGVuZ3RoICE9PSBvcHRpb25zLmFyaXR5KSB7XG4gICAgZGVmaW5lUHJvcGVydHkodmFsdWUsICdsZW5ndGgnLCB7IHZhbHVlOiBvcHRpb25zLmFyaXR5IH0pO1xuICB9XG4gIHRyeSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgaGFzT3duKG9wdGlvbnMsICdjb25zdHJ1Y3RvcicpICYmIG9wdGlvbnMuY29uc3RydWN0b3IpIHtcbiAgICAgIGlmIChERVNDUklQVE9SUykgZGVmaW5lUHJvcGVydHkodmFsdWUsICdwcm90b3R5cGUnLCB7IHdyaXRhYmxlOiBmYWxzZSB9KTtcbiAgICAvLyBpbiBWOCB+IENocm9tZSA1MywgcHJvdG90eXBlcyBvZiBzb21lIG1ldGhvZHMsIGxpa2UgYEFycmF5LnByb3RvdHlwZS52YWx1ZXNgLCBhcmUgbm9uLXdyaXRhYmxlXG4gICAgfSBlbHNlIGlmICh2YWx1ZS5wcm90b3R5cGUpIHZhbHVlLnByb3RvdHlwZSA9IHVuZGVmaW5lZDtcbiAgfSBjYXRjaCAoZXJyb3IpIHsgLyogZW1wdHkgKi8gfVxuICB2YXIgc3RhdGUgPSBlbmZvcmNlSW50ZXJuYWxTdGF0ZSh2YWx1ZSk7XG4gIGlmICghaGFzT3duKHN0YXRlLCAnc291cmNlJykpIHtcbiAgICBzdGF0ZS5zb3VyY2UgPSBqb2luKFRFTVBMQVRFLCB0eXBlb2YgbmFtZSA9PSAnc3RyaW5nJyA/IG5hbWUgOiAnJyk7XG4gIH0gcmV0dXJuIHZhbHVlO1xufTtcblxuLy8gYWRkIGZha2UgRnVuY3Rpb24jdG9TdHJpbmcgZm9yIGNvcnJlY3Qgd29yayB3cmFwcGVkIG1ldGhvZHMgLyBjb25zdHJ1Y3RvcnMgd2l0aCBtZXRob2RzIGxpa2UgTG9EYXNoIGlzTmF0aXZlXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0ZW5kLW5hdGl2ZSAtLSByZXF1aXJlZFxuRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nID0gbWFrZUJ1aWx0SW4oZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gIHJldHVybiBpc0NhbGxhYmxlKHRoaXMpICYmIGdldEludGVybmFsU3RhdGUodGhpcykuc291cmNlIHx8IGluc3BlY3RTb3VyY2UodGhpcyk7XG59LCAndG9TdHJpbmcnKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBtYWtlQnVpbHRJbiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9tYWtlLWJ1aWx0LWluJyk7XG52YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWRlZmluZS1wcm9wZXJ0eScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIG5hbWUsIGRlc2NyaXB0b3IpIHtcbiAgaWYgKGRlc2NyaXB0b3IuZ2V0KSBtYWtlQnVpbHRJbihkZXNjcmlwdG9yLmdldCwgbmFtZSwgeyBnZXR0ZXI6IHRydWUgfSk7XG4gIGlmIChkZXNjcmlwdG9yLnNldCkgbWFrZUJ1aWx0SW4oZGVzY3JpcHRvci5zZXQsIG5hbWUsIHsgc2V0dGVyOiB0cnVlIH0pO1xuICByZXR1cm4gZGVmaW5lUHJvcGVydHkuZih0YXJnZXQsIG5hbWUsIGRlc2NyaXB0b3IpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hbi1vYmplY3QnKTtcblxuLy8gYFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3NgIGdldHRlciBpbXBsZW1lbnRhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1nZXQtcmVnZXhwLnByb3RvdHlwZS5mbGFnc1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0aGF0ID0gYW5PYmplY3QodGhpcyk7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgaWYgKHRoYXQuaGFzSW5kaWNlcykgcmVzdWx0ICs9ICdkJztcbiAgaWYgKHRoYXQuZ2xvYmFsKSByZXN1bHQgKz0gJ2cnO1xuICBpZiAodGhhdC5pZ25vcmVDYXNlKSByZXN1bHQgKz0gJ2knO1xuICBpZiAodGhhdC5tdWx0aWxpbmUpIHJlc3VsdCArPSAnbSc7XG4gIGlmICh0aGF0LmRvdEFsbCkgcmVzdWx0ICs9ICdzJztcbiAgaWYgKHRoYXQudW5pY29kZSkgcmVzdWx0ICs9ICd1JztcbiAgaWYgKHRoYXQudW5pY29kZVNldHMpIHJlc3VsdCArPSAndic7XG4gIGlmICh0aGF0LnN0aWNreSkgcmVzdWx0ICs9ICd5JztcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgZGVmaW5lQnVpbHRJbkFjY2Vzc29yID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2RlZmluZS1idWlsdC1pbi1hY2Nlc3NvcicpO1xudmFyIHJlZ0V4cEZsYWdzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3JlZ2V4cC1mbGFncycpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG5cbi8vIGJhYmVsLW1pbmlmeSBhbmQgQ2xvc3VyZSBDb21waWxlciB0cmFuc3BpbGVzIFJlZ0V4cCgnLicsICdkJykgLT4gLy4vZCBhbmQgaXQgY2F1c2VzIFN5bnRheEVycm9yXG52YXIgUmVnRXhwID0gZ2xvYmFsLlJlZ0V4cDtcbnZhciBSZWdFeHBQcm90b3R5cGUgPSBSZWdFeHAucHJvdG90eXBlO1xuXG52YXIgRk9SQ0VEID0gREVTQ1JJUFRPUlMgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICB2YXIgSU5ESUNFU19TVVBQT1JUID0gdHJ1ZTtcbiAgdHJ5IHtcbiAgICBSZWdFeHAoJy4nLCAnZCcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIElORElDRVNfU1VQUE9SVCA9IGZhbHNlO1xuICB9XG5cbiAgdmFyIE8gPSB7fTtcbiAgLy8gbW9kZXJuIFY4IGJ1Z1xuICB2YXIgY2FsbHMgPSAnJztcbiAgdmFyIGV4cGVjdGVkID0gSU5ESUNFU19TVVBQT1JUID8gJ2RnaW1zeScgOiAnZ2ltc3knO1xuXG4gIHZhciBhZGRHZXR0ZXIgPSBmdW5jdGlvbiAoa2V5LCBjaHIpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXMvbm8tb2JqZWN0LWRlZmluZXByb3BlcnR5IC0tIHNhZmVcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywga2V5LCB7IGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbHMgKz0gY2hyO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSB9KTtcbiAgfTtcblxuICB2YXIgcGFpcnMgPSB7XG4gICAgZG90QWxsOiAncycsXG4gICAgZ2xvYmFsOiAnZycsXG4gICAgaWdub3JlQ2FzZTogJ2knLFxuICAgIG11bHRpbGluZTogJ20nLFxuICAgIHN0aWNreTogJ3knXG4gIH07XG5cbiAgaWYgKElORElDRVNfU1VQUE9SVCkgcGFpcnMuaGFzSW5kaWNlcyA9ICdkJztcblxuICBmb3IgKHZhciBrZXkgaW4gcGFpcnMpIGFkZEdldHRlcihrZXksIHBhaXJzW2tleV0pO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1vYmplY3QtZ2V0b3ducHJvcGVydHlkZXNjcmlwdG9yIC0tIHNhZmVcbiAgdmFyIHJlc3VsdCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoUmVnRXhwUHJvdG90eXBlLCAnZmxhZ3MnKS5nZXQuY2FsbChPKTtcblxuICByZXR1cm4gcmVzdWx0ICE9PSBleHBlY3RlZCB8fCBjYWxscyAhPT0gZXhwZWN0ZWQ7XG59KTtcblxuLy8gYFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3NgIGdldHRlclxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1nZXQtcmVnZXhwLnByb3RvdHlwZS5mbGFnc1xuaWYgKEZPUkNFRCkgZGVmaW5lQnVpbHRJbkFjY2Vzc29yKFJlZ0V4cFByb3RvdHlwZSwgJ2ZsYWdzJywge1xuICBjb25maWd1cmFibGU6IHRydWUsXG4gIGdldDogcmVnRXhwRmxhZ3Ncbn0pO1xuIiwiLy8gY29uc3QgcmVwbGFjZW1lbnRzID0ge1xuLy8gICBBU0NJSVB1bmN0dWF0aW9uOiAnIVwiIyQlJlxcJygpKissXFxcXC0uLzo7PD0+P0BcXFxcW1xcXFxdXl9ge3x9ficsXG4vLyAgIFRyaWdnZXJDaGFyczogJ2BfXFwqXFxbXFxdXFwoXFwpJyxcbi8vICAgU2NoZW1lOiBgW0EtWmEtel1bQS1aYS16MC05XFwrXFwuXFwtXXsxLDMxfWAsXG4vLyAgIEVtYWlsOiBgW2EtekEtWjAtOS4hIyQlJicqKy89P15fXFxge3x9fi1dK0BbYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8oPzpcXFxcLlthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPykqYCwgLy8gRnJvbSBDb21tb25NYXJrIHNwZWNcblxuLy8gfVxuY29uc3QgcmVwbGFjZW1lbnRzID0ge1xuICBBU0NJSVB1bmN0dWF0aW9uOiAvWyFcIiMkJSYnKCkqKyxcXC0uLzo7PD0+P0BbXFxdXl9ge3x9flxcXFxdLywgIFxuICBOb3RUcmlnZ2VyQ2hhcjogL1teYF8qW1xcXSgpPD4hfl0vLFxuICBTY2hlbWU6IC9bQS1aYS16XVtBLVphLXowLTkrLi1dezEsMzF9LyxcbiAgRW1haWw6IC9bYS16QS1aMC05LiEjJCUmJyorLz0/Xl9ge3x9fi1dK0BbYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8oPzpcXC5bYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8pKi8sIC8vIEZyb20gQ29tbW9uTWFyayBzcGVjXG4gIEhUTUxPcGVuVGFnOiAvPEhUTUxUYWdOYW1lKD86SFRNTEF0dHJpYnV0ZSkqXFxzKlxcLz8+LyxcbiAgSFRNTENsb3NlVGFnOiAvPFxcL0hUTUxUYWdOYW1lXFxzKj4vLFxuICBIVE1MVGFnTmFtZTogL1tBLVphLXpdW0EtWmEtejAtOS1dKi8sIFxuICBIVE1MQ29tbWVudDogLzwhLS0oPzpbXj4tXXwoPzpbXj4tXSg/OlteLV18LVteLV0pKlteLV0pKS0tPi8sXG4gIEhUTUxQSTogLzxcXD8oPzp8LnwoPzpbXj9dfFxcP1tePl0pKilcXD8+LyxcbiAgSFRNTERlY2xhcmF0aW9uOiAvPCFbQS1aXStcXHNbXj5dKj4vLFxuICBIVE1MQ0RBVEE6IC88IVxcW0NEQVRBXFxbLio/XFxdXFxdPi8sXG4gIEhUTUxBdHRyaWJ1dGU6IC9cXHMrW0EtWmEtel86XVtBLVphLXowLTlfLjotXSooPzpIVE1MQXR0VmFsdWUpPy8sXG4gIEhUTUxBdHRWYWx1ZTogL1xccyo9XFxzKig/Oig/OidbXiddKicpfCg/OlwiW15cIl0qXCIpfCg/OlteXFxzXCInPTw+YF0rKSkvLFxuICBLbm93blRhZzogL2FkZHJlc3N8YXJ0aWNsZXxhc2lkZXxiYXNlfGJhc2Vmb250fGJsb2NrcXVvdGV8Ym9keXxjYXB0aW9ufGNlbnRlcnxjb2x8Y29sZ3JvdXB8ZGR8ZGV0YWlsc3xkaWFsb2d8ZGlyfGRpdnxkbHxkdHxmaWVsZHNldHxmaWdjYXB0aW9ufGZpZ3VyZXxmb290ZXJ8Zm9ybXxmcmFtZXxmcmFtZXNldHxoMXxoMnxoM3xoNHxoNXxoNnxoZWFkfGhlYWRlcnxocnxodG1sfGlmcmFtZXxsZWdlbmR8bGl8bGlua3xtYWlufG1lbnV8bWVudWl0ZW18bmF2fG5vZnJhbWVzfG9sfG9wdGdyb3VwfG9wdGlvbnxwfHBhcmFtfHNlY3Rpb258c291cmNlfHN1bW1hcnl8dGFibGV8dGJvZHl8dGR8dGZvb3R8dGh8dGhlYWR8dGl0bGV8dHJ8dHJhY2t8dWwvXG59XG5cbi8vIEZyb20gQ29tbW9uTWFyay5qcy4gXG5jb25zdCBwdW5jdHVhdGlvbkxlYWRpbmcgPSBuZXcgUmVnRXhwKC9eKD86WyFcIiMkJSYnKCkqKyxcXC0uLzo7PD0+P0BbXFxdXFxcXF5fYHt8fX5cXHhBMVxceEE3XFx4QUJcXHhCNlxceEI3XFx4QkJcXHhCRlxcdTAzN0VcXHUwMzg3XFx1MDU1QS1cXHUwNTVGXFx1MDU4OVxcdTA1OEFcXHUwNUJFXFx1MDVDMFxcdTA1QzNcXHUwNUM2XFx1MDVGM1xcdTA1RjRcXHUwNjA5XFx1MDYwQVxcdTA2MENcXHUwNjBEXFx1MDYxQlxcdTA2MUVcXHUwNjFGXFx1MDY2QS1cXHUwNjZEXFx1MDZENFxcdTA3MDAtXFx1MDcwRFxcdTA3RjctXFx1MDdGOVxcdTA4MzAtXFx1MDgzRVxcdTA4NUVcXHUwOTY0XFx1MDk2NVxcdTA5NzBcXHUwQUYwXFx1MERGNFxcdTBFNEZcXHUwRTVBXFx1MEU1QlxcdTBGMDQtXFx1MEYxMlxcdTBGMTRcXHUwRjNBLVxcdTBGM0RcXHUwRjg1XFx1MEZEMC1cXHUwRkQ0XFx1MEZEOVxcdTBGREFcXHUxMDRBLVxcdTEwNEZcXHUxMEZCXFx1MTM2MC1cXHUxMzY4XFx1MTQwMFxcdTE2NkRcXHUxNjZFXFx1MTY5QlxcdTE2OUNcXHUxNkVCLVxcdTE2RURcXHUxNzM1XFx1MTczNlxcdTE3RDQtXFx1MTdENlxcdTE3RDgtXFx1MTdEQVxcdTE4MDAtXFx1MTgwQVxcdTE5NDRcXHUxOTQ1XFx1MUExRVxcdTFBMUZcXHUxQUEwLVxcdTFBQTZcXHUxQUE4LVxcdTFBQURcXHUxQjVBLVxcdTFCNjBcXHUxQkZDLVxcdTFCRkZcXHUxQzNCLVxcdTFDM0ZcXHUxQzdFXFx1MUM3RlxcdTFDQzAtXFx1MUNDN1xcdTFDRDNcXHUyMDEwLVxcdTIwMjdcXHUyMDMwLVxcdTIwNDNcXHUyMDQ1LVxcdTIwNTFcXHUyMDUzLVxcdTIwNUVcXHUyMDdEXFx1MjA3RVxcdTIwOERcXHUyMDhFXFx1MjMwOC1cXHUyMzBCXFx1MjMyOVxcdTIzMkFcXHUyNzY4LVxcdTI3NzVcXHUyN0M1XFx1MjdDNlxcdTI3RTYtXFx1MjdFRlxcdTI5ODMtXFx1Mjk5OFxcdTI5RDgtXFx1MjlEQlxcdTI5RkNcXHUyOUZEXFx1MkNGOS1cXHUyQ0ZDXFx1MkNGRVxcdTJDRkZcXHUyRDcwXFx1MkUwMC1cXHUyRTJFXFx1MkUzMC1cXHUyRTQyXFx1MzAwMS1cXHUzMDAzXFx1MzAwOC1cXHUzMDExXFx1MzAxNC1cXHUzMDFGXFx1MzAzMFxcdTMwM0RcXHUzMEEwXFx1MzBGQlxcdUE0RkVcXHVBNEZGXFx1QTYwRC1cXHVBNjBGXFx1QTY3M1xcdUE2N0VcXHVBNkYyLVxcdUE2RjdcXHVBODc0LVxcdUE4NzdcXHVBOENFXFx1QThDRlxcdUE4RjgtXFx1QThGQVxcdUE4RkNcXHVBOTJFXFx1QTkyRlxcdUE5NUZcXHVBOUMxLVxcdUE5Q0RcXHVBOURFXFx1QTlERlxcdUFBNUMtXFx1QUE1RlxcdUFBREVcXHVBQURGXFx1QUFGMFxcdUFBRjFcXHVBQkVCXFx1RkQzRVxcdUZEM0ZcXHVGRTEwLVxcdUZFMTlcXHVGRTMwLVxcdUZFNTJcXHVGRTU0LVxcdUZFNjFcXHVGRTYzXFx1RkU2OFxcdUZFNkFcXHVGRTZCXFx1RkYwMS1cXHVGRjAzXFx1RkYwNS1cXHVGRjBBXFx1RkYwQy1cXHVGRjBGXFx1RkYxQVxcdUZGMUJcXHVGRjFGXFx1RkYyMFxcdUZGM0ItXFx1RkYzRFxcdUZGM0ZcXHVGRjVCXFx1RkY1RFxcdUZGNUYtXFx1RkY2NV18XFx1RDgwMFtcXHVERDAwLVxcdUREMDJcXHVERjlGXFx1REZEMF18XFx1RDgwMVxcdURENkZ8XFx1RDgwMltcXHVEQzU3XFx1REQxRlxcdUREM0ZcXHVERTUwLVxcdURFNThcXHVERTdGXFx1REVGMC1cXHVERUY2XFx1REYzOS1cXHVERjNGXFx1REY5OS1cXHVERjlDXXxcXHVEODA0W1xcdURDNDctXFx1REM0RFxcdURDQkJcXHVEQ0JDXFx1RENCRS1cXHVEQ0MxXFx1REQ0MC1cXHVERDQzXFx1REQ3NFxcdURENzVcXHVEREM1LVxcdUREQzlcXHVERENEXFx1REREQlxcdUREREQtXFx1RERERlxcdURFMzgtXFx1REUzRFxcdURFQTldfFxcdUQ4MDVbXFx1RENDNlxcdUREQzEtXFx1REREN1xcdURFNDEtXFx1REU0M1xcdURGM0MtXFx1REYzRV18XFx1RDgwOVtcXHVEQzcwLVxcdURDNzRdfFxcdUQ4MUFbXFx1REU2RVxcdURFNkZcXHVERUY1XFx1REYzNy1cXHVERjNCXFx1REY0NF18XFx1RDgyRlxcdURDOUZ8XFx1RDgzNltcXHVERTg3LVxcdURFOEJdKS8pO1xuXG5jb25zdCBwdW5jdHVhdGlvblRyYWlsaW5nID0gbmV3IFJlZ0V4cCgvKD86WyFcIiMkJSYnKCkqKyxcXC0uLzo7PD0+P0BbXFxdXFxcXF5fYHt8fX5cXHhBMVxceEE3XFx4QUJcXHhCNlxceEI3XFx4QkJcXHhCRlxcdTAzN0VcXHUwMzg3XFx1MDU1QS1cXHUwNTVGXFx1MDU4OVxcdTA1OEFcXHUwNUJFXFx1MDVDMFxcdTA1QzNcXHUwNUM2XFx1MDVGM1xcdTA1RjRcXHUwNjA5XFx1MDYwQVxcdTA2MENcXHUwNjBEXFx1MDYxQlxcdTA2MUVcXHUwNjFGXFx1MDY2QS1cXHUwNjZEXFx1MDZENFxcdTA3MDAtXFx1MDcwRFxcdTA3RjctXFx1MDdGOVxcdTA4MzAtXFx1MDgzRVxcdTA4NUVcXHUwOTY0XFx1MDk2NVxcdTA5NzBcXHUwQUYwXFx1MERGNFxcdTBFNEZcXHUwRTVBXFx1MEU1QlxcdTBGMDQtXFx1MEYxMlxcdTBGMTRcXHUwRjNBLVxcdTBGM0RcXHUwRjg1XFx1MEZEMC1cXHUwRkQ0XFx1MEZEOVxcdTBGREFcXHUxMDRBLVxcdTEwNEZcXHUxMEZCXFx1MTM2MC1cXHUxMzY4XFx1MTQwMFxcdTE2NkRcXHUxNjZFXFx1MTY5QlxcdTE2OUNcXHUxNkVCLVxcdTE2RURcXHUxNzM1XFx1MTczNlxcdTE3RDQtXFx1MTdENlxcdTE3RDgtXFx1MTdEQVxcdTE4MDAtXFx1MTgwQVxcdTE5NDRcXHUxOTQ1XFx1MUExRVxcdTFBMUZcXHUxQUEwLVxcdTFBQTZcXHUxQUE4LVxcdTFBQURcXHUxQjVBLVxcdTFCNjBcXHUxQkZDLVxcdTFCRkZcXHUxQzNCLVxcdTFDM0ZcXHUxQzdFXFx1MUM3RlxcdTFDQzAtXFx1MUNDN1xcdTFDRDNcXHUyMDEwLVxcdTIwMjdcXHUyMDMwLVxcdTIwNDNcXHUyMDQ1LVxcdTIwNTFcXHUyMDUzLVxcdTIwNUVcXHUyMDdEXFx1MjA3RVxcdTIwOERcXHUyMDhFXFx1MjMwOC1cXHUyMzBCXFx1MjMyOVxcdTIzMkFcXHUyNzY4LVxcdTI3NzVcXHUyN0M1XFx1MjdDNlxcdTI3RTYtXFx1MjdFRlxcdTI5ODMtXFx1Mjk5OFxcdTI5RDgtXFx1MjlEQlxcdTI5RkNcXHUyOUZEXFx1MkNGOS1cXHUyQ0ZDXFx1MkNGRVxcdTJDRkZcXHUyRDcwXFx1MkUwMC1cXHUyRTJFXFx1MkUzMC1cXHUyRTQyXFx1MzAwMS1cXHUzMDAzXFx1MzAwOC1cXHUzMDExXFx1MzAxNC1cXHUzMDFGXFx1MzAzMFxcdTMwM0RcXHUzMEEwXFx1MzBGQlxcdUE0RkVcXHVBNEZGXFx1QTYwRC1cXHVBNjBGXFx1QTY3M1xcdUE2N0VcXHVBNkYyLVxcdUE2RjdcXHVBODc0LVxcdUE4NzdcXHVBOENFXFx1QThDRlxcdUE4RjgtXFx1QThGQVxcdUE4RkNcXHVBOTJFXFx1QTkyRlxcdUE5NUZcXHVBOUMxLVxcdUE5Q0RcXHVBOURFXFx1QTlERlxcdUFBNUMtXFx1QUE1RlxcdUFBREVcXHVBQURGXFx1QUFGMFxcdUFBRjFcXHVBQkVCXFx1RkQzRVxcdUZEM0ZcXHVGRTEwLVxcdUZFMTlcXHVGRTMwLVxcdUZFNTJcXHVGRTU0LVxcdUZFNjFcXHVGRTYzXFx1RkU2OFxcdUZFNkFcXHVGRTZCXFx1RkYwMS1cXHVGRjAzXFx1RkYwNS1cXHVGRjBBXFx1RkYwQy1cXHVGRjBGXFx1RkYxQVxcdUZGMUJcXHVGRjFGXFx1RkYyMFxcdUZGM0ItXFx1RkYzRFxcdUZGM0ZcXHVGRjVCXFx1RkY1RFxcdUZGNUYtXFx1RkY2NV18XFx1RDgwMFtcXHVERDAwLVxcdUREMDJcXHVERjlGXFx1REZEMF18XFx1RDgwMVxcdURENkZ8XFx1RDgwMltcXHVEQzU3XFx1REQxRlxcdUREM0ZcXHVERTUwLVxcdURFNThcXHVERTdGXFx1REVGMC1cXHVERUY2XFx1REYzOS1cXHVERjNGXFx1REY5OS1cXHVERjlDXXxcXHVEODA0W1xcdURDNDctXFx1REM0RFxcdURDQkJcXHVEQ0JDXFx1RENCRS1cXHVEQ0MxXFx1REQ0MC1cXHVERDQzXFx1REQ3NFxcdURENzVcXHVEREM1LVxcdUREQzlcXHVERENEXFx1REREQlxcdUREREQtXFx1RERERlxcdURFMzgtXFx1REUzRFxcdURFQTldfFxcdUQ4MDVbXFx1RENDNlxcdUREQzEtXFx1REREN1xcdURFNDEtXFx1REU0M1xcdURGM0MtXFx1REYzRV18XFx1RDgwOVtcXHVEQzcwLVxcdURDNzRdfFxcdUQ4MUFbXFx1REU2RVxcdURFNkZcXHVERUY1XFx1REYzNy1cXHVERjNCXFx1REY0NF18XFx1RDgyRlxcdURDOUZ8XFx1RDgzNltcXHVERTg3LVxcdURFOEJdKSQvKTtcblxuLy8gZXhwb3J0IGNvbnN0IGlubGluZVRyaWdnZXJDaGFycyA9IG5ldyBSZWdFeHAoYFske3JlcGxhY2VtZW50cy5UcmlnZ2VyQ2hhcnN9XWApO1xuXG4vKipcbiAqIFRoaXMgaXMgQ29tbW9uTWFyaydzIGJsb2NrIGdyYW1tYXIsIGJ1dCB3ZSdyZSBpZ25vcmluZyBuZXN0ZWQgYmxvY2tzIGhlcmUuICBcbiAqLyBcbmNvbnN0IGxpbmVHcmFtbWFyID0geyBcbiAgVE1IMTogeyBcbiAgICByZWdleHA6IC9eKCB7MCwzfSNcXHMpKC4qPykoKD86XFxzKyMrXFxzKik/KSQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTUgxXCI+JDE8L3NwYW4+JCQyPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNSDFcIj4kMzwvc3Bhbj4nXG4gIH0sXG4gIFRNSDI6IHsgXG4gICAgcmVnZXhwOiAvXiggezAsM30jI1xccykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIFxuICAgIHJlcGxhY2VtZW50OiAnPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNSDJcIj4kMTwvc3Bhbj4kJDI8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1IMlwiPiQzPC9zcGFuPidcbiAgfSxcbiAgVE1IMzogeyBcbiAgICByZWdleHA6IC9eKCB7MCwzfSMjI1xccykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIFxuICAgIHJlcGxhY2VtZW50OiAnPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNSDNcIj4kMTwvc3Bhbj4kJDI8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1IM1wiPiQzPC9zcGFuPidcbiAgfSxcbiAgVE1INDogeyBcbiAgICByZWdleHA6IC9eKCB7MCwzfSMjIyNcXHMpKC4qPykoKD86XFxzKyMrXFxzKik/KSQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTUg0XCI+JDE8L3NwYW4+JCQyPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNSDRcIj4kMzwvc3Bhbj4nXG4gIH0sXG4gIFRNSDU6IHsgXG4gICAgcmVnZXhwOiAvXiggezAsM30jIyMjI1xccykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIFxuICAgIHJlcGxhY2VtZW50OiAnPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNSDVcIj4kMTwvc3Bhbj4kJDI8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1INVwiPiQzPC9zcGFuPidcbiAgfSxcbiAgVE1INjogeyBcbiAgICByZWdleHA6IC9eKCB7MCwzfSMjIyMjI1xccykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIFxuICAgIHJlcGxhY2VtZW50OiAnPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNSDZcIj4kMTwvc3Bhbj4kJDI8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1INlwiPiQzPC9zcGFuPidcbiAgfSxcbiAgVE1CbG9ja3F1b3RlOiB7IFxuICAgIHJlZ2V4cDogL14oIHswLDN9PlsgXT8pKC4qKSQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTUJsb2NrcXVvdGVcIj4kMTwvc3Bhbj4kJDInXG4gIH0sXG4gIFRNQ29kZUZlbmNlQmFja3RpY2tPcGVuOiB7IFxuICAgIHJlZ2V4cDogL14oIHswLDN9KD88c2VxPmBgYGAqKVxccyopKFteYF0qPykoXFxzKikkLywgXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1Db2RlRmVuY2VCYWNrdGlja1wiPiQxPC9zcGFuPjxzcGFuIGNsYXNzPVwiVE1JbmZvU3RyaW5nXCI+JDM8L3NwYW4+JDQnXG4gIH0sXG4gIFRNQ29kZUZlbmNlVGlsZGVPcGVuOiB7IFxuICAgIHJlZ2V4cDogL14oIHswLDN9KD88c2VxPn5+fn4qKVxccyopKC4qPykoXFxzKikkLywgXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1Db2RlRmVuY2VUaWxkZVwiPiQxPC9zcGFuPjxzcGFuIGNsYXNzPVwiVE1JbmZvU3RyaW5nXCI+JDM8L3NwYW4+JDQnXG4gIH0sXG4gIFRNQ29kZUZlbmNlQmFja3RpY2tDbG9zZTogeyBcbiAgICByZWdleHA6IC9eKCB7MCwzfSg/PHNlcT5gYGBgKikpKFxccyopJC8sIFxuICAgIHJlcGxhY2VtZW50OiAnPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNQ29kZUZlbmNlQmFja3RpY2tcIj4kMTwvc3Bhbj4kMydcbiAgfSxcbiAgVE1Db2RlRmVuY2VUaWxkZUNsb3NlOiB7IFxuICAgIHJlZ2V4cDogL14oIHswLDN9KD88c2VxPn5+fn4qKSkoXFxzKikkLywgXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1Db2RlRmVuY2VUaWxkZVwiPiQxPC9zcGFuPiQzJ1xuICB9LFxuICBUTUJsYW5rTGluZTogeyBcbiAgICByZWdleHA6IC9eKFsgXFx0XSopJC8sIFxuICAgIHJlcGxhY2VtZW50OiAnJDAnXG4gIH0sXG4gIFRNU2V0ZXh0SDFNYXJrZXI6IHsgXG4gICAgcmVnZXhwOiAvXiB7MCwzfT0rXFxzKiQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTVNldGV4dEgxTWFya2VyXCI+JDA8L3NwYW4+J1xuICB9LFxuICBUTVNldGV4dEgyTWFya2VyOiB7IFxuICAgIHJlZ2V4cDogL14gezAsM30tK1xccyokLywgXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1TZXRleHRIMU1hcmtlclwiPiQwPC9zcGFuPidcbiAgfSxcbiAgVE1IUjogeyBcbiAgICByZWdleHA6IC9eKCB7MCwzfShcXCpbIFxcdF0qXFwqWyBcXHRdKlxcKlsgXFx0Kl0qKXwoLVsgXFx0XSotWyBcXHRdKi1bIFxcdC1dKil8KF9bIFxcdF0qX1sgXFx0XSpfWyBcXHRfXSopKSQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTUhSXCI+JDA8L3NwYW4+J1xuICB9LFxuICBUTVVMOiB7IFxuICAgIHJlZ2V4cDogL14oIHswLDN9WysqLV0gezEsNH0pKC4qKSQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTVVMXCI+JDE8L3NwYW4+JCQyJ1xuICB9LFxuICBUTU9MOiB7IFxuICAgIHJlZ2V4cDogL14oIHswLDN9XFxkezEsOX1bLildIHsxLDR9KSguKikkLywgXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1PTFwiPiQxPC9zcGFuPiQkMidcbiAgfSxcbiAgLy8gVE9ETzogVGhpcyBpcyBjdXJyZW50bHkgcHJldmVudGluZyBzdWJsaXN0cyAoYW5kIGFueSBjb250ZW50IHdpdGhpbiBsaXN0IGl0ZW1zLCByZWFsbHkpIGZyb20gd29ya2luZ1xuICBUTUluZGVudGVkQ29kZTogeyBcbiAgICByZWdleHA6IC9eKCB7NH18XFx0KSguKikkLywgXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1JbmRlbnRlZENvZGVcIj4kMTwvc3Bhbj4kMidcbiAgfSxcbiAgVE1MaW5rUmVmZXJlbmNlRGVmaW5pdGlvbjoge1xuICAgIC8vIFRPRE86IExpbmsgZGVzdGluYXRpb24gY2FuJ3QgaW5jbHVkZSB1bmJhbGFuY2VkIHBhcmFudGhlc2VzLCBidXQgd2UganVzdCBpZ25vcmUgdGhhdCBoZXJlIFxuICAgIHJlZ2V4cDogL14oIHswLDN9XFxbXFxzKikoW15cXHNcXF1dKD86W15cXF1dfFxcXFxcXF0pKj8pKFxccypcXF06XFxzKikoKD86W15cXHM8Pl0rKXwoPzo8KD86W148PlxcXFxdfFxcXFwuKSo+KSk/KFxccyopKCg/OlxcKCg/OlteKClcXFxcXXxcXFxcLikqXFwpKXwoPzpcIig/OlteXCJcXFxcXXxcXFxcLikqXCIpfCg/OicoPzpbXidcXFxcXXxcXFxcLikqJykpPyhcXHMqKSQvLCBcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTUxpbmtSZWZlcmVuY2VEZWZpbml0aW9uXCI+JDE8L3NwYW4+PHNwYW4gY2xhc3M9XCJUTUxpbmtMYWJlbCBUTUxpbmtMYWJlbF9EZWZpbml0aW9uXCI+JDI8L3NwYW4+PHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNTGlua1JlZmVyZW5jZURlZmluaXRpb25cIj4kMzwvc3Bhbj48c3BhbiBjbGFzcz1cIlRNTGlua0Rlc3RpbmF0aW9uXCI+JDQ8L3NwYW4+JDU8c3BhbiBjbGFzcz1cIlRNTGlua1RpdGxlXCI+JDY8L3NwYW4+JDcnLFxuICAgIGxhYmVsUGxhY2Vob2xkZXI6IDIsIC8vIHRoaXMgZGVmaW5lcyB3aGljaCBwbGFjZWhvbGRlciBpbiB0aGUgYWJvdmUgcmVnZXggaXMgdGhlIGxpbmsgXCJsYWJlbFwiXG4gIH0sXG59O1xuXG4vKipcbiAqIEhUTUwgYmxvY2tzIGhhdmUgbXVsdGlwbGUgZGlmZmVyZW50IGNsYXNzZXMgb2Ygb3BlbmVyIGFuZCBjbG9zZXIuIFRoaXMgYXJyYXkgZGVmaW5lcyBhbGwgdGhlIGNhc2VzXG4gKi9cbnZhciBodG1sQmxvY2tHcmFtbWFyID0gW1xuICB7IHN0YXJ0OiAvXiB7MCwzfTwoPzpzY3JpcHR8cHJlfHN0eWxlKSg/Olxcc3w+fCQpL2ksIGVuZDogLyg/OjxcXC9zY3JpcHQ+fDxcXC9wcmU+fDxcXC9zdHlsZT4pL2ksIHBhcmFJbnRlcnJ1cHQ6IHRydWUgfSxcbiAgeyBzdGFydDogL14gezAsM308IS0tLywgZW5kOiAvLS0+LywgcGFyYUludGVycnVwdDogdHJ1ZSB9LFxuICB7IHN0YXJ0OiAvXiB7MCwzfTxcXD8vLCBlbmQ6IC9cXD8+LywgcGFyYUludGVycnVwdDogdHJ1ZSB9LFxuICB7IHN0YXJ0OiAvXiB7MCwzfTwhW0EtWl0vLCBlbmQ6IC8+LywgcGFyYUludGVycnVwdCA6IHRydWV9LFxuICB7IHN0YXJ0OiAvXiB7MCwzfTwhXFxbQ0RBVEFcXFsvLCBlbmQ6IC9cXF1cXF0+LywgcGFyYUludGVycnVwdCA6IHRydWV9LFxuICB7IHN0YXJ0OiAvXiB7MCwzfSg/Ojx8PFxcLykoPzpLbm93blRhZykoPzpcXHN8PnxcXC8+fCQpL2ksIGVuZDogZmFsc2UsIHBhcmFJbnRlcnJ1cHQ6IHRydWV9LFxuICB7IHN0YXJ0OiAvXiB7MCwzfSg/OkhUTUxPcGVuVGFnfEhUTUxDbG9zZVRhZylcXHMqJC8sIGVuZDogZmFsc2UsIHBhcmFJbnRlcnJ1cHQ6IGZhbHNlfSxcbl07XG5cbi8qKlxuICogU3RydWN0dXJlIG9mIHRoZSBvYmplY3Q6XG4gKiBUb3AgbGV2ZWwgZW50cmllcyBhcmUgcnVsZXMsIGVhY2ggY29uc2lzdGluZyBvZiBhIHJlZ3VsYXIgZXhwcmVzc2lvbnMgKGluIHN0cmluZyBmb3JtYXQpIGFzIHdlbGwgYXMgYSByZXBsYWNlbWVudC5cbiAqIEluIHRoZSByZWd1bGFyIGV4cHJlc3Npb25zLCByZXBsYWNlbWVudHMgZnJvbSB0aGUgb2JqZWN0ICdyZXBsYWNlbWVudHMnIHdpbGwgYmUgcHJvY2Vzc2VkIGJlZm9yZSBjb21waWxpbmcgaW50byB0aGUgcHJvcGVydHkgcmVnZXhwLlxuICovXG52YXIgaW5saW5lR3JhbW1hciA9IHtcbiAgZXNjYXBlIDoge1xuICAgIHJlZ2V4cDogL15cXFxcKEFTQ0lJUHVuY3R1YXRpb24pLyxcbiAgICByZXBsYWNlbWVudCA6ICc8c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1Fc2NhcGVcIj5cXFxcPC9zcGFuPiQxJ1xuICB9LFxuICBjb2RlIDoge1xuICAgIHJlZ2V4cDogL14oYCspKCg/OlteYF0pfCg/OlteYF0uKj9bXmBdKSkoXFwxKS8sXG4gICAgcmVwbGFjZW1lbnQgOiAnPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNQ29kZVwiPiQxPC9zcGFuPjxjb2RlIGNsYXNzPVwiVE1Db2RlXCI+JDI8L2NvZGU+PHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrX1RNQ29kZVwiPiQzPC9zcGFuPicgXG4gIH0sXG4gIGF1dG9saW5rIDoge1xuICAgIHJlZ2V4cDogL148KCg/OlNjaGVtZTpbXlxcczw+XSopfCg/OkVtYWlsKSk+LyxcbiAgICByZXBsYWNlbWVudDogJzxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya19UTUF1dG9saW5rXCI+Jmx0Ozwvc3Bhbj48c3BhbiBjbGFzcz1cIlRNQXV0b2xpbmtcIj4kMTwvc3Bhbj48c3BhbiBjbGFzcz1cIlRNTWFyayBUTU1hcmtfVE1BdXRvbGlua1wiPiZndDs8L3NwYW4+J1xuICB9LFxuICBodG1sIDoge1xuICAgIHJlZ2V4cDogL14oKD86SFRNTE9wZW5UYWcpfCg/OkhUTUxDbG9zZVRhZyl8KD86SFRNTENvbW1lbnQpfCg/OkhUTUxQSSl8KD86SFRNTERlY2xhcmF0aW9uKXwoPzpIVE1MQ0RBVEEpKS8sXG4gICAgcmVwbGFjZW1lbnQ6ICc8c3BhbiBjbGFzcz1cIlRNSFRNTFwiPiQxPC9zcGFuPicsXG4gIH0sXG4gIGxpbmtPcGVuIDoge1xuICAgIHJlZ2V4cDogL15cXFsvLFxuICAgIHJlcGxhY2VtZW50OiAnJ1xuICB9LFxuICBpbWFnZU9wZW4gOiB7XG4gICAgcmVnZXhwOiAvXiFcXFsvLFxuICAgIHJlcGxhY2VtZW50IDogJydcbiAgfSxcbiAgbGlua0xhYmVsIDoge1xuICAgIHJlZ2V4cDogL14oXFxbXFxzKikoW15cXF1dKj8pKFxccypcXF0pLyxcbiAgICByZXBsYWNlbWVudDogJycsXG4gICAgbGFiZWxQbGFjZWhvbGRlcjogMlxuICB9LFxuICBkZWZhdWx0IDoge1xuICAgIHJlZ2V4cDogL14oLnwoPzpOb3RUcmlnZ2VyQ2hhcispKS8sXG4gICAgcmVwbGFjZW1lbnQ6ICckMSdcbiAgfVxufTtcblxuLy8gUHJvY2VzcyByZXBsYWNlbWVudHMgaW4gcmVnZXhwc1xuY29uc3QgcmVwbGFjZW1lbnRSZWdleHAgPSBuZXcgUmVnRXhwKE9iamVjdC5rZXlzKHJlcGxhY2VtZW50cykuam9pbignfCcpKTtcblxuLy8gSW5saW5lXG5jb25zdCBpbmxpbmVSdWxlcyA9Wy4uLk9iamVjdC5rZXlzKGlubGluZUdyYW1tYXIpXTtcbmZvciAobGV0IHJ1bGUgb2YgaW5saW5lUnVsZXMpIHtcbiAgbGV0IHJlID0gaW5saW5lR3JhbW1hcltydWxlXS5yZWdleHAuc291cmNlO1xuICAvLyBSZXBsYWNlIHdoaWxlIHRoZXJlIGlzIHNvbWV0aGluZyB0byByZXBsYWNlLiBUaGlzIG1lYW5zIGl0IGFsc28gd29ya3Mgb3ZlciBtdWx0aXBsZSBsZXZlbHMgKHJlcGxhY2VtZW50cyBjb250YWluaW5nIHJlcGxhY2VtZW50cylcbiAgd2hpbGUgKHJlLm1hdGNoKHJlcGxhY2VtZW50UmVnZXhwKSkge1xuICAgIHJlID0gcmUucmVwbGFjZShyZXBsYWNlbWVudFJlZ2V4cCwgKHN0cmluZykgPT4geyByZXR1cm4gcmVwbGFjZW1lbnRzW3N0cmluZ10uc291cmNlOyB9KTtcbiAgfVxuICBpbmxpbmVHcmFtbWFyW3J1bGVdLnJlZ2V4cCA9IG5ldyBSZWdFeHAocmUsIGlubGluZUdyYW1tYXJbcnVsZV0ucmVnZXhwLmZsYWdzKTtcbn1cblxuLy8gSFRNTCBCbG9jayAob25seSBvcGVuaW5nIHJ1bGUgaXMgcHJvY2Vzc2VkIGN1cnJlbnRseSlcbmZvciAobGV0IHJ1bGUgb2YgaHRtbEJsb2NrR3JhbW1hcikge1xuICBsZXQgcmUgPSBydWxlLnN0YXJ0LnNvdXJjZTtcbiAgLy8gUmVwbGFjZSB3aGlsZSB0aGVyZSBpcyBzb21ldGhpbmcgdG8gcmVwbGFjZS4gVGhpcyBtZWFucyBpdCBhbHNvIHdvcmtzIG92ZXIgbXVsdGlwbGUgbGV2ZWxzIChyZXBsYWNlbWVudHMgY29udGFpbmluZyByZXBsYWNlbWVudHMpXG4gIHdoaWxlIChyZS5tYXRjaChyZXBsYWNlbWVudFJlZ2V4cCkpIHtcbiAgICByZSA9IHJlLnJlcGxhY2UocmVwbGFjZW1lbnRSZWdleHAsIChzdHJpbmcpID0+IHsgcmV0dXJuIHJlcGxhY2VtZW50c1tzdHJpbmddLnNvdXJjZTsgfSk7XG4gIH1cbiAgcnVsZS5zdGFydCA9IG5ldyBSZWdFeHAocmUsIHJ1bGUuc3RhcnQuZmxhZ3MpO1xufVxuXG4vKipcbiAqIEVzY2FwZXMgSFRNTCBzcGVjaWFsIGNoYXJhY3RlcnMgKDwsID4sIGFuZCAmKSBpbiB0aGUgc3RyaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgcmF3IHN0cmluZyB0byBiZSBlc2NhcGVkXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgc3RyaW5nLCByZWFkeSB0byBiZSB1c2VkIGluIEhUTUxcbiAqL1xuZnVuY3Rpb24gaHRtbGVzY2FwZShzdHJpbmcpIHtcbiAgcmV0dXJuIChzdHJpbmcgPyBzdHJpbmcgOiAnJylcbiAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgIC5yZXBsYWNlKC88L2csICcmbHQ7JylcbiAgICAucmVwbGFjZSgvPi9nLCAnJmd0OycpO1xufVxuLyoqXG4gKiBDb250YWlucyB0aGUgY29tbWFuZHMgdGhhdCBjYW4gYmUgc2VudCB0byB0aGUgZWRpdG9yLiBDb250YWlucyBvYmplY3RzIHdpdGggYSBuYW1lIHJlcHJlc2VudGluZyB0aGUgbmFtZSBvZiB0aGUgY29tbWFuZC5cbiAqIEVhY2ggb2YgdGhlIG9iamVjdHMgY29udGFpbnMgdGhlIGZvbGxvd2luZyBrZXlzOlxuICogXG4gKiAgIC0gdHlwZTogQ2FuIGJlIGVpdGhlciBpbmxpbmUgKGZvciBpbmxpbmUgZm9ybWF0dGluZykgb3IgbGluZSAoZm9yIGJsb2NrIC8gbGluZSBmb3JtYXR0aW5nKS5cbiAqICAgLSBjbGFzc05hbWU6IFVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGNvbW1hbmQgaXMgYWN0aXZlIGF0IGEgZ2l2ZW4gcG9zaXRpb24uIFxuICogICAgIEZvciBsaW5lIGZvcm1hdHRpbmcsIHRoaXMgbG9va3MgYXQgdGhlIGNsYXNzIG9mIHRoZSBsaW5lIGVsZW1lbnQuIEZvciBpbmxpbmUgZWxlbWVudHMsIHRyaWVzIHRvIGZpbmQgYW4gZW5jbG9zaW5nIGVsZW1lbnQgd2l0aCB0aGF0IGNsYXNzLlxuICogICAtIHNldCAvIHVuc2V0OiBDb250YWluIGluc3RydWN0aW9ucyBob3cgdG8gc2V0IGFuZCB1bnNldCB0aGUgY29tbWFuZC4gRm9yIGxpbmUgdHlwZSBjb21tYW5kcywgYm90aCBjb25zaXN0IG9mIGEgcGF0dGVybiBhbmQgcmVwbGFjZW1lbnQgdGhhdCBcbiAqICAgICB3aWxsIGJlIGFwcGxpZWQgdG8gZWFjaCBsaW5lICh1c2luZyBTdHJpbmcucmVwbGFjZSkuIEZvciBpbmxpbmUgdHlwZSBjb21tYW5kcywgdGhlIHNldCBvYmplY3QgY29udGFpbnMgYSBwcmUgYW5kIHBvc3Qgc3RyaW5nIHdoaWNoIHdpbGxcbiAqICAgICBiZSBpbnNlcnRlZCBiZWZvcmUgYW5kIGFmdGVyIHRoZSBzZWxlY3Rpb24uIFRoZSB1bnNldCBvYmplY3QgY29udGFpbnMgYSBwcmVQYXR0ZXJuIGFuZCBhIHBvc3RQYXR0ZXJuLiBCb3RoIHNob3VsZCBiZSByZWd1bGFyIGV4cHJlc3Npb25zIGFuZCBcbiAqICAgICB0aGV5IHdpbGwgYmUgYXBwbGllZCB0byB0aGUgcG9ydGlvbiBvZiB0aGUgbGluZSBiZWZvcmUgYW5kIGFmdGVyIHRoZSBzZWxlY3Rpb24gKHVzaW5nIFN0cmluZy5yZXBsYWNlLCB3aXRoIGFuIGVtcHR5IHJlcGxhY2VtZW50IHN0cmluZykuXG4gKi9cbmNvbnN0IGNvbW1hbmRzID0ge1xuICAvLyBSZXBsYWNlbWVudHMgZm9yIHVuc2V0IGZvciBpbmxpbmUgY29tbWFuZHMgYXJlICcnIGJ5IGRlZmF1bHRcbiAgYm9sZDoge1xuICAgIHR5cGU6ICdpbmxpbmUnLCBcbiAgICBjbGFzc05hbWU6ICdUTVN0cm9uZycsIFxuICAgIHNldDoge3ByZTogJyoqJywgcG9zdDogJyoqJ30sIFxuICAgIHVuc2V0OiB7cHJlUGF0dGVybjogLyg/OlxcKlxcKnxfXykkLywgcG9zdFBhdHRlcm46IC9eKD86XFwqXFwqfF9fKS99XG4gIH0sIFxuICBpdGFsaWM6IHtcbiAgICB0eXBlOiAnaW5saW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1FbScsIFxuICAgIHNldDoge3ByZTogJyonLCBwb3N0OiAnKid9LCBcbiAgICB1bnNldDoge3ByZVBhdHRlcm46IC8oPzpcXCp8XykkLywgcG9zdFBhdHRlcm46IC9eKD86XFwqfF8pL31cbiAgfSxcbiAgY29kZToge1xuICAgIHR5cGU6ICdpbmxpbmUnLCBcbiAgICBjbGFzc05hbWU6ICdUTUNvZGUnLCBcbiAgICBzZXQ6IHtwcmU6ICdgJywgcG9zdDogJ2AnfSwgXG4gICAgdW5zZXQ6IHtwcmVQYXR0ZXJuOiAvYCskLywgcG9zdFBhdHRlcm46IC9eYCsvfSAvLyBGSVhNRSB0aGlzIGRvZXNuJ3QgZW5zdXJlIGJhbGFuY2VkIGJhY2t0aWNrcyByaWdodCBub3dcbiAgfSwgXG4gIHN0cmlrZXRocm91Z2g6IHtcbiAgICB0eXBlOiAnaW5saW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1TdHJpa2V0aHJvdWdoJywgXG4gICAgc2V0OiB7cHJlOiAnfn4nLCBwb3N0OiAnfn4nfSwgXG4gICAgdW5zZXQ6IHtwcmVQYXR0ZXJuOi9+fiQvLCBwb3N0UGF0dGVybjogL15+fi8gfVxuICB9LFxuICBoMToge1xuICAgIHR5cGU6ICdsaW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1IMScsIFxuICAgIHNldDoge3BhdHRlcm46IC9eKCB7MCwzfSg/Oig/OiMrfFswLTldezEsOX1bKS5dfFs+XFwtKitdKVxccyspPykoLiopJC8sIHJlcGxhY2VtZW50OiAnIyAkMid9LCBcbiAgICB1bnNldDoge3BhdHRlcm46IC9eKCB7MCwzfSNcXHMrKSguKj8pKCg/OlxccysjK1xccyopPykkLywgcmVwbGFjZW1lbnQ6ICckMid9XG4gIH0sXG4gIGgyOiB7XG4gICAgdHlwZTogJ2xpbmUnLCBcbiAgICBjbGFzc05hbWU6ICdUTUgyJywgXG4gICAgc2V0OiB7cGF0dGVybjogL14oIHswLDN9KD86KD86Iyt8WzAtOV17MSw5fVspLl18Wz5cXC0qK10pXFxzKyk/KSguKikkLywgcmVwbGFjZW1lbnQ6ICcjIyAkMid9LCBcbiAgICB1bnNldDoge3BhdHRlcm46IC9eKCB7MCwzfSMjXFxzKykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIHJlcGxhY2VtZW50OiAnJDInfVxuICB9LFxuICBoMzoge1xuICAgIHR5cGU6ICdsaW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1IMycsIFxuICAgIHNldDoge3BhdHRlcm46IC9eKCB7MCwzfSg/Oig/OiMrfFswLTldezEsOX1bKS5dfFs+XFwtKitdKVxccyspPykoLiopJC8sIHJlcGxhY2VtZW50OiAnIyMjICQyJ30sIFxuICAgIHVuc2V0OiB7cGF0dGVybjogL14oIHswLDN9IyMjXFxzKykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIHJlcGxhY2VtZW50OiAnJDInfVxuICB9LFxuICBoNDoge1xuICAgIHR5cGU6ICdsaW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1INCcsIFxuICAgIHNldDoge3BhdHRlcm46IC9eKCB7MCwzfSg/Oig/OiMrfFswLTldezEsOX1bKS5dfFs+XFwtKitdKVxccyspPykoLiopJC8sIHJlcGxhY2VtZW50OiAnIyMjIyAkMid9LCBcbiAgICB1bnNldDoge3BhdHRlcm46IC9eKCB7MCwzfSMjIyNcXHMrKSguKj8pKCg/OlxccysjK1xccyopPykkLywgcmVwbGFjZW1lbnQ6ICckMid9XG4gIH0sXG4gIGg1OiB7XG4gICAgdHlwZTogJ2xpbmUnLCBcbiAgICBjbGFzc05hbWU6ICdUTUg1JywgXG4gICAgc2V0OiB7cGF0dGVybjogL14oIHswLDN9KD86KD86Iyt8WzAtOV17MSw5fVspLl18Wz5cXC0qK10pXFxzKyk/KSguKikkLywgcmVwbGFjZW1lbnQ6ICcjIyMjIyAkMid9LCBcbiAgICB1bnNldDoge3BhdHRlcm46IC9eKCB7MCwzfSMjIyMjXFxzKykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIHJlcGxhY2VtZW50OiAnJDInfVxuICB9LFxuICBoNjoge1xuICAgIHR5cGU6ICdsaW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1INicsIFxuICAgIHNldDoge3BhdHRlcm46IC9eKCB7MCwzfSg/Oig/OiMrfFswLTldezEsOX1bKS5dfFs+XFwtKitdKVxccyspPykoLiopJC8sIHJlcGxhY2VtZW50OiAnIyMjIyMjICQyJ30sIFxuICAgIHVuc2V0OiB7cGF0dGVybjogL14oIHswLDN9IyMjIyMjXFxzKykoLio/KSgoPzpcXHMrIytcXHMqKT8pJC8sIHJlcGxhY2VtZW50OiAnJDInfVxuICB9LFxuICB1bDoge1xuICAgIHR5cGU6ICdsaW5lJywgXG4gICAgY2xhc3NOYW1lOiAnVE1VTCcsIFxuICAgIHNldDoge3BhdHRlcm46IC9eKCB7MCwzfSg/Oig/OiMrfFswLTldezEsOX1bKS5dfFs+XFwtKitdKVxccyspPykoLiopJC8sIHJlcGxhY2VtZW50OiAnLSAkMid9LCBcbiAgICB1bnNldDoge3BhdHRlcm46IC9eKCB7MCwzfVsrKi1dIHsxLDR9KSguKikkLywgcmVwbGFjZW1lbnQ6ICckMid9XG4gIH0sXG4gIG9sOiB7XG4gICAgdHlwZTogJ2xpbmUnLCBcbiAgICBjbGFzc05hbWU6ICdUTU9MJywgXG4gICAgc2V0OiB7cGF0dGVybjogL14oIHswLDN9KD86KD86Iyt8WzAtOV17MSw5fVspLl18Wz5cXC0qK10pXFxzKyk/KSguKikkLywgcmVwbGFjZW1lbnQ6ICckIy4gJDInfSwgXG4gICAgdW5zZXQ6IHtwYXR0ZXJuOiAvXiggezAsM31cXGR7MSw5fVsuKV0gezEsNH0pKC4qKSQvLCByZXBsYWNlbWVudDogJyQyJ31cbiAgfSwgXG4gIGJsb2NrcXVvdGU6IHtcbiAgICB0eXBlOiAnbGluZScsIFxuICAgIGNsYXNzTmFtZTogJ1RNQmxvY2txdW90ZScsIFxuICAgIHNldDoge3BhdHRlcm46IC9eKCB7MCwzfSg/Oig/OiMrfFswLTldezEsOX1bKS5dfFs+XFwtKitdKVxccyspPykoLiopJC8sIHJlcGxhY2VtZW50OiAnPiAkMid9LCBcbiAgICB1bnNldDoge3BhdHRlcm46IC9eKCB7MCwzfT5bIF0/KSguKikkLywgcmVwbGFjZW1lbnQ6ICckMid9XG4gIH0sXG59O1xuXG5leHBvcnQgeyBsaW5lR3JhbW1hciwgaW5saW5lR3JhbW1hciwgcHVuY3R1YXRpb25MZWFkaW5nLCBwdW5jdHVhdGlvblRyYWlsaW5nLCBodG1sZXNjYXBlLCBodG1sQmxvY2tHcmFtbWFyLCBjb21tYW5kcyB9OyIsImltcG9ydCB7XG4gIGlubGluZUdyYW1tYXIsXG4gIGxpbmVHcmFtbWFyLFxuICBwdW5jdHVhdGlvbkxlYWRpbmcsXG4gIHB1bmN0dWF0aW9uVHJhaWxpbmcsXG4gIGh0bWxlc2NhcGUsXG4gIGh0bWxCbG9ja0dyYW1tYXIsXG4gIGNvbW1hbmRzLFxufSBmcm9tIFwiLi9ncmFtbWFyXCI7XG5cbmNsYXNzIEVkaXRvciB7XG4gIGNvbnN0cnVjdG9yKHByb3BzID0ge30pIHtcbiAgICB0aGlzLmUgPSBudWxsO1xuICAgIHRoaXMudGV4dGFyZWEgPSBudWxsO1xuICAgIHRoaXMubGluZXMgPSBbXTtcbiAgICB0aGlzLmxpbmVFbGVtZW50cyA9IFtdO1xuICAgIHRoaXMubGluZVR5cGVzID0gW107XG4gICAgdGhpcy5saW5lQ2FwdHVyZXMgPSBbXTtcbiAgICB0aGlzLmxpbmVSZXBsYWNlbWVudHMgPSBbXTtcbiAgICB0aGlzLmxpbmtMYWJlbHMgPSBbXTtcbiAgICB0aGlzLmxpbmVEaXJ0eSA9IFtdO1xuICAgIHRoaXMubGFzdENvbW1hbmRTdGF0ZSA9IG51bGw7XG5cbiAgICB0aGlzLmxpc3RlbmVycyA9IHtcbiAgICAgIGNoYW5nZTogW10sXG4gICAgICBzZWxlY3Rpb246IFtdLFxuICAgIH07XG5cbiAgICBsZXQgZWxlbWVudCA9IHByb3BzLmVsZW1lbnQ7XG4gICAgdGhpcy50ZXh0YXJlYSA9IHByb3BzLnRleHRhcmVhO1xuXG4gICAgaWYgKHRoaXMudGV4dGFyZWEpIHtcbiAgICAgIGlmICghdGhpcy50ZXh0YXJlYS50YWdOYW1lKSB7XG4gICAgICAgIHRoaXMudGV4dGFyZWEgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnRleHRhcmVhKTtcbiAgICAgIH1cbiAgICAgIGlmICghZWxlbWVudCkgZWxlbWVudCA9IHRoaXMudGV4dGFyZWE7XG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQgJiYgIWVsZW1lbnQudGFnTmFtZSkge1xuICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHByb3BzLmVsZW1lbnQpO1xuICAgIH1cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF07XG4gICAgfVxuICAgIGlmIChlbGVtZW50LnRhZ05hbWUgPT0gXCJURVhUQVJFQVwiKSB7XG4gICAgICB0aGlzLnRleHRhcmVhID0gZWxlbWVudDtcbiAgICAgIGVsZW1lbnQgPSB0aGlzLnRleHRhcmVhLnBhcmVudE5vZGU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dGFyZWEpIHtcbiAgICAgIHRoaXMudGV4dGFyZWEuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgIH1cblxuICAgIHRoaXMuY3JlYXRlRWRpdG9yRWxlbWVudChlbGVtZW50KTtcbiAgICAvLyBUT0RPIFBsYWNlaG9sZGVyIGZvciBlbXB0eSBjb250ZW50XG4gICAgdGhpcy5zZXRDb250ZW50KFxuICAgICAgcHJvcHMuY29udGVudCB8fFxuICAgICAgICAodGhpcy50ZXh0YXJlYVxuICAgICAgICAgID8gdGhpcy50ZXh0YXJlYS52YWx1ZVxuICAgICAgICAgIDogXCIjIEhlbGxvIFRpbnlNREUhXFxuRWRpdCAqKmhlcmUqKlwiKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgZWRpdG9yIGVsZW1lbnQgaW5zaWRlIHRoZSB0YXJnZXQgZWxlbWVudCBvZiB0aGUgRE9NIHRyZWVcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIHRhcmdldCBlbGVtZW50IG9mIHRoZSBET00gdHJlZVxuICAgKi9cbiAgY3JlYXRlRWRpdG9yRWxlbWVudChlbGVtZW50KSB7XG4gICAgdGhpcy5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICB0aGlzLmUuY2xhc3NOYW1lID0gXCJUaW55TURFXCI7XG4gICAgdGhpcy5lLmNvbnRlbnRFZGl0YWJsZSA9IHRydWU7XG4gICAgLy8gVGhlIGZvbGxvd2luZyBpcyBpbXBvcnRhbnQgZm9yIGZvcm1hdHRpbmcgcHVycG9zZXMsIGJ1dCBhbHNvIHNpbmNlIG90aGVyd2lzZSB0aGUgYnJvd3NlciByZXBsYWNlcyBzdWJzZXF1ZW50IHNwYWNlcyB3aXRoICAmbmJzcDsgJm5ic3A7XG4gICAgLy8gVGhhdCBicmVha3MgYSBsb3Qgb2Ygc3R1ZmYsIHNvIHdlIGRvIHRoaXMgaGVyZSBhbmQgbm90IGluIENTU+KAlHRoZXJlZm9yZSwgeW91IGRvbid0IGhhdmUgdG8gcmVtZW1iZXIgdG8gcHV0IHRoaXMgaW4gdGhlIENTUyBmaWxlXG4gICAgdGhpcy5lLnN0eWxlLndoaXRlU3BhY2UgPSBcInByZS13cmFwXCI7XG4gICAgLy8gQXZvaWQgZm9ybWF0dGluZyAoQiAvIEkgLyBVKSBwb3BwaW5nIHVwIG9uIGlPU1xuICAgIHRoaXMuZS5zdHlsZS53ZWJraXRVc2VyTW9kaWZ5ID0gXCJyZWFkLXdyaXRlLXBsYWludGV4dC1vbmx5XCI7XG4gICAgaWYgKFxuICAgICAgdGhpcy50ZXh0YXJlYSAmJlxuICAgICAgdGhpcy50ZXh0YXJlYS5wYXJlbnROb2RlID09IGVsZW1lbnQgJiZcbiAgICAgIHRoaXMudGV4dGFyZWEubmV4dFNpYmxpbmdcbiAgICApIHtcbiAgICAgIGVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRoaXMuZSwgdGhpcy50ZXh0YXJlYS5uZXh0U2libGluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5lKTtcbiAgICB9XG5cbiAgICB0aGlzLmUuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIChlKSA9PiB0aGlzLmhhbmRsZUlucHV0RXZlbnQoZSkpO1xuICAgIHRoaXMuZS5hZGRFdmVudExpc3RlbmVyKFwiY29tcG9zaXRpb25lbmRcIiwgKGUpID0+IHRoaXMuaGFuZGxlSW5wdXRFdmVudChlKSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCAoZSkgPT5cbiAgICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uQ2hhbmdlRXZlbnQoZSlcbiAgICApO1xuICAgIHRoaXMuZS5hZGRFdmVudExpc3RlbmVyKFwicGFzdGVcIiwgKGUpID0+IHRoaXMuaGFuZGxlUGFzdGUoZSkpO1xuICAgIHRoaXMubGluZUVsZW1lbnRzID0gdGhpcy5lLmNoaWxkTm9kZXM7IC8vIHRoaXMgd2lsbCBhdXRvbWF0aWNhbGx5IHVwZGF0ZVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGVkaXRvciBjb250ZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudCBUaGUgbmV3IE1hcmtkb3duIGNvbnRlbnRcbiAgICovXG4gIHNldENvbnRlbnQoY29udGVudCkge1xuICAgIC8vIERlbGV0ZSBhbnkgZXhpc3RpbmcgY29udGVudFxuICAgIHdoaWxlICh0aGlzLmUuZmlyc3RDaGlsZCkge1xuICAgICAgdGhpcy5lLnJlbW92ZUNoaWxkKHRoaXMuZS5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgdGhpcy5saW5lcyA9IGNvbnRlbnQuc3BsaXQoLyg/OlxcclxcbnxcXHJ8XFxuKS8pO1xuICAgIHRoaXMubGluZURpcnR5ID0gW107XG4gICAgZm9yIChsZXQgbGluZU51bSA9IDA7IGxpbmVOdW0gPCB0aGlzLmxpbmVzLmxlbmd0aDsgbGluZU51bSsrKSB7XG4gICAgICBsZXQgbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgdGhpcy5lLmFwcGVuZENoaWxkKGxlKTtcbiAgICAgIHRoaXMubGluZURpcnR5LnB1c2godHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMubGluZVR5cGVzID0gbmV3IEFycmF5KHRoaXMubGluZXMubGVuZ3RoKTtcbiAgICB0aGlzLnVwZGF0ZUZvcm1hdHRpbmcoKTtcbiAgICB0aGlzLmZpcmVDaGFuZ2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBlZGl0b3IgY29udGVudCBhcyBhIE1hcmtkb3duIHN0cmluZy5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGVkaXRvciBjb250ZW50IGFzIGEgbWFya2Rvd24gc3RyaW5nXG4gICAqL1xuICBnZXRDb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLmxpbmVzLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyB0aGUgbWFpbiBtZXRob2QgdG8gdXBkYXRlIHRoZSBmb3JtYXR0aW5nIChmcm9tIHRoaXMubGluZXMgdG8gSFRNTCBvdXRwdXQpXG4gICAqL1xuICB1cGRhdGVGb3JtYXR0aW5nKCkge1xuICAgIC8vIEZpcnN0LCBwYXJzZSBsaW5lIHR5cGVzLiBUaGlzIHdpbGwgdXBkYXRlIHRoaXMubGluZVR5cGVzLCB0aGlzLmxpbmVSZXBsYWNlbWVudHMsIGFuZCB0aGlzLmxpbmVDYXB0dXJlc1xuICAgIC8vIFdlIGRvbid0IGFwcGx5IHRoZSBmb3JtYXR0aW5nIHlldFxuICAgIHRoaXMudXBkYXRlTGluZVR5cGVzKCk7XG4gICAgLy8gQ29sbGVjdCBhbnkgdmFsaWQgbGluayBsYWJlbHMgZnJvbSBsaW5rIHJlZmVyZW5jZSBkZWZpbml0aW9uc+KAlHdlIG5lZWQgdGhhdCBmb3IgZm9ybWF0dGluZyB0byBkZXRlcm1pbmUgd2hhdCdzIGEgdmFsaWQgbGlua1xuICAgIHRoaXMudXBkYXRlTGlua0xhYmVscygpO1xuICAgIC8vIE5vdywgYXBwbHkgdGhlIGZvcm1hdHRpbmdcbiAgICB0aGlzLmFwcGx5TGluZVR5cGVzKCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGlzLmxpbmtMYWJlbHM6IEZvciBldmVyeSBsaW5rIHJlZmVyZW5jZSBkZWZpbml0aW9uIChsaW5lIHR5cGUgVE1MaW5rUmVmZXJlbmNlRGVmaW5pdGlvbiksIHdlIGNvbGxlY3QgdGhlIGxhYmVsXG4gICAqL1xuICB1cGRhdGVMaW5rTGFiZWxzKCkge1xuICAgIHRoaXMubGlua0xhYmVscyA9IFtdO1xuICAgIGZvciAobGV0IGwgPSAwOyBsIDwgdGhpcy5saW5lcy5sZW5ndGg7IGwrKykge1xuICAgICAgaWYgKHRoaXMubGluZVR5cGVzW2xdID09IFwiVE1MaW5rUmVmZXJlbmNlRGVmaW5pdGlvblwiKSB7XG4gICAgICAgIHRoaXMubGlua0xhYmVscy5wdXNoKFxuICAgICAgICAgIHRoaXMubGluZUNhcHR1cmVzW2xdW1xuICAgICAgICAgICAgbGluZUdyYW1tYXIuVE1MaW5rUmVmZXJlbmNlRGVmaW5pdGlvbi5sYWJlbFBsYWNlaG9sZGVyXG4gICAgICAgICAgXVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcmVwbGFjZSBwbGFjZWhvbGRlcnMgZnJvbSBhIFJlZ0V4cCBjYXB0dXJlLiBUaGUgcmVwbGFjZW1lbnQgc3RyaW5nIGNhbiBjb250YWluIHJlZ3VsYXIgZG9sbGFyIHBsYWNlaG9sZGVycyAoZS5nLiwgJDEpLFxuICAgKiB3aGljaCBhcmUgaW50ZXJwcmV0ZWQgbGlrZSBpbiBTdHJpbmcucmVwbGFjZSgpLCBidXQgYWxzbyBkb3VibGUgZG9sbGFyIHBsYWNlaG9sZGVycyAoJCQxKS4gSW4gdGhlIGNhc2Ugb2YgZG91YmxlIGRvbGxhciBwbGFjZWhvbGRlcnMsXG4gICAqIE1hcmtkb3duIGlubGluZSBncmFtbWFyIGlzIGFwcGxpZWQgb24gdGhlIGNvbnRlbnQgb2YgdGhlIGNhcHR1cmVkIHN1Ymdyb3VwLCBpLmUuLCAkJDEgcHJvY2Vzc2VzIGlubGluZSBNYXJrZG93biBncmFtbWFyIGluIHRoZSBjb250ZW50IG9mIHRoZVxuICAgKiBmaXJzdCBjYXB0dXJlZCBzdWJncm91cCwgYW5kIHJlcGxhY2VzIGAkJDFgIHdpdGggdGhlIHJlc3VsdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlcGxhY2VtZW50IFRoZSByZXBsYWNlbWVudCBzdHJpbmcsIGluY2x1ZGluZyBwbGFjZWhvbGRlcnMuXG4gICAqIEBwYXJhbSAgY2FwdHVyZSBUaGUgcmVzdWx0IG9mIGEgUmVnRXhwLmV4ZWMoKSBjYWxsXG4gICAqIEByZXR1cm5zIFRoZSByZXBsYWNlbWVudCBzdHJpbmcsIHdpdGggcGxhY2Vob2xkZXJzIHJlcGxhY2VkIGZyb20gdGhlIGNhcHR1cmUgcmVzdWx0LlxuICAgKi9cbiAgcmVwbGFjZShyZXBsYWNlbWVudCwgY2FwdHVyZSkge1xuICAgIHJldHVybiByZXBsYWNlbWVudC5yZXBsYWNlKC8oXFwkezEsMn0pKFswLTldKS9nLCAoc3RyLCBwMSwgcDIpID0+IHtcbiAgICAgIGlmIChwMSA9PSBcIiRcIikgcmV0dXJuIGh0bWxlc2NhcGUoY2FwdHVyZVtwMl0pO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gYDxzcGFuIGNsYXNzPVwiVE1JbmxpbmVGb3JtYXR0ZWRcIj4ke3RoaXMucHJvY2Vzc0lubGluZVN0eWxlcyhcbiAgICAgICAgICBjYXB0dXJlW3AyXVxuICAgICAgICApfTwvc3Bhbj5gO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgdGhlIGxpbmUgdHlwZXMgKGZyb20gdGhpcy5saW5lVHlwZXMgYXMgd2VsbCBhcyB0aGUgY2FwdHVyZSByZXN1bHQgaW4gdGhpcy5saW5lUmVwbGFjZW1lbnRzIGFuZCB0aGlzLmxpbmVDYXB0dXJlcylcbiAgICogYW5kIHByb2Nlc3NlcyBpbmxpbmUgZm9ybWF0dGluZyBmb3IgYWxsIGxpbmVzLlxuICAgKi9cbiAgYXBwbHlMaW5lVHlwZXMoKSB7XG4gICAgZm9yIChsZXQgbGluZU51bSA9IDA7IGxpbmVOdW0gPCB0aGlzLmxpbmVzLmxlbmd0aDsgbGluZU51bSsrKSB7XG4gICAgICBpZiAodGhpcy5saW5lRGlydHlbbGluZU51bV0pIHtcbiAgICAgICAgbGV0IGNvbnRlbnRIVE1MID0gdGhpcy5yZXBsYWNlKFxuICAgICAgICAgIHRoaXMubGluZVJlcGxhY2VtZW50c1tsaW5lTnVtXSxcbiAgICAgICAgICB0aGlzLmxpbmVDYXB0dXJlc1tsaW5lTnVtXVxuICAgICAgICApO1xuICAgICAgICAvLyB0aGlzLmxpbmVIVE1MW2xpbmVOdW1dID0gKGNvbnRlbnRIVE1MID09ICcnID8gJzxiciAvPicgOiBjb250ZW50SFRNTCk7IC8vIFByZXZlbnQgZW1wdHkgZWxlbWVudHMgd2hpY2ggY2FuJ3QgYmUgc2VsZWN0ZWQgZXRjLlxuICAgICAgICB0aGlzLmxpbmVFbGVtZW50c1tsaW5lTnVtXS5jbGFzc05hbWUgPSB0aGlzLmxpbmVUeXBlc1tsaW5lTnVtXTtcbiAgICAgICAgdGhpcy5saW5lRWxlbWVudHNbbGluZU51bV0ucmVtb3ZlQXR0cmlidXRlKFwic3R5bGVcIik7XG4gICAgICAgIHRoaXMubGluZUVsZW1lbnRzW2xpbmVOdW1dLmlubmVySFRNTCA9XG4gICAgICAgICAgY29udGVudEhUTUwgPT0gXCJcIiA/IFwiPGJyIC8+XCIgOiBjb250ZW50SFRNTDsgLy8gUHJldmVudCBlbXB0eSBlbGVtZW50cyB3aGljaCBjYW4ndCBiZSBzZWxlY3RlZCBldGMuXG4gICAgICB9XG4gICAgICB0aGlzLmxpbmVFbGVtZW50c1tsaW5lTnVtXS5kYXRhc2V0LmxpbmVOdW0gPSBsaW5lTnVtO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGxpbmUgdHlwZXMgZm9yIGFsbCBsaW5lcyBiYXNlZCBvbiB0aGUgbGluZSAvIGJsb2NrIGdyYW1tYXIuIENhcHR1cmVzIHRoZSByZXN1bHRzIG9mIHRoZSByZXNwZWN0aXZlIGxpbmVcbiAgICogZ3JhbW1hciByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgKiBVcGRhdGVzIHRoaXMubGluZVR5cGVzLCB0aGlzLmxpbmVDYXB0dXJlcywgYW5kIHRoaXMubGluZVJlcGxhY2VtZW50cy5cbiAgICovXG4gIHVwZGF0ZUxpbmVUeXBlcygpIHtcbiAgICBsZXQgY29kZUJsb2NrVHlwZSA9IGZhbHNlO1xuICAgIGxldCBjb2RlQmxvY2tTZXFMZW5ndGggPSAwO1xuICAgIGxldCBodG1sQmxvY2sgPSBmYWxzZTtcblxuICAgIGZvciAobGV0IGxpbmVOdW0gPSAwOyBsaW5lTnVtIDwgdGhpcy5saW5lcy5sZW5ndGg7IGxpbmVOdW0rKykge1xuICAgICAgbGV0IGxpbmVUeXBlID0gXCJUTVBhcmFcIjtcbiAgICAgIGxldCBsaW5lQ2FwdHVyZSA9IFt0aGlzLmxpbmVzW2xpbmVOdW1dXTtcbiAgICAgIGxldCBsaW5lUmVwbGFjZW1lbnQgPSBcIiQkMFwiOyAvLyBEZWZhdWx0IHJlcGxhY2VtZW50IGZvciBwYXJhZ3JhcGg6IElubGluZSBmb3JtYXQgdGhlIGVudGlyZSBsaW5lXG5cbiAgICAgIC8vIENoZWNrIG9uZ29pbmcgY29kZSBibG9ja3NcbiAgICAgIC8vIGlmIChsaW5lTnVtID4gMCAmJiAodGhpcy5saW5lVHlwZXNbbGluZU51bSAtIDFdID09ICdUTUNvZGVGZW5jZUJhY2t0aWNrT3BlbicgfHwgdGhpcy5saW5lVHlwZXNbbGluZU51bSAtIDFdID09ICdUTUZlbmNlZENvZGVCYWNrdGljaycpKSB7XG4gICAgICBpZiAoY29kZUJsb2NrVHlwZSA9PSBcIlRNQ29kZUZlbmNlQmFja3RpY2tPcGVuXCIpIHtcbiAgICAgICAgLy8gV2UncmUgaW4gYSBiYWNrdGljay1mZW5jZWQgY29kZSBibG9jaywgY2hlY2sgaWYgdGhlIGN1cnJlbnQgbGluZSBjbG9zZXMgaXRcbiAgICAgICAgbGV0IGNhcHR1cmUgPSBsaW5lR3JhbW1hci5UTUNvZGVGZW5jZUJhY2t0aWNrQ2xvc2UucmVnZXhwLmV4ZWMoXG4gICAgICAgICAgdGhpcy5saW5lc1tsaW5lTnVtXVxuICAgICAgICApO1xuICAgICAgICBpZiAoY2FwdHVyZSAmJiBjYXB0dXJlLmdyb3Vwc1tcInNlcVwiXS5sZW5ndGggPj0gY29kZUJsb2NrU2VxTGVuZ3RoKSB7XG4gICAgICAgICAgbGluZVR5cGUgPSBcIlRNQ29kZUZlbmNlQmFja3RpY2tDbG9zZVwiO1xuICAgICAgICAgIGxpbmVSZXBsYWNlbWVudCA9IGxpbmVHcmFtbWFyLlRNQ29kZUZlbmNlQmFja3RpY2tDbG9zZS5yZXBsYWNlbWVudDtcbiAgICAgICAgICBsaW5lQ2FwdHVyZSA9IGNhcHR1cmU7XG4gICAgICAgICAgY29kZUJsb2NrVHlwZSA9IGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxpbmVUeXBlID0gXCJUTUZlbmNlZENvZGVCYWNrdGlja1wiO1xuICAgICAgICAgIGxpbmVSZXBsYWNlbWVudCA9ICc8c3BhbiBjbGFzcz1cIlRNRmVuY2VkQ29kZVwiPiQwPGJyIC8+PC9zcGFuPic7XG4gICAgICAgICAgbGluZUNhcHR1cmUgPSBbdGhpcy5saW5lc1tsaW5lTnVtXV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGlmIChsaW5lTnVtID4gMCAmJiAodGhpcy5saW5lVHlwZXNbbGluZU51bSAtIDFdID09ICdUTUNvZGVGZW5jZVRpbGRlT3BlbicgfHwgdGhpcy5saW5lVHlwZXNbbGluZU51bSAtIDFdID09ICdUTUZlbmNlZENvZGVUaWxkZScpKSB7XG4gICAgICBlbHNlIGlmIChjb2RlQmxvY2tUeXBlID09IFwiVE1Db2RlRmVuY2VUaWxkZU9wZW5cIikge1xuICAgICAgICAvLyBXZSdyZSBpbiBhIHRpbGRlLWZlbmNlZCBjb2RlIGJsb2NrXG4gICAgICAgIGxldCBjYXB0dXJlID0gbGluZUdyYW1tYXIuVE1Db2RlRmVuY2VUaWxkZUNsb3NlLnJlZ2V4cC5leGVjKFxuICAgICAgICAgIHRoaXMubGluZXNbbGluZU51bV1cbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGNhcHR1cmUgJiYgY2FwdHVyZS5ncm91cHNbXCJzZXFcIl0ubGVuZ3RoID49IGNvZGVCbG9ja1NlcUxlbmd0aCkge1xuICAgICAgICAgIGxpbmVUeXBlID0gXCJUTUNvZGVGZW5jZVRpbGRlQ2xvc2VcIjtcbiAgICAgICAgICBsaW5lUmVwbGFjZW1lbnQgPSBsaW5lR3JhbW1hci5UTUNvZGVGZW5jZVRpbGRlQ2xvc2UucmVwbGFjZW1lbnQ7XG4gICAgICAgICAgbGluZUNhcHR1cmUgPSBjYXB0dXJlO1xuICAgICAgICAgIGNvZGVCbG9ja1R5cGUgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsaW5lVHlwZSA9IFwiVE1GZW5jZWRDb2RlVGlsZGVcIjtcbiAgICAgICAgICBsaW5lUmVwbGFjZW1lbnQgPSAnPHNwYW4gY2xhc3M9XCJUTUZlbmNlZENvZGVcIj4kMDxiciAvPjwvc3Bhbj4nO1xuICAgICAgICAgIGxpbmVDYXB0dXJlID0gW3RoaXMubGluZXNbbGluZU51bV1dO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIEhUTUwgYmxvY2sgdHlwZXNcbiAgICAgIGlmIChsaW5lVHlwZSA9PSBcIlRNUGFyYVwiICYmIGh0bWxCbG9jayA9PT0gZmFsc2UpIHtcbiAgICAgICAgZm9yIChsZXQgaHRtbEJsb2NrVHlwZSBvZiBodG1sQmxvY2tHcmFtbWFyKSB7XG4gICAgICAgICAgaWYgKHRoaXMubGluZXNbbGluZU51bV0ubWF0Y2goaHRtbEJsb2NrVHlwZS5zdGFydCkpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoaW5nIHN0YXJ0IGNvbmRpdGlvbi4gQ2hlY2sgaWYgdGhpcyB0YWcgY2FuIHN0YXJ0IGhlcmUgKG5vdCBhbGwgc3RhcnQgY29uZGl0aW9ucyBhbGxvdyBicmVha2luZyBhIHBhcmFncmFwaCkuXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGh0bWxCbG9ja1R5cGUucGFyYUludGVycnVwdCB8fFxuICAgICAgICAgICAgICBsaW5lTnVtID09IDAgfHxcbiAgICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmVUeXBlc1tsaW5lTnVtIC0gMV0gPT0gXCJUTVBhcmFcIiB8fFxuICAgICAgICAgICAgICAgIHRoaXMubGluZVR5cGVzW2xpbmVOdW0gLSAxXSA9PSBcIlRNVUxcIiB8fFxuICAgICAgICAgICAgICAgIHRoaXMubGluZVR5cGVzW2xpbmVOdW0gLSAxXSA9PSBcIlRNT0xcIiB8fFxuICAgICAgICAgICAgICAgIHRoaXMubGluZVR5cGVzW2xpbmVOdW0gLSAxXSA9PSBcIlRNQmxvY2txdW90ZVwiXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBodG1sQmxvY2sgPSBodG1sQmxvY2tUeXBlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGh0bWxCbG9jayAhPT0gZmFsc2UpIHtcbiAgICAgICAgbGluZVR5cGUgPSBcIlRNSFRNTEJsb2NrXCI7XG4gICAgICAgIGxpbmVSZXBsYWNlbWVudCA9ICc8c3BhbiBjbGFzcz1cIlRNSFRNTENvbnRlbnRcIj4kMDxiciAvPjwvc3Bhbj4nOyAvLyBObyBmb3JtYXR0aW5nIGluIFRNSFRNTEJsb2NrXG4gICAgICAgIGxpbmVDYXB0dXJlID0gW3RoaXMubGluZXNbbGluZU51bV1dOyAvLyBUaGlzIHNob3VsZCBhbHJlYWR5IGJlIHNldCBidXQgYmV0dGVyIHNhZmUgdGhhbiBzb3JyeVxuXG4gICAgICAgIC8vIENoZWNrIGlmIEhUTUwgYmxvY2sgc2hvdWxkIGJlIGNsb3NlZFxuICAgICAgICBpZiAoaHRtbEJsb2NrLmVuZCkge1xuICAgICAgICAgIC8vIFNwZWNpZmljIGVuZCBjb25kaXRpb25cbiAgICAgICAgICBpZiAodGhpcy5saW5lc1tsaW5lTnVtXS5tYXRjaChodG1sQmxvY2suZW5kKSkge1xuICAgICAgICAgICAgaHRtbEJsb2NrID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHNwZWNpZmljIGVuZCBjb25kaXRpb24sIGVuZHMgd2l0aCBibGFuayBsaW5lXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgbGluZU51bSA9PSB0aGlzLmxpbmVzLmxlbmd0aCAtIDEgfHxcbiAgICAgICAgICAgIHRoaXMubGluZXNbbGluZU51bSArIDFdLm1hdGNoKGxpbmVHcmFtbWFyLlRNQmxhbmtMaW5lLnJlZ2V4cClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGh0bWxCbG9jayA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBhbGwgcmVnZXhwcyBpZiB3ZSBoYXZlbid0IGFwcGxpZWQgb25lIG9mIHRoZSBjb2RlIGJsb2NrIHR5cGVzXG4gICAgICBpZiAobGluZVR5cGUgPT0gXCJUTVBhcmFcIikge1xuICAgICAgICBmb3IgKGxldCB0eXBlIGluIGxpbmVHcmFtbWFyKSB7XG4gICAgICAgICAgaWYgKGxpbmVHcmFtbWFyW3R5cGVdLnJlZ2V4cCkge1xuICAgICAgICAgICAgbGV0IGNhcHR1cmUgPSBsaW5lR3JhbW1hclt0eXBlXS5yZWdleHAuZXhlYyh0aGlzLmxpbmVzW2xpbmVOdW1dKTtcbiAgICAgICAgICAgIGlmIChjYXB0dXJlKSB7XG4gICAgICAgICAgICAgIGxpbmVUeXBlID0gdHlwZTtcbiAgICAgICAgICAgICAgbGluZVJlcGxhY2VtZW50ID0gbGluZUdyYW1tYXJbdHlwZV0ucmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgIGxpbmVDYXB0dXJlID0gY2FwdHVyZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHdlJ3ZlIG9wZW5lZCBhIGNvZGUgYmxvY2ssIHJlbWVtYmVyIHRoYXRcbiAgICAgIGlmIChcbiAgICAgICAgbGluZVR5cGUgPT0gXCJUTUNvZGVGZW5jZUJhY2t0aWNrT3BlblwiIHx8XG4gICAgICAgIGxpbmVUeXBlID09IFwiVE1Db2RlRmVuY2VUaWxkZU9wZW5cIlxuICAgICAgKSB7XG4gICAgICAgIGNvZGVCbG9ja1R5cGUgPSBsaW5lVHlwZTtcbiAgICAgICAgY29kZUJsb2NrU2VxTGVuZ3RoID0gbGluZUNhcHR1cmUuZ3JvdXBzW1wic2VxXCJdLmxlbmd0aDtcbiAgICAgIH1cblxuICAgICAgLy8gTGluayByZWZlcmVuY2UgZGVmaW5pdGlvbiBhbmQgaW5kZW50ZWQgY29kZSBjYW4ndCBpbnRlcnJ1cHQgYSBwYXJhZ3JhcGhcbiAgICAgIGlmIChcbiAgICAgICAgKGxpbmVUeXBlID09IFwiVE1JbmRlbnRlZENvZGVcIiB8fFxuICAgICAgICAgIGxpbmVUeXBlID09IFwiVE1MaW5rUmVmZXJlbmNlRGVmaW5pdGlvblwiKSAmJlxuICAgICAgICBsaW5lTnVtID4gMCAmJlxuICAgICAgICAodGhpcy5saW5lVHlwZXNbbGluZU51bSAtIDFdID09IFwiVE1QYXJhXCIgfHxcbiAgICAgICAgICB0aGlzLmxpbmVUeXBlc1tsaW5lTnVtIC0gMV0gPT0gXCJUTVVMXCIgfHxcbiAgICAgICAgICB0aGlzLmxpbmVUeXBlc1tsaW5lTnVtIC0gMV0gPT0gXCJUTU9MXCIgfHxcbiAgICAgICAgICB0aGlzLmxpbmVUeXBlc1tsaW5lTnVtIC0gMV0gPT0gXCJUTUJsb2NrcXVvdGVcIilcbiAgICAgICkge1xuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gVE1QYXJhXG4gICAgICAgIGxpbmVUeXBlID0gXCJUTVBhcmFcIjtcbiAgICAgICAgbGluZUNhcHR1cmUgPSBbdGhpcy5saW5lc1tsaW5lTnVtXV07XG4gICAgICAgIGxpbmVSZXBsYWNlbWVudCA9IFwiJCQwXCI7XG4gICAgICB9XG5cbiAgICAgIC8vIFNldGV4dCBIMiBtYXJrZXJzIHRoYXQgY2FuIGFsc28gYmUgaW50ZXJwcmV0ZWQgYXMgYW4gZW1wdHkgbGlzdCBpdGVtIHNob3VsZCBiZSByZWdhcmRlZCBhcyBzdWNoIChhcyBwZXIgQ29tbW9uTWFyayBzcGVjKVxuICAgICAgaWYgKGxpbmVUeXBlID09IFwiVE1TZXRleHRIMk1hcmtlclwiKSB7XG4gICAgICAgIGxldCBjYXB0dXJlID0gbGluZUdyYW1tYXIuVE1VTC5yZWdleHAuZXhlYyh0aGlzLmxpbmVzW2xpbmVOdW1dKTtcbiAgICAgICAgaWYgKGNhcHR1cmUpIHtcbiAgICAgICAgICBsaW5lVHlwZSA9IFwiVE1VTFwiO1xuICAgICAgICAgIGxpbmVSZXBsYWNlbWVudCA9IGxpbmVHcmFtbWFyLlRNVUwucmVwbGFjZW1lbnQ7XG4gICAgICAgICAgbGluZUNhcHR1cmUgPSBjYXB0dXJlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFNldGV4dCBoZWFkaW5ncyBhcmUgb25seSB2YWxpZCBpZiBwcmVjZWRlZCBieSBhIHBhcmFncmFwaCAoYW5kIGlmIHNvLCB0aGV5IGNoYW5nZSB0aGUgdHlwZSBvZiB0aGUgcHJldmlvdXMgcGFyYWdyYXBoKVxuICAgICAgaWYgKGxpbmVUeXBlID09IFwiVE1TZXRleHRIMU1hcmtlclwiIHx8IGxpbmVUeXBlID09IFwiVE1TZXRleHRIMk1hcmtlclwiKSB7XG4gICAgICAgIGlmIChsaW5lTnVtID09IDAgfHwgdGhpcy5saW5lVHlwZXNbbGluZU51bSAtIDFdICE9IFwiVE1QYXJhXCIpIHtcbiAgICAgICAgICAvLyBTZXRleHQgbWFya2VyIGlzIGludmFsaWQuIEhvd2V2ZXIsIGEgSDIgbWFya2VyIG1pZ2h0IHN0aWxsIGJlIGEgdmFsaWQgSFIsIHNvIGxldCdzIGNoZWNrIHRoYXRcbiAgICAgICAgICBsZXQgY2FwdHVyZSA9IGxpbmVHcmFtbWFyLlRNSFIucmVnZXhwLmV4ZWModGhpcy5saW5lc1tsaW5lTnVtXSk7XG4gICAgICAgICAgaWYgKGNhcHR1cmUpIHtcbiAgICAgICAgICAgIC8vIFZhbGlkIEhSXG4gICAgICAgICAgICBsaW5lVHlwZSA9IFwiVE1IUlwiO1xuICAgICAgICAgICAgbGluZUNhcHR1cmUgPSBjYXB0dXJlO1xuICAgICAgICAgICAgbGluZVJlcGxhY2VtZW50ID0gbGluZUdyYW1tYXIuVE1IUi5yZXBsYWNlbWVudDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gTm90IHZhbGlkIEhSLCBmb3JtYXQgYXMgVE1QYXJhXG4gICAgICAgICAgICBsaW5lVHlwZSA9IFwiVE1QYXJhXCI7XG4gICAgICAgICAgICBsaW5lQ2FwdHVyZSA9IFt0aGlzLmxpbmVzW2xpbmVOdW1dXTtcbiAgICAgICAgICAgIGxpbmVSZXBsYWNlbWVudCA9IFwiJCQwXCI7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFZhbGlkIHNldGV4dCBtYXJrZXIuIENoYW5nZSB0eXBlcyBvZiBwcmVjZWRpbmcgcGFyYSBsaW5lc1xuICAgICAgICAgIGxldCBoZWFkaW5nTGluZSA9IGxpbmVOdW0gLSAxO1xuICAgICAgICAgIGNvbnN0IGhlYWRpbmdMaW5lVHlwZSA9XG4gICAgICAgICAgICBsaW5lVHlwZSA9PSBcIlRNU2V0ZXh0SDFNYXJrZXJcIiA/IFwiVE1TZXRleHRIMVwiIDogXCJUTVNldGV4dEgyXCI7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgaWYgKHRoaXMubGluZVR5cGVzW2hlYWRpbmdMaW5lVHlwZV0gIT0gaGVhZGluZ0xpbmVUeXBlKSB7XG4gICAgICAgICAgICAgIHRoaXMubGluZVR5cGVzW2hlYWRpbmdMaW5lXSA9IGhlYWRpbmdMaW5lVHlwZTtcbiAgICAgICAgICAgICAgdGhpcy5saW5lRGlydHlbaGVhZGluZ0xpbmVUeXBlXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmxpbmVSZXBsYWNlbWVudHNbaGVhZGluZ0xpbmVdID0gXCIkJDBcIjtcbiAgICAgICAgICAgIHRoaXMubGluZUNhcHR1cmVzW2hlYWRpbmdMaW5lXSA9IFt0aGlzLmxpbmVzW2hlYWRpbmdMaW5lXV07XG5cbiAgICAgICAgICAgIGhlYWRpbmdMaW5lLS07XG4gICAgICAgICAgfSB3aGlsZSAoaGVhZGluZ0xpbmUgPj0gMCAmJiB0aGlzLmxpbmVUeXBlc1toZWFkaW5nTGluZV0gPT0gXCJUTVBhcmFcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIExhc3RseSwgc2F2ZSB0aGUgbGluZSBzdHlsZSB0byBiZSBhcHBsaWVkIGxhdGVyXG4gICAgICBpZiAodGhpcy5saW5lVHlwZXNbbGluZU51bV0gIT0gbGluZVR5cGUpIHtcbiAgICAgICAgdGhpcy5saW5lVHlwZXNbbGluZU51bV0gPSBsaW5lVHlwZTtcbiAgICAgICAgdGhpcy5saW5lRGlydHlbbGluZU51bV0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5saW5lUmVwbGFjZW1lbnRzW2xpbmVOdW1dID0gbGluZVJlcGxhY2VtZW50O1xuICAgICAgdGhpcy5saW5lQ2FwdHVyZXNbbGluZU51bV0gPSBsaW5lQ2FwdHVyZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyBhbGwgbGluZSBjb250ZW50cyBmcm9tIHRoZSBIVE1MLCB0aGVuIHJlLWFwcGxpZXMgZm9ybWF0dGluZy5cbiAgICovXG4gIHVwZGF0ZUxpbmVDb250ZW50c0FuZEZvcm1hdHRpbmcoKSB7XG4gICAgdGhpcy5jbGVhckRpcnR5RmxhZygpO1xuICAgIHRoaXMudXBkYXRlTGluZUNvbnRlbnRzKCk7XG4gICAgdGhpcy51cGRhdGVGb3JtYXR0aW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdHMgdG8gcGFyc2UgYSBsaW5rIG9yIGltYWdlIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBUaGlzIGFzc3VtZXMgdGhhdCB0aGUgb3BlbmluZyBbIG9yICFbIGhhcyBhbHJlYWR5IGJlZW4gbWF0Y2hlZC5cbiAgICogUmV0dXJucyBmYWxzZSBpZiB0aGlzIGlzIG5vdCBhIHZhbGlkIGxpbmssIGltYWdlLiBTZWUgYmVsb3cgZm9yIG1vcmUgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IG9yaWdpbmFsU3RyaW5nIFRoZSBvcmlnaW5hbCBzdHJpbmcsIHN0YXJ0aW5nIGF0IHRoZSBvcGVuaW5nIG1hcmtlciAoWyBvciAhWylcbiAgICogQHBhcmFtIHtib29sZWFufSBpc0ltYWdlIFdoZXRoZXIgb3Igbm90IHRoaXMgaXMgYW4gaW1hZ2UgKG9wZW5lciA9PSAhWylcbiAgICogQHJldHVybnMgZmFsc2UgaWYgbm90IGEgdmFsaWQgbGluayAvIGltYWdlLlxuICAgKiBPdGhlcndpc2UgcmV0dXJucyBhbiBvYmplY3Qgd2l0aCB0d28gcHJvcGVydGllczogb3V0cHV0IGlzIHRoZSBzdHJpbmcgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIHByb2Nlc3NlZCBvdXRwdXQsXG4gICAqIGNoYXJDb3VudCBpcyB0aGUgbnVtYmVyIG9mIGlucHV0IGNoYXJhY3RlcnMgKGZyb20gb3JpZ2luYWxTdHJpbmcpIGNvbnN1bWVkLlxuICAgKi9cbiAgcGFyc2VMaW5rT3JJbWFnZShvcmlnaW5hbFN0cmluZywgaXNJbWFnZSkge1xuICAgIC8vIFNraXAgdGhlIG9wZW5pbmcgYnJhY2tldFxuICAgIGxldCB0ZXh0T2Zmc2V0ID0gaXNJbWFnZSA/IDIgOiAxO1xuICAgIGxldCBvcGVuZXIgPSBvcmlnaW5hbFN0cmluZy5zdWJzdHIoMCwgdGV4dE9mZnNldCk7XG4gICAgbGV0IHR5cGUgPSBpc0ltYWdlID8gXCJUTUltYWdlXCIgOiBcIlRNTGlua1wiO1xuICAgIGxldCBjdXJyZW50T2Zmc2V0ID0gdGV4dE9mZnNldDtcblxuICAgIGxldCBicmFja2V0TGV2ZWwgPSAxO1xuICAgIGxldCBsaW5rVGV4dCA9IGZhbHNlO1xuICAgIGxldCBsaW5rUmVmID0gZmFsc2U7XG4gICAgbGV0IGxpbmtMYWJlbCA9IFtdO1xuICAgIGxldCBsaW5rRGV0YWlscyA9IFtdOyAvLyBJZiBtYXRjaGVkLCB0aGlzIHdpbGwgYmUgYW4gYXJyYXk6IFt3aGl0ZXNwYWNlICsgbGluayBkZXN0aW5hdGlvbiBkZWxpbWl0ZXIsIGxpbmsgZGVzdGluYXRpb24sIGxpbmsgZGVzdGluYXRpb24gZGVsaW1pdGVyLCB3aGl0ZXNwYWNlLCBsaW5rIHRpdGxlIGRlbGltaXRlciwgbGluayB0aXRsZSwgbGluayB0aXRsZSBkZWxpbWl0ZXIgKyB3aGl0ZXNwYWNlXS4gQWxsIGNhbiBiZSBlbXB0eSBzdHJpbmdzLlxuXG4gICAgdGV4dE91dGVyOiB3aGlsZSAoXG4gICAgICBjdXJyZW50T2Zmc2V0IDwgb3JpZ2luYWxTdHJpbmcubGVuZ3RoICYmXG4gICAgICBsaW5rVGV4dCA9PT0gZmFsc2UgLyogZW1wdHkgc3RyaW5nIGlzIG9rYXkgKi9cbiAgICApIHtcbiAgICAgIGxldCBzdHJpbmcgPSBvcmlnaW5hbFN0cmluZy5zdWJzdHIoY3VycmVudE9mZnNldCk7XG5cbiAgICAgIC8vIENhcHR1cmUgYW55IGVzY2FwZXMgYW5kIGNvZGUgYmxvY2tzIGF0IGN1cnJlbnQgcG9zaXRpb24sIHRoZXkgYmluZCBtb3JlIHN0cm9uZ2x5IHRoYW4gbGlua3NcbiAgICAgIC8vIFdlIGRvbid0IGhhdmUgdG8gYWN0dWFsbHkgcHJvY2VzcyB0aGVtIGhlcmUsIHRoYXQnbGwgYmUgZG9uZSBsYXRlciBpbiBjYXNlIHRoZSBsaW5rIC8gaW1hZ2UgaXMgdmFsaWQsIGJ1dCB3ZSBuZWVkIHRvIHNraXAgb3ZlciB0aGVtLlxuICAgICAgZm9yIChsZXQgcnVsZSBvZiBbXCJlc2NhcGVcIiwgXCJjb2RlXCIsIFwiYXV0b2xpbmtcIiwgXCJodG1sXCJdKSB7XG4gICAgICAgIGxldCBjYXAgPSBpbmxpbmVHcmFtbWFyW3J1bGVdLnJlZ2V4cC5leGVjKHN0cmluZyk7XG4gICAgICAgIGlmIChjYXApIHtcbiAgICAgICAgICBjdXJyZW50T2Zmc2V0ICs9IGNhcFswXS5sZW5ndGg7XG4gICAgICAgICAgY29udGludWUgdGV4dE91dGVyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBpbWFnZS4gSXQncyBva2F5IGZvciBhbiBpbWFnZSB0byBiZSBpbmNsdWRlZCBpbiBhIGxpbmsgb3IgaW1hZ2VcbiAgICAgIGlmIChzdHJpbmcubWF0Y2goaW5saW5lR3JhbW1hci5pbWFnZU9wZW4ucmVnZXhwKSkge1xuICAgICAgICAvLyBPcGVuaW5nIGltYWdlLiBJdCdzIG9rYXkgaWYgdGhpcyBpcyBhIG1hdGNoaW5nIHBhaXIgb2YgYnJhY2tldHNcbiAgICAgICAgYnJhY2tldExldmVsKys7XG4gICAgICAgIGN1cnJlbnRPZmZzZXQgKz0gMjtcbiAgICAgICAgY29udGludWUgdGV4dE91dGVyO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBmb3IgbGluayAobm90IGFuIGltYWdlIGJlY2F1c2UgdGhhdCB3b3VsZCBoYXZlIGJlZW4gY2FwdHVyZWQgYW5kIHNraXBwZWQgb3ZlciBhYm92ZSlcbiAgICAgIGlmIChzdHJpbmcubWF0Y2goaW5saW5lR3JhbW1hci5saW5rT3Blbi5yZWdleHApKSB7XG4gICAgICAgIC8vIE9wZW5pbmcgYnJhY2tldC4gVHdvIHRoaW5ncyB0byBkbzpcbiAgICAgICAgLy8gMSkgaXQncyBva2F5IGlmIHRoaXMgcGFydCBvZiBhIHBhaXIgb2YgYnJhY2tldHMuXG4gICAgICAgIC8vIDIpIElmIHdlIGFyZSBjdXJyZW50bHkgdHJ5aW5nIHRvIHBhcnNlIGEgbGluaywgdGhpcyBuZXN0ZWQgYnJhY2tldCBtdXNuJ3Qgc3RhcnQgYSB2YWxpZCBsaW5rIChubyBuZXN0ZWQgbGlua3MgYWxsb3dlZClcbiAgICAgICAgYnJhY2tldExldmVsKys7XG4gICAgICAgIC8vIGlmIChicmFja2V0TGV2ZWwgPj0gMikgcmV0dXJuIGZhbHNlOyAvLyBOZXN0ZWQgdW5lc2NhcGVkIGJyYWNrZXRzLCB0aGlzIGRvZXNuJ3QgcXVhbGlmeSBhcyBhIGxpbmsgLyBpbWFnZVxuICAgICAgICBpZiAoIWlzSW1hZ2UpIHtcbiAgICAgICAgICBpZiAodGhpcy5wYXJzZUxpbmtPckltYWdlKHN0cmluZywgZmFsc2UpKSB7XG4gICAgICAgICAgICAvLyBWYWxpZCBsaW5rIGluc2lkZSB0aGlzIHBvc3NpYmxlIGxpbmssIHdoaWNoIG1ha2VzIHRoaXMgbGluayBpbnZhbGlkIChpbm5lciBsaW5rcyBiZWF0IG91dGVyIG9uZXMpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRPZmZzZXQgKz0gMTtcbiAgICAgICAgY29udGludWUgdGV4dE91dGVyO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBmb3IgY2xvc2luZyBicmFja2V0XG4gICAgICBpZiAoc3RyaW5nLm1hdGNoKC9eXFxdLykpIHtcbiAgICAgICAgYnJhY2tldExldmVsLS07XG4gICAgICAgIGlmIChicmFja2V0TGV2ZWwgPT0gMCkge1xuICAgICAgICAgIC8vIEZvdW5kIG1hdGNoaW5nIGJyYWNrZXQgYW5kIGhhdmVuJ3QgZm91bmQgYW55dGhpbmcgZGlzcXVhbGlmeWluZyB0aGlzIGFzIGxpbmsgLyBpbWFnZS5cbiAgICAgICAgICBsaW5rVGV4dCA9IG9yaWdpbmFsU3RyaW5nLnN1YnN0cihcbiAgICAgICAgICAgIHRleHRPZmZzZXQsXG4gICAgICAgICAgICBjdXJyZW50T2Zmc2V0IC0gdGV4dE9mZnNldFxuICAgICAgICAgICk7XG4gICAgICAgICAgY3VycmVudE9mZnNldCsrO1xuICAgICAgICAgIGNvbnRpbnVlIHRleHRPdXRlcjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBOb3RoaW5nIG1hdGNoZXMsIHByb2NlZWQgdG8gbmV4dCBjaGFyXG4gICAgICBjdXJyZW50T2Zmc2V0Kys7XG4gICAgfVxuXG4gICAgLy8gRGlkIHdlIGZpbmQgYSBsaW5rIHRleHQgKGkuZS4sIGZpbmQgYSBtYXRjaGluZyBjbG9zaW5nIGJyYWNrZXQ/KVxuICAgIGlmIChsaW5rVGV4dCA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTsgLy8gTm9wZVxuXG4gICAgLy8gU28gZmFyLCBzbyBnb29kLiBXZSd2ZSBnb3QgYSB2YWxpZCBsaW5rIHRleHQuIExldCdzIHNlZSB3aGF0IHR5cGUgb2YgbGluayB0aGlzIGlzXG4gICAgbGV0IG5leHRDaGFyID1cbiAgICAgIGN1cnJlbnRPZmZzZXQgPCBvcmlnaW5hbFN0cmluZy5sZW5ndGhcbiAgICAgICAgPyBvcmlnaW5hbFN0cmluZy5zdWJzdHIoY3VycmVudE9mZnNldCwgMSlcbiAgICAgICAgOiBcIlwiO1xuXG4gICAgLy8gUkVGRVJFTkNFIExJTktTXG4gICAgaWYgKG5leHRDaGFyID09IFwiW1wiKSB7XG4gICAgICBsZXQgc3RyaW5nID0gb3JpZ2luYWxTdHJpbmcuc3Vic3RyKGN1cnJlbnRPZmZzZXQpO1xuICAgICAgbGV0IGNhcCA9IGlubGluZUdyYW1tYXIubGlua0xhYmVsLnJlZ2V4cC5leGVjKHN0cmluZyk7XG4gICAgICBpZiAoY2FwKSB7XG4gICAgICAgIC8vIFZhbGlkIGxpbmsgbGFiZWxcbiAgICAgICAgY3VycmVudE9mZnNldCArPSBjYXBbMF0ubGVuZ3RoO1xuICAgICAgICBsaW5rTGFiZWwucHVzaChjYXBbMV0sIGNhcFsyXSwgY2FwWzNdKTtcbiAgICAgICAgaWYgKGNhcFtpbmxpbmVHcmFtbWFyLmxpbmtMYWJlbC5sYWJlbFBsYWNlaG9sZGVyXSkge1xuICAgICAgICAgIC8vIEZ1bGwgcmVmZXJlbmNlIGxpbmtcbiAgICAgICAgICBsaW5rUmVmID0gY2FwW2lubGluZUdyYW1tYXIubGlua0xhYmVsLmxhYmVsUGxhY2Vob2xkZXJdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIENvbGxhcHNlZCByZWZlcmVuY2UgbGlua1xuICAgICAgICAgIGxpbmtSZWYgPSBsaW5rVGV4dC50cmltKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vdCBhIHZhbGlkIGxpbmsgbGFiZWxcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobmV4dENoYXIgIT0gXCIoXCIpIHtcbiAgICAgIC8vIFNob3J0Y3V0IHJlZiBsaW5rXG4gICAgICBsaW5rUmVmID0gbGlua1RleHQudHJpbSgpO1xuXG4gICAgICAvLyBJTkxJTkUgTElOS1NcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbmV4dENoYXIgPT0gJygnXG5cbiAgICAgIC8vIFBvdGVudGlhbCBpbmxpbmUgbGlua1xuICAgICAgY3VycmVudE9mZnNldCsrO1xuXG4gICAgICBsZXQgcGFyZW50aGVzaXNMZXZlbCA9IDE7XG4gICAgICBpbmxpbmVPdXRlcjogd2hpbGUgKFxuICAgICAgICBjdXJyZW50T2Zmc2V0IDwgb3JpZ2luYWxTdHJpbmcubGVuZ3RoICYmXG4gICAgICAgIHBhcmVudGhlc2lzTGV2ZWwgPiAwXG4gICAgICApIHtcbiAgICAgICAgbGV0IHN0cmluZyA9IG9yaWdpbmFsU3RyaW5nLnN1YnN0cihjdXJyZW50T2Zmc2V0KTtcblxuICAgICAgICAvLyBQcm9jZXNzIHdoaXRlc3BhY2VcbiAgICAgICAgbGV0IGNhcCA9IC9eXFxzKy8uZXhlYyhzdHJpbmcpO1xuICAgICAgICBpZiAoY2FwKSB7XG4gICAgICAgICAgc3dpdGNoIChsaW5rRGV0YWlscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgbGlua0RldGFpbHMucHVzaChjYXBbMF0pO1xuICAgICAgICAgICAgICBicmVhazsgLy8gT3BlbmluZyB3aGl0ZXNwYWNlXG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goY2FwWzBdKTtcbiAgICAgICAgICAgICAgYnJlYWs7IC8vIE9wZW4gZGVzdGluYXRpb24sIGJ1dCBub3QgYSBkZXN0aW5hdGlvbiB5ZXQ7IGRlc2luYXRpb24gb3BlbmVkIHdpdGggPFxuICAgICAgICAgICAgY2FzZSAyOiAvLyBPcGVuIGRlc3RpbmF0aW9uIHdpdGggY29udGVudCBpbiBpdC4gV2hpdGVzcGFjZSBvbmx5IGFsbG93ZWQgaWYgb3BlbmVkIGJ5IGFuZ2xlIGJyYWNrZXQsIG90aGVyd2lzZSB0aGlzIGNsb3NlcyB0aGUgZGVzdGluYXRpb25cbiAgICAgICAgICAgICAgaWYgKGxpbmtEZXRhaWxzWzBdLm1hdGNoKC88LykpIHtcbiAgICAgICAgICAgICAgICBsaW5rRGV0YWlsc1sxXSA9IGxpbmtEZXRhaWxzWzFdLmNvbmNhdChjYXBbMF0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRoZXNpc0xldmVsICE9IDEpIHJldHVybiBmYWxzZTsgLy8gVW5iYWxhbmNlZCBwYXJlbnRoZXNpc1xuICAgICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7IC8vIEVtcHR5IGVuZCBkZWxpbWl0ZXIgZm9yIGRlc3RpbmF0aW9uXG4gICAgICAgICAgICAgICAgbGlua0RldGFpbHMucHVzaChjYXBbMF0pOyAvLyBXaGl0ZXNwYWNlIGluIGJldHdlZW4gZGVzdGluYXRpb24gYW5kIHRpdGxlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goY2FwWzBdKTtcbiAgICAgICAgICAgICAgYnJlYWs7IC8vIFdoaXRlc3BhY2UgYmV0d2VlbiBkZXN0aW5hdGlvbiBhbmQgdGl0bGVcbiAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4gKG5vIG9wZW5lciBmb3IgdGl0bGUgeWV0LCBidXQgbW9yZSB3aGl0ZXNwYWNlIHRvIGNhcHR1cmUpXG4gICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7IC8vIFdoaXRlc3BhY2UgYXQgYmVnaW5uaW5nIG9mIHRpdGxlLCBwdXNoIGVtcHR5IHRpdGxlIGFuZCBjb250aW51ZVxuICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICBsaW5rRGV0YWlsc1s1XSA9IGxpbmtEZXRhaWxzWzVdLmNvbmNhdChjYXBbMF0pO1xuICAgICAgICAgICAgICBicmVhazsgLy8gV2hpdGVzcGFjZSBpbiB0aXRsZVxuICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBsaW5rRGV0YWlsc1s2XSA9IGxpbmtEZXRhaWxzWzZdLmNvbmNhdChjYXBbMF0pO1xuICAgICAgICAgICAgICBicmVhazsgLy8gV2hpdGVzcGFjZSBhZnRlciBjbG9zaW5nIGRlbGltaXRlclxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBXZSBzaG91bGQgbmV2ZXIgZ2V0IGhlcmVcbiAgICAgICAgICB9XG4gICAgICAgICAgY3VycmVudE9mZnNldCArPSBjYXBbMF0ubGVuZ3RoO1xuICAgICAgICAgIGNvbnRpbnVlIGlubGluZU91dGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyBiYWNrc2xhc2ggZXNjYXBlc1xuICAgICAgICBjYXAgPSBpbmxpbmVHcmFtbWFyLmVzY2FwZS5yZWdleHAuZXhlYyhzdHJpbmcpO1xuICAgICAgICBpZiAoY2FwKSB7XG4gICAgICAgICAgc3dpdGNoIChsaW5rRGV0YWlscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgbGlua0RldGFpbHMucHVzaChcIlwiKTsgLy8gdGhpcyBvcGVucyB0aGUgbGluayBkZXN0aW5hdGlvbiwgYWRkIGVtcHR5IG9wZW5pbmcgZGVsaW1pdGVyIGFuZCBwcm9jZWVkIHRvIG5leHQgY2FzZVxuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBsaW5rRGV0YWlscy5wdXNoKGNhcFswXSk7XG4gICAgICAgICAgICAgIGJyZWFrOyAvLyBUaGlzIG9wZW5zIHRoZSBsaW5rIGRlc3RpbmF0aW9uLCBhcHBlbmQgaXRcbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgbGlua0RldGFpbHNbMV0gPSBsaW5rRGV0YWlsc1sxXS5jb25jYXQoY2FwWzBdKTtcbiAgICAgICAgICAgICAgYnJlYWs7IC8vIFBhcnQgb2YgdGhlIGxpbmsgZGVzdGluYXRpb25cbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBMYWNraW5nIG9wZW5pbmcgZGVsaW1pdGVyIGZvciBsaW5rIHRpdGxlXG4gICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gTGNha2luZyBvcGVuaW5nIGRlbGltaXRlciBmb3IgbGluayB0aXRsZVxuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICBsaW5rRGV0YWlscy5wdXNoKFwiXCIpOyAvLyBUaGlzIG9wZW5zIHRoZSBsaW5rIHRpdGxlXG4gICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzWzVdID0gbGlua0RldGFpbHNbNV0uY29uY2F0KGNhcFswXSk7XG4gICAgICAgICAgICAgIGJyZWFrOyAvLyBQYXJ0IG9mIHRoZSBsaW5rIHRpdGxlXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEFmdGVyIGxpbmsgdGl0bGUgd2FzIGNsb3NlZCwgd2l0aG91dCBjbG9zaW5nIHBhcmVudGhlc2lzXG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnRPZmZzZXQgKz0gY2FwWzBdLmxlbmd0aDtcbiAgICAgICAgICBjb250aW51ZSBpbmxpbmVPdXRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb2Nlc3Mgb3BlbmluZyBhbmdsZSBicmFja2V0IGFzIGRlaWxpbWl0ZXIgb2YgZGVzdGluYXRpb25cbiAgICAgICAgaWYgKGxpbmtEZXRhaWxzLmxlbmd0aCA8IDIgJiYgc3RyaW5nLm1hdGNoKC9ePC8pKSB7XG4gICAgICAgICAgaWYgKGxpbmtEZXRhaWxzLmxlbmd0aCA9PSAwKSBsaW5rRGV0YWlscy5wdXNoKFwiXCIpO1xuICAgICAgICAgIGxpbmtEZXRhaWxzWzBdID0gbGlua0RldGFpbHNbMF0uY29uY2F0KFwiPFwiKTtcbiAgICAgICAgICBjdXJyZW50T2Zmc2V0Kys7XG4gICAgICAgICAgY29udGludWUgaW5saW5lT3V0ZXI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm9jZXNzIGNsb3NpbmcgYW5nbGUgYnJhY2tldCBhcyBkZWxpbWl0ZXIgb2YgZGVzdGluYXRpb25cbiAgICAgICAgaWYgKFxuICAgICAgICAgIChsaW5rRGV0YWlscy5sZW5ndGggPT0gMSB8fCBsaW5rRGV0YWlscy5sZW5ndGggPT0gMikgJiZcbiAgICAgICAgICBzdHJpbmcubWF0Y2goL14+LylcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKGxpbmtEZXRhaWxzLmxlbmd0aCA9PSAxKSBsaW5rRGV0YWlscy5wdXNoKFwiXCIpOyAvLyBFbXB0eSBsaW5rIGRlc3RpbmF0aW9uXG4gICAgICAgICAgbGlua0RldGFpbHMucHVzaChcIj5cIik7XG4gICAgICAgICAgY3VycmVudE9mZnNldCsrO1xuICAgICAgICAgIGNvbnRpbnVlIGlubGluZU91dGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyAgbm9uLXBhcmVudGhlc2lzIGRlbGltaXRlciBmb3IgdGl0bGUuXG4gICAgICAgIGNhcCA9IC9eW1wiJ10vLmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgLy8gRm9yIHRoaXMgdG8gYmUgYSB2YWxpZCBvcGVuZXIsIHdlIGhhdmUgdG8gZWl0aGVyIGhhdmUgbm8gZGVzdGluYXRpb24sIG9ubHkgd2hpdGVzcGFjZSBzbyBmYXIsXG4gICAgICAgIC8vIG9yIGEgZGVzdGluYXRpb24gd2l0aCB0cmFpbGluZyB3aGl0ZXNwYWNlLlxuICAgICAgICBpZiAoXG4gICAgICAgICAgY2FwICYmXG4gICAgICAgICAgKGxpbmtEZXRhaWxzLmxlbmd0aCA9PSAwIHx8XG4gICAgICAgICAgICBsaW5rRGV0YWlscy5sZW5ndGggPT0gMSB8fFxuICAgICAgICAgICAgbGlua0RldGFpbHMubGVuZ3RoID09IDQpXG4gICAgICAgICkge1xuICAgICAgICAgIHdoaWxlIChsaW5rRGV0YWlscy5sZW5ndGggPCA0KSBsaW5rRGV0YWlscy5wdXNoKFwiXCIpO1xuICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goY2FwWzBdKTtcbiAgICAgICAgICBjdXJyZW50T2Zmc2V0Kys7XG4gICAgICAgICAgY29udGludWUgaW5saW5lT3V0ZXI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3IgdGhpcyB0byBiZSBhIHZhbGlkIGNsb3Nlciwgd2UgaGF2ZSB0byBoYXZlIGFuIG9wZW5lciBhbmQgc29tZSBvciBubyB0aXRsZSwgYW5kIHRoaXMgaGFzIHRvIG1hdGNoIHRoZSBvcGVuZXJcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGNhcCAmJlxuICAgICAgICAgIChsaW5rRGV0YWlscy5sZW5ndGggPT0gNSB8fCBsaW5rRGV0YWlscy5sZW5ndGggPT0gNikgJiZcbiAgICAgICAgICBsaW5rRGV0YWlsc1s0XSA9PSBjYXBbMF1cbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKGxpbmtEZXRhaWxzLmxlbmd0aCA9PSA1KSBsaW5rRGV0YWlscy5wdXNoKFwiXCIpOyAvLyBFbXB0eSBsaW5rIHRpdGxlXG4gICAgICAgICAgbGlua0RldGFpbHMucHVzaChjYXBbMF0pO1xuICAgICAgICAgIGN1cnJlbnRPZmZzZXQrKztcbiAgICAgICAgICBjb250aW51ZSBpbmxpbmVPdXRlcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBPdGhlciBjYXNlcyAobGlua0RldGFpbHMubGVuZ3RoID09IDIsIDMsIDcpIHdpbGwgYmUgaGFuZGxlZCB3aXRoIHRoZSBcImRlZmF1bHRcIiBjYXNlIGJlbG93LlxuXG4gICAgICAgIC8vIFByb2Nlc3Mgb3BlbmluZyBwYXJlbnRoZXNpc1xuICAgICAgICBpZiAoc3RyaW5nLm1hdGNoKC9eXFwoLykpIHtcbiAgICAgICAgICBzd2l0Y2ggKGxpbmtEZXRhaWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICBsaW5rRGV0YWlscy5wdXNoKFwiXCIpOyAvLyB0aGlzIG9wZW5zIHRoZSBsaW5rIGRlc3RpbmF0aW9uLCBhZGQgZW1wdHkgb3BlbmluZyBkZWxpbWl0ZXIgYW5kIHByb2NlZWQgdG8gbmV4dCBjYXNlXG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7IC8vIFRoaXMgb3BlbnMgdGhlIGxpbmsgZGVzdGluYXRpb25cbiAgICAgICAgICAgIGNhc2UgMjogLy8gUGFydCBvZiB0aGUgbGluayBkZXN0aW5hdGlvblxuICAgICAgICAgICAgICBsaW5rRGV0YWlsc1sxXSA9IGxpbmtEZXRhaWxzWzFdLmNvbmNhdChcIihcIik7XG4gICAgICAgICAgICAgIGlmICghbGlua0RldGFpbHNbMF0ubWF0Y2goLzwkLykpIHBhcmVudGhlc2lzTGV2ZWwrKztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7IC8vICBvcGVuaW5nIGRlbGltaXRlciBmb3IgbGluayB0aXRsZVxuICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICBsaW5rRGV0YWlscy5wdXNoKFwiKFwiKTtcbiAgICAgICAgICAgICAgYnJlYWs7IC8vIG9wZW5pbmcgZGVsaW1pdGVyIGZvciBsaW5rIHRpdGxlXG4gICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7IC8vIG9wZW5zIHRoZSBsaW5rIHRpdGxlLCBhZGQgZW1wdHkgdGl0bGUgY29udGVudCBhbmQgcHJvY2VlZCB0byBuZXh0IGNhc2VcbiAgICAgICAgICAgIGNhc2UgNjogLy8gUGFydCBvZiB0aGUgbGluayB0aXRsZS4gVW4tZXNjYXBlZCBwYXJlbnRoZXNpcyBvbmx5IGFsbG93ZWQgaW4gXCIgb3IgJyBkZWxpbWl0ZWQgdGl0bGVcbiAgICAgICAgICAgICAgaWYgKGxpbmtEZXRhaWxzWzRdID09IFwiKFwiKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzWzVdID0gbGlua0RldGFpbHNbNV0uY29uY2F0KFwiKFwiKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEFmdGVyIGxpbmsgdGl0bGUgd2FzIGNsb3NlZCwgd2l0aG91dCBjbG9zaW5nIHBhcmVudGhlc2lzXG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnRPZmZzZXQrKztcbiAgICAgICAgICBjb250aW51ZSBpbmxpbmVPdXRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb2Nlc3MgY2xvc2luZyBwYXJlbnRoZXNpc1xuICAgICAgICBpZiAoc3RyaW5nLm1hdGNoKC9eXFwpLykpIHtcbiAgICAgICAgICBpZiAobGlua0RldGFpbHMubGVuZ3RoIDw9IDIpIHtcbiAgICAgICAgICAgIC8vIFdlIGFyZSBpbnNpZGUgdGhlIGxpbmsgZGVzdGluYXRpb24uIFBhcmVudGhlc2VzIGhhdmUgdG8gYmUgbWF0Y2hlZCBpZiBub3QgaW4gYW5nbGUgYnJhY2tldHNcbiAgICAgICAgICAgIHdoaWxlIChsaW5rRGV0YWlscy5sZW5ndGggPCAyKSBsaW5rRGV0YWlscy5wdXNoKFwiXCIpO1xuXG4gICAgICAgICAgICBpZiAoIWxpbmtEZXRhaWxzWzBdLm1hdGNoKC88JC8pKSBwYXJlbnRoZXNpc0xldmVsLS07XG5cbiAgICAgICAgICAgIGlmIChwYXJlbnRoZXNpc0xldmVsID4gMCkge1xuICAgICAgICAgICAgICBsaW5rRGV0YWlsc1sxXSA9IGxpbmtEZXRhaWxzWzFdLmNvbmNhdChcIilcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChsaW5rRGV0YWlscy5sZW5ndGggPT0gNSB8fCBsaW5rRGV0YWlscy5sZW5ndGggPT0gNikge1xuICAgICAgICAgICAgLy8gV2UgYXJlIGluc2lkZSB0aGUgbGluayB0aXRsZS5cbiAgICAgICAgICAgIGlmIChsaW5rRGV0YWlsc1s0XSA9PSBcIihcIikge1xuICAgICAgICAgICAgICAvLyBUaGlzIGNsb3NlcyB0aGUgbGluayB0aXRsZVxuICAgICAgICAgICAgICBpZiAobGlua0RldGFpbHMubGVuZ3RoID09IDUpIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCIpXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gSnVzdCByZWd1bGFyIG9sJyBjb250ZW50XG4gICAgICAgICAgICAgIGlmIChsaW5rRGV0YWlscy5sZW5ndGggPT0gNSkgbGlua0RldGFpbHMucHVzaChcIilcIik7XG4gICAgICAgICAgICAgIGVsc2UgbGlua0RldGFpbHNbNV0gPSBsaW5rRGV0YWlsc1s1XS5jb25jYXQoXCIpXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJlbnRoZXNpc0xldmVsLS07IC8vIFRoaXMgc2hvdWxkIGRlY3JlYXNlIGl0IGZyb20gMSB0byAwLi4uXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBhcmVudGhlc2lzTGV2ZWwgPT0gMCkge1xuICAgICAgICAgICAgLy8gTm8gaW52YWxpZCBjb25kaXRpb24sIGxldCdzIG1ha2Ugc3VyZSB0aGUgbGlua0RldGFpbHMgYXJyYXkgaXMgY29tcGxldGVcbiAgICAgICAgICAgIHdoaWxlIChsaW5rRGV0YWlscy5sZW5ndGggPCA3KSBsaW5rRGV0YWlscy5wdXNoKFwiXCIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN1cnJlbnRPZmZzZXQrKztcbiAgICAgICAgICBjb250aW51ZSBpbmxpbmVPdXRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFueSBvbGQgY2hhcmFjdGVyXG4gICAgICAgIGNhcCA9IC9eLi8uZXhlYyhzdHJpbmcpO1xuICAgICAgICBpZiAoY2FwKSB7XG4gICAgICAgICAgc3dpdGNoIChsaW5rRGV0YWlscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgbGlua0RldGFpbHMucHVzaChcIlwiKTsgLy8gdGhpcyBvcGVucyB0aGUgbGluayBkZXN0aW5hdGlvbiwgYWRkIGVtcHR5IG9wZW5pbmcgZGVsaW1pdGVyIGFuZCBwcm9jZWVkIHRvIG5leHQgY2FzZVxuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBsaW5rRGV0YWlscy5wdXNoKGNhcFswXSk7XG4gICAgICAgICAgICAgIGJyZWFrOyAvLyBUaGlzIG9wZW5zIHRoZSBsaW5rIGRlc3RpbmF0aW9uLCBhcHBlbmQgaXRcbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgbGlua0RldGFpbHNbMV0gPSBsaW5rRGV0YWlsc1sxXS5jb25jYXQoY2FwWzBdKTtcbiAgICAgICAgICAgICAgYnJlYWs7IC8vIFBhcnQgb2YgdGhlIGxpbmsgZGVzdGluYXRpb25cbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBMYWNraW5nIG9wZW5pbmcgZGVsaW1pdGVyIGZvciBsaW5rIHRpdGxlXG4gICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gTGNha2luZyBvcGVuaW5nIGRlbGltaXRlciBmb3IgbGluayB0aXRsZVxuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICBsaW5rRGV0YWlscy5wdXNoKFwiXCIpOyAvLyBUaGlzIG9wZW5zIHRoZSBsaW5rIHRpdGxlXG4gICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGxpbmtEZXRhaWxzWzVdID0gbGlua0RldGFpbHNbNV0uY29uY2F0KGNhcFswXSk7XG4gICAgICAgICAgICAgIGJyZWFrOyAvLyBQYXJ0IG9mIHRoZSBsaW5rIHRpdGxlXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEFmdGVyIGxpbmsgdGl0bGUgd2FzIGNsb3NlZCwgd2l0aG91dCBjbG9zaW5nIHBhcmVudGhlc2lzXG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnRPZmZzZXQgKz0gY2FwWzBdLmxlbmd0aDtcbiAgICAgICAgICBjb250aW51ZSBpbmxpbmVPdXRlcjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBcIkluZmluaXRlIGxvb3BcIjsgLy8gd2Ugc2hvdWxkIG5ldmVyIGdldCBoZXJlIHNpbmNlIHRoZSBsYXN0IHRlc3QgbWF0Y2hlcyBhbnkgY2hhcmFjdGVyXG4gICAgICB9XG4gICAgICBpZiAocGFyZW50aGVzaXNMZXZlbCA+IDApIHJldHVybiBmYWxzZTsgLy8gUGFyZW50aGVzKGVzKSBub3QgY2xvc2VkXG4gICAgfVxuXG4gICAgaWYgKGxpbmtSZWYgIT09IGZhbHNlKSB7XG4gICAgICAvLyBSZWYgbGluazsgY2hlY2sgdGhhdCBsaW5rUmVmIGlzIHZhbGlkXG4gICAgICBsZXQgdmFsaWQgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGxhYmVsIG9mIHRoaXMubGlua0xhYmVscykge1xuICAgICAgICBpZiAobGFiZWwgPT0gbGlua1JlZikge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IGxhYmVsID0gdmFsaWRcbiAgICAgICAgPyBcIlRNTGlua0xhYmVsIFRNTGlua0xhYmVsX1ZhbGlkXCJcbiAgICAgICAgOiBcIlRNTGlua0xhYmVsIFRNTGlua0xhYmVsX0ludmFsaWRcIjtcbiAgICAgIGxldCBvdXRwdXQgPSBgPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrXyR7dHlwZX1cIj4ke29wZW5lcn08L3NwYW4+PHNwYW4gY2xhc3M9XCIke3R5cGV9ICR7XG4gICAgICAgIGxpbmtMYWJlbC5sZW5ndGggPCAzIHx8ICFsaW5rTGFiZWxbMV0gPyBsYWJlbCA6IFwiXCJcbiAgICAgIH1cIj4ke3RoaXMucHJvY2Vzc0lubGluZVN0eWxlcyhcbiAgICAgICAgbGlua1RleHRcbiAgICAgICl9PC9zcGFuPjxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya18ke3R5cGV9XCI+XTwvc3Bhbj5gO1xuXG4gICAgICBpZiAobGlua0xhYmVsLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgIG91dHB1dCA9IG91dHB1dC5jb25jYXQoXG4gICAgICAgICAgYDxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya18ke3R5cGV9XCI+JHtsaW5rTGFiZWxbMF19PC9zcGFuPmAsXG4gICAgICAgICAgYDxzcGFuIGNsYXNzPVwiJHtsYWJlbH1cIj4ke2xpbmtMYWJlbFsxXX08L3NwYW4+YCxcbiAgICAgICAgICBgPHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrXyR7dHlwZX1cIj4ke2xpbmtMYWJlbFsyXX08L3NwYW4+YFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3V0cHV0OiBvdXRwdXQsXG4gICAgICAgIGNoYXJDb3VudDogY3VycmVudE9mZnNldCxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChsaW5rRGV0YWlscykge1xuICAgICAgLy8gSW5saW5lIGxpbmtcblxuICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBidXQgYmV0dGVyIHNhZmUgdGhhbiBzb3JyeS5cbiAgICAgIHdoaWxlIChsaW5rRGV0YWlscy5sZW5ndGggPCA3KSB7XG4gICAgICAgIGxpbmtEZXRhaWxzLnB1c2goXCJcIik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG91dHB1dDogYDxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya18ke3R5cGV9XCI+JHtvcGVuZXJ9PC9zcGFuPjxzcGFuIGNsYXNzPVwiJHt0eXBlfVwiPiR7dGhpcy5wcm9jZXNzSW5saW5lU3R5bGVzKFxuICAgICAgICAgIGxpbmtUZXh0XG4gICAgICAgICl9PC9zcGFuPjxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya18ke3R5cGV9XCI+XSgke1xuICAgICAgICAgIGxpbmtEZXRhaWxzWzBdXG4gICAgICAgIH08L3NwYW4+PHNwYW4gY2xhc3M9XCIke3R5cGV9RGVzdGluYXRpb25cIj4ke1xuICAgICAgICAgIGxpbmtEZXRhaWxzWzFdXG4gICAgICAgIH08L3NwYW4+PHNwYW4gY2xhc3M9XCJUTU1hcmsgVE1NYXJrXyR7dHlwZX1cIj4ke2xpbmtEZXRhaWxzWzJdfSR7XG4gICAgICAgICAgbGlua0RldGFpbHNbM11cbiAgICAgICAgfSR7bGlua0RldGFpbHNbNF19PC9zcGFuPjxzcGFuIGNsYXNzPVwiJHt0eXBlfVRpdGxlXCI+JHtcbiAgICAgICAgICBsaW5rRGV0YWlsc1s1XVxuICAgICAgICB9PC9zcGFuPjxzcGFuIGNsYXNzPVwiVE1NYXJrIFRNTWFya18ke3R5cGV9XCI+JHtsaW5rRGV0YWlsc1s2XX0pPC9zcGFuPmAsXG4gICAgICAgIGNoYXJDb3VudDogY3VycmVudE9mZnNldCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdHMgYSBtYXJrZG93biBzdHJpbmcgYXMgSFRNTCwgdXNpbmcgTWFya2Rvd24gaW5saW5lIGZvcm1hdHRpbmcuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcmlnaW5hbFN0cmluZyBUaGUgaW5wdXQgKG1hcmtkb3duIGlubGluZSBmb3JtYXR0ZWQpIHN0cmluZ1xuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgSFRNTCBmb3JtYXR0ZWQgb3V0cHV0XG4gICAqL1xuICBwcm9jZXNzSW5saW5lU3R5bGVzKG9yaWdpbmFsU3RyaW5nKSB7XG4gICAgbGV0IHByb2Nlc3NlZCA9IFwiXCI7XG4gICAgbGV0IHN0YWNrID0gW107IC8vIFN0YWNrIGlzIGFuIGFycmF5IG9mIG9iamVjdHMgb2YgdGhlIGZvcm1hdDoge2RlbGltaXRlciwgZGVsaW1TdHJpbmcsIGNvdW50LCBvdXRwdXR9XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgbGV0IHN0cmluZyA9IG9yaWdpbmFsU3RyaW5nO1xuXG4gICAgb3V0ZXI6IHdoaWxlIChzdHJpbmcpIHtcbiAgICAgIC8vIFByb2Nlc3Mgc2ltcGxlIHJ1bGVzIChub24tZGVsaW1pdGVyKVxuICAgICAgZm9yIChsZXQgcnVsZSBvZiBbXCJlc2NhcGVcIiwgXCJjb2RlXCIsIFwiYXV0b2xpbmtcIiwgXCJodG1sXCJdKSB7XG4gICAgICAgIGxldCBjYXAgPSBpbmxpbmVHcmFtbWFyW3J1bGVdLnJlZ2V4cC5leGVjKHN0cmluZyk7XG4gICAgICAgIGlmIChjYXApIHtcbiAgICAgICAgICBzdHJpbmcgPSBzdHJpbmcuc3Vic3RyKGNhcFswXS5sZW5ndGgpO1xuICAgICAgICAgIG9mZnNldCArPSBjYXBbMF0ubGVuZ3RoO1xuICAgICAgICAgIHByb2Nlc3NlZCArPSBpbmxpbmVHcmFtbWFyW3J1bGVdLnJlcGxhY2VtZW50XG4gICAgICAgICAgICAvLyAucmVwbGFjZSgvXFwkXFwkKFsxLTldKS9nLCAoc3RyLCBwMSkgPT4gcHJvY2Vzc0lubGluZVN0eWxlcyhjYXBbcDFdKSkgLy8gdG9kbyByZWN1cnNpdmUgY2FsbGluZ1xuICAgICAgICAgICAgLnJlcGxhY2UoL1xcJChbMS05XSkvZywgKHN0ciwgcDEpID0+IGh0bWxlc2NhcGUoY2FwW3AxXSkpO1xuICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBsaW5rcyAvIGltYWdlc1xuICAgICAgbGV0IHBvdGVudGlhbExpbmsgPSBzdHJpbmcubWF0Y2goaW5saW5lR3JhbW1hci5saW5rT3Blbi5yZWdleHApO1xuICAgICAgbGV0IHBvdGVudGlhbEltYWdlID0gc3RyaW5nLm1hdGNoKGlubGluZUdyYW1tYXIuaW1hZ2VPcGVuLnJlZ2V4cCk7XG4gICAgICBpZiAocG90ZW50aWFsSW1hZ2UgfHwgcG90ZW50aWFsTGluaykge1xuICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUxpbmtPckltYWdlKHN0cmluZywgcG90ZW50aWFsSW1hZ2UpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcHJvY2Vzc2VkID0gYCR7cHJvY2Vzc2VkfSR7cmVzdWx0Lm91dHB1dH1gO1xuICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zdWJzdHIocmVzdWx0LmNoYXJDb3VudCk7XG4gICAgICAgICAgb2Zmc2V0ICs9IHJlc3VsdC5jaGFyQ291bnQ7XG4gICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZm9yIGVtIC8gc3Ryb25nIGRlbGltaXRlcnNcbiAgICAgIGxldCBjYXAgPSAvKF5cXCorKXwoXl8rKS8uZXhlYyhzdHJpbmcpO1xuICAgICAgaWYgKGNhcCkge1xuICAgICAgICBsZXQgZGVsaW1Db3VudCA9IGNhcFswXS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRlbGltU3RyaW5nID0gY2FwWzBdO1xuICAgICAgICBjb25zdCBjdXJyZW50RGVsaW1pdGVyID0gY2FwWzBdWzBdOyAvLyBUaGlzIHNob3VsZCBiZSAqIG9yIF9cblxuICAgICAgICBzdHJpbmcgPSBzdHJpbmcuc3Vic3RyKGNhcFswXS5sZW5ndGgpO1xuXG4gICAgICAgIC8vIFdlIGhhdmUgYSBkZWxpbWl0ZXIgcnVuLiBMZXQncyBjaGVjayBpZiBpdCBjYW4gb3BlbiBvciBjbG9zZSBhbiBlbXBoYXNpcy5cblxuICAgICAgICBjb25zdCBwcmVjZWRpbmcgPSBvZmZzZXQgPiAwID8gb3JpZ2luYWxTdHJpbmcuc3Vic3RyKDAsIG9mZnNldCkgOiBcIiBcIjsgLy8gYmVnaW5uaW5nIGFuZCBlbmQgb2YgbGluZSBjb3VudCBhcyB3aGl0ZXNwYWNlXG4gICAgICAgIGNvbnN0IGZvbGxvd2luZyA9XG4gICAgICAgICAgb2Zmc2V0ICsgY2FwWzBdLmxlbmd0aCA8IG9yaWdpbmFsU3RyaW5nLmxlbmd0aCA/IHN0cmluZyA6IFwiIFwiO1xuXG4gICAgICAgIGNvbnN0IHB1bmN0dWF0aW9uRm9sbG93cyA9IGZvbGxvd2luZy5tYXRjaChwdW5jdHVhdGlvbkxlYWRpbmcpO1xuICAgICAgICBjb25zdCBwdW5jdHVhdGlvblByZWNlZGVzID0gcHJlY2VkaW5nLm1hdGNoKHB1bmN0dWF0aW9uVHJhaWxpbmcpO1xuICAgICAgICBjb25zdCB3aGl0ZXNwYWNlRm9sbG93cyA9IGZvbGxvd2luZy5tYXRjaCgvXlxccy8pO1xuICAgICAgICBjb25zdCB3aGl0ZXNwYWNlUHJlY2VkZXMgPSBwcmVjZWRpbmcubWF0Y2goL1xccyQvKTtcblxuICAgICAgICAvLyBUaGVzZSBhcmUgdGhlIHJ1bGVzIGZvciByaWdodC1mbGFua2luZyBhbmQgbGVmdC1mbGFua2luZyBkZWxpbWl0ZXIgcnVucyBhcyBwZXIgQ29tbW9uTWFyayBzcGVjXG4gICAgICAgIGxldCBjYW5PcGVuID1cbiAgICAgICAgICAhd2hpdGVzcGFjZUZvbGxvd3MgJiZcbiAgICAgICAgICAoIXB1bmN0dWF0aW9uRm9sbG93cyB8fFxuICAgICAgICAgICAgISF3aGl0ZXNwYWNlUHJlY2VkZXMgfHxcbiAgICAgICAgICAgICEhcHVuY3R1YXRpb25QcmVjZWRlcyk7XG4gICAgICAgIGxldCBjYW5DbG9zZSA9XG4gICAgICAgICAgIXdoaXRlc3BhY2VQcmVjZWRlcyAmJlxuICAgICAgICAgICghcHVuY3R1YXRpb25QcmVjZWRlcyB8fCAhIXdoaXRlc3BhY2VGb2xsb3dzIHx8ICEhcHVuY3R1YXRpb25Gb2xsb3dzKTtcblxuICAgICAgICAvLyBVbmRlcnNjb3JlcyBoYXZlIG1vcmUgZGV0YWlsZWQgcnVsZXMgdGhhbiBqdXN0IGJlaW5nIHBhcnQgb2YgbGVmdC0gb3IgcmlnaHQtZmxhbmtpbmcgcnVuOlxuICAgICAgICBpZiAoY3VycmVudERlbGltaXRlciA9PSBcIl9cIiAmJiBjYW5PcGVuICYmIGNhbkNsb3NlKSB7XG4gICAgICAgICAgY2FuT3BlbiA9IHB1bmN0dWF0aW9uUHJlY2VkZXM7XG4gICAgICAgICAgY2FuQ2xvc2UgPSBwdW5jdHVhdGlvbkZvbGxvd3M7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgZGVsaW1pdGVyIGNhbiBjbG9zZSwgY2hlY2sgdGhlIHN0YWNrIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGl0IGNhbiBjbG9zZVxuICAgICAgICBpZiAoY2FuQ2xvc2UpIHtcbiAgICAgICAgICBsZXQgc3RhY2tQb2ludGVyID0gc3RhY2subGVuZ3RoIC0gMTtcbiAgICAgICAgICAvLyBTZWUgaWYgd2UgY2FuIGZpbmQgYSBtYXRjaGluZyBvcGVuaW5nIGRlbGltaXRlciwgbW92ZSBkb3duIHRocm91Z2ggdGhlIHN0YWNrXG4gICAgICAgICAgd2hpbGUgKGRlbGltQ291bnQgJiYgc3RhY2tQb2ludGVyID49IDApIHtcbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFja1BvaW50ZXJdLmRlbGltaXRlciA9PSBjdXJyZW50RGVsaW1pdGVyKSB7XG4gICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGEgbWF0Y2hpbmcgZGVsaW1pdGVyLCBsZXQncyBjb25zdHJ1Y3QgdGhlIGZvcm1hdHRlZCBzdHJpbmdcblxuICAgICAgICAgICAgICAvLyBGaXJzdGx5LCBpZiB3ZSBza2lwcGVkIGFueSBzdGFjayBsZXZlbHMsIHBvcCB0aGVtIGltbWVkaWF0ZWx5IChub24tbWF0Y2hpbmcgZGVsaW1pdGVycylcbiAgICAgICAgICAgICAgd2hpbGUgKHN0YWNrUG9pbnRlciA8IHN0YWNrLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRyeSA9IHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgICAgIHByb2Nlc3NlZCA9IGAke2VudHJ5Lm91dHB1dH0ke2VudHJ5LmRlbGltU3RyaW5nLnN1YnN0cihcbiAgICAgICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAgICAgICBlbnRyeS5jb3VudFxuICAgICAgICAgICAgICAgICl9JHtwcm9jZXNzZWR9YDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIFRoZW4sIGZvcm1hdCB0aGUgc3RyaW5nXG4gICAgICAgICAgICAgIGlmIChkZWxpbUNvdW50ID49IDIgJiYgc3RhY2tbc3RhY2tQb2ludGVyXS5jb3VudCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgLy8gU3Ryb25nXG4gICAgICAgICAgICAgICAgcHJvY2Vzc2VkID0gYDxzcGFuIGNsYXNzPVwiVE1NYXJrXCI+JHtjdXJyZW50RGVsaW1pdGVyfSR7Y3VycmVudERlbGltaXRlcn08L3NwYW4+PHN0cm9uZyBjbGFzcz1cIlRNU3Ryb25nXCI+JHtwcm9jZXNzZWR9PC9zdHJvbmc+PHNwYW4gY2xhc3M9XCJUTU1hcmtcIj4ke2N1cnJlbnREZWxpbWl0ZXJ9JHtjdXJyZW50RGVsaW1pdGVyfTwvc3Bhbj5gO1xuICAgICAgICAgICAgICAgIGRlbGltQ291bnQgLT0gMjtcbiAgICAgICAgICAgICAgICBzdGFja1tzdGFja1BvaW50ZXJdLmNvdW50IC09IDI7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gRW1cbiAgICAgICAgICAgICAgICBwcm9jZXNzZWQgPSBgPHNwYW4gY2xhc3M9XCJUTU1hcmtcIj4ke2N1cnJlbnREZWxpbWl0ZXJ9PC9zcGFuPjxlbSBjbGFzcz1cIlRNRW1cIj4ke3Byb2Nlc3NlZH08L2VtPjxzcGFuIGNsYXNzPVwiVE1NYXJrXCI+JHtjdXJyZW50RGVsaW1pdGVyfTwvc3Bhbj5gO1xuICAgICAgICAgICAgICAgIGRlbGltQ291bnQgLT0gMTtcbiAgICAgICAgICAgICAgICBzdGFja1tzdGFja1BvaW50ZXJdLmNvdW50IC09IDE7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBJZiB0aGF0IHN0YWNrIGxldmVsIGlzIGVtcHR5IG5vdywgcG9wIGl0XG4gICAgICAgICAgICAgIGlmIChzdGFja1tzdGFja1BvaW50ZXJdLmNvdW50ID09IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgZW50cnkgPSBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgICAgICBwcm9jZXNzZWQgPSBgJHtlbnRyeS5vdXRwdXR9JHtwcm9jZXNzZWR9YDtcbiAgICAgICAgICAgICAgICBzdGFja1BvaW50ZXItLTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gVGhpcyBzdGFjayBsZXZlbCdzIGRlbGltaXRlciB0eXBlIGRvZXNuJ3QgbWF0Y2ggdGhlIGN1cnJlbnQgZGVsaW1pdGVyIHR5cGVcbiAgICAgICAgICAgICAgLy8gR28gZG93biBvbmUgbGV2ZWwgaW4gdGhlIHN0YWNrXG4gICAgICAgICAgICAgIHN0YWNrUG9pbnRlci0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgc3RpbGwgZGVsaW1pdGVycyBsZWZ0LCBhbmQgdGhlIGRlbGltaXRlciBydW4gY2FuIG9wZW4sIHB1c2ggaXQgb24gdGhlIHN0YWNrXG4gICAgICAgIGlmIChkZWxpbUNvdW50ICYmIGNhbk9wZW4pIHtcbiAgICAgICAgICBzdGFjay5wdXNoKHtcbiAgICAgICAgICAgIGRlbGltaXRlcjogY3VycmVudERlbGltaXRlcixcbiAgICAgICAgICAgIGRlbGltU3RyaW5nOiBkZWxpbVN0cmluZyxcbiAgICAgICAgICAgIGNvdW50OiBkZWxpbUNvdW50LFxuICAgICAgICAgICAgb3V0cHV0OiBwcm9jZXNzZWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcHJvY2Vzc2VkID0gXCJcIjsgLy8gQ3VycmVudCBmb3JtYXR0ZWQgb3V0cHV0IGhhcyBiZWVuIHB1c2hlZCBvbiB0aGUgc3RhY2sgYW5kIHdpbGwgYmUgcHJlcGVuZGVkIHdoZW4gdGhlIHN0YWNrIGdldHMgcG9wcGVkXG4gICAgICAgICAgZGVsaW1Db3VudCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBbnkgZGVsaW1pdGVycyB0aGF0IGFyZSBsZWZ0IChjbG9zaW5nIHVubWF0Y2hlZCkgYXJlIGFwcGVuZGVkIHRvIHRoZSBvdXRwdXQuXG4gICAgICAgIGlmIChkZWxpbUNvdW50KSB7XG4gICAgICAgICAgcHJvY2Vzc2VkID0gYCR7cHJvY2Vzc2VkfSR7ZGVsaW1TdHJpbmcuc3Vic3RyKDAsIGRlbGltQ291bnQpfWA7XG4gICAgICAgIH1cblxuICAgICAgICBvZmZzZXQgKz0gY2FwWzBdLmxlbmd0aDtcbiAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBzdHJpa2V0aHJvdWdoIGRlbGltaXRlclxuICAgICAgY2FwID0gL15+fi8uZXhlYyhzdHJpbmcpO1xuICAgICAgaWYgKGNhcCkge1xuICAgICAgICBsZXQgY29uc3VtZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IHN0YWNrUG9pbnRlciA9IHN0YWNrLmxlbmd0aCAtIDE7XG4gICAgICAgIC8vIFNlZSBpZiB3ZSBjYW4gZmluZCBhIG1hdGNoaW5nIG9wZW5pbmcgZGVsaW1pdGVyLCBtb3ZlIGRvd24gdGhyb3VnaCB0aGUgc3RhY2tcbiAgICAgICAgd2hpbGUgKCFjb25zdW1lZCAmJiBzdGFja1BvaW50ZXIgPj0gMCkge1xuICAgICAgICAgIGlmIChzdGFja1tzdGFja1BvaW50ZXJdLmRlbGltaXRlciA9PSBcIn5cIikge1xuICAgICAgICAgICAgLy8gV2UgZm91bmQgYSBtYXRjaGluZyBkZWxpbWl0ZXIsIGxldCdzIGNvbnN0cnVjdCB0aGUgZm9ybWF0dGVkIHN0cmluZ1xuXG4gICAgICAgICAgICAvLyBGaXJzdGx5LCBpZiB3ZSBza2lwcGVkIGFueSBzdGFjayBsZXZlbHMsIHBvcCB0aGVtIGltbWVkaWF0ZWx5IChub24tbWF0Y2hpbmcgZGVsaW1pdGVycylcbiAgICAgICAgICAgIHdoaWxlIChzdGFja1BvaW50ZXIgPCBzdGFjay5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gc3RhY2sucG9wKCk7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZCA9IGAke2VudHJ5Lm91dHB1dH0ke2VudHJ5LmRlbGltU3RyaW5nLnN1YnN0cihcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIGVudHJ5LmNvdW50XG4gICAgICAgICAgICAgICl9JHtwcm9jZXNzZWR9YDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVGhlbiwgZm9ybWF0IHRoZSBzdHJpbmdcbiAgICAgICAgICAgIHByb2Nlc3NlZCA9IGA8c3BhbiBjbGFzcz1cIlRNTWFya1wiPn5+PC9zcGFuPjxkZWwgY2xhc3M9XCJUTVN0cmlrZXRocm91Z2hcIj4ke3Byb2Nlc3NlZH08L2RlbD48c3BhbiBjbGFzcz1cIlRNTWFya1wiPn5+PC9zcGFuPmA7XG4gICAgICAgICAgICBsZXQgZW50cnkgPSBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHByb2Nlc3NlZCA9IGAke2VudHJ5Lm91dHB1dH0ke3Byb2Nlc3NlZH1gO1xuICAgICAgICAgICAgY29uc3VtZWQgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGlzIHN0YWNrIGxldmVsJ3MgZGVsaW1pdGVyIHR5cGUgZG9lc24ndCBtYXRjaCB0aGUgY3VycmVudCBkZWxpbWl0ZXIgdHlwZVxuICAgICAgICAgICAgLy8gR28gZG93biBvbmUgbGV2ZWwgaW4gdGhlIHN0YWNrXG4gICAgICAgICAgICBzdGFja1BvaW50ZXItLTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgc3RpbGwgZGVsaW1pdGVycyBsZWZ0LCBhbmQgdGhlIGRlbGltaXRlciBydW4gY2FuIG9wZW4sIHB1c2ggaXQgb24gdGhlIHN0YWNrXG4gICAgICAgIGlmICghY29uc3VtZWQpIHtcbiAgICAgICAgICBzdGFjay5wdXNoKHtcbiAgICAgICAgICAgIGRlbGltaXRlcjogXCJ+XCIsXG4gICAgICAgICAgICBkZWxpbVN0cmluZzogXCJ+flwiLFxuICAgICAgICAgICAgY291bnQ6IDIsXG4gICAgICAgICAgICBvdXRwdXQ6IHByb2Nlc3NlZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwcm9jZXNzZWQgPSBcIlwiOyAvLyBDdXJyZW50IGZvcm1hdHRlZCBvdXRwdXQgaGFzIGJlZW4gcHVzaGVkIG9uIHRoZSBzdGFjayBhbmQgd2lsbCBiZSBwcmVwZW5kZWQgd2hlbiB0aGUgc3RhY2sgZ2V0cyBwb3BwZWRcbiAgICAgICAgfVxuXG4gICAgICAgIG9mZnNldCArPSBjYXBbMF0ubGVuZ3RoO1xuICAgICAgICBzdHJpbmcgPSBzdHJpbmcuc3Vic3RyKGNhcFswXS5sZW5ndGgpO1xuICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgIH1cblxuICAgICAgLy8gUHJvY2VzcyAnZGVmYXVsdCcgcnVsZVxuICAgICAgY2FwID0gaW5saW5lR3JhbW1hci5kZWZhdWx0LnJlZ2V4cC5leGVjKHN0cmluZyk7XG4gICAgICBpZiAoY2FwKSB7XG4gICAgICAgIHN0cmluZyA9IHN0cmluZy5zdWJzdHIoY2FwWzBdLmxlbmd0aCk7XG4gICAgICAgIG9mZnNldCArPSBjYXBbMF0ubGVuZ3RoO1xuICAgICAgICBwcm9jZXNzZWQgKz0gaW5saW5lR3JhbW1hci5kZWZhdWx0LnJlcGxhY2VtZW50LnJlcGxhY2UoXG4gICAgICAgICAgL1xcJChbMS05XSkvZyxcbiAgICAgICAgICAoc3RyLCBwMSkgPT4gaHRtbGVzY2FwZShjYXBbcDFdKVxuICAgICAgICApO1xuICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgIH1cbiAgICAgIHRocm93IFwiSW5maW5pdGUgbG9vcCFcIjtcbiAgICB9XG5cbiAgICAvLyBFbXB0eSB0aGUgc3RhY2ssIGFueSBvcGVuaW5nIGRlbGltaXRlcnMgYXJlIHVudXNlZFxuICAgIHdoaWxlIChzdGFjay5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gc3RhY2sucG9wKCk7XG4gICAgICBwcm9jZXNzZWQgPSBgJHtlbnRyeS5vdXRwdXR9JHtlbnRyeS5kZWxpbVN0cmluZy5zdWJzdHIoXG4gICAgICAgIDAsXG4gICAgICAgIGVudHJ5LmNvdW50XG4gICAgICApfSR7cHJvY2Vzc2VkfWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb2Nlc3NlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIGxpbmUgZGlydHkgZmxhZyAocmVzZXRzIGl0IHRvIGFuIGFycmF5IG9mIGZhbHNlKVxuICAgKi9cbiAgY2xlYXJEaXJ0eUZsYWcoKSB7XG4gICAgdGhpcy5saW5lRGlydHkgPSBuZXcgQXJyYXkodGhpcy5saW5lcy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5saW5lRGlydHkubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMubGluZURpcnR5W2ldID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGNsYXNzIHByb3BlcnRpZXMgKGxpbmVzLCBsaW5lRWxlbWVudHMpIGZyb20gdGhlIERPTS5cbiAgICogQHJldHVybnMgdHJ1ZSBpZiBjb250ZW50cyBjaGFuZ2VkXG4gICAqL1xuICB1cGRhdGVMaW5lQ29udGVudHMoKSB7XG4gICAgLy8gdGhpcy5saW5lRGlydHkgPSBbXTtcbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGNoYW5nZWQgYW55dGhpbmcgYWJvdXQgdGhlIG51bWJlciBvZiBsaW5lcyAoaW5zZXJ0ZWQgb3IgZGVsZXRlZCBhIHBhcmFncmFwaClcbiAgICAvLyA8IDAgbWVhbnMgbGluZShzKSByZW1vdmVkOyA+IDAgbWVhbnMgbGluZShzKSBhZGRlZFxuICAgIGxldCBsaW5lRGVsdGEgPSB0aGlzLmUuY2hpbGRFbGVtZW50Q291bnQgLSB0aGlzLmxpbmVzLmxlbmd0aDtcbiAgICBpZiAobGluZURlbHRhKSB7XG4gICAgICAvLyB5dXAuIExldCdzIHRyeSBob3cgbXVjaCB3ZSBjYW4gc2FsdmFnZSAoZmluZCBvdXQgd2hpY2ggbGluZXMgZnJvbSBiZWdpbm5pbmcgYW5kIGVuZCB3ZXJlIHVuY2hhbmdlZClcbiAgICAgIC8vIEZpbmQgbGluZXMgZnJvbSB0aGUgYmVnaW5uaW5nIHRoYXQgaGF2ZW4ndCBjaGFuZ2VkLi4uXG4gICAgICBsZXQgZmlyc3RDaGFuZ2VkTGluZSA9IDA7XG4gICAgICB3aGlsZSAoXG4gICAgICAgIGZpcnN0Q2hhbmdlZExpbmUgPD0gdGhpcy5saW5lcy5sZW5ndGggJiZcbiAgICAgICAgZmlyc3RDaGFuZ2VkTGluZSA8PSB0aGlzLmxpbmVFbGVtZW50cy5sZW5ndGggJiZcbiAgICAgICAgdGhpcy5saW5lRWxlbWVudHNbZmlyc3RDaGFuZ2VkTGluZV0gJiYgLy8gQ2hlY2sgdGhhdCB0aGUgbGluZSBlbGVtZW50IGhhc24ndCBiZWVuIGRlbGV0ZWRcbiAgICAgICAgdGhpcy5saW5lc1tmaXJzdENoYW5nZWRMaW5lXSA9PVxuICAgICAgICAgIHRoaXMubGluZUVsZW1lbnRzW2ZpcnN0Q2hhbmdlZExpbmVdLnRleHRDb250ZW50XG4gICAgICApIHtcbiAgICAgICAgZmlyc3RDaGFuZ2VkTGluZSsrO1xuICAgICAgfVxuXG4gICAgICAvLyBFbmQgYWxzbyBmcm9tIHRoZSBlbmRcbiAgICAgIGxldCBsYXN0Q2hhbmdlZExpbmUgPSAtMTtcbiAgICAgIHdoaWxlIChcbiAgICAgICAgLWxhc3RDaGFuZ2VkTGluZSA8IHRoaXMubGluZXMubGVuZ3RoICYmXG4gICAgICAgIC1sYXN0Q2hhbmdlZExpbmUgPCB0aGlzLmxpbmVFbGVtZW50cy5sZW5ndGggJiZcbiAgICAgICAgdGhpcy5saW5lc1t0aGlzLmxpbmVzLmxlbmd0aCArIGxhc3RDaGFuZ2VkTGluZV0gPT1cbiAgICAgICAgICB0aGlzLmxpbmVFbGVtZW50c1t0aGlzLmxpbmVFbGVtZW50cy5sZW5ndGggKyBsYXN0Q2hhbmdlZExpbmVdXG4gICAgICAgICAgICAudGV4dENvbnRlbnRcbiAgICAgICkge1xuICAgICAgICBsYXN0Q2hhbmdlZExpbmUtLTtcbiAgICAgIH1cblxuICAgICAgbGV0IGxpbmVzVG9EZWxldGUgPVxuICAgICAgICB0aGlzLmxpbmVzLmxlbmd0aCArIGxhc3RDaGFuZ2VkTGluZSArIDEgLSBmaXJzdENoYW5nZWRMaW5lO1xuICAgICAgaWYgKGxpbmVzVG9EZWxldGUgPCAtbGluZURlbHRhKSBsaW5lc1RvRGVsZXRlID0gLWxpbmVEZWx0YTtcbiAgICAgIGlmIChsaW5lc1RvRGVsZXRlIDwgMCkgbGluZXNUb0RlbGV0ZSA9IDA7XG5cbiAgICAgIGxldCBsaW5lc1RvQWRkID0gW107XG4gICAgICBmb3IgKGxldCBsID0gMDsgbCA8IGxpbmVzVG9EZWxldGUgKyBsaW5lRGVsdGE7IGwrKykge1xuICAgICAgICBsaW5lc1RvQWRkLnB1c2godGhpcy5saW5lRWxlbWVudHNbZmlyc3RDaGFuZ2VkTGluZSArIGxdLnRleHRDb250ZW50KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3BsaWNlTGluZXMoZmlyc3RDaGFuZ2VkTGluZSwgbGluZXNUb0RlbGV0ZSwgbGluZXNUb0FkZCwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBsaW5lcyBhZGRlZCBvciByZW1vdmVkXG4gICAgICBmb3IgKGxldCBsaW5lID0gMDsgbGluZSA8IHRoaXMubGluZUVsZW1lbnRzLmxlbmd0aDsgbGluZSsrKSB7XG4gICAgICAgIGxldCBlID0gdGhpcy5saW5lRWxlbWVudHNbbGluZV07XG4gICAgICAgIGxldCBjdCA9IGUudGV4dENvbnRlbnQ7XG4gICAgICAgIGlmICh0aGlzLmxpbmVzW2xpbmVdICE9PSBjdCkge1xuICAgICAgICAgIC8vIExpbmUgY2hhbmdlZCwgdXBkYXRlIGl0XG4gICAgICAgICAgdGhpcy5saW5lc1tsaW5lXSA9IGN0O1xuICAgICAgICAgIHRoaXMubGluZURpcnR5W2xpbmVdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzZXMgYSBuZXcgcGFyYWdyYXBoLlxuICAgKiBAcGFyYW0gc2VsIFRoZSBjdXJyZW50IHNlbGVjdGlvblxuICAgKi9cbiAgcHJvY2Vzc05ld1BhcmFncmFwaChzZWwpIHtcbiAgICBpZiAoIXNlbCkgcmV0dXJuO1xuXG4gICAgLy8gVXBkYXRlIGxpbmVzIGZyb20gY29udGVudFxuICAgIHRoaXMudXBkYXRlTGluZUNvbnRlbnRzKCk7XG5cbiAgICBsZXQgY29udGludWFibGVUeXBlID0gZmFsc2U7XG4gICAgLy8gTGV0J3Mgc2VlIGlmIHdlIG5lZWQgdG8gY29udGludWUgYSBsaXN0XG5cbiAgICBsZXQgY2hlY2tMaW5lID0gc2VsLmNvbCA+IDAgPyBzZWwucm93IDogc2VsLnJvdyAtIDE7XG4gICAgc3dpdGNoICh0aGlzLmxpbmVUeXBlc1tjaGVja0xpbmVdKSB7XG4gICAgICBjYXNlIFwiVE1VTFwiOlxuICAgICAgICBjb250aW51YWJsZVR5cGUgPSBcIlRNVUxcIjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiVE1PTFwiOlxuICAgICAgICBjb250aW51YWJsZVR5cGUgPSBcIlRNT0xcIjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiVE1JbmRlbnRlZENvZGVcIjpcbiAgICAgICAgY29udGludWFibGVUeXBlID0gXCJUTUluZGVudGVkQ29kZVwiO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBsZXQgbGluZXMgPSB0aGlzLmxpbmVzW3NlbC5yb3ddXG4gICAgICAucmVwbGFjZSgvXFxuXFxuJC8sIFwiXFxuXCIpXG4gICAgICAuc3BsaXQoLyg/OlxcclxcbnxcXG58XFxyKS8pO1xuICAgIGlmIChsaW5lcy5sZW5ndGggPT0gMSkge1xuICAgICAgLy8gTm8gbmV3IGxpbmVcbiAgICAgIHRoaXMudXBkYXRlRm9ybWF0dGluZygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNwbGljZUxpbmVzKHNlbC5yb3csIDEsIGxpbmVzLCB0cnVlKTtcbiAgICBzZWwucm93Kys7XG4gICAgc2VsLmNvbCA9IDA7XG5cbiAgICBpZiAoY29udGludWFibGVUeXBlKSB7XG4gICAgICAvLyBDaGVjayBpZiB0aGUgcHJldmlvdXMgbGluZSB3YXMgbm9uLWVtcHR5XG4gICAgICBsZXQgY2FwdHVyZSA9IGxpbmVHcmFtbWFyW2NvbnRpbnVhYmxlVHlwZV0ucmVnZXhwLmV4ZWMoXG4gICAgICAgIHRoaXMubGluZXNbc2VsLnJvdyAtIDFdXG4gICAgICApO1xuICAgICAgaWYgKGNhcHR1cmUpIHtcbiAgICAgICAgLy8gQ29udmVudGlvbjogY2FwdHVyZVsxXSBpcyB0aGUgbGluZSB0eXBlIG1hcmtlciwgY2FwdHVyZVsyXSBpcyB0aGUgY29udGVudFxuICAgICAgICBpZiAoY2FwdHVyZVsyXSkge1xuICAgICAgICAgIC8vIFByZXZpb3VzIGxpbmUgaGFzIGNvbnRlbnQsIGNvbnRpbnVlIHRoZSBjb250aW51YWJsZSB0eXBlXG5cbiAgICAgICAgICAvLyBIYWNrIGZvciBPTDogaW5jcmVtZW50IG51bWJlclxuICAgICAgICAgIGlmIChjb250aW51YWJsZVR5cGUgPT0gXCJUTU9MXCIpIHtcbiAgICAgICAgICAgIGNhcHR1cmVbMV0gPSBjYXB0dXJlWzFdLnJlcGxhY2UoL1xcZHsxLDl9LywgKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQocmVzdWx0WzBdKSArIDE7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5saW5lc1tzZWwucm93XSA9IGAke2NhcHR1cmVbMV19JHt0aGlzLmxpbmVzW3NlbC5yb3ddfWA7XG4gICAgICAgICAgdGhpcy5saW5lRGlydHlbc2VsLnJvd10gPSB0cnVlO1xuICAgICAgICAgIHNlbC5jb2wgPSBjYXB0dXJlWzFdLmxlbmd0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBQcmV2aW91cyBsaW5lIGhhcyBubyBjb250ZW50LCByZW1vdmUgdGhlIGNvbnRpbnVhYmxlIHR5cGUgZnJvbSB0aGUgcHJldmlvdXMgcm93XG4gICAgICAgICAgdGhpcy5saW5lc1tzZWwucm93IC0gMV0gPSBcIlwiO1xuICAgICAgICAgIHRoaXMubGluZURpcnR5W3NlbC5yb3cgLSAxXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy51cGRhdGVGb3JtYXR0aW5nKCk7XG4gIH1cblxuICAvLyAvKipcbiAgLy8gICogUHJvY2Vzc2VzIGEgXCJkZWxldGVcIiBpbnB1dCBhY3Rpb24uXG4gIC8vICAqIEBwYXJhbSB7b2JqZWN0fSBmb2N1cyBUaGUgc2VsZWN0aW9uXG4gIC8vICAqIEBwYXJhbSB7Ym9vbGVhbn0gZm9yd2FyZCBJZiB0cnVlLCBwZXJmb3JtcyBhIGZvcndhcmQgZGVsZXRlLCBvdGhlcndpc2UgcGVyZm9ybXMgYSBiYWNrd2FyZCBkZWxldGVcbiAgLy8gICovXG4gIC8vIHByb2Nlc3NEZWxldGUoZm9jdXMsIGZvcndhcmQpIHtcbiAgLy8gICBpZiAoIWZvY3VzKSByZXR1cm47XG4gIC8vICAgbGV0IGFuY2hvciA9IHRoaXMuZ2V0U2VsZWN0aW9uKHRydWUpO1xuICAvLyAgIC8vIERvIHdlIGhhdmUgYSBub24tZW1wdHkgc2VsZWN0aW9uP1xuICAvLyAgIGlmIChmb2N1cy5jb2wgIT0gYW5jaG9yLmNvbCB8fCBmb2N1cy5yb3cgIT0gYW5jaG9yLnJvdykge1xuICAvLyAgICAgLy8gbm9uLWVtcHR5LiBkaXJlY3Rpb24gZG9lc24ndCBtYXR0ZXIuXG4gIC8vICAgICB0aGlzLnBhc3RlKCcnLCBhbmNob3IsIGZvY3VzKTtcbiAgLy8gICB9IGVsc2Uge1xuICAvLyAgICAgaWYgKGZvcndhcmQpIHtcbiAgLy8gICAgICAgaWYgKGZvY3VzLmNvbCA8IHRoaXMubGluZXNbZm9jdXMucm93XS5sZW5ndGgpIHRoaXMucGFzdGUoJycsIHtyb3c6IGZvY3VzLnJvdywgY29sOiBmb2N1cy5jb2wgKyAxfSwgZm9jdXMpO1xuICAvLyAgICAgICBlbHNlIGlmIChmb2N1cy5jb2wgPCB0aGlzLmxpbmVzLmxlbmd0aCkgdGhpcy5wYXN0ZSgnJywge3JvdzogZm9jdXMucm93ICsgMSwgY29sOiAwfSwgZm9jdXMpO1xuICAvLyAgICAgICAvLyBPdGhlcndpc2UsIHdlJ3JlIGF0IHRoZSB2ZXJ5IGVuZCBhbmQgY2FuJ3QgZGVsZXRlIGZvcndhcmRcbiAgLy8gICAgIH0gZWxzZSB7XG4gIC8vICAgICAgIGlmIChmb2N1cy5jb2wgPiAwKSB0aGlzLnBhc3RlKCcnLCB7cm93OiBmb2N1cy5yb3csIGNvbDogZm9jdXMuY29sIC0gMX0sIGZvY3VzKTtcbiAgLy8gICAgICAgZWxzZSBpZiAoZm9jdXMucm93ID4gMCkgdGhpcy5wYXN0ZSgnJywge3JvdzogZm9jdXMucm93IC0gMSwgY29sOiB0aGlzLmxpbmVzW2ZvY3VzLnJvdyAtIDFdLmxlbmd0aCAtIDF9LCBmb2N1cyk7XG4gIC8vICAgICAgIC8vIE90aGVyd2lzZSwgd2UncmUgYXQgdGhlIHZlcnkgYmVnaW5uaW5nIGFuZCBjYW4ndCBkZWxldGUgYmFja3dhcmRzXG4gIC8vICAgICB9XG4gIC8vICAgfVxuXG4gIC8vIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0aW9uIGNvdW50ZWQgYnkgcm93IGFuZCBjb2x1bW4gb2YgdGhlIGVkaXRvciBNYXJrZG93biBjb250ZW50IChhcyBvcHBvc2VkIHRvIHRoZSBwb3NpdGlvbiBpbiB0aGUgRE9NKS5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBnZXRBbmNob3IgaWYgc2V0IHRvIHRydWUsIGdldHMgdGhlIHNlbGVjdGlvbiBhbmNob3IgKHN0YXJ0IHBvaW50IG9mIHRoZSBzZWxlY3Rpb24pLCBvdGhlcndpc2UgZ2V0cyB0aGUgZm9jdXMgKGVuZCBwb2ludCkuXG4gICAqIEByZXR1cm4ge29iamVjdH0gQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgc2VsZWN0aW9uLCB3aXRoIHByb3BlcnRpZXMgY29sIGFuZCByb3cuXG4gICAqL1xuICBnZXRTZWxlY3Rpb24oZ2V0QW5jaG9yID0gZmFsc2UpIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgbGV0IHN0YXJ0Tm9kZSA9IGdldEFuY2hvciA/IHNlbGVjdGlvbi5hbmNob3JOb2RlIDogc2VsZWN0aW9uLmZvY3VzTm9kZTtcbiAgICBpZiAoIXN0YXJ0Tm9kZSkgcmV0dXJuIG51bGw7XG4gICAgbGV0IG9mZnNldCA9IGdldEFuY2hvciA/IHNlbGVjdGlvbi5hbmNob3JPZmZzZXQgOiBzZWxlY3Rpb24uZm9jdXNPZmZzZXQ7XG4gICAgaWYgKHN0YXJ0Tm9kZSA9PSB0aGlzLmUpIHtcbiAgICAgIGlmIChvZmZzZXQgPCB0aGlzLmxpbmVzLmxlbmd0aClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByb3c6IG9mZnNldCxcbiAgICAgICAgICBjb2w6IDAsXG4gICAgICAgIH07XG4gICAgICByZXR1cm4ge1xuICAgICAgICByb3c6IG9mZnNldCAtIDEsXG4gICAgICAgIGNvbDogdGhpcy5saW5lc1tvZmZzZXQgLSAxXS5sZW5ndGgsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGxldCBjb2wgPSB0aGlzLmNvbXB1dGVDb2x1bW4oc3RhcnROb2RlLCBvZmZzZXQpO1xuICAgIGlmIChjb2wgPT09IG51bGwpIHJldHVybiBudWxsOyAvLyBXZSBhcmUgb3V0c2lkZSBvZiB0aGUgZWRpdG9yXG5cbiAgICAvLyBGaW5kIHRoZSByb3cgbm9kZVxuICAgIGxldCBub2RlID0gc3RhcnROb2RlO1xuICAgIHdoaWxlIChub2RlLnBhcmVudEVsZW1lbnQgIT0gdGhpcy5lKSB7XG4gICAgICBub2RlID0gbm9kZS5wYXJlbnRFbGVtZW50O1xuICAgIH1cblxuICAgIGxldCByb3cgPSAwO1xuICAgIC8vIENoZWNrIGlmIHdlIGNhbiByZWFkIGEgbGluZSBudW1iZXIgZnJvbSB0aGUgZGF0YS1saW5lLW51bSBhdHRyaWJ1dGUuXG4gICAgLy8gVGhlIGxhc3QgY29uZGl0aW9uIGlzIGEgc2VjdXJpdHkgbWVhc3VyZSBzaW5jZSBpbnNlcnRpbmcgYSBuZXcgcGFyYWdyYXBoIGNvcGllcyB0aGUgcHJldmlvdXMgcm93cycgbGluZSBudW1iZXJcbiAgICBpZiAoXG4gICAgICBub2RlLmRhdGFzZXQgJiZcbiAgICAgIG5vZGUuZGF0YXNldC5saW5lTnVtICYmXG4gICAgICAoIW5vZGUucHJldmlvdXNTaWJsaW5nIHx8XG4gICAgICAgIG5vZGUucHJldmlvdXNTaWJsaW5nLmRhdGFzZXQubGluZU51bSAhPSBub2RlLmRhdGFzZXQubGluZU51bSlcbiAgICApIHtcbiAgICAgIHJvdyA9IHBhcnNlSW50KG5vZGUuZGF0YXNldC5saW5lTnVtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hpbGUgKG5vZGUucHJldmlvdXNTaWJsaW5nKSB7XG4gICAgICAgIHJvdysrO1xuICAgICAgICBub2RlID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHJvdzogcm93LCBjb2w6IGNvbCwgbm9kZTogc3RhcnROb2RlIH07XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgYSBjb2x1bW4gd2l0aGluIGFuIGVkaXRvciBsaW5lIGZyb20gYSBub2RlIGFuZCBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS5cbiAgICogQHBhcmFtIHtOb2RlfSBzdGFydE5vZGUgVGhlIG5vZGVcbiAgICogQHBhcmFtIHtpbnR9IG9mZnNldCBUSGUgc2VsZWN0aW9uXG4gICAqIEByZXR1cm5zIHtpbnR9IHRoZSBjb2x1bW4sIG9yIG51bGwgaWYgdGhlIG5vZGUgaXMgbm90IGluc2lkZSB0aGUgZWRpdG9yXG4gICAqL1xuICBjb21wdXRlQ29sdW1uKHN0YXJ0Tm9kZSwgb2Zmc2V0KSB7XG4gICAgbGV0IG5vZGUgPSBzdGFydE5vZGU7XG4gICAgbGV0IGNvbDtcbiAgICAvLyBGaXJzdCwgbWFrZSBzdXJlIHdlJ3JlIGFjdHVhbGx5IGluIHRoZSBlZGl0b3IuXG4gICAgd2hpbGUgKG5vZGUgJiYgbm9kZS5wYXJlbnROb2RlICE9IHRoaXMuZSkge1xuICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICB9XG4gICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBUaGVyZSBhcmUgdHdvIHdheXMgdGhhdCBvZmZzZXQgY2FuIGJlIGRlZmluZWQ6XG4gICAgLy8gLSBFaXRoZXIsIHRoZSBub2RlIGlzIGEgdGV4dCBub2RlLCBpbiB3aGljaCBjYXNlIGl0IGlzIHRoZSBvZmZzZXQgd2l0aGluIHRoZSB0ZXh0XG4gICAgLy8gLSBPciwgdGhlIG5vZGUgaXMgYW4gZWxlbWVudCB3aXRoIGNoaWxkIG5vdGVzLCBpbiB3aGljaCBjYXNlIHRoZSBvZmZzZXQgcmVmZXJzIHRvIHRoZVxuICAgIC8vICAgY2hpbGQgbm9kZSBhZnRlciB3aGljaCB0aGUgc2VsZWN0aW9uIGlzIGxvY2F0ZWRcbiAgICBpZiAoc3RhcnROb2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSB8fCBvZmZzZXQgPT09IDApIHtcbiAgICAgIC8vIEluIHRoZSBjYXNlIHRoYXQgdGhlIG5vZGUgaXMgbm9uLXRleHQgbm9kZSBidXQgdGhlIG9mZnNldCBpcyAwLFxuICAgICAgLy8gVGhlIHNlbGVjdGlvbiBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoYXQgZWxlbWVudCBzbyB3ZVxuICAgICAgLy8gY2FuIHNpbXBseSB1c2UgdGhlIHNhbWUgYXBwcm9hY2ggYXMgaWYgaXQgd2VyZSBhdCB0aGUgYmVnaW5uaW5nXG4gICAgICAvLyBvZiBhIHRleHQgbm9kZS5cbiAgICAgIGNvbCA9IG9mZnNldDtcbiAgICAgIG5vZGUgPSBzdGFydE5vZGU7XG4gICAgfSBlbHNlIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICBub2RlID0gc3RhcnROb2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV07XG4gICAgICBjb2wgPSBub2RlLnRleHRDb250ZW50Lmxlbmd0aDtcbiAgICB9XG4gICAgd2hpbGUgKG5vZGUucGFyZW50Tm9kZSAhPSB0aGlzLmUpIHtcbiAgICAgIGlmIChub2RlLnByZXZpb3VzU2libGluZykge1xuICAgICAgICBub2RlID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgIGNvbCArPSBub2RlLnRleHRDb250ZW50Lmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb2w7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgRE9NIG5vZGUgYW5kIG9mZnNldCB3aXRoaW4gdGhhdCBub2RlIGZyb20gYSBwb3NpdGlvbiBleHByZXNzZWQgYXMgcm93IGFuZCBjb2x1bW4uXG4gICAqIEBwYXJhbSB7aW50fSByb3cgUm93IChsaW5lIG51bWJlcilcbiAgICogQHBhcmFtIHtpbnR9IGNvbCBDb2x1bW5cbiAgICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggdHdvIHByb3BlcnRpZXM6IG5vZGUgYW5kIG9mZnNldC4gb2Zmc2V0IG1heSBiZSBudWxsO1xuICAgKi9cbiAgY29tcHV0ZU5vZGVBbmRPZmZzZXQocm93LCBjb2wsIGJpbmRSaWdodCA9IGZhbHNlKSB7XG4gICAgaWYgKHJvdyA+PSB0aGlzLmxpbmVFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIFNlbGVjdGlvbiBwYXN0IHRoZSBlbmQgb2YgdGV4dCwgc2V0IHNlbGVjdGlvbiB0byBlbmQgb2YgdGV4dFxuICAgICAgcm93ID0gdGhpcy5saW5lRWxlbWVudHMubGVuZ3RoIC0gMTtcbiAgICAgIGNvbCA9IHRoaXMubGluZXNbcm93XS5sZW5ndGg7XG4gICAgfVxuICAgIGlmIChjb2wgPiB0aGlzLmxpbmVzW3Jvd10ubGVuZ3RoKSB7XG4gICAgICBjb2wgPSB0aGlzLmxpbmVzW3Jvd10ubGVuZ3RoO1xuICAgIH1cbiAgICBjb25zdCBwYXJlbnROb2RlID0gdGhpcy5saW5lRWxlbWVudHNbcm93XTtcbiAgICBsZXQgbm9kZSA9IHBhcmVudE5vZGUuZmlyc3RDaGlsZDtcblxuICAgIGxldCBjaGlsZHJlbkNvbXBsZXRlID0gZmFsc2U7XG4gICAgLy8gZGVmYXVsdCByZXR1cm4gdmFsdWVcbiAgICBsZXQgcnYgPSB7XG4gICAgICBub2RlOiBwYXJlbnROb2RlLmZpcnN0Q2hpbGQgPyBwYXJlbnROb2RlLmZpcnN0Q2hpbGQgOiBwYXJlbnROb2RlLFxuICAgICAgb2Zmc2V0OiAwLFxuICAgIH07XG5cbiAgICB3aGlsZSAobm9kZSAhPSBwYXJlbnROb2RlKSB7XG4gICAgICBpZiAoIWNoaWxkcmVuQ29tcGxldGUgJiYgbm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgICAgaWYgKG5vZGUubm9kZVZhbHVlLmxlbmd0aCA+PSBjb2wpIHtcbiAgICAgICAgICBpZiAoYmluZFJpZ2h0ICYmIG5vZGUubm9kZVZhbHVlLmxlbmd0aCA9PSBjb2wpIHtcbiAgICAgICAgICAgIC8vIFNlbGVjdGlvbiBpcyBhdCB0aGUgZW5kIG9mIHRoaXMgdGV4dCBub2RlLCBidXQgd2UgYXJlIGJpbmRpbmcgcmlnaHQgKHByZWZlciBhbiBvZmZzZXQgb2YgMCBpbiB0aGUgbmV4dCB0ZXh0IG5vZGUpXG4gICAgICAgICAgICAvLyBSZW1lbWJlciByZXR1cm4gdmFsdWUgaW4gY2FzZSB3ZSBkb24ndCBmaW5kIGFub3RoZXIgdGV4dCBub2RlXG4gICAgICAgICAgICBydiA9IHsgbm9kZTogbm9kZSwgb2Zmc2V0OiBjb2wgfTtcbiAgICAgICAgICAgIGNvbCA9IDA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IG5vZGUsIG9mZnNldDogY29sIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbCAtPSBub2RlLm5vZGVWYWx1ZS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghY2hpbGRyZW5Db21wbGV0ZSAmJiBub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgbm9kZSA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgICAgIH0gZWxzZSBpZiAobm9kZS5uZXh0U2libGluZykge1xuICAgICAgICBjaGlsZHJlbkNvbXBsZXRlID0gZmFsc2U7XG4gICAgICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hpbGRyZW5Db21wbGV0ZSA9IHRydWU7XG4gICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRWl0aGVyLCB0aGUgcG9zaXRpb24gd2FzIGludmFsaWQgYW5kIHdlIGp1c3QgcmV0dXJuIHRoZSBkZWZhdWx0IHJldHVybiB2YWx1ZVxuICAgIC8vIE9yIHdlIGFyZSBiaW5kaW5nIHJpZ2h0IGFuZCB0aGUgc2VsZWN0aW9uIGlzIGF0IHRoZSBlbmQgb2YgdGhlIGxpbmVcbiAgICByZXR1cm4gcnY7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgc2VsZWN0aW9uIGJhc2VkIG9uIHJvd3MgYW5kIGNvbHVtbnMgd2l0aGluIHRoZSBlZGl0b3IgTWFya2Rvd24gY29udGVudC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGZvY3VzIE9iamVjdCByZXByZXNlbnRpbmcgdGhlIHNlbGVjdGlvbiwgbmVlZHMgdG8gaGF2ZSBwcm9wZXJ0aWVzIHJvdyBhbmQgY29sLlxuICAgKiBAcGFyYW0gYW5jaG9yIEFuY2hvciBvZiB0aGUgc2VsZWN0aW9uLiBJZiBub3QgZ2l2ZW4sIGFzc3VtZXMgdGhlIGN1cnJlbnQgYW5jaG9yLlxuICAgKi9cbiAgc2V0U2VsZWN0aW9uKGZvY3VzLCBhbmNob3IgPSBudWxsKSB7XG4gICAgaWYgKCFmb2N1cykgcmV0dXJuO1xuXG4gICAgbGV0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcblxuICAgIGxldCB7IG5vZGU6IGZvY3VzTm9kZSwgb2Zmc2V0OiBmb2N1c09mZnNldCB9ID0gdGhpcy5jb21wdXRlTm9kZUFuZE9mZnNldChcbiAgICAgIGZvY3VzLnJvdyxcbiAgICAgIGZvY3VzLmNvbCxcbiAgICAgIGFuY2hvciAmJiBhbmNob3Iucm93ID09IGZvY3VzLnJvdyAmJiBhbmNob3IuY29sID4gZm9jdXMuY29sXG4gICAgKTsgLy8gQmluZCBzZWxlY3Rpb24gcmlnaHQgaWYgYW5jaG9yIGlzIGluIHRoZSBzYW1lIHJvdyBhbmQgYmVoaW5kIHRoZSBmb2N1c1xuICAgIGxldCBhbmNob3JOb2RlID0gbnVsbCxcbiAgICAgIGFuY2hvck9mZnNldCA9IG51bGw7XG4gICAgaWYgKGFuY2hvciAmJiAoYW5jaG9yLnJvdyAhPSBmb2N1cy5yb3cgfHwgYW5jaG9yLmNvbCAhPSBmb2N1cy5jb2wpKSB7XG4gICAgICBsZXQgeyBub2RlLCBvZmZzZXQgfSA9IHRoaXMuY29tcHV0ZU5vZGVBbmRPZmZzZXQoXG4gICAgICAgIGFuY2hvci5yb3csXG4gICAgICAgIGFuY2hvci5jb2wsXG4gICAgICAgIGZvY3VzLnJvdyA9PSBhbmNob3Iucm93ICYmIGZvY3VzLmNvbCA+IGFuY2hvci5jb2xcbiAgICAgICk7XG4gICAgICBhbmNob3JOb2RlID0gbm9kZTtcbiAgICAgIGFuY2hvck9mZnNldCA9IG9mZnNldDtcbiAgICB9XG5cbiAgICBpZiAoYW5jaG9yTm9kZSkgcmFuZ2Uuc2V0U3RhcnQoYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0KTtcbiAgICBlbHNlIHJhbmdlLnNldFN0YXJ0KGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpO1xuICAgIHJhbmdlLnNldEVuZChmb2N1c05vZGUsIGZvY3VzT2Zmc2V0KTtcblxuICAgIGxldCB3aW5kb3dTZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgd2luZG93U2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHdpbmRvd1NlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gIH1cblxuICAvKipcbiAgICogRXZlbnQgaGFuZGxlciBmb3IgaW5wdXQgZXZlbnRzXG4gICAqL1xuICBoYW5kbGVJbnB1dEV2ZW50KGV2ZW50KSB7XG4gICAgLy8gRm9yIGNvbXBvc2l0aW9uIGlucHV0LCB3ZSBhcmUgb25seSB1cGRhdGluZyB0aGUgdGV4dCBhZnRlciB3ZSBoYXZlIHJlY2VpdmVkXG4gICAgLy8gYSBjb21wb3NpdGlvbmVuZCBldmVudCwgc28gd2UgcmV0dXJuIHVwb24gaW5zZXJ0Q29tcG9zaXRpb25UZXh0LlxuICAgIC8vIE90aGVyd2lzZSwgdGhlIERPTSBjaGFuZ2VzIGJyZWFrIHRoZSB0ZXh0IGlucHV0LlxuICAgIGlmIChldmVudC5pbnB1dFR5cGUgPT0gXCJpbnNlcnRDb21wb3NpdGlvblRleHRcIikgcmV0dXJuO1xuXG4gICAgbGV0IGZvY3VzID0gdGhpcy5nZXRTZWxlY3Rpb24oKTtcblxuICAgIGlmIChcbiAgICAgIChldmVudC5pbnB1dFR5cGUgPT0gXCJpbnNlcnRQYXJhZ3JhcGhcIiB8fFxuICAgICAgICBldmVudC5pbnB1dFR5cGUgPT0gXCJpbnNlcnRMaW5lQnJlYWtcIikgJiZcbiAgICAgIGZvY3VzXG4gICAgKSB7XG4gICAgICB0aGlzLmNsZWFyRGlydHlGbGFnKCk7XG4gICAgICB0aGlzLnByb2Nlc3NOZXdQYXJhZ3JhcGgoZm9jdXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuZS5maXJzdENoaWxkKSB7XG4gICAgICAgIHRoaXMuZS5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cIlRNQmxhbmtMaW5lXCI+PGJyPjwvZGl2Pic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmZpeE5vZGVIaWVyYXJjaHkoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlTGluZUNvbnRlbnRzQW5kRm9ybWF0dGluZygpO1xuICAgIH1cbiAgICBpZiAoZm9jdXMpIHtcbiAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKGZvY3VzKTtcbiAgICB9XG5cbiAgICB0aGlzLmZpcmVDaGFuZ2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXhlcyB0aGUgbm9kZSBoaWVyYXJjaHkg4oCTIG1ha2VzIHN1cmUgdGhhdCBlYWNoIGxpbmUgaXMgaW4gYSBkaXYsIGFuZCB0aGVyZSBhcmUgbm8gbmVzdGVkIGRpdnNcbiAgICovXG4gIGZpeE5vZGVIaWVyYXJjaHkoKSB7XG4gICAgY29uc3Qgb3JpZ2luYWxDaGlsZHJlbiA9IEFycmF5LmZyb20odGhpcy5lLmNoaWxkTm9kZXMpO1xuXG4gICAgY29uc3QgcmVwbGFjZUNoaWxkID0gKGNoaWxkLCAuLi5uZXdDaGlsZHJlbikgPT4ge1xuICAgICAgY29uc3QgcGFyZW50ID0gY2hpbGQucGFyZW50RWxlbWVudDtcbiAgICAgIGNvbnN0IG5leHRTaWJsaW5nID0gY2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICAgICAgbmV3Q2hpbGRyZW4uZm9yRWFjaCgobmV3Q2hpbGQpID0+XG4gICAgICAgIG5leHRTaWJsaW5nXG4gICAgICAgICAgPyBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCBuZXh0U2libGluZylcbiAgICAgICAgICA6IHBhcmVudC5hcHBlbmRDaGlsZChuZXdDaGlsZClcbiAgICAgICk7XG4gICAgfTtcblxuICAgIG9yaWdpbmFsQ2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUgfHwgY2hpbGQudGFnTmFtZSAhPT0gXCJESVZcIikge1xuICAgICAgICAvLyBGb3VuZCBhIGNoaWxkIG5vZGUgdGhhdCdzIGVpdGhlciBub3QgYW4gZWxlbWVudCBvciBub3QgYSBkaXYuIFdyYXAgaXQgaW4gYSBkaXYuXG4gICAgICAgIGNvbnN0IGRpdldyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICByZXBsYWNlQ2hpbGQoY2hpbGQsIGRpdldyYXBwZXIpO1xuICAgICAgICBkaXZXcmFwcGVyLmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hpbGQuY2hpbGROb2Rlcy5sZW5ndGggPT0gMCkge1xuICAgICAgICAvLyBFbXB0eSBkaXYgY2hpbGQgbm9kZSwgaW5jbHVkZSBhdCBsZWFzdCBhIDxiciAvPlxuICAgICAgICBjaGlsZC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYnJcIikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZ3JhbmRDaGlsZHJlbiA9IEFycmF5LmZyb20oY2hpbGQuY2hpbGROb2Rlcyk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBncmFuZENoaWxkcmVuLnNvbWUoXG4gICAgICAgICAgICAoZ3JhbmRDaGlsZCkgPT5cbiAgICAgICAgICAgICAgZ3JhbmRDaGlsZC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiZcbiAgICAgICAgICAgICAgZ3JhbmRDaGlsZC50YWdOYW1lID09PSBcIkRJVlwiXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gcmVwbGFjZUNoaWxkKGNoaWxkLCBncmFuZENoaWxkcmVuKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEV2ZW50IGhhbmRsZXIgZm9yIFwic2VsZWN0aW9uY2hhbmdlXCIgZXZlbnRzLlxuICAgKi9cbiAgaGFuZGxlU2VsZWN0aW9uQ2hhbmdlRXZlbnQoKSB7XG4gICAgdGhpcy5maXJlU2VsZWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gXCJzcGxpY2VcIiBuZXcgbGluZXMgaW50byB0aGUgYXJyYXlzIHRoaXMubGluZXMsIHRoaXMubGluZURpcnR5LCB0aGlzLmxpbmVUeXBlcywgYW5kIHRoZSBET00gZWxlbWVudHNcbiAgICogdW5kZXJuZWF0aCB0aGUgZWRpdG9yIGVsZW1lbnQuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGVzc2VudGlhbGx5IEFycmF5LnNwbGljZSwgb25seSB0aGF0IHRoZSB0aGlyZCBwYXJhbWV0ZXIgdGFrZXMgYW4gdW4tc3ByZWFkIGFycmF5IChhbmQgdGhlIGZvcnRoIHBhcmFtZXRlcilcbiAgICogZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBET00gc2hvdWxkIGFsc28gYmUgYWRqdXN0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7aW50fSBzdGFydExpbmUgUG9zaXRpb24gYXQgd2hpY2ggdG8gc3RhcnQgY2hhbmdpbmcgdGhlIGFycmF5IG9mIGxpbmVzXG4gICAqIEBwYXJhbSB7aW50fSBsaW5lc1RvRGVsZXRlIE51bWJlciBvZiBsaW5lcyB0byBkZWxldGVcbiAgICogQHBhcmFtIHthcnJheX0gbGluZXNUb0luc2VydCBBcnJheSBvZiBzdHJpbmdzIHJlcHJlc2VudGluZyB0aGUgbGluZXMgdG8gYmUgaW5zZXJ0ZWRcbiAgICogQHBhcmFtIHtib29sZWFufSBhZGp1c3RMaW5lRWxlbWVudHMgSWYgdHJ1ZSwgdGhlbiA8ZGl2PiBlbGVtZW50cyBhcmUgYWxzbyBpbnNlcnRlZCBpbiB0aGUgRE9NIGF0IHRoZSByZXNwZWN0aXZlIHBvc2l0aW9uXG4gICAqL1xuICBzcGxpY2VMaW5lcyhcbiAgICBzdGFydExpbmUsXG4gICAgbGluZXNUb0RlbGV0ZSA9IDAsXG4gICAgbGluZXNUb0luc2VydCA9IFtdLFxuICAgIGFkanVzdExpbmVFbGVtZW50cyA9IHRydWVcbiAgKSB7XG4gICAgaWYgKGFkanVzdExpbmVFbGVtZW50cykge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lc1RvRGVsZXRlOyBpKyspIHtcbiAgICAgICAgdGhpcy5lLnJlbW92ZUNoaWxkKHRoaXMuZS5jaGlsZE5vZGVzW3N0YXJ0TGluZV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBpbnNlcnRlZEJsYW5rID0gW107XG4gICAgbGV0IGluc2VydGVkRGlydHkgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXNUb0luc2VydC5sZW5ndGg7IGkrKykge1xuICAgICAgaW5zZXJ0ZWRCbGFuay5wdXNoKFwiXCIpO1xuICAgICAgaW5zZXJ0ZWREaXJ0eS5wdXNoKHRydWUpO1xuICAgICAgaWYgKGFkanVzdExpbmVFbGVtZW50cykge1xuICAgICAgICBpZiAodGhpcy5lLmNoaWxkTm9kZXNbc3RhcnRMaW5lXSlcbiAgICAgICAgICB0aGlzLmUuaW5zZXJ0QmVmb3JlKFxuICAgICAgICAgICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSxcbiAgICAgICAgICAgIHRoaXMuZS5jaGlsZE5vZGVzW3N0YXJ0TGluZV1cbiAgICAgICAgICApO1xuICAgICAgICBlbHNlIHRoaXMuZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxpbmVzLnNwbGljZShzdGFydExpbmUsIGxpbmVzVG9EZWxldGUsIC4uLmxpbmVzVG9JbnNlcnQpO1xuICAgIHRoaXMubGluZVR5cGVzLnNwbGljZShzdGFydExpbmUsIGxpbmVzVG9EZWxldGUsIC4uLmluc2VydGVkQmxhbmspO1xuICAgIHRoaXMubGluZURpcnR5LnNwbGljZShzdGFydExpbmUsIGxpbmVzVG9EZWxldGUsIC4uLmluc2VydGVkRGlydHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV2ZW50IGhhbmRsZXIgZm9yIHRoZSBcInBhc3RlXCIgZXZlbnRcbiAgICovXG4gIGhhbmRsZVBhc3RlKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIGdldCB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGNsaXBib2FyZFxuICAgIGxldCB0ZXh0ID0gKGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQpLmNsaXBib2FyZERhdGEuZ2V0RGF0YShcbiAgICAgIFwidGV4dC9wbGFpblwiXG4gICAgKTtcblxuICAgIC8vIGluc2VydCB0ZXh0IG1hbnVhbGx5XG4gICAgdGhpcy5wYXN0ZSh0ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXN0ZXMgdGhlIHRleHQgYXQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIChvciBhdCB0aGUgZW5kLCBpZiBubyBjdXJyZW50IHNlbGVjdGlvbilcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovXG4gIHBhc3RlKHRleHQsIGFuY2hvciA9IG51bGwsIGZvY3VzID0gbnVsbCkge1xuICAgIGlmICghYW5jaG9yKSBhbmNob3IgPSB0aGlzLmdldFNlbGVjdGlvbih0cnVlKTtcbiAgICBpZiAoIWZvY3VzKSBmb2N1cyA9IHRoaXMuZ2V0U2VsZWN0aW9uKGZhbHNlKTtcbiAgICBsZXQgYmVnaW5uaW5nLCBlbmQ7XG4gICAgaWYgKCFmb2N1cykge1xuICAgICAgZm9jdXMgPSB7XG4gICAgICAgIHJvdzogdGhpcy5saW5lcy5sZW5ndGggLSAxLFxuICAgICAgICBjb2w6IHRoaXMubGluZXNbdGhpcy5saW5lcy5sZW5ndGggLSAxXS5sZW5ndGgsXG4gICAgICB9OyAvLyBJbnNlcnQgYXQgZW5kXG4gICAgfVxuICAgIGlmICghYW5jaG9yKSB7XG4gICAgICBhbmNob3IgPSBmb2N1cztcbiAgICB9XG4gICAgaWYgKFxuICAgICAgYW5jaG9yLnJvdyA8IGZvY3VzLnJvdyB8fFxuICAgICAgKGFuY2hvci5yb3cgPT0gZm9jdXMucm93ICYmIGFuY2hvci5jb2wgPD0gZm9jdXMuY29sKVxuICAgICkge1xuICAgICAgYmVnaW5uaW5nID0gYW5jaG9yO1xuICAgICAgZW5kID0gZm9jdXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJlZ2lubmluZyA9IGZvY3VzO1xuICAgICAgZW5kID0gYW5jaG9yO1xuICAgIH1cbiAgICBsZXQgaW5zZXJ0ZWRMaW5lcyA9IHRleHQuc3BsaXQoLyg/OlxcclxcbnxcXHJ8XFxuKS8pO1xuICAgIGxldCBsaW5lQmVmb3JlID0gdGhpcy5saW5lc1tiZWdpbm5pbmcucm93XS5zdWJzdHIoMCwgYmVnaW5uaW5nLmNvbCk7XG4gICAgbGV0IGxpbmVFbmQgPSB0aGlzLmxpbmVzW2VuZC5yb3ddLnN1YnN0cihlbmQuY29sKTtcbiAgICBpbnNlcnRlZExpbmVzWzBdID0gbGluZUJlZm9yZS5jb25jYXQoaW5zZXJ0ZWRMaW5lc1swXSk7XG4gICAgbGV0IGVuZENvbFBvcyA9IGluc2VydGVkTGluZXNbaW5zZXJ0ZWRMaW5lcy5sZW5ndGggLSAxXS5sZW5ndGg7XG4gICAgaW5zZXJ0ZWRMaW5lc1tpbnNlcnRlZExpbmVzLmxlbmd0aCAtIDFdID1cbiAgICAgIGluc2VydGVkTGluZXNbaW5zZXJ0ZWRMaW5lcy5sZW5ndGggLSAxXS5jb25jYXQobGluZUVuZCk7XG4gICAgdGhpcy5zcGxpY2VMaW5lcyhiZWdpbm5pbmcucm93LCAxICsgZW5kLnJvdyAtIGJlZ2lubmluZy5yb3csIGluc2VydGVkTGluZXMpO1xuICAgIGZvY3VzLnJvdyA9IGJlZ2lubmluZy5yb3cgKyBpbnNlcnRlZExpbmVzLmxlbmd0aCAtIDE7XG4gICAgZm9jdXMuY29sID0gZW5kQ29sUG9zO1xuICAgIHRoaXMudXBkYXRlRm9ybWF0dGluZygpO1xuICAgIHRoaXMuc2V0U2VsZWN0aW9uKGZvY3VzKTtcbiAgICB0aGlzLmZpcmVDaGFuZ2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgKGxvd2VzdCBpbiB0aGUgRE9NIHRyZWUpIGNvbW1vbiBhbmNlc3RvciBvZiB0d28gRE9NIG5vZGVzLlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGUxIHRoZSBmaXJzdCBub2RlXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZTIgdGhlIHNlY29uZCBub2RlXG4gICAqIEByZXR1cm5zIHtOb2RlfSBUaGUgY29tbWVuIGFuY2VzdG9yIG5vZGUsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gY29tbW9uIGFuY2VzdG9yXG4gICAqL1xuICBjb21wdXRlQ29tbW9uQW5jZXN0b3Iobm9kZTEsIG5vZGUyKSB7XG4gICAgaWYgKCFub2RlMSB8fCAhbm9kZTIpIHJldHVybiBudWxsO1xuICAgIGlmIChub2RlMSA9PSBub2RlMikgcmV0dXJuIG5vZGUxO1xuICAgIGNvbnN0IGFuY2VzdHJ5ID0gKG5vZGUpID0+IHtcbiAgICAgIGxldCBhbmNlc3RyeSA9IFtdO1xuICAgICAgd2hpbGUgKG5vZGUpIHtcbiAgICAgICAgYW5jZXN0cnkudW5zaGlmdChub2RlKTtcbiAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhbmNlc3RyeTtcbiAgICB9O1xuXG4gICAgY29uc3QgYW5jZXN0cnkxID0gYW5jZXN0cnkobm9kZTEpO1xuICAgIGNvbnN0IGFuY2VzdHJ5MiA9IGFuY2VzdHJ5KG5vZGUyKTtcblxuICAgIGlmIChhbmNlc3RyeTFbMF0gIT0gYW5jZXN0cnkyWzBdKSByZXR1cm4gbnVsbDtcbiAgICBsZXQgaTtcbiAgICBmb3IgKGkgPSAwOyBhbmNlc3RyeTFbaV0gPT0gYW5jZXN0cnkyW2ldOyBpKyspO1xuICAgIHJldHVybiBhbmNlc3RyeTFbaSAtIDFdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSAobG93ZXN0IGluIHRoZSBET00gdHJlZSkgZW5jbG9zaW5nIERPTSBub2RlIHdpdGggYSBnaXZlbiBjbGFzcy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGZvY3VzIFRoZSBmb2N1cyBzZWxlY3Rpb24gb2JqZWN0XG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhbmNob3IgVGhlIGFuY2hvciBzZWxlY3Rpb24gb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWUgVGhlIGNsYXNzIG5hbWUgdG8gZmluZFxuICAgKiBAcmV0dXJucyB7Tm9kZX0gVGhlIGVuY2xvc2luZyBET00gbm9kZSB3aXRoIHRoZSByZXNwZWN0aXZlIGNsYXNzIChpbnNpZGUgdGhlIGVkaXRvciksIGlmIHRoZXJlIGlzIG9uZTsgbnVsbCBvdGhlcndpc2UuXG4gICAqL1xuICBjb21wdXRlRW5jbG9zaW5nTWFya3VwTm9kZShmb2N1cywgYW5jaG9yLCBjbGFzc05hbWUpIHtcbiAgICBsZXQgbm9kZSA9IG51bGw7XG4gICAgaWYgKCFmb2N1cykgcmV0dXJuIG51bGw7XG4gICAgaWYgKCFhbmNob3IpIHtcbiAgICAgIG5vZGUgPSBmb2N1cy5ub2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZm9jdXMucm93ICE9IGFuY2hvci5yb3cpIHJldHVybiBudWxsO1xuICAgICAgbm9kZSA9IHRoaXMuY29tcHV0ZUNvbW1vbkFuY2VzdG9yKGZvY3VzLm5vZGUsIGFuY2hvci5ub2RlKTtcbiAgICB9XG4gICAgaWYgKCFub2RlKSByZXR1cm4gbnVsbDtcbiAgICB3aGlsZSAobm9kZSAhPSB0aGlzLmUpIHtcbiAgICAgIGlmIChub2RlLmNsYXNzTmFtZSAmJiBub2RlLmNsYXNzTmFtZS5pbmNsdWRlcyhjbGFzc05hbWUpKSByZXR1cm4gbm9kZTtcbiAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIC8vIEFzY2VuZGVkIGFsbCB0aGUgd2F5IHRvIHRoZSBlZGl0b3IgZWxlbWVudFxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHN0YXRlICh0cnVlIC8gZmFsc2UpIG9mIGFsbCBjb21tYW5kcy5cbiAgICogQHBhcmFtIGZvY3VzIEZvY3VzIG9mIHRoZSBzZWxlY3Rpb24uIElmIG5vdCBnaXZlbiwgYXNzdW1lcyB0aGUgY3VycmVudCBmb2N1cy5cbiAgICogQHBhcmFtIGFuY2hvciBBbmNob3Igb2YgdGhlIHNlbGVjdGlvbi4gSWYgbm90IGdpdmVuLCBhc3N1bWVzIHRoZSBjdXJyZW50IGFuY2hvci5cbiAgICovXG4gIGdldENvbW1hbmRTdGF0ZShmb2N1cyA9IG51bGwsIGFuY2hvciA9IG51bGwpIHtcbiAgICBsZXQgY29tbWFuZFN0YXRlID0ge307XG4gICAgaWYgKCFmb2N1cykgZm9jdXMgPSB0aGlzLmdldFNlbGVjdGlvbihmYWxzZSk7XG4gICAgaWYgKCFhbmNob3IpIGFuY2hvciA9IHRoaXMuZ2V0U2VsZWN0aW9uKHRydWUpO1xuICAgIGlmICghZm9jdXMpIHtcbiAgICAgIGZvciAobGV0IGNtZCBpbiBjb21tYW5kcykge1xuICAgICAgICBjb21tYW5kU3RhdGVbY21kXSA9IG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29tbWFuZFN0YXRlO1xuICAgIH1cbiAgICBpZiAoIWFuY2hvcikgYW5jaG9yID0gZm9jdXM7XG5cbiAgICBsZXQgc3RhcnQsIGVuZDtcbiAgICBpZiAoXG4gICAgICBhbmNob3Iucm93IDwgZm9jdXMucm93IHx8XG4gICAgICAoYW5jaG9yLnJvdyA9PSBmb2N1cy5yb3cgJiYgYW5jaG9yLmNvbCA8IGZvY3VzLmNvbClcbiAgICApIHtcbiAgICAgIHN0YXJ0ID0gYW5jaG9yO1xuICAgICAgZW5kID0gZm9jdXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0ID0gZm9jdXM7XG4gICAgICBlbmQgPSBhbmNob3I7XG4gICAgfVxuICAgIGlmIChlbmQucm93ID4gc3RhcnQucm93ICYmIGVuZC5jb2wgPT0gMCkge1xuICAgICAgZW5kLnJvdy0tO1xuICAgICAgZW5kLmNvbCA9IHRoaXMubGluZXNbZW5kLnJvd10ubGVuZ3RoOyAvLyBTZWxlY3Rpb24gdG8gYmVnaW5uaW5nIG9mIG5leHQgbGluZSBpcyBzYWlkIHRvIGVuZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsYXN0IGxpbmVcbiAgICB9XG5cbiAgICBmb3IgKGxldCBjbWQgaW4gY29tbWFuZHMpIHtcbiAgICAgIGlmIChjb21tYW5kc1tjbWRdLnR5cGUgPT0gXCJpbmxpbmVcIikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWZvY3VzIHx8XG4gICAgICAgICAgZm9jdXMucm93ICE9IGFuY2hvci5yb3cgfHxcbiAgICAgICAgICAhdGhpcy5pc0lubGluZUZvcm1hdHRpbmdBbGxvd2VkKGZvY3VzLCBhbmNob3IpXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbW1hbmRTdGF0ZVtjbWRdID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBUaGUgY29tbWFuZCBzdGF0ZSBpcyB0cnVlIGlmIHRoZXJlIGlzIGEgcmVzcGVjdGl2ZSBlbmNsb3NpbmcgbWFya3VwIG5vZGUgKGUuZy4sIHRoZSBzZWxlY3Rpb24gaXMgZW5jbG9zZWQgaW4gYSA8Yj4uLjwvYj4pIC4uLlxuICAgICAgICAgIGNvbW1hbmRTdGF0ZVtjbWRdID1cbiAgICAgICAgICAgICEhdGhpcy5jb21wdXRlRW5jbG9zaW5nTWFya3VwTm9kZShcbiAgICAgICAgICAgICAgZm9jdXMsXG4gICAgICAgICAgICAgIGFuY2hvcixcbiAgICAgICAgICAgICAgY29tbWFuZHNbY21kXS5jbGFzc05hbWVcbiAgICAgICAgICAgICkgfHxcbiAgICAgICAgICAgIC8vIC4uLiBvciBpZiBpdCdzIGFuIGVtcHR5IHN0cmluZyBwcmVjZWRlZCBieSBhbmQgZm9sbG93ZWQgYnkgZm9ybWF0dGluZyBtYXJrZXJzLCBlLmcuICoqfCoqIHdoZXJlIHwgaXMgdGhlIGN1cnNvclxuICAgICAgICAgICAgKGZvY3VzLmNvbCA9PSBhbmNob3IuY29sICYmXG4gICAgICAgICAgICAgICEhdGhpcy5saW5lc1tmb2N1cy5yb3ddXG4gICAgICAgICAgICAgICAgLnN1YnN0cigwLCBmb2N1cy5jb2wpXG4gICAgICAgICAgICAgICAgLm1hdGNoKGNvbW1hbmRzW2NtZF0udW5zZXQucHJlUGF0dGVybikgJiZcbiAgICAgICAgICAgICAgISF0aGlzLmxpbmVzW2ZvY3VzLnJvd11cbiAgICAgICAgICAgICAgICAuc3Vic3RyKGZvY3VzLmNvbClcbiAgICAgICAgICAgICAgICAubWF0Y2goY29tbWFuZHNbY21kXS51bnNldC5wb3N0UGF0dGVybikpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY29tbWFuZHNbY21kXS50eXBlID09IFwibGluZVwiKSB7XG4gICAgICAgIGlmICghZm9jdXMpIHtcbiAgICAgICAgICBjb21tYW5kU3RhdGVbY21kXSA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5saW5lVHlwZXNbc3RhcnQucm93XSA9PSBjb21tYW5kc1tjbWRdLmNsYXNzTmFtZTtcblxuICAgICAgICAgIGZvciAobGV0IGxpbmUgPSBzdGFydC5yb3c7IGxpbmUgPD0gZW5kLnJvdzsgbGluZSsrKSB7XG4gICAgICAgICAgICBpZiAoKHRoaXMubGluZVR5cGVzW2xpbmVdID09IGNvbW1hbmRzW2NtZF0uY2xhc3NOYW1lKSAhPSBzdGF0ZSkge1xuICAgICAgICAgICAgICBzdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb21tYW5kU3RhdGVbY21kXSA9IHN0YXRlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb21tYW5kU3RhdGU7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIGNvbW1hbmQgc3RhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbW1hbmRcbiAgICogQHBhcmFtIHtib29sZWFufSBzdGF0ZVxuICAgKi9cbiAgc2V0Q29tbWFuZFN0YXRlKGNvbW1hbmQsIHN0YXRlKSB7XG4gICAgaWYgKGNvbW1hbmRzW2NvbW1hbmRdLnR5cGUgPT0gXCJpbmxpbmVcIikge1xuICAgICAgbGV0IGFuY2hvciA9IHRoaXMuZ2V0U2VsZWN0aW9uKHRydWUpO1xuICAgICAgbGV0IGZvY3VzID0gdGhpcy5nZXRTZWxlY3Rpb24oZmFsc2UpO1xuICAgICAgaWYgKCFhbmNob3IpIGFuY2hvciA9IGZvY3VzO1xuICAgICAgaWYgKCFhbmNob3IpIHJldHVybjtcbiAgICAgIGlmIChhbmNob3Iucm93ICE9IGZvY3VzLnJvdykgcmV0dXJuO1xuICAgICAgaWYgKCF0aGlzLmlzSW5saW5lRm9ybWF0dGluZ0FsbG93ZWQoZm9jdXMsIGFuY2hvcikpIHJldHVybjtcbiAgICAgIGxldCBtYXJrdXBOb2RlID0gdGhpcy5jb21wdXRlRW5jbG9zaW5nTWFya3VwTm9kZShcbiAgICAgICAgZm9jdXMsXG4gICAgICAgIGFuY2hvcixcbiAgICAgICAgY29tbWFuZHNbY29tbWFuZF0uY2xhc3NOYW1lXG4gICAgICApO1xuICAgICAgdGhpcy5jbGVhckRpcnR5RmxhZygpO1xuXG4gICAgICAvLyBGaXJzdCBjYXNlOiBUaGVyZSdzIGFuIGVuY2xvc2luZyBtYXJrdXAgbm9kZSwgcmVtb3ZlIHRoZSBtYXJrZXJzIGFyb3VuZCB0aGF0IG1hcmt1cCBub2RlXG4gICAgICBpZiAobWFya3VwTm9kZSkge1xuICAgICAgICB0aGlzLmxpbmVEaXJ0eVtmb2N1cy5yb3ddID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgc3RhcnRDb2wgPSB0aGlzLmNvbXB1dGVDb2x1bW4obWFya3VwTm9kZSwgMCk7XG4gICAgICAgIGNvbnN0IGxlbiA9IG1hcmt1cE5vZGUudGV4dENvbnRlbnQubGVuZ3RoO1xuICAgICAgICBjb25zdCBsZWZ0ID0gdGhpcy5saW5lc1tmb2N1cy5yb3ddXG4gICAgICAgICAgLnN1YnN0cigwLCBzdGFydENvbClcbiAgICAgICAgICAucmVwbGFjZShjb21tYW5kc1tjb21tYW5kXS51bnNldC5wcmVQYXR0ZXJuLCBcIlwiKTtcbiAgICAgICAgY29uc3QgbWlkID0gdGhpcy5saW5lc1tmb2N1cy5yb3ddLnN1YnN0cihzdGFydENvbCwgbGVuKTtcbiAgICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLmxpbmVzW2ZvY3VzLnJvd11cbiAgICAgICAgICAuc3Vic3RyKHN0YXJ0Q29sICsgbGVuKVxuICAgICAgICAgIC5yZXBsYWNlKGNvbW1hbmRzW2NvbW1hbmRdLnVuc2V0LnBvc3RQYXR0ZXJuLCBcIlwiKTtcbiAgICAgICAgdGhpcy5saW5lc1tmb2N1cy5yb3ddID0gbGVmdC5jb25jYXQobWlkLCByaWdodCk7XG4gICAgICAgIGFuY2hvci5jb2wgPSBsZWZ0Lmxlbmd0aDtcbiAgICAgICAgZm9jdXMuY29sID0gYW5jaG9yLmNvbCArIGxlbjtcbiAgICAgICAgdGhpcy51cGRhdGVGb3JtYXR0aW5nKCk7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKGZvY3VzLCBhbmNob3IpO1xuICAgICAgICB0aGlzLmZpcmVDaGFuZ2UoKTtcblxuICAgICAgICAvLyBTZWNvbmQgY2FzZTogRW1wdHkgc2VsZWN0aW9uIHdpdGggc3Vycm91bmRpbmcgZm9ybWF0dGluZyBtYXJrZXJzLCByZW1vdmUgdGhvc2VcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGZvY3VzLmNvbCA9PSBhbmNob3IuY29sICYmXG4gICAgICAgICEhdGhpcy5saW5lc1tmb2N1cy5yb3ddXG4gICAgICAgICAgLnN1YnN0cigwLCBmb2N1cy5jb2wpXG4gICAgICAgICAgLm1hdGNoKGNvbW1hbmRzW2NvbW1hbmRdLnVuc2V0LnByZVBhdHRlcm4pICYmXG4gICAgICAgICEhdGhpcy5saW5lc1tmb2N1cy5yb3ddXG4gICAgICAgICAgLnN1YnN0cihmb2N1cy5jb2wpXG4gICAgICAgICAgLm1hdGNoKGNvbW1hbmRzW2NvbW1hbmRdLnVuc2V0LnBvc3RQYXR0ZXJuKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMubGluZURpcnR5W2ZvY3VzLnJvd10gPSB0cnVlO1xuICAgICAgICBjb25zdCBsZWZ0ID0gdGhpcy5saW5lc1tmb2N1cy5yb3ddXG4gICAgICAgICAgLnN1YnN0cigwLCBmb2N1cy5jb2wpXG4gICAgICAgICAgLnJlcGxhY2UoY29tbWFuZHNbY29tbWFuZF0udW5zZXQucHJlUGF0dGVybiwgXCJcIik7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5saW5lc1tmb2N1cy5yb3ddXG4gICAgICAgICAgLnN1YnN0cihmb2N1cy5jb2wpXG4gICAgICAgICAgLnJlcGxhY2UoY29tbWFuZHNbY29tbWFuZF0udW5zZXQucG9zdFBhdHRlcm4sIFwiXCIpO1xuICAgICAgICB0aGlzLmxpbmVzW2ZvY3VzLnJvd10gPSBsZWZ0LmNvbmNhdChyaWdodCk7XG4gICAgICAgIGZvY3VzLmNvbCA9IGFuY2hvci5jb2wgPSBsZWZ0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy51cGRhdGVGb3JtYXR0aW5nKCk7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKGZvY3VzLCBhbmNob3IpO1xuICAgICAgICB0aGlzLmZpcmVDaGFuZ2UoKTtcblxuICAgICAgICAvLyBOb3QgY3VycmVudGx5IGZvcm1hdHRlZCwgaW5zZXJ0IGZvcm1hdHRpbmcgbWFya2Vyc1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVHJpbSBhbnkgc3BhY2VzIGZyb20gdGhlIHNlbGVjdGlvblxuICAgICAgICBsZXQgeyBzdGFydENvbCwgZW5kQ29sIH0gPVxuICAgICAgICAgIGZvY3VzLmNvbCA8IGFuY2hvci5jb2xcbiAgICAgICAgICAgID8geyBzdGFydENvbDogZm9jdXMuY29sLCBlbmRDb2w6IGFuY2hvci5jb2wgfVxuICAgICAgICAgICAgOiB7IHN0YXJ0Q29sOiBhbmNob3IuY29sLCBlbmRDb2w6IGZvY3VzLmNvbCB9O1xuXG4gICAgICAgIGxldCBtYXRjaCA9IHRoaXMubGluZXNbZm9jdXMucm93XVxuICAgICAgICAgIC5zdWJzdHIoc3RhcnRDb2wsIGVuZENvbCAtIHN0YXJ0Q29sKVxuICAgICAgICAgIC5tYXRjaCgvXig/PGxlYWRpbmc+XFxzKikuKlxcUyg/PHRyYWlsaW5nPlxccyopJC8pO1xuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICBzdGFydENvbCArPSBtYXRjaC5ncm91cHMubGVhZGluZy5sZW5ndGg7XG4gICAgICAgICAgZW5kQ29sIC09IG1hdGNoLmdyb3Vwcy50cmFpbGluZy5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICBmb2N1cy5jb2wgPSBzdGFydENvbDtcbiAgICAgICAgYW5jaG9yLmNvbCA9IGVuZENvbDtcblxuICAgICAgICAvLyBKdXN0IGluc2VydCBtYXJrdXAgYmVmb3JlIGFuZCBhZnRlciBhbmQgaG9wZSBmb3IgdGhlIGJlc3QuXG4gICAgICAgIHRoaXMud3JhcFNlbGVjdGlvbihcbiAgICAgICAgICBjb21tYW5kc1tjb21tYW5kXS5zZXQucHJlLFxuICAgICAgICAgIGNvbW1hbmRzW2NvbW1hbmRdLnNldC5wb3N0LFxuICAgICAgICAgIGZvY3VzLFxuICAgICAgICAgIGFuY2hvclxuICAgICAgICApO1xuICAgICAgICB0aGlzLmZpcmVDaGFuZ2UoKTtcbiAgICAgICAgLy8gVE9ETyBjbGVhbiB0aGlzIHVwIHNvIHRoYXQgbWFya3VwIHJlbWFpbnMgcHJvcGVybHkgbmVzdGVkXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb21tYW5kc1tjb21tYW5kXS50eXBlID09IFwibGluZVwiKSB7XG4gICAgICBsZXQgYW5jaG9yID0gdGhpcy5nZXRTZWxlY3Rpb24odHJ1ZSk7XG4gICAgICBsZXQgZm9jdXMgPSB0aGlzLmdldFNlbGVjdGlvbihmYWxzZSk7XG4gICAgICBpZiAoIWFuY2hvcikgYW5jaG9yID0gZm9jdXM7XG4gICAgICBpZiAoIWZvY3VzKSByZXR1cm47XG4gICAgICB0aGlzLmNsZWFyRGlydHlGbGFnKCk7XG4gICAgICBsZXQgc3RhcnQgPSBhbmNob3Iucm93ID4gZm9jdXMucm93ID8gZm9jdXMgOiBhbmNob3I7XG4gICAgICBsZXQgZW5kID0gYW5jaG9yLnJvdyA+IGZvY3VzLnJvdyA/IGFuY2hvciA6IGZvY3VzO1xuICAgICAgaWYgKGVuZC5yb3cgPiBzdGFydC5yb3cgJiYgZW5kLmNvbCA9PSAwKSB7XG4gICAgICAgIGVuZC5yb3ctLTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgbGluZSA9IHN0YXJ0LnJvdzsgbGluZSA8PSBlbmQucm93OyBsaW5lKyspIHtcbiAgICAgICAgaWYgKHN0YXRlICYmIHRoaXMubGluZVR5cGVzW2xpbmVdICE9IGNvbW1hbmRzW2NvbW1hbmRdLmNsYXNzTmFtZSkge1xuICAgICAgICAgIHRoaXMubGluZXNbbGluZV0gPSB0aGlzLmxpbmVzW2xpbmVdLnJlcGxhY2UoXG4gICAgICAgICAgICBjb21tYW5kc1tjb21tYW5kXS5zZXQucGF0dGVybixcbiAgICAgICAgICAgIGNvbW1hbmRzW2NvbW1hbmRdLnNldC5yZXBsYWNlbWVudC5yZXBsYWNlKFxuICAgICAgICAgICAgICBcIiQjXCIsXG4gICAgICAgICAgICAgIGxpbmUgLSBzdGFydC5yb3cgKyAxXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLmxpbmVEaXJ0eVtsaW5lXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzdGF0ZSAmJiB0aGlzLmxpbmVUeXBlc1tsaW5lXSA9PSBjb21tYW5kc1tjb21tYW5kXS5jbGFzc05hbWUpIHtcbiAgICAgICAgICB0aGlzLmxpbmVzW2xpbmVdID0gdGhpcy5saW5lc1tsaW5lXS5yZXBsYWNlKFxuICAgICAgICAgICAgY29tbWFuZHNbY29tbWFuZF0udW5zZXQucGF0dGVybixcbiAgICAgICAgICAgIGNvbW1hbmRzW2NvbW1hbmRdLnVuc2V0LnJlcGxhY2VtZW50XG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLmxpbmVEaXJ0eVtsaW5lXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlRm9ybWF0dGluZygpO1xuICAgICAgdGhpcy5zZXRTZWxlY3Rpb24oXG4gICAgICAgIHsgcm93OiBlbmQucm93LCBjb2w6IHRoaXMubGluZXNbZW5kLnJvd10ubGVuZ3RoIH0sXG4gICAgICAgIHsgcm93OiBzdGFydC5yb3csIGNvbDogMCB9XG4gICAgICApO1xuICAgICAgdGhpcy5maXJlQ2hhbmdlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBvciBub3QgaW5saW5lIGZvcm1hdHRpbmcgaXMgYWxsb3dlZCBhdCB0aGUgY3VycmVudCBmb2N1c1xuICAgKiBAcGFyYW0ge29iamVjdH0gZm9jdXMgVGhlIGN1cnJlbnQgZm9jdXNcbiAgICovXG4gIGlzSW5saW5lRm9ybWF0dGluZ0FsbG93ZWQoKSB7XG4gICAgLy8gVE9ETyBSZW1vdmUgcGFyYW1ldGVycyBmcm9tIGFsbCBjYWxsc1xuICAgIGNvbnN0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbCB8fCAhc2VsLmZvY3VzTm9kZSB8fCAhc2VsLmFuY2hvck5vZGUpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIENoZWNrIGlmIHdlIGNhbiBmaW5kIGEgY29tbW9uIGFuY2VzdG9yIHdpdGggdGhlIGNsYXNzIGBUTUlubGluZUZvcm1hdHRlZGBcblxuICAgIC8vIFNwZWNpYWwgY2FzZTogRW1wdHkgc2VsZWN0aW9uIHJpZ2h0IGJlZm9yZSBgVE1JbmxpbmVGb3JtYXR0ZWRgXG4gICAgaWYgKFxuICAgICAgc2VsLmlzQ29sbGFwc2VkICYmXG4gICAgICBzZWwuZm9jdXNOb2RlLm5vZGVUeXBlID09IDMgJiZcbiAgICAgIHNlbC5mb2N1c09mZnNldCA9PSBzZWwuZm9jdXNOb2RlLm5vZGVWYWx1ZS5sZW5ndGhcbiAgICApIHtcbiAgICAgIGxldCBub2RlO1xuICAgICAgZm9yIChcbiAgICAgICAgbm9kZSA9IHNlbC5mb2N1c05vZGU7XG4gICAgICAgIG5vZGUgJiYgbm9kZS5uZXh0U2libGluZyA9PSBudWxsO1xuICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBub2RlICYmXG4gICAgICAgIG5vZGUubmV4dFNpYmxpbmcuY2xhc3NOYW1lICYmXG4gICAgICAgIG5vZGUubmV4dFNpYmxpbmcuY2xhc3NOYW1lLmluY2x1ZGVzKFwiVE1JbmxpbmVGb3JtYXR0ZWRcIilcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gTG9vayBmb3IgYSBjb21tb24gYW5jZXN0b3JcbiAgICBsZXQgYW5jZXN0b3IgPSB0aGlzLmNvbXB1dGVDb21tb25BbmNlc3RvcihzZWwuZm9jdXNOb2RlLCBzZWwuYW5jaG9yTm9kZSk7XG4gICAgaWYgKCFhbmNlc3RvcikgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlcmUncyBhbiBhbmNlc3RvciBvZiBjbGFzcyAnVE1JbmxpbmVGb3JtYXR0ZWQnIG9yICdUTUJsYW5rTGluZSdcbiAgICB3aGlsZSAoYW5jZXN0b3IgJiYgYW5jZXN0b3IgIT0gdGhpcy5lKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGFuY2VzdG9yLmNsYXNzTmFtZSAmJlxuICAgICAgICAoYW5jZXN0b3IuY2xhc3NOYW1lLmluY2x1ZGVzKFwiVE1JbmxpbmVGb3JtYXR0ZWRcIikgfHxcbiAgICAgICAgICBhbmNlc3Rvci5jbGFzc05hbWUuaW5jbHVkZXMoXCJUTUJsYW5rTGluZVwiKSlcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudE5vZGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbiB0aGUgc3RyaW5ncyBwcmUgYW5kIHBvc3QuIElmIHRoZSBzZWxlY3Rpb24gaXMgbm90IG9uIG9uZSBsaW5lLCByZXR1cm5zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJlIFRoZSBzdHJpbmcgdG8gaW5zZXJ0IGJlZm9yZSB0aGUgc2VsZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zdCBUaGUgc3RyaW5nIHRvIGluc2VydCBhZnRlciB0aGUgc2VsZWN0aW9uLlxuICAgKiBAcGFyYW0ge29iamVjdH0gZm9jdXMgVGhlIGN1cnJlbnQgc2VsZWN0aW9uIGZvY3VzLiBJZiBudWxsLCBzZWxlY3Rpb24gd2lsbCBiZSBjb21wdXRlZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFuY2hvciBUaGUgY3VycmVudCBzZWxlY3Rpb24gZm9jdXMuIElmIG51bGwsIHNlbGVjdGlvbiB3aWxsIGJlIGNvbXB1dGVkLlxuICAgKi9cbiAgd3JhcFNlbGVjdGlvbihwcmUsIHBvc3QsIGZvY3VzID0gbnVsbCwgYW5jaG9yID0gbnVsbCkge1xuICAgIGlmICghZm9jdXMpIGZvY3VzID0gdGhpcy5nZXRTZWxlY3Rpb24oZmFsc2UpO1xuICAgIGlmICghYW5jaG9yKSBhbmNob3IgPSB0aGlzLmdldFNlbGVjdGlvbih0cnVlKTtcbiAgICBpZiAoIWZvY3VzIHx8ICFhbmNob3IgfHwgZm9jdXMucm93ICE9IGFuY2hvci5yb3cpIHJldHVybjtcbiAgICB0aGlzLmxpbmVEaXJ0eVtmb2N1cy5yb3ddID0gdHJ1ZTtcblxuICAgIGNvbnN0IHN0YXJ0Q29sID0gZm9jdXMuY29sIDwgYW5jaG9yLmNvbCA/IGZvY3VzLmNvbCA6IGFuY2hvci5jb2w7XG4gICAgY29uc3QgZW5kQ29sID0gZm9jdXMuY29sIDwgYW5jaG9yLmNvbCA/IGFuY2hvci5jb2wgOiBmb2N1cy5jb2w7XG4gICAgY29uc3QgbGVmdCA9IHRoaXMubGluZXNbZm9jdXMucm93XS5zdWJzdHIoMCwgc3RhcnRDb2wpLmNvbmNhdChwcmUpO1xuICAgIGNvbnN0IG1pZCA9XG4gICAgICBlbmRDb2wgPT0gc3RhcnRDb2xcbiAgICAgICAgPyBcIlwiXG4gICAgICAgIDogdGhpcy5saW5lc1tmb2N1cy5yb3ddLnN1YnN0cihzdGFydENvbCwgZW5kQ29sIC0gc3RhcnRDb2wpO1xuICAgIGNvbnN0IHJpZ2h0ID0gcG9zdC5jb25jYXQodGhpcy5saW5lc1tmb2N1cy5yb3ddLnN1YnN0cihlbmRDb2wpKTtcbiAgICB0aGlzLmxpbmVzW2ZvY3VzLnJvd10gPSBsZWZ0LmNvbmNhdChtaWQsIHJpZ2h0KTtcbiAgICBhbmNob3IuY29sID0gbGVmdC5sZW5ndGg7XG4gICAgZm9jdXMuY29sID0gYW5jaG9yLmNvbCArIG1pZC5sZW5ndGg7XG5cbiAgICB0aGlzLnVwZGF0ZUZvcm1hdHRpbmcoKTtcbiAgICB0aGlzLnNldFNlbGVjdGlvbihmb2N1cywgYW5jaG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIHRoZSBjb21tYW5kIHN0YXRlIGZvciBhIGNvbW1hbmQgKHRydWUgPC0+IGZhbHNlKVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29tbWFuZCBUaGUgZWRpdG9yIGNvbW1hbmRcbiAgICovXG4gIHRvZ2dsZUNvbW1hbmRTdGF0ZShjb21tYW5kKSB7XG4gICAgaWYgKCF0aGlzLmxhc3RDb21tYW5kU3RhdGUpIHRoaXMubGFzdENvbW1hbmRTdGF0ZSA9IHRoaXMuZ2V0Q29tbWFuZFN0YXRlKCk7XG4gICAgdGhpcy5zZXRDb21tYW5kU3RhdGUoY29tbWFuZCwgIXRoaXMubGFzdENvbW1hbmRTdGF0ZVtjb21tYW5kXSk7XG4gIH1cblxuICAvKipcbiAgICogRmlyZXMgYSBjaGFuZ2UgZXZlbnQuIFVwZGF0ZXMgdGhlIGxpbmtlZCB0ZXh0YXJlYSBhbmQgbm90aWZpZXMgYW55IGV2ZW50IGxpc3RlbmVycy5cbiAgICovXG4gIGZpcmVDaGFuZ2UoKSB7XG4gICAgaWYgKCF0aGlzLnRleHRhcmVhICYmICF0aGlzLmxpc3RlbmVycy5jaGFuZ2UubGVuZ3RoKSByZXR1cm47XG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuZ2V0Q29udGVudCgpO1xuICAgIGlmICh0aGlzLnRleHRhcmVhKSB0aGlzLnRleHRhcmVhLnZhbHVlID0gY29udGVudDtcbiAgICBmb3IgKGxldCBsaXN0ZW5lciBvZiB0aGlzLmxpc3RlbmVycy5jaGFuZ2UpIHtcbiAgICAgIGxpc3RlbmVyKHtcbiAgICAgICAgY29udGVudDogY29udGVudCxcbiAgICAgICAgbGluZXNEaXJ0eTogdGhpcy5saW5lc0RpcnR5LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpcmVzIGEgXCJzZWxlY3Rpb24gY2hhbmdlZFwiIGV2ZW50LlxuICAgKi9cbiAgZmlyZVNlbGVjdGlvbigpIHtcbiAgICBpZiAodGhpcy5saXN0ZW5lcnMuc2VsZWN0aW9uICYmIHRoaXMubGlzdGVuZXJzLnNlbGVjdGlvbi5sZW5ndGgpIHtcbiAgICAgIGxldCBmb2N1cyA9IHRoaXMuZ2V0U2VsZWN0aW9uKGZhbHNlKTtcbiAgICAgIGxldCBhbmNob3IgPSB0aGlzLmdldFNlbGVjdGlvbih0cnVlKTtcbiAgICAgIGxldCBjb21tYW5kU3RhdGUgPSB0aGlzLmdldENvbW1hbmRTdGF0ZShmb2N1cywgYW5jaG9yKTtcbiAgICAgIGlmICh0aGlzLmxhc3RDb21tYW5kU3RhdGUpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLmxhc3RDb21tYW5kU3RhdGUsIGNvbW1hbmRTdGF0ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxhc3RDb21tYW5kU3RhdGUgPSBPYmplY3QuYXNzaWduKHt9LCBjb21tYW5kU3RhdGUpO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgbGlzdGVuZXIgb2YgdGhpcy5saXN0ZW5lcnMuc2VsZWN0aW9uKSB7XG4gICAgICAgIGxpc3RlbmVyKHtcbiAgICAgICAgICBmb2N1czogZm9jdXMsXG4gICAgICAgICAgYW5jaG9yOiBhbmNob3IsXG4gICAgICAgICAgY29tbWFuZFN0YXRlOiB0aGlzLmxhc3RDb21tYW5kU3RhdGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIGV2ZW50IGxpc3RlbmVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgdHlwZSBvZiBldmVudCB0byBsaXN0ZW4gdG8uIENhbiBiZSAnY2hhbmdlJyBvciAnc2VsZWN0aW9uJ1xuICAgKiBAcGFyYW0geyp9IGxpc3RlbmVyIEZ1bmN0aW9uIG9mIHRoZSB0eXBlIChldmVudCkgPT4ge30gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IG9jY3Vycy5cbiAgICovXG4gIGFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICBpZiAodHlwZS5tYXRjaCgvXig/OmNoYW5nZXxpbnB1dCkkL2kpKSB7XG4gICAgICB0aGlzLmxpc3RlbmVycy5jaGFuZ2UucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuICAgIGlmICh0eXBlLm1hdGNoKC9eKD86c2VsZWN0aW9ufHNlbGVjdGlvbmNoYW5nZSkkL2kpKSB7XG4gICAgICB0aGlzLmxpc3RlbmVycy5zZWxlY3Rpb24ucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEVkaXRvcjtcbiJdLCJuYW1lcyI6WyJzdmciLCJibG9ja3F1b3RlIiwiYm9sZCIsImNsZWFyX2Zvcm1hdHRpbmciLCJjb2RlIiwiaDEiLCJoMiIsImhyIiwiaW1hZ2UiLCJpdGFsaWMiLCJsaW5rIiwib2wiLCJzdHJpa2V0aHJvdWdoIiwidWwiLCJpc01hY0xpa2UiLCJ0ZXN0IiwibmF2aWdhdG9yIiwicGxhdGZvcm0iLCJEZWZhdWx0Q29tbWFuZHMiLCJuYW1lIiwiYWN0aW9uIiwiaW5uZXJIVE1MIiwidGl0bGUiLCJob3RrZXkiLCJlZGl0b3IiLCJpc0lubGluZUZvcm1hdHRpbmdBbGxvd2VkIiwid3JhcFNlbGVjdGlvbiIsImVuYWJsZWQiLCJmb2N1cyIsImFuY2hvciIsInBhc3RlIiwiQ29tbWFuZEJhciIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJlIiwiY29tbWFuZHMiLCJidXR0b25zIiwic3RhdGUiLCJob3RrZXlzIiwiZWxlbWVudCIsInRhZ05hbWUiLCJkb2N1bWVudCIsImdldEVsZW1lbnRCeUlkIiwiYm9keSIsImNyZWF0ZUNvbW1hbmRCYXJFbGVtZW50IiwiYWRkRXZlbnRMaXN0ZW5lciIsImhhbmRsZUtleWRvd24iLCJzZXRFZGl0b3IiLCJwYXJlbnRFbGVtZW50IiwiY3JlYXRlRWxlbWVudCIsImNsYXNzTmFtZSIsImNvbW1hbmQiLCJlbCIsImFwcGVuZENoaWxkIiwiY29tbWFuZE5hbWUiLCJPYmplY3QiLCJhc3NpZ24iLCJrZXlzIiwic3BsaXQiLCJtb2RpZmllcnMiLCJtb2RpZmllcmV4cGxhbmF0aW9uIiwiaSIsImxlbmd0aCIsInB1c2giLCJtYXRjaCIsImtleSIsInRvTG93ZXJDYXNlIiwiY29uY2F0Iiwiam9pbiIsImhhbmRsZUNsaWNrIiwiZXZlbnQiLCJwcmV2ZW50RGVmYXVsdCIsInNldENvbW1hbmRTdGF0ZSIsImhhbmRsZVNlbGVjdGlvbiIsImNvbW1hbmRTdGF0ZSIsInVuZGVmaW5lZCIsIm91dGVyIiwibW9kaWZpZXIiLCJjaGVjayIsIml0IiwiTWF0aCIsIm1vZHVsZSIsImdsb2JhbFRoaXMiLCJ3aW5kb3ciLCJzZWxmIiwiZ2xvYmFsIiwidGhpcyIsIkZ1bmN0aW9uIiwiZXhlYyIsImVycm9yIiwiZmFpbHMiLCJyZXF1aXJlIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJiaW5kIiwiaGFzT3duUHJvcGVydHkiLCJOQVRJVkVfQklORCIsIkZ1bmN0aW9uUHJvdG90eXBlIiwicHJvdG90eXBlIiwiY2FsbCIsInVuY3VycnlUaGlzV2l0aEJpbmQiLCJmbiIsImFwcGx5IiwiYXJndW1lbnRzIiwiZG9jdW1lbnRBbGwiLCJhbGwiLCJJU19IVE1MRERBIiwiJGRvY3VtZW50QWxsIiwiYXJndW1lbnQiLCJpc051bGxPclVuZGVmaW5lZCIsIiRUeXBlRXJyb3IiLCJUeXBlRXJyb3IiLCJyZXF1aXJlT2JqZWN0Q29lcmNpYmxlIiwiJE9iamVjdCIsInVuY3VycnlUaGlzIiwidG9PYmplY3QiLCJoYXNPd24iLCJERVNDUklQVE9SUyIsImdldERlc2NyaXB0b3IiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJFWElTVFMiLCJQUk9QRVIiLCJzb21ldGhpbmciLCJDT05GSUdVUkFCTEUiLCJjb25maWd1cmFibGUiLCJ2YWx1ZSIsIndyaXRhYmxlIiwiZGVmaW5lR2xvYmFsUHJvcGVydHkiLCJTSEFSRUQiLCJzdG9yZSIsImlzQ2FsbGFibGUiLCJmdW5jdGlvblRvU3RyaW5nIiwidG9TdHJpbmciLCJpbnNwZWN0U291cmNlIiwiV2Vha01hcCIsIlN0cmluZyIsImlzT2JqZWN0IiwiYSIsIiRTdHJpbmciLCJhRnVuY3Rpb24iLCJuYW1lc3BhY2UiLCJtZXRob2QiLCJpc1Byb3RvdHlwZU9mIiwidXNlckFnZW50IiwicHJvY2VzcyIsIkRlbm8iLCJ2ZXJzaW9ucyIsInZlcnNpb24iLCJ2OCIsIlY4X1ZFUlNJT04iLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJzeW1ib2wiLCJTeW1ib2wiLCJzaGFtIiwiTkFUSVZFX1NZTUJPTCIsIml0ZXJhdG9yIiwiZ2V0QnVpbHRJbiIsIlVTRV9TWU1CT0xfQVNfVUlEIiwiJFN5bWJvbCIsInRyeVRvU3RyaW5nIiwiYUNhbGxhYmxlIiwiViIsIlAiLCJmdW5jIiwiaW5wdXQiLCJwcmVmIiwidmFsIiwidmFsdWVPZiIsIm1vZGUiLCJjb3B5cmlnaHQiLCJsaWNlbnNlIiwic291cmNlIiwiaWQiLCJwb3N0Zml4IiwicmFuZG9tIiwic2hhcmVkIiwidWlkIiwiV2VsbEtub3duU3ltYm9sc1N0b3JlIiwiY3JlYXRlV2VsbEtub3duU3ltYm9sIiwid2l0aG91dFNldHRlciIsImlzU3ltYm9sIiwiZ2V0TWV0aG9kIiwib3JkaW5hcnlUb1ByaW1pdGl2ZSIsIndlbGxLbm93blN5bWJvbCIsIlRPX1BSSU1JVElWRSIsImV4b3RpY1RvUHJpbSIsInJlc3VsdCIsInRvUHJpbWl0aXZlIiwiSUU4X0RPTV9ERUZJTkUiLCJWOF9QUk9UT1RZUEVfREVGSU5FX0JVRyIsImFuT2JqZWN0IiwidG9Qcm9wZXJ0eUtleSIsIiRkZWZpbmVQcm9wZXJ0eSIsIiRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJFTlVNRVJBQkxFIiwiV1JJVEFCTEUiLCJleHBvcnRzIiwiTyIsIkF0dHJpYnV0ZXMiLCJjdXJyZW50IiwiZW51bWVyYWJsZSIsImJpdG1hcCIsImRlZmluZVByb3BlcnR5TW9kdWxlIiwiY3JlYXRlUHJvcGVydHlEZXNjcmlwdG9yIiwib2JqZWN0IiwiZiIsIk5BVElWRV9XRUFLX01BUCIsImNyZWF0ZU5vbkVudW1lcmFibGVQcm9wZXJ0eSIsInNoYXJlZEtleSIsIk9CSkVDVF9BTFJFQURZX0lOSVRJQUxJWkVEIiwic2V0IiwiaGFzIiwiZW5mb3JjZSIsImdldHRlckZvciIsIlRZUEUiLCJ0eXBlIiwibWV0YWRhdGEiLCJmYWNhZGUiLCJTVEFURSIsIkNPTkZJR1VSQUJMRV9GVU5DVElPTl9OQU1FIiwiSW50ZXJuYWxTdGF0ZU1vZHVsZSIsImVuZm9yY2VJbnRlcm5hbFN0YXRlIiwiZ2V0SW50ZXJuYWxTdGF0ZSIsInN0cmluZ1NsaWNlIiwic2xpY2UiLCJyZXBsYWNlIiwiQ09ORklHVVJBQkxFX0xFTkdUSCIsIlRFTVBMQVRFIiwibWFrZUJ1aWx0SW4iLCJvcHRpb25zIiwiZ2V0dGVyIiwic2V0dGVyIiwiYXJpdHkiLCJ0YXJnZXQiLCJkZXNjcmlwdG9yIiwidGhhdCIsImhhc0luZGljZXMiLCJpZ25vcmVDYXNlIiwibXVsdGlsaW5lIiwiZG90QWxsIiwidW5pY29kZSIsInVuaWNvZGVTZXRzIiwic3RpY2t5IiwiZGVmaW5lQnVpbHRJbkFjY2Vzc29yIiwicmVnRXhwRmxhZ3MiLCJSZWdFeHAiLCJSZWdFeHBQcm90b3R5cGUiLCJGT1JDRUQiLCJJTkRJQ0VTX1NVUFBPUlQiLCJjYWxscyIsImV4cGVjdGVkIiwiYWRkR2V0dGVyIiwiY2hyIiwicGFpcnMiLCJyZXBsYWNlbWVudHMiLCJBU0NJSVB1bmN0dWF0aW9uIiwiTm90VHJpZ2dlckNoYXIiLCJTY2hlbWUiLCJFbWFpbCIsIkhUTUxPcGVuVGFnIiwiSFRNTENsb3NlVGFnIiwiSFRNTFRhZ05hbWUiLCJIVE1MQ29tbWVudCIsIkhUTUxQSSIsIkhUTUxEZWNsYXJhdGlvbiIsIkhUTUxDREFUQSIsIkhUTUxBdHRyaWJ1dGUiLCJIVE1MQXR0VmFsdWUiLCJLbm93blRhZyIsInB1bmN0dWF0aW9uTGVhZGluZyIsInB1bmN0dWF0aW9uVHJhaWxpbmciLCJsaW5lR3JhbW1hciIsIlRNSDEiLCJyZWdleHAiLCJyZXBsYWNlbWVudCIsIlRNSDIiLCJUTUgzIiwiVE1INCIsIlRNSDUiLCJUTUg2IiwiVE1CbG9ja3F1b3RlIiwiVE1Db2RlRmVuY2VCYWNrdGlja09wZW4iLCJUTUNvZGVGZW5jZVRpbGRlT3BlbiIsIlRNQ29kZUZlbmNlQmFja3RpY2tDbG9zZSIsIlRNQ29kZUZlbmNlVGlsZGVDbG9zZSIsIlRNQmxhbmtMaW5lIiwiVE1TZXRleHRIMU1hcmtlciIsIlRNU2V0ZXh0SDJNYXJrZXIiLCJUTUhSIiwiVE1VTCIsIlRNT0wiLCJUTUluZGVudGVkQ29kZSIsIlRNTGlua1JlZmVyZW5jZURlZmluaXRpb24iLCJsYWJlbFBsYWNlaG9sZGVyIiwiaHRtbEJsb2NrR3JhbW1hciIsInN0YXJ0IiwiZW5kIiwicGFyYUludGVycnVwdCIsImlubGluZUdyYW1tYXIiLCJlc2NhcGUiLCJhdXRvbGluayIsImh0bWwiLCJsaW5rT3BlbiIsImltYWdlT3BlbiIsImxpbmtMYWJlbCIsImRlZmF1bHQiLCJyZXBsYWNlbWVudFJlZ2V4cCIsImlubGluZVJ1bGVzIiwicnVsZSIsInJlIiwic3RyaW5nIiwiZmxhZ3MiLCJodG1sZXNjYXBlIiwicHJlIiwicG9zdCIsInVuc2V0IiwicHJlUGF0dGVybiIsInBvc3RQYXR0ZXJuIiwicGF0dGVybiIsImgzIiwiaDQiLCJoNSIsImg2IiwiRWRpdG9yIiwidGV4dGFyZWEiLCJsaW5lcyIsImxpbmVFbGVtZW50cyIsImxpbmVUeXBlcyIsImxpbmVDYXB0dXJlcyIsImxpbmVSZXBsYWNlbWVudHMiLCJsaW5rTGFiZWxzIiwibGluZURpcnR5IiwibGFzdENvbW1hbmRTdGF0ZSIsImxpc3RlbmVycyIsImNoYW5nZSIsInNlbGVjdGlvbiIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwicGFyZW50Tm9kZSIsInN0eWxlIiwiZGlzcGxheSIsImNyZWF0ZUVkaXRvckVsZW1lbnQiLCJzZXRDb250ZW50IiwiY29udGVudCIsImNvbnRlbnRFZGl0YWJsZSIsIndoaXRlU3BhY2UiLCJ3ZWJraXRVc2VyTW9kaWZ5IiwibmV4dFNpYmxpbmciLCJpbnNlcnRCZWZvcmUiLCJoYW5kbGVJbnB1dEV2ZW50IiwiaGFuZGxlU2VsZWN0aW9uQ2hhbmdlRXZlbnQiLCJoYW5kbGVQYXN0ZSIsImNoaWxkTm9kZXMiLCJmaXJzdENoaWxkIiwicmVtb3ZlQ2hpbGQiLCJsaW5lTnVtIiwibGUiLCJBcnJheSIsInVwZGF0ZUZvcm1hdHRpbmciLCJmaXJlQ2hhbmdlIiwiZ2V0Q29udGVudCIsInVwZGF0ZUxpbmVUeXBlcyIsInVwZGF0ZUxpbmtMYWJlbHMiLCJhcHBseUxpbmVUeXBlcyIsImwiLCJjYXB0dXJlIiwic3RyIiwicDEiLCJwMiIsInByb2Nlc3NJbmxpbmVTdHlsZXMiLCJjb250ZW50SFRNTCIsInJlbW92ZUF0dHJpYnV0ZSIsImRhdGFzZXQiLCJjb2RlQmxvY2tUeXBlIiwiY29kZUJsb2NrU2VxTGVuZ3RoIiwiaHRtbEJsb2NrIiwibGluZVR5cGUiLCJsaW5lQ2FwdHVyZSIsImxpbmVSZXBsYWNlbWVudCIsImdyb3VwcyIsImh0bWxCbG9ja1R5cGUiLCJoZWFkaW5nTGluZSIsImhlYWRpbmdMaW5lVHlwZSIsInVwZGF0ZUxpbmVDb250ZW50c0FuZEZvcm1hdHRpbmciLCJjbGVhckRpcnR5RmxhZyIsInVwZGF0ZUxpbmVDb250ZW50cyIsInBhcnNlTGlua09ySW1hZ2UiLCJvcmlnaW5hbFN0cmluZyIsImlzSW1hZ2UiLCJ0ZXh0T2Zmc2V0Iiwib3BlbmVyIiwic3Vic3RyIiwiY3VycmVudE9mZnNldCIsImJyYWNrZXRMZXZlbCIsImxpbmtUZXh0IiwibGlua1JlZiIsImxpbmtEZXRhaWxzIiwidGV4dE91dGVyIiwiY2FwIiwibmV4dENoYXIiLCJ0cmltIiwicGFyZW50aGVzaXNMZXZlbCIsImlubGluZU91dGVyIiwidmFsaWQiLCJsYWJlbCIsIm91dHB1dCIsImNoYXJDb3VudCIsInByb2Nlc3NlZCIsInN0YWNrIiwib2Zmc2V0IiwicG90ZW50aWFsTGluayIsInBvdGVudGlhbEltYWdlIiwiZGVsaW1Db3VudCIsImRlbGltU3RyaW5nIiwiY3VycmVudERlbGltaXRlciIsInByZWNlZGluZyIsImZvbGxvd2luZyIsInB1bmN0dWF0aW9uRm9sbG93cyIsInB1bmN0dWF0aW9uUHJlY2VkZXMiLCJ3aGl0ZXNwYWNlRm9sbG93cyIsIndoaXRlc3BhY2VQcmVjZWRlcyIsImNhbk9wZW4iLCJjYW5DbG9zZSIsInN0YWNrUG9pbnRlciIsImRlbGltaXRlciIsImVudHJ5IiwicG9wIiwiY291bnQiLCJjb25zdW1lZCIsImxpbmVEZWx0YSIsImNoaWxkRWxlbWVudENvdW50IiwiZmlyc3RDaGFuZ2VkTGluZSIsInRleHRDb250ZW50IiwibGFzdENoYW5nZWRMaW5lIiwibGluZXNUb0RlbGV0ZSIsImxpbmVzVG9BZGQiLCJzcGxpY2VMaW5lcyIsImxpbmUiLCJjdCIsInByb2Nlc3NOZXdQYXJhZ3JhcGgiLCJzZWwiLCJjb250aW51YWJsZVR5cGUiLCJjaGVja0xpbmUiLCJjb2wiLCJyb3ciLCJwYXJzZUludCIsImdldFNlbGVjdGlvbiIsImdldEFuY2hvciIsInN0YXJ0Tm9kZSIsImFuY2hvck5vZGUiLCJmb2N1c05vZGUiLCJhbmNob3JPZmZzZXQiLCJmb2N1c09mZnNldCIsImNvbXB1dGVDb2x1bW4iLCJub2RlIiwicHJldmlvdXNTaWJsaW5nIiwibm9kZVR5cGUiLCJOb2RlIiwiVEVYVF9OT0RFIiwiY29tcHV0ZU5vZGVBbmRPZmZzZXQiLCJiaW5kUmlnaHQiLCJjaGlsZHJlbkNvbXBsZXRlIiwicnYiLCJub2RlVmFsdWUiLCJzZXRTZWxlY3Rpb24iLCJyYW5nZSIsImNyZWF0ZVJhbmdlIiwic2V0U3RhcnQiLCJzZXRFbmQiLCJ3aW5kb3dTZWxlY3Rpb24iLCJyZW1vdmVBbGxSYW5nZXMiLCJhZGRSYW5nZSIsImlucHV0VHlwZSIsImZpeE5vZGVIaWVyYXJjaHkiLCJvcmlnaW5hbENoaWxkcmVuIiwiZnJvbSIsInJlcGxhY2VDaGlsZCIsImNoaWxkIiwicGFyZW50IiwiX2xlbiIsIm5ld0NoaWxkcmVuIiwiX2tleSIsImZvckVhY2giLCJuZXdDaGlsZCIsIkVMRU1FTlRfTk9ERSIsImRpdldyYXBwZXIiLCJncmFuZENoaWxkcmVuIiwic29tZSIsImdyYW5kQ2hpbGQiLCJmaXJlU2VsZWN0aW9uIiwic3RhcnRMaW5lIiwibGluZXNUb0luc2VydCIsImFkanVzdExpbmVFbGVtZW50cyIsImluc2VydGVkQmxhbmsiLCJpbnNlcnRlZERpcnR5Iiwic3BsaWNlIiwidGV4dCIsIm9yaWdpbmFsRXZlbnQiLCJjbGlwYm9hcmREYXRhIiwiZ2V0RGF0YSIsImJlZ2lubmluZyIsImluc2VydGVkTGluZXMiLCJsaW5lQmVmb3JlIiwibGluZUVuZCIsImVuZENvbFBvcyIsImNvbXB1dGVDb21tb25BbmNlc3RvciIsIm5vZGUxIiwibm9kZTIiLCJhbmNlc3RyeSIsInVuc2hpZnQiLCJhbmNlc3RyeTEiLCJhbmNlc3RyeTIiLCJjb21wdXRlRW5jbG9zaW5nTWFya3VwTm9kZSIsImluY2x1ZGVzIiwiZ2V0Q29tbWFuZFN0YXRlIiwiY21kIiwibWFya3VwTm9kZSIsInN0YXJ0Q29sIiwibGVuIiwibGVmdCIsIm1pZCIsInJpZ2h0IiwiZW5kQ29sIiwibGVhZGluZyIsInRyYWlsaW5nIiwiaXNDb2xsYXBzZWQiLCJhbmNlc3RvciIsInRvZ2dsZUNvbW1hbmRTdGF0ZSIsImxpc3RlbmVyIiwibGluZXNEaXJ0eSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0VBQUEsTUFBTUEsR0FBRyxHQUFHO0VBQ1ZDLEVBQUFBLFVBQVUsRUFBRyxDQUE4aUIsNmlCQUFBLENBQUE7RUFDM2pCQyxFQUFBQSxJQUFJLEVBQUcsQ0FBZ1csK1ZBQUEsQ0FBQTtFQUN2V0MsRUFBQUEsZ0JBQWdCLEVBQUcsQ0FBdU8sc09BQUEsQ0FBQTtFQUMxUEMsRUFBQUEs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
|